diff --git a/app/bootstrap.php b/app/bootstrap.php
index ec60a1708dacc3d2238960e5b1c9e7c0da05cc92..c8e676cb69cffd5cf32de8f12f9f83987cc6619a 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -11,14 +11,14 @@ error_reporting(E_ALL);
 #ini_set('display_errors', 1);
 
 /* PHP version validation */
-if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50700 || PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) {
+if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID >= 50605 && PHP_VERSION_ID < 50700 || PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) {
     if (PHP_SAPI == 'cli') {
-        echo 'Magento supports PHP 5.6, 7.0.2, 7.0.4, and 7.0.6 or later. ' .
+        echo 'Magento supports PHP 5.6.5, 7.0.2, 7.0.4, and 7.0.6 or later. ' .
             'Please read http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html';
     } else {
         echo <<<HTML
 <div style="font:12px/1.35em arial, helvetica, sans-serif;">
-    <p>Magento supports PHP 5.6, 7.0.2, 7.0.4, and 7.0.6 or later. Please read
+    <p>Magento supports PHP 5.6.5, 7.0.2, 7.0.4, and 7.0.6 or later. Please read
     <a target="_blank" href="http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html">
     Magento System Requirements</a>.
 </div>
@@ -35,6 +35,17 @@ $umaskFile = BP . '/magento_umask';
 $mask = file_exists($umaskFile) ? octdec(file_get_contents($umaskFile)) : 002;
 umask($mask);
 
+if (empty($_SERVER['ENABLE_IIS_REWRITES']) || ($_SERVER['ENABLE_IIS_REWRITES'] != 1)) {
+    /*
+     * Unset headers used by IIS URL rewrites.
+     */
+    unset($_SERVER['HTTP_X_REWRITE_URL']);
+    unset($_SERVER['HTTP_X_ORIGINAL_URL']);
+    unset($_SERVER['IIS_WasUrlRewritten']);
+    unset($_SERVER['UNENCODED_URL']);
+    unset($_SERVER['ORIG_PATH_INFO']);
+}
+
 if (!empty($_SERVER['MAGE_PROFILER'])
     && isset($_SERVER['HTTP_ACCEPT'])
     && strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false
diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json
index 527268df36b41efe5078528138342a03fa33745d..09d8ce41bbb03607a2f8cd16831454c8565a5204 100644
--- a/app/code/Magento/AdminNotification/composer.json
+++ b/app/code/Magento/AdminNotification/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-admin-notification",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-media-storage": "100.2.*",
diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json
index 65ea7524dffff5bb778aaf5ec7658302072cfaf9..2fc465fa3c3dfd7a51abdd713f0c5c6dfd6843c6 100644
--- a/app/code/Magento/AdvancedPricingImportExport/composer.json
+++ b/app/code/Magento/AdvancedPricingImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-advanced-pricing-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-inventory": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json
index 0ca367d4854dfe5c35811d15aee4d718c0a4edb7..af88e8376dc756cb9e1f6180848df41e6fd8b5f3 100644
--- a/app/code/Magento/Authorization/composer.json
+++ b/app/code/Magento/Authorization/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-authorization",
     "description": "Authorization module provides access to Magento ACL functionality.",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json
index 0c9e9641b6076850310edd75a2a4ea5ed3ccd094..b93cb6688f56d826a8d981518612897aae6f1ac8 100644
--- a/app/code/Magento/Authorizenet/composer.json
+++ b/app/code/Magento/Authorizenet/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-authorizenet",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-sales": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-quote": "100.2.*",
diff --git a/app/code/Magento/Authorizenet/i18n/en_US.csv b/app/code/Magento/Authorizenet/i18n/en_US.csv
index 7183c706dc0a2ed264e7e73d0e11743cbf450b40..45025304c4e4423d77f60e1e26af4f2da6a8a569 100644
--- a/app/code/Magento/Authorizenet/i18n/en_US.csv
+++ b/app/code/Magento/Authorizenet/i18n/en_US.csv
@@ -64,3 +64,4 @@ Debug,Debug
 "Minimum Order Total","Minimum Order Total"
 "Maximum Order Total","Maximum Order Total"
 "Sort Order","Sort Order"
+"Sorry, but something went wrong. Please contact the seller.","Sorry, but something went wrong. Please contact the seller."
diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
index cd05960c17633844fb1c57e92794066186a45965..86ec8e0c3922109170e19f4191fdbf7e27dc43d5 100644
--- a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
+++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
@@ -5,15 +5,16 @@
 define(
     [
         'jquery',
-        'Magento_Payment/js/view/payment/iframe'
+        'Magento_Payment/js/view/payment/iframe',
+        'mage/translate'
     ],
-    function ($, Component) {
+    function ($, Component, $t) {
         'use strict';
 
         return Component.extend({
             defaults: {
                 template: 'Magento_Authorizenet/payment/authorizenet-directpost',
-                timeoutMessage: 'Sorry, but something went wrong. Please contact the seller.'
+                timeoutMessage: $t('Sorry, but something went wrong. Please contact the seller.')
             },
             placeOrderHandler: null,
             validateHandler: null,
diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json
index 7d428636a1f45e23d81879c99baaeef6744518fc..5cfe6955b46bb99f6dd8c76cd58e3ba9bb6f28ad 100644
--- a/app/code/Magento/Backend/composer.json
+++ b/app/code/Magento/Backend/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-backend",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-directory": "100.2.*",
         "magento/module-developer": "100.2.*",
diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json
index 21ed6f1780a41348c5bb26556c14fcaa02c08770..ee05d6726db4c3bea7460893242d546a511fe0cc 100644
--- a/app/code/Magento/Backup/composer.json
+++ b/app/code/Magento/Backup/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-backup",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-cron": "100.2.*",
diff --git a/app/code/Magento/Braintree/composer.json b/app/code/Magento/Braintree/composer.json
index 3b77e208837a4a4341baabbae615b7e35b266500..91cacf6add2b891dc4ad759cb6b1e9a6990cb397 100644
--- a/app/code/Magento/Braintree/composer.json
+++ b/app/code/Magento/Braintree/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-braintree",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/magento-composer-installer": "*",
         "magento/module-config": "100.2.*",
diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
index 184260c39e954d1c5a1fd6d45b34f09fcab9daa7..075a1fdaf1fc118f42832fa438762715420a585a 100644
--- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
+++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
@@ -98,7 +98,6 @@ define([
             quote.totals.subscribe(function () {
                 if (self.grandTotalAmount !== quote.totals()['base_grand_total']) {
                     self.grandTotalAmount = quote.totals()['base_grand_total'];
-                    self.reInitPayPal();
                 }
             });
 
diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
index 50a3caaf68b3bd39ce1458e4883b4c1dd35c0525..538c80d9b1cf27af4ba14c911b0d0a6913c403c7 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
@@ -268,15 +268,12 @@ class BundlePanel extends AbstractModifier
             'arguments' => [
                 'data' => [
                     'config' => [
-                        'componentType' => 'dynamicRows',
+                        'componentType' => Container::NAME,
+                        'component' => 'Magento_Bundle/js/components/bundle-dynamic-rows',
                         'template' => 'ui/dynamic-rows/templates/collapsible',
-                        'label' => '',
                         'additionalClasses' => 'admin__field-wide',
-                        'collapsibleHeader' => true,
-                        'columnsHeader' => false,
-                        'deleteProperty' => false,
-                        'addButton' => false,
                         'dataScope' => 'data.bundle_options',
+                        'bundleSelectionsName' => 'product_bundle_container.bundle_selections'
                     ],
                 ],
             ],
@@ -318,14 +315,11 @@ class BundlePanel extends AbstractModifier
                                     'arguments' => [
                                         'data' => [
                                             'config' => [
-                                                'componentType' => DynamicRows::NAME,
-                                                'label' => '',
+                                                'componentType' => Container::NAME,
+                                                'component' => 'Magento_Bundle/js/components/bundle-dynamic-rows-grid',
                                                 'sortOrder' => 50,
                                                 'additionalClasses' => 'admin__field-wide',
-                                                'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid',
                                                 'template' => 'ui/dynamic-rows/templates/default',
-                                                'columnsHeader' => false,
-                                                'columnsHeaderAfterRender' => true,
                                                 'provider' => 'product_form.product_form_data_source',
                                                 'dataProvider' => '${ $.dataScope }' . '.bundle_button_proxy',
                                                 'identificationDRProperty' => 'product_id',
@@ -343,8 +337,7 @@ class BundlePanel extends AbstractModifier
                                                     'selection_qty' => '',
                                                 ],
                                                 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'],
-                                                'source' => 'product',
-                                                'addButton' => false,
+                                                'source' => 'product'
                                             ],
                                         ],
                                     ],
@@ -561,7 +554,7 @@ class BundlePanel extends AbstractModifier
                         'componentType' => Container::NAME,
                         'isTemplate' => true,
                         'component' => 'Magento_Ui/js/dynamic-rows/record',
-                        'is_collection' => true,
+                        'is_collection' => true
                     ],
                 ],
             ],
diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json
index ab587044476db47c0a824cfdb130988f22591971..24756bdf950a7a42431e31cbc08090ca0141eb27 100644
--- a/app/code/Magento/Bundle/composer.json
+++ b/app/code/Magento/Bundle/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-bundle",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-tax": "100.2.*",
diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js
new file mode 100644
index 0000000000000000000000000000000000000000..e9a924e1cffe696688fed502bc715347c8afb8d2
--- /dev/null
+++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js
@@ -0,0 +1,59 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'underscore',
+    'Magento_Ui/js/dynamic-rows/dynamic-rows-grid'
+], function (_, dynamicRowsGrid) {
+    'use strict';
+
+    return dynamicRowsGrid.extend({
+        defaults: {
+            label: '',
+            columnsHeader: false,
+            columnsHeaderAfterRender: true,
+            addButton: false
+        },
+
+        /**
+         * Initialize elements from grid
+         *
+         * @param {Array} data
+         *
+         * @returns {Object} Chainable.
+         */
+        initElements: function (data) {
+            var newData = this.getNewData(data),
+                recordIndex;
+
+            this.parsePagesData(data);
+
+            if (newData.length) {
+                if (this.insertData().length) {
+                    recordIndex = data.length - newData.length - 1;
+
+                    _.each(newData, function (newRecord) {
+                        this.processingAddChild(newRecord, ++recordIndex, newRecord[this.identificationProperty]);
+                    }, this);
+                }
+            }
+
+            return this;
+        },
+
+        /**
+         * Mapping value from grid
+         *
+         * @param {Array} data
+         */
+        mappingValue: function (data) {
+            if (_.isEmpty(data)) {
+                return;
+            }
+
+            this._super();
+        }
+    });
+});
diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js
new file mode 100644
index 0000000000000000000000000000000000000000..b36d8003a399fb4af88d3e3cfab34559e2e80bea
--- /dev/null
+++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js
@@ -0,0 +1,98 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'underscore',
+    'mageUtils',
+    'uiRegistry',
+    'Magento_Ui/js/dynamic-rows/dynamic-rows'
+], function (_, utils, registry, dynamicRows) {
+    'use strict';
+
+    return dynamicRows.extend({
+        defaults: {
+            label: '',
+            collapsibleHeader: true,
+            columnsHeader: false,
+            deleteProperty: false,
+            addButton: false
+        },
+
+        /**
+         * Set new data to dataSource,
+         * delete element
+         *
+         * @param {Array} data - record data
+         */
+        _updateData: function (data) {
+            var elems = _.clone(this.elems()),
+                path,
+                dataArr,
+                optionBaseData;
+
+            dataArr = this.recordData.splice(this.startIndex, this.recordData().length - this.startIndex);
+            dataArr.splice(0, this.pageSize);
+            elems = _.sortBy(this.elems(), function (elem) {
+                return ~~elem.index;
+            });
+
+            data.concat(dataArr).forEach(function (rec, idx) {
+                if (elems[idx]) {
+                    elems[idx].recordId = rec[this.identificationProperty];
+                }
+
+                if (!rec.position) {
+                    rec.position = this.maxPosition;
+                    this.setMaxPosition();
+                }
+
+                path = this.dataScope + '.' + this.index + '.' + (this.startIndex + idx);
+                optionBaseData = _.pick(rec, function (value) {
+                    return !_.isObject(value);
+                });
+                this.source.set(path, optionBaseData);
+                this.source.set(path + '.bundle_button_proxy', []);
+                this.source.set(path + '.bundle_selections', []);
+                this.removeBundleItemsFromOption(idx);
+                _.each(rec['bundle_selections'], function (obj, index) {
+                    this.source.set(path + '.bundle_button_proxy' + '.' + index, rec['bundle_button_proxy'][index]);
+                    this.source.set(path + '.bundle_selections' + '.' + index, obj);
+                }, this);
+            }, this);
+
+            this.elems(elems);
+        },
+
+        /**
+         *  Removes nested dynamic-rows-grid rendered records from option
+         *
+         * @param {Number|String} index - element index
+         */
+        removeBundleItemsFromOption: function (index) {
+            var bundleSelections = registry.get(this.name + '.' + index + '.' + this.bundleSelectionsName),
+                bundleSelectionsLength = (bundleSelections.elems() || []).length,
+                i;
+
+            if (bundleSelectionsLength) {
+                for (i = 0; i < bundleSelectionsLength; i++) {
+                    bundleSelections.elems()[0].destroy();
+                }
+            }
+        },
+
+        /**
+        * {@inheritdoc}
+        */
+        processingAddChild: function (ctx, index, prop) {
+            var recordIds = _.map(this.recordData(), function (rec) {
+                return parseInt(rec['record_id'], 10);
+            }),
+            maxRecordId = _.max(recordIds);
+
+            prop = maxRecordId > -1 ? maxRecordId + 1 : prop;
+            this._super(ctx, index, prop);
+        }
+    });
+});
diff --git a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
index 1a76acf17475670674c064c8384d628b87d924a7..607ac6e03a75a8beeb644c84a11400eee09012d9 100644
--- a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
+++ b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
@@ -295,6 +295,10 @@ define([
             case 'hidden':
                 optionHash = 'bundle-option-' + optionName + '##' + optionValue;
                 optionQty = optionConfig[optionValue].qty || 0;
+                canQtyCustomize = optionConfig[optionValue].customQty === '1';
+                qtyField = element.data('qtyField');
+                qtyField.data('option', element);
+                toggleQtyField(qtyField, optionQty, optionId, optionValue, canQtyCustomize);
                 tempChanges = utils.deepClone(optionConfig[optionValue].prices);
                 tempChanges = applyTierPrice(tempChanges, optionQty, optionConfig);
                 tempChanges = applyQty(tempChanges, optionQty);
diff --git a/app/code/Magento/BundleImportExport/composer.json b/app/code/Magento/BundleImportExport/composer.json
index 3d7900d98287c1eba32a5badd2d5b2fdc1857f25..2f5e3afdbff86ded9c88161ebea832c29b37f229 100644
--- a/app/code/Magento/BundleImportExport/composer.json
+++ b/app/code/Magento/BundleImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-bundle-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-import-export": "100.2.*",
         "magento/module-catalog-import-export": "100.2.*",
diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json
index cafccadb41ad869ff87ee8eb154c747f569a4c79..c886e069b66e37d3b0c7a12af377a250cfc75192 100644
--- a/app/code/Magento/CacheInvalidate/composer.json
+++ b/app/code/Magento/CacheInvalidate/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-cache-invalidate",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-page-cache": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index 9d0ce3db92aa402a7c247fed21185953c4707342..45ecd32464e9cc3f647264420961d6848b0445e9 100644
--- a/app/code/Magento/Captcha/composer.json
+++ b/app/code/Magento/Captcha/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-captcha",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-customer": "100.2.*",
         "magento/module-checkout": "100.2.*",
diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
index d9702c5073fb653c132c89d761e9ddf14faa34c1..f1bb89d4424f7f4436abea0c137a0457a0ad13c8 100644
--- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
+++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
@@ -124,7 +124,7 @@ class AbstractProduct extends \Magento\Framework\View\Element\Template
      */
     public function getAddToCartUrl($product, $additional = [])
     {
-        if ($product->getTypeInstance()->hasRequiredOptions($product)) {
+        if (!$product->getTypeInstance()->isPossibleBuyFromList($product)) {
             if (!isset($additional['_escape'])) {
                 $additional['_escape'] = true;
             }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
index 4375092591d194962b108e2ba0351b1a03fa7e5c..40516e55e930c4021699dad26b43a4e83fe26a80 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
@@ -281,7 +281,7 @@ class FlatTableBuilder
             if (!empty($columnValueNames)) {
                 $select->joinLeft(
                     $temporaryValueTableName,
-                    sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName),
+                    sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryValueTableName),
                     $columnValueNames
                 );
                 $allColumns = array_merge($allColumns, $columnValueNames);
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 9e9f18e0113717ad6853ea5d4512661a897e926c..c913c82de1acdecbf3328c37fe7529dfbab193ba 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -22,7 +22,6 @@ use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionFactory;
  * @method Product setHasError(bool $value)
  * @method \Magento\Catalog\Model\ResourceModel\Product getResource()
  * @method null|bool getHasError()
- * @method Product setAssociatedProductIds(array $productIds)
  * @method array getAssociatedProductIds()
  * @method Product setNewVariationsAttributeSetId(int $value)
  * @method int getNewVariationsAttributeSetId()
@@ -2614,4 +2613,16 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         }
         return $this->mediaGalleryProcessor;
     }
+
+    /**
+     * Set the associated products
+     *
+     * @param array $productIds
+     * @return $this
+     */
+    public function setAssociatedProductIds(array $productIds)
+    {
+        $this->getExtensionAttributes()->setConfigurableProductLinks($productIds);
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php
index 7d8b464db3b34cd116d2c8c7adae86113040e67f..34e1ad30ad434add33508bb63c7b8b1a78ddc9fb 100644
--- a/app/code/Magento/Catalog/Model/Product/Image.php
+++ b/app/code/Magento/Catalog/Model/Product/Image.php
@@ -498,8 +498,7 @@ class Image extends \Magento\Framework\Model\AbstractModel
         $path = [
             $this->_catalogProductMediaConfig->getBaseMediaPath(),
             'cache',
-            $this->_storeManager->getStore()->getId(),
-            $path[] = $this->getDestinationSubdir(),
+            $this->getDestinationSubdir(),
         ];
         if (!empty($this->_width) || !empty($this->_height)) {
             $path[] = "{$this->_width}x{$this->_height}";
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index 6de6ea6c6c6bca8029aee2be5749d555690d48c8..11b8d03fc7ee5cc23dd627e65ad9651a5b243b7d 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -1092,4 +1092,15 @@ abstract class AbstractType
     {
         return [];
     }
+
+    /**
+     * Check if product can be potentially buyed from the category page or some other list
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return bool
+     */
+    public function isPossibleBuyFromList($product)
+    {
+        return !$this->hasRequiredOptions($product);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index 4385c8add37aef25dc52a888d2ff839b49e734db..27796e1cda2a167848c2a3b8fb0d096f40c172d6 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -640,6 +640,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
 
         $collection->load();
 
+        $collection->addCategoryIds();
         $searchResult = $this->searchResultsFactory->create();
         $searchResult->setSearchCriteria($searchCriteria);
         $searchResult->setItems($collection->getItems());
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php
index d9612f18c9111df4634e18cb8b9abf523643f2e5..432bc696ef7cecd822b5168e7da70a9ed1cd4fc5 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php
@@ -197,7 +197,7 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\
         )->joinLeft(
             ['e' => $this->getTable('catalog_product_entity')],
             'e.' . $linkField .' = l.parent_id',
-            ['e.entity_id as parent_id']
+            []
         )->join(
             ['cs' => $this->getTable('store')],
             '',
@@ -205,9 +205,17 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\
         )->join(
             ['i' => $idxTable],
             'l.child_id = i.entity_id AND cs.store_id = i.store_id',
-            ['attribute_id', 'store_id', 'value']
+            []
         )->group(
-            ['parent_id', 'i.attribute_id', 'i.store_id', 'i.value']
+            ['parent_id', 'i.attribute_id', 'i.store_id', 'i.value', 'l.child_id']
+        )->columns(
+            [
+                'parent_id' => 'e.entity_id',
+                'attribute_id' => 'i.attribute_id',
+                'store_id' => 'i.store_id',
+                'value' => 'i.value',
+                'source_id' => 'l.child_id'
+            ]
         );
         if ($parentIds !== null) {
             $select->where('e.entity_id IN(?)', $parentIds);
@@ -222,7 +230,7 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\
                 'select' => $select,
                 'entity_field' => new \Zend_Db_Expr('l.parent_id'),
                 'website_field' => new \Zend_Db_Expr('cs.website_id'),
-                'store_field' => new \Zend_Db_Expr('cs.store_id')
+                'store_field' => new \Zend_Db_Expr('cs.store_id'),
             ]
         );
 
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php
index e8d9889e68d59384e74cfb3fc0491a2edb8f3edb..a45d4f13a1a9a811fffb6269bf94575675c60d80 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php
@@ -85,6 +85,7 @@ class Decimal extends AbstractEav
                 'pdd.attribute_id',
                 'cs.store_id',
                 'value' => $productValueExpression,
+                'source_id' => 'cpe.entity_id',
             ]
         );
 
@@ -116,7 +117,7 @@ class Decimal extends AbstractEav
                 'select' => $select,
                 'entity_field' => new \Zend_Db_Expr('cpe.entity_id'),
                 'website_field' => new \Zend_Db_Expr('cs.website_id'),
-                'store_field' => new \Zend_Db_Expr('cs.store_id')
+                'store_field' => new \Zend_Db_Expr('cs.store_id'),
             ]
         );
 
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php
index c4eda1c987192acb5dd7e5ce003fe8b9cff0bdc6..1d37c57aa8b251bc73edf6e4a06aed1789cdc476 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php
@@ -178,6 +178,7 @@ class Source extends AbstractEav
                 'pid.attribute_id',
                 'pid.store_id',
                 'value' => $ifNullSql,
+                'pid.entity_id',
             ]
         )->where(
             'pid.attribute_id IN(?)',
@@ -200,7 +201,7 @@ class Source extends AbstractEav
                 'select' => $select,
                 'entity_field' => new \Zend_Db_Expr('pid.entity_id'),
                 'website_field' => new \Zend_Db_Expr('pid.website_id'),
-                'store_field' => new \Zend_Db_Expr('pid.store_id')
+                'store_field' => new \Zend_Db_Expr('pid.store_id'),
             ]
         );
         $query = $select->insertFromSelect($idxTable);
@@ -221,11 +222,7 @@ class Source extends AbstractEav
         $connection = $this->getConnection();
 
         // prepare multiselect attributes
-        if ($attributeId === null) {
-            $attrIds = $this->_getIndexableAttributes(true);
-        } else {
-            $attrIds = [$attributeId];
-        }
+        $attrIds = $attributeId === null ? $this->_getIndexableAttributes(true) : [$attributeId];
 
         if (!$attrIds) {
             return $this;
@@ -247,20 +244,20 @@ class Source extends AbstractEav
         $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value');
         $select = $connection->select()->from(
             ['pvd' => $this->getTable('catalog_product_entity_varchar')],
-            [$productIdField, 'attribute_id']
+            []
         )->join(
             ['cs' => $this->getTable('store')],
             '',
-            ['store_id']
+            []
         )->joinLeft(
             ['pvs' => $this->getTable('catalog_product_entity_varchar')],
             "pvs.{$productIdField} = pvd.{$productIdField} AND pvs.attribute_id = pvd.attribute_id"
             . ' AND pvs.store_id=cs.store_id',
-            ['value' => $productValueExpression]
+            []
         )->joinLeft(
             ['cpe' => $this->getTable('catalog_product_entity')],
             "cpe.{$productIdField} = pvd.{$productIdField}",
-            ['entity_id']
+            []
         )->where(
             'pvd.store_id=?',
             $connection->getIfNullSql('pvs.store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID)
@@ -272,6 +269,14 @@ class Source extends AbstractEav
             $attrIds
         )->where(
             'cpe.entity_id IS NOT NULL'
+        )->columns(
+            [
+                'entity_id' => 'cpe.entity_id',
+                'attribute_id' => 'attribute_id',
+                'store_id' => 'cs.store_id',
+                'value' => $productValueExpression,
+                'source_id' => 'cpe.entity_id',
+            ]
         );
 
         $statusCond = $connection->quoteInto('=?', ProductStatus::STATUS_ENABLED);
@@ -289,30 +294,11 @@ class Source extends AbstractEav
                 'select' => $select,
                 'entity_field' => new \Zend_Db_Expr('cpe.entity_id'),
                 'website_field' => new \Zend_Db_Expr('cs.website_id'),
-                'store_field' => new \Zend_Db_Expr('cs.store_id')
+                'store_field' => new \Zend_Db_Expr('cs.store_id'),
             ]
         );
 
-        $i = 0;
-        $data = [];
-        $query = $select->query();
-        while ($row = $query->fetch()) {
-            $values = explode(',', $row['value']);
-            foreach ($values as $valueId) {
-                if (isset($options[$row['attribute_id']][$valueId])) {
-                    $data[] = [$row['entity_id'], $row['attribute_id'], $row['store_id'], $valueId];
-                    $i++;
-                    if ($i % 10000 == 0) {
-                        $this->_saveIndexData($data);
-                        $data = [];
-                    }
-                }
-            }
-        }
-
-        $this->_saveIndexData($data);
-        unset($options);
-        unset($data);
+        $this->saveDataFromSelect($select, $options);
 
         return $this;
     }
@@ -331,7 +317,7 @@ class Source extends AbstractEav
         $connection = $this->getConnection();
         $connection->insertArray(
             $this->getIdxTable(),
-            ['entity_id', 'attribute_id', 'store_id', 'value'],
+            ['entity_id', 'attribute_id', 'store_id', 'value', 'source_id'],
             $data
         );
         return $this;
@@ -348,4 +334,31 @@ class Source extends AbstractEav
     {
         return $this->tableStrategy->getTableName('catalog_product_index_eav');
     }
+
+    /**
+     * @param \Magento\Framework\DB\Select $select
+     * @param array $options
+     * @return void
+     */
+    private function saveDataFromSelect(\Magento\Framework\DB\Select $select, array $options)
+    {
+        $i = 0;
+        $data = [];
+        $query = $select->query();
+        while ($row = $query->fetch()) {
+            $values = explode(',', $row['value']);
+            foreach ($values as $valueId) {
+                if (isset($options[$row['attribute_id']][$valueId])) {
+                    $data[] = [$row['entity_id'], $row['attribute_id'], $row['store_id'], $valueId, $row['source_id']];
+                    $i++;
+                    if ($i % 10000 == 0) {
+                        $this->_saveIndexData($data);
+                        $data = [];
+                    }
+                }
+            }
+        }
+
+        $this->_saveIndexData($data);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php
index 289445ae2daf07c4132f6d69372c84fcfb36a066..2b979ff79fe5c498215b6b144e71897b9ca2c913 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php
@@ -368,7 +368,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface
                 'select' => $select,
                 'entity_field' => new \Zend_Db_Expr('e.entity_id'),
                 'website_field' => new \Zend_Db_Expr('cw.website_id'),
-                'store_field' => new \Zend_Db_Expr('cs.store_id')
+                'store_field' => new \Zend_Db_Expr('cs.store_id'),
             ]
         );
 
diff --git a/app/code/Magento/Catalog/Setup/InstallSchema.php b/app/code/Magento/Catalog/Setup/InstallSchema.php
index 171e96efe9b0a1e714e1331fc2ed95a175cd58fb..a2ba6aa283f6516021f0baffaafd6e6470c060f0 100644
--- a/app/code/Magento/Catalog/Setup/InstallSchema.php
+++ b/app/code/Magento/Catalog/Setup/InstallSchema.php
@@ -18,6 +18,7 @@ class InstallSchema implements InstallSchemaInterface
     /**
      * {@inheritdoc}
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     * @throws \Zend_Db_Exception
      */
     public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
     {
@@ -2429,7 +2430,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('catalog_product_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php
index cbcce1d427bb6c91fa000bff0b4a069ab02d034f..7fc2ef7d219ba917aa59c9887749a9024bda49ce 100755
--- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php
+++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php
@@ -61,9 +61,56 @@ class UpgradeSchema implements UpgradeSchemaInterface
             }
         }
 
+        if (version_compare($context->getVersion(), '2.1.2', '<')) {
+            $this->addSourceEntityIdToProductEavIndex($setup);
+        }
+
         $setup->endSetup();
     }
 
+    /**
+     * Add the column 'source_id' to the Product EAV index tables.
+     * It allows to identify which entity was used to create value in the index.
+     * It is useful to identify original entity in a composite products.
+     *
+     * @param SchemaSetupInterface $setup
+     * @return void
+     */
+    private function addSourceEntityIdToProductEavIndex(SchemaSetupInterface $setup)
+    {
+        $tables = [
+            'catalog_product_index_eav',
+            'catalog_product_index_eav_idx',
+            'catalog_product_index_eav_tmp',
+            'catalog_product_index_eav_decimal',
+            'catalog_product_index_eav_decimal_idx',
+            'catalog_product_index_eav_decimal_tmp',
+        ];
+        $connection = $setup->getConnection();
+        foreach ($tables as $tableName) {
+            $tableName = $setup->getTable($tableName);
+            $connection->addColumn(
+                $tableName,
+                'source_id',
+                [
+                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+                    'unsigned' => true,
+                    'nullable' => false,
+                    'default' => 0,
+                    'comment' => 'Original entity Id for attribute value',
+                ]
+            );
+            $connection->dropIndex($tableName, $connection->getPrimaryKeyName($tableName));
+            $primaryKeyFields = ['entity_id', 'attribute_id', 'store_id', 'value', 'source_id'];
+            $setup->getConnection()->addIndex(
+                $tableName,
+                $connection->getIndexName($tableName, $primaryKeyFields),
+                $primaryKeyFields,
+                \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_PRIMARY
+            );
+        }
+    }
+
     /**
      * @param SchemaSetupInterface $setup
      * @return void
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
index f420f140b35820e3cbcebf986ed305217523aab2..39e3263722a7c3f84fce9f6ce3e5b8ee2f2899d6 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
@@ -154,9 +154,9 @@ class ListProductTest extends \PHPUnit_Framework_TestCase
         ];
 
         $this->typeInstanceMock->expects($this->once())
-            ->method('hasRequiredOptions')
+            ->method('isPossibleBuyFromList')
             ->with($this->equalTo($this->productMock))
-            ->will($this->returnValue(false));
+            ->will($this->returnValue(true));
         $this->cartHelperMock->expects($this->any())
             ->method('getAddUrl')
             ->with($this->equalTo($this->productMock), $this->equalTo([]))
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php
index 7e5a8305467e8e979a9ccc79d39d7ffdb70bb339..d90261f068f5023d8987bab6d64585032385c8ee 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php
@@ -107,44 +107,42 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase
 
     public function testBuild()
     {
-        list($storeId, $changedIds, $valueFieldSuffix, $tableDropSuffix, $fillTmpTables) = [1, [], '', '', true];
+        $storeId = 1;
+        $changedIds = [];
+        $valueFieldSuffix = '_value';
+        $tableDropSuffix = '';
+        $fillTmpTables = true;
         $tableName = 'catalog_product_entity';
         $attributeTable = 'catalog_product_entity_int';
         $temporaryTableName = 'catalog_product_entity_int_tmp_indexer';
-        $temporaryValueTableName = 'catalog_product_entity_int_tmp_indexer';
+        $temporaryValueTableName = 'catalog_product_entity_int_tmp_indexer_value';
         $linkField = 'entity_id';
         $statusId = 22;
+        $eavCustomField = 'space_weight';
+        $eavCustomValueField = $eavCustomField . $valueFieldSuffix;
         $this->flatIndexerMock->expects($this->once())->method('getAttributes')->willReturn([]);
         $this->flatIndexerMock->expects($this->exactly(3))->method('getFlatColumns')
-            ->willReturnOnConsecutiveCalls(
-                [],
-                [$linkField => []],
-                [$linkField => []]
-            );
+            ->willReturnOnConsecutiveCalls([], [$eavCustomValueField => []], [$eavCustomValueField => []]);
         $this->flatIndexerMock->expects($this->once())->method('getFlatIndexes')->willReturn([]);
         $statusAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $eavCustomAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->flatIndexerMock->expects($this->once())->method('getTablesStructure')
             ->willReturn(
                 [
-                    'catalog_product_entity' => [
-                        $linkField => $statusAttributeMock
-                    ],
+                    'catalog_product_entity' => [$linkField => $statusAttributeMock],
                     'catalog_product_entity_int' => [
-                        $linkField => $statusAttributeMock
+                        $linkField => $statusAttributeMock,
+                        $eavCustomField => $eavCustomAttributeMock
                     ]
                 ]
             );
         $this->flatIndexerMock->expects($this->atLeastOnce())->method('getTable')
-            ->withConsecutive(
-                [$tableName],
-                ['catalog_product_website']
-            )
-            ->willReturnOnConsecutiveCalls(
-                $tableName,
-                'catalog_product_website'
-            );
+            ->withConsecutive([$tableName], ['catalog_product_website'])
+            ->willReturnOnConsecutiveCalls($tableName, 'catalog_product_website');
         $this->flatIndexerMock->expects($this->once())->method('getAttribute')
             ->with('status')
             ->willReturn($statusAttributeMock);
@@ -155,6 +153,9 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase
         $statusAttributeMock->expects($this->atLeastOnce())->method('getBackend')->willReturn(
             $backendMock
         );
+        $eavCustomAttributeMock->expects($this->atLeastOnce())->method('getBackend')->willReturn(
+            $backendMock
+        );
         $statusAttributeMock->expects($this->atLeastOnce())->method('getId')->willReturn($statusId);
         $tableMock = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class)
             ->disableOriginalConstructor()
@@ -185,12 +186,12 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase
                 [
                     $temporaryTableName,
                     "e.{$linkField} = {$temporaryTableName}.{$linkField}",
-                    [$linkField]
+                    [$linkField, $eavCustomField]
                 ],
                 [
                     $temporaryValueTableName,
-                    "e.{$linkField} = " . $temporaryValueTableName . ".{$linkField}",
-                    [$linkField]
+                    "e.{$linkField} = {$temporaryValueTableName}.{$linkField}",
+                    [$eavCustomValueField]
                 ]
             )->willReturnSelf();
         $this->metadataPoolMock->expects($this->atLeastOnce())->method('getMetadata')->with(ProductInterface::class)
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
index a032ffa33b37561117fac3f6e603cb77dd34152d..44f7f87cc2c62afc2c09d262bbd2721683fcfea3 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
@@ -180,7 +180,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
         $this->image->setBaseFile('/somefile.png');
         $this->assertEquals('catalog/product/somefile.png', $this->image->getBaseFile());
         $this->assertEquals(
-            'catalog/product/cache/1//beff4985b56e3afdbeabfc89641a4582/somefile.png',
+            'catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png',
             $this->image->getNewFile()
         );
     }
@@ -302,7 +302,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
         $this->testSetGetBaseFile();
         $url = $this->image->getUrl();
         $this->assertEquals(
-            'http://magento.com/media/catalog/product/cache/1//beff4985b56e3afdbeabfc89641a4582/somefile.png',
+            'http://magento.com/media/catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png',
             $url
         );
     }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index e91bb469eb112d4de70cba92bff5b93ca069ca58..8c08d0c63bc5e93c7ab690f6441eaa02281b3255 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -715,6 +715,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
             ->method('process')
             ->with($searchCriteriaMock, $collectionMock);
         $collectionMock->expects($this->once())->method('load');
+        $collectionMock->expects($this->once())->method('addCategoryIds');
         $collectionMock->expects($this->once())->method('getItems')->willReturn([$itemsMock]);
         $collectionMock->expects($this->once())->method('getSize')->willReturn(128);
         $searchResultsMock = $this->getMock(
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php
index 2172e184a9a2ed400d80eb89314855c69fb2c7c1..7a55bd31e3deef64ddeaf5b452cc1b7eb389517c 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php
@@ -24,7 +24,9 @@ class ImagesTest extends AbstractModifierTest
 
     public function testModifyData()
     {
-        $this->assertSame($this->getSampleData(), $this->getModel()->modifyData($this->getSampleData()));
+        $this->productMock->expects($this->once())->method('getId')->willReturn(2051);
+        $actualResult = $this->getModel()->modifyData($this->getSampleData());
+        $this->assertSame("", $actualResult[2051]['product']['media_gallery']['images'][0]['label']);
     }
 
     public function testModifyMeta()
@@ -40,4 +42,24 @@ class ImagesTest extends AbstractModifierTest
 
         $this->assertSame([], $this->getModel()->modifyMeta($meta));
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getSampleData()
+    {
+        return [
+            2051 => [
+                'product' => [
+                    'media_gallery' => [
+                        'images' => [
+                            [
+                                'label' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+    }
 }
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php
index 0fbba264f7e93383f07434a7fe2ebf4586d54516..886c7a070adf93b68ec54f45813ba80911029e44 100755
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php
@@ -315,17 +315,6 @@ class General extends AbstractModifier
             $importsConfig = [
                 'mask' => $this->locator->getStore()->getConfig('catalog/fields_masks/' . $listener),
                 'component' => 'Magento_Catalog/js/components/import-handler',
-                'imports' => [
-                    'handleNameChanges' => '${$.provider}:data.product.name',
-                    'handleDescriptionChanges' => '${$.provider}:data.product.description',
-                    'handleSkuChanges' => '${$.provider}:data.product.sku',
-                    'handleColorChanges' => '${$.provider}:data.product.color',
-                    'handleCountryChanges' => '${$.provider}:data.product.country_of_manufacture',
-                    'handleGenderChanges' => '${$.provider}:data.product.gender',
-                    'handleMaterialChanges' => '${$.provider}:data.product.material',
-                    'handleShortDescriptionChanges' => '${$.provider}:data.product.short_description',
-                    'handleSizeChanges' => '${$.provider}:data.product.size'
-                ],
                 'allowImport' => !$this->locator->getProduct()->getId(),
             ];
 
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php
index 810a06df4a42f76392ee54525eb5bf6ffc5f489f..a8536cacc79668797ac961e1082c7b8c0f020e76 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php
@@ -51,6 +51,21 @@ class Images extends AbstractModifier
      */
     public function modifyData(array $data)
     {
+        /** @var \Magento\Catalog\Api\Data\ProductInterface $product */
+        $product = $this->locator->getProduct();
+        $modelId = $product->getId();
+        if (
+            isset($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery'])
+            && !empty($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery'])
+            && !empty($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images'])
+        ) {
+            foreach ($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images'] as $index => $image) {
+                if (!isset($image['label'])) {
+                    $data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images'][$index]['label'] = "";
+                }
+            }
+        };
+
         return $data;
     }
 }
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index 64157f6bc8af74e82975668e43a62ef583227908..8c77dd77f98b74a53ee1124a16c473d843d21d60 100644
--- a/app/code/Magento/Catalog/composer.json
+++ b/app/code/Magento/Catalog/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-eav": "100.2.*",
         "magento/module-cms": "101.1.*",
diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml
index c629bf6a180ccc0ec42e51a67352f6eaa673dd86..0c9e6bb356fe14101d467a04aa91b23fb6873f09 100644
--- a/app/code/Magento/Catalog/etc/module.xml
+++ b/app/code/Magento/Catalog/etc/module.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
-    <module name="Magento_Catalog" setup_version="2.1.1">
+    <module name="Magento_Catalog" setup_version="2.1.2">
         <sequence>
             <module name="Magento_Eav"/>
             <module name="Magento_Cms"/>
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
index e67bde152475f62769d6eaff73548893f98ed7d0..a0aec918ccda24f1ae05486bc5d9ec59522f0ca7 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
@@ -4,148 +4,78 @@
  */
 
 define([
+    'Magento_Ui/js/form/element/abstract',
     'underscore',
-    'Magento_Ui/js/form/element/textarea'
-], function (_, Textarea) {
+    'uiRegistry'
+], function (Abstract, _, registry) {
     'use strict';
 
-    return Textarea.extend({
+    return Abstract.extend({
         defaults: {
             allowImport: true,
             autoImportIfEmpty: false,
-            values: {
-                'name': '',
-                'description': '',
-                'sku': '',
-                'color': '',
-                'country_of_manufacture': '',
-                'gender': '',
-                'material': '',
-                'short_description': '',
-                'size': ''
-            },
-            valueUpdate: 'input',
-            mask: ''
+            values: {},
+            mask: '',
+            queryTemplate: 'ns = ${ $.ns }, index = '
         },
 
-        /**
-         * Handle name value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleNameChanges: function (newValue) {
-            this.values.name = newValue;
-            this.updateValue();
-        },
-
-        /**
-         * Handle description value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleDescriptionChanges: function (newValue) {
-            this.values.description = newValue;
-            this.updateValue();
-        },
+        /** @inheritdoc */
+        initialize: function () {
+            this._super();
 
-        /**
-         * Handle sku value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleSkuChanges: function (newValue) {
-            if (this.code !== 'sku') {
-                this.values.sku = newValue;
-                this.updateValue();
+            if (this.allowImport) {
+                this.setHandlers();
             }
         },
 
         /**
-         * Handle color value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleColorChanges: function (newValue) {
-            this.values.color = newValue;
-            this.updateValue();
-        },
-
-        /**
-         * Handle country value changes, if it's allowed
-         *
-         * @param {String} newValue
+         * Split mask placeholder and attach events to placeholder fields.
          */
-        handleCountryChanges: function (newValue) {
-            this.values.country = newValue;
-            this.updateValue();
-        },
+        setHandlers: function () {
+            var str = this.mask || '',
+                placeholders;
 
-        /**
-         * Handle gender value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleGenderChanges: function (newValue) {
-            this.values.gender = newValue;
-            this.updateValue();
-        },
+            placeholders = str.match(/{{(.*?)}}/g); // Get placeholders
 
-        /**
-         * Handle material value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleMaterialChanges: function (newValue) {
-            this.values.material = newValue;
-            this.updateValue();
-        },
+            _.each(placeholders, function (placeholder) {
+                placeholder = placeholder.replace(/[{{}}]/g, ''); // Remove curly braces
 
-        /**
-         * Handle short description value changes, if it's allowed
-         *
-         * @param {String} newValue
-         */
-        handleShortDescriptionChanges: function (newValue) {
-            this.values['short_description'] = newValue;
-            this.updateValue();
+                registry.get(this.queryTemplate + placeholder, function (component) {
+                    this.values[placeholder] = component.getPreview();
+                    component.on('value', this.updateValue.bind(this, placeholder, component));
+                    component.valueUpdate = 'keyup';
+                }.bind(this));
+            }, this);
         },
 
         /**
-         * Handle size value changes, if it's allowed
+         * Update field with mask value, if it's allowed.
          *
-         * @param {String} newValue
+         * @param {Object} placeholder
+         * @param {Object} component
          */
-        handleSizeChanges: function (newValue) {
-            this.values.size = newValue;
-            this.updateValue();
-        },
+        updateValue: function (placeholder, component) {
+            var string = this.mask || '',
+                nonEmptyValueFlag = false;
 
-        /**
-         * Update field value, if it's allowed
-         */
-        updateValue: function () {
-            var str = this.mask || '',
-                nonEmptyValueFlag = false,
-                tmpElement;
+            if (placeholder) {
+                this.values[placeholder] = component.getPreview() || '';
+            }
 
             if (!this.allowImport) {
                 return;
             }
 
-            if (str) {
-                _.each(this.values, function (propertyValue, propertyName) {
-                    str = str.replace('{{' + propertyName + '}}', propertyValue);
-                    nonEmptyValueFlag = nonEmptyValueFlag || !!propertyValue;
-                });
-            }
-
-            // strip tags
-            tmpElement = document.createElement('div');
-            tmpElement.innerHTML = str;
-            str =  tmpElement.textContent || tmpElement.innerText || '';
+            _.each(this.values, function (propertyValue, propertyName) {
+                string = string.replace('{{' + propertyName + '}}', propertyValue);
+                nonEmptyValueFlag = nonEmptyValueFlag || !!propertyValue;
+            });
 
             if (nonEmptyValueFlag) {
-                this.value(str);
+                string = string.replace(/(<([^>]+)>)/ig, ''); // Remove html tags
+                this.value(string);
+            } else {
+                this.value('');
             }
         },
 
@@ -169,13 +99,20 @@ define([
          *  and disallow/allow import value
          */
         userChanges: function () {
+
+            /**
+             *  As userChanges is called before updateValue,
+             *  we forced to get value from component by reference
+             */
+            var actualValue = arguments[1].currentTarget.value;
+
             this._super();
 
-            if (this.value() === '') {
+            if (actualValue === '') {
                 this.allowImport = true;
 
                 if (this.autoImportIfEmpty) {
-                    this.updateValue();
+                    this.updateValue(null, null);
                 }
             } else {
                 this.allowImport = false;
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
index 4c8ae8eaae9524fe75f74ba5f0dd45ef045c2954..298cdcc29e953a74625a3834edab6b9a5eb47631 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
@@ -28,53 +28,6 @@
                     </block>
                     <block class="Magento\Catalog\Block\Product\ProductList\Toolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml">
                         <block class="Magento\Theme\Block\Html\Pager" name="product_list_toolbar_pager"/>
-                        <!-- The following code shows how to set your own pager increments -->
-                        <!--
-                            <action method="setDefaultListPerPage">
-                            <argument name="limit" xsi:type="string">4</argument>
-                        </action>
-                        <action method="setDefaultGridPerPage">
-                            <argument name="limit" xsi:type="string">3</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">list</argument>
-                            <argument name="limit" xsi:type="string">2</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">list</argument>
-                            <argument name="limit" xsi:type="string">4</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">list</argument>
-                            <argument name="limit" xsi:type="string">6</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">list</argument>
-                            <argument name="limit" xsi:type="string">8</argument>
-                        </action>
-                        <action method="addPagerLimit" translate="label">
-                            <argument name="mode" xsi:type="string">list</argument>
-                            <argument name="limit" xsi:type="string">all</argument>
-                            <argument name="label" xsi:type="string">All</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">grid</argument>
-                            <argument name="limit" xsi:type="string">3</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">grid</argument>
-                            <argument name="limit" xsi:type="string">6</argument>
-                        </action>
-                        <action method="addPagerLimit">
-                            <argument name="mode" xsi:type="string">grid</argument>
-                            <argument name="limit" xsi:type="string">9</argument>
-                        </action>
-                        <action method="addPagerLimit" translate="label">
-                            <argument name="mode" xsi:type="string">grid</argument>
-                            <argument name="limit" xsi:type="string">all</argument>
-                            <argument name="label" xsi:type="string">All</argument>
-                        </action>
-                        -->
                     </block>
                     <action method="setToolbarBlockName">
                         <argument name="name" xsi:type="string">product_list_toolbar</argument>
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
index 45c9f73e051c788c55f24d2f95f1e286c7d6bd02..7db4f5d745626c0da12d9a4032bc5466c57f282b 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
@@ -84,6 +84,17 @@ define([
                     }
 
                     if (res.backUrl) {
+                        var eventData = {
+                            'form': form,
+                            'redirectParameters': []
+                        }
+                        // trigger global event, so other modules will be able add parameters to redirect url
+                        $('body').trigger('catalogCategoryAddToCartRedirect', eventData);
+                        if (eventData.redirectParameters.length > 0) {
+                            var parameters = res.backUrl.split('#');
+                            parameters.push(eventData.redirectParameters.join('&'));
+                            res.backUrl = parameters.join('#');
+                        }
                         window.location = res.backUrl;
                         return;
                     }
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index afb2e86b6248a79523405c78acd1cf27953b90c2..54208dcdba534139c96e8fd975e0757f9ecb11e1 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -2304,7 +2304,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
 
         $sku = $rowData[self::COL_SKU];
 
-        if (isset($this->_oldSku[$sku])) {
+        if (isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) {
             // can we get all necessary data from existent DB product?
             // check for supported type of existing product
             if (isset($this->_productTypeModels[$this->_oldSku[$sku]['type_id']])) {
@@ -2356,7 +2356,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
             $rowAttributesValid = $productTypeValidator->isRowValid(
                 $rowData,
                 $rowNum,
-                !isset($this->_oldSku[$sku])
+                !(isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior())
             );
             if (!$rowAttributesValid && self::SCOPE_DEFAULT == $rowScope) {
                 // mark SCOPE_DEFAULT row as invalid for future child rows if product not in DB already
diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json
index 7dbd7f4bc5e656ff09712549886e97a95fa3f4f1..8ed5f43692df51482038e1d1f7d4b91f05fd8c23 100644
--- a/app/code/Magento/CatalogImportExport/composer.json
+++ b/app/code/Magento/CatalogImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-url-rewrite": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/CatalogInventory/Setup/UpgradeData.php b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php
index db3408c01b77f9fc620ee0862f2f71f2eec232c5..1741ffce9cdfa1bc0374666a704386241e935f67 100644
--- a/app/code/Magento/CatalogInventory/Setup/UpgradeData.php
+++ b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php
@@ -54,7 +54,7 @@ class UpgradeData implements UpgradeDataInterface
     public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
     {
         $setup->startSetup();
-        if (version_compare($context->getVersion(), '2.0.2') < 0) {
+        if (version_compare($context->getVersion(), '2.2.0') < 0) {
             $this->upgradeCatalogInventoryStockItem($setup);
         }
         $setup->endSetup();
diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json
index 254d8d2db4bf9db35b338507cdd744d1aaf0e152..684f616ecd6fcfca7088c257afec000fba6a4b1d 100644
--- a/app/code/Magento/CatalogInventory/composer.json
+++ b/app/code/Magento/CatalogInventory/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-inventory",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/CatalogInventory/etc/events.xml b/app/code/Magento/CatalogInventory/etc/events.xml
index a1476c2c3f8b161568a042725d6b04c37aeb1be9..d9db59b7a17663b48b2ba2df7677d4147cba11b5 100644
--- a/app/code/Magento/CatalogInventory/etc/events.xml
+++ b/app/code/Magento/CatalogInventory/etc/events.xml
@@ -33,9 +33,6 @@
     <event name="sales_order_item_cancel">
         <observer name="inventory" instance="Magento\CatalogInventory\Observer\CancelOrderItemObserver"/>
     </event>
-    <event name="sales_order_creditmemo_save_after">
-        <observer name="inventory" instance="Magento\CatalogInventory\Observer\RefundOrderInventoryObserver"/>
-    </event>
     <event name="catalog_product_save_after">
         <observer name="inventory" instance="Magento\CatalogInventory\Observer\SaveInventoryDataObserver"/>
     </event>
diff --git a/app/code/Magento/CatalogInventory/etc/module.xml b/app/code/Magento/CatalogInventory/etc/module.xml
index 711d18bead9c9ece376e74f3b13aced3419b7806..7aff70e2258312c49a6a6cde35bb87c5cb0e8400 100644
--- a/app/code/Magento/CatalogInventory/etc/module.xml
+++ b/app/code/Magento/CatalogInventory/etc/module.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
-    <module name="Magento_CatalogInventory" setup_version="2.0.2">
+    <module name="Magento_CatalogInventory" setup_version="2.2.0">
         <sequence>
             <module name="Magento_Catalog"/>
         </sequence>
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index 71eb5b49db1fc68eadb064968796cfdaf1081d60..004ab82a028d3aba288b71a234dead24d63a4755 100644
--- a/app/code/Magento/CatalogRule/composer.json
+++ b/app/code/Magento/CatalogRule/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-rule",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-rule": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json
index cc51269e2d9720e380612cf56c712ff2459bbe35..b930380f7bb025ea409be398c013c12773cb2f20 100644
--- a/app/code/Magento/CatalogRuleConfigurable/composer.json
+++ b/app/code/Magento/CatalogRuleConfigurable/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-rule-configurable",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-configurable-product": "100.2.*",
         "magento/framework": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php
index 9b75e6e6e0c325819d09f543cc445ae61eb7fb84..ddf86951068acc3c95017e54e489faf92e4b28cc 100644
--- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php
@@ -6,6 +6,7 @@
 namespace Magento\CatalogSearch\Model\Adapter\Mysql\Aggregation;
 
 use Magento\Catalog\Model\Product;
+use Magento\CatalogInventory\Model\Stock;
 use Magento\Customer\Model\Session;
 use Magento\Eav\Model\Config;
 use Magento\Framework\App\ResourceConnection;
@@ -79,7 +80,13 @@ class DataProvider implements DataProviderInterface
 
         $select = $this->getSelect();
 
-        if ($attribute->getAttributeCode() == 'price') {
+        $select->joinInner(
+            ['entities' => $entityIdsTable->getName()],
+            'main_table.entity_id  = entities.entity_id',
+            []
+        );
+
+        if ($attribute->getAttributeCode() === 'price') {
             /** @var \Magento\Store\Model\Store $store */
             $store = $this->scopeResolver->getScope($currentScope);
             if (!$store instanceof \Magento\Store\Model\Store) {
@@ -94,19 +101,24 @@ class DataProvider implements DataProviderInterface
             $currentScopeId = $this->scopeResolver->getScope($currentScope)
                 ->getId();
             $table = $this->resource->getTableName(
-                'catalog_product_index_eav' . ($attribute->getBackendType() == 'decimal' ? '_decimal' : '')
+                'catalog_product_index_eav' . ($attribute->getBackendType() === 'decimal' ? '_decimal' : '')
             );
-            $select->from(['main_table' => $table], ['value'])
+            $subSelect = $select;
+            $subSelect->from(['main_table' => $table], ['main_table.value'])
+                ->joinLeft(
+                    ['stock_index' => $this->resource->getTableName('cataloginventory_stock_status')],
+                    'main_table.source_id = stock_index.product_id',
+                    []
+                )
                 ->where('main_table.attribute_id = ?', $attribute->getAttributeId())
-                ->where('main_table.store_id = ? ', $currentScopeId);
+                ->where('main_table.store_id = ? ', $currentScopeId)
+                ->where('stock_index.stock_status = ?', Stock::STOCK_IN_STOCK)
+                ->group(['main_table.entity_id', 'main_table.value']);
+            $parentSelect = $this->getSelect();
+            $parentSelect->from(['main_table' => $subSelect], ['main_table.value']);
+            $select = $parentSelect;
         }
 
-        $select->joinInner(
-            ['entities' => $entityIdsTable->getName()],
-            'main_table.entity_id  = entities.entity_id',
-            []
-        );
-
         return $select;
     }
 
diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..7099ce2502b19e21de48ae570e2dc063be6162d1
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Adapter\Mysql\Filter;
+
+
+use Magento\CatalogSearch\Model\Search\RequestGenerator;
+
+/**
+ * Purpose of class is to resolve table alias for Search Request filter
+ */
+class AliasResolver
+{
+    /**
+     * The suffix for stock status filter that may be added to the query beside the filter query
+     * Used when showing of Out of Stock products is disabled.
+     */
+    const STOCK_FILTER_SUFFIX = '_stock';
+
+    /**
+     * @param \Magento\Framework\Search\Request\FilterInterface $filter
+     * @return string alias of the filter in database
+     */
+    public function getAlias(\Magento\Framework\Search\Request\FilterInterface $filter)
+    {
+        $alias = null;
+        $field = $filter->getField();
+        switch ($field) {
+            case 'price':
+                $alias = 'price_index';
+                break;
+            case 'category_ids':
+                $alias = 'category_ids_index';
+                break;
+            default:
+                $alias = $field . RequestGenerator::FILTER_SUFFIX;
+                break;
+        }
+        return $alias;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php
index 05205f04f8b99cd903f345f8c1f7dc04384e7aee..fb579c1dce29c7da26b35288ff61040363f4f510 100644
--- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php
@@ -8,8 +8,11 @@ namespace Magento\CatalogSearch\Model\Adapter\Mysql\Filter;
 use Magento\Catalog\Api\Data\ProductInterface;
 use Magento\Catalog\Model\Product;
 use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\CatalogInventory\Model\Stock;
 use Magento\CatalogSearch\Model\Search\TableMapper;
 use Magento\Eav\Model\Config;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\App\ScopeResolverInterface;
 use Magento\Framework\DB\Adapter\AdapterInterface;
@@ -17,6 +20,7 @@ use Magento\Framework\EntityManager\MetadataPool;
 use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
 use Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface;
 use Magento\Framework\Search\Request\FilterInterface;
+use Magento\Store\Model\ScopeInterface;
 use Magento\Store\Model\Store;
 
 /**
@@ -60,9 +64,14 @@ class Preprocessor implements PreprocessorInterface
     private $metadataPool;
 
     /**
-     * @var TableMapper
+     * @var ScopeConfigInterface
      */
-    private $tableMapper;
+    private $scopeConfig;
+
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
 
     /**
      * @param ConditionManager $conditionManager
@@ -71,6 +80,9 @@ class Preprocessor implements PreprocessorInterface
      * @param ResourceConnection $resource
      * @param TableMapper $tableMapper
      * @param string $attributePrefix
+     * @param ScopeConfigInterface $scopeConfig
+     * @param AliasResolver $aliasResolver
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(
         ConditionManager $conditionManager,
@@ -78,7 +90,9 @@ class Preprocessor implements PreprocessorInterface
         Config $config,
         ResourceConnection $resource,
         TableMapper $tableMapper,
-        $attributePrefix
+        $attributePrefix,
+        ScopeConfigInterface $scopeConfig = null,
+        AliasResolver $aliasResolver = null
     ) {
         $this->conditionManager = $conditionManager;
         $this->scopeResolver = $scopeResolver;
@@ -86,7 +100,16 @@ class Preprocessor implements PreprocessorInterface
         $this->resource = $resource;
         $this->connection = $resource->getConnection();
         $this->attributePrefix = $attributePrefix;
-        $this->tableMapper = $tableMapper;
+
+        if (null === $scopeConfig) {
+            $scopeConfig = ObjectManager::getInstance()->get(ScopeConfigInterface::class);
+        }
+        if (null === $aliasResolver) {
+            $aliasResolver = ObjectManager::getInstance()->get(AliasResolver::class);
+        }
+
+        $this->scopeConfig = $scopeConfig;
+        $this->aliasResolver = $aliasResolver;
     }
 
     /**
@@ -117,7 +140,7 @@ class Preprocessor implements PreprocessorInterface
         } elseif ($filter->getField() === 'category_ids') {
             return 'category_ids_index.category_id = ' . (int) $filter->getValue();
         } elseif ($attribute->isStatic()) {
-            $alias = $this->tableMapper->getMappingAlias($filter);
+            $alias = $this->aliasResolver->getAlias($filter);
             $resultQuery = str_replace(
                 $this->connection->quoteIdentifier($attribute->getAttributeCode()),
                 $this->connection->quoteIdentifier($alias . '.' . $attribute->getAttributeCode()),
@@ -208,7 +231,7 @@ class Preprocessor implements PreprocessorInterface
      */
     private function processTermSelect(FilterInterface $filter, $isNegation)
     {
-        $alias = $this->tableMapper->getMappingAlias($filter);
+        $alias = $this->aliasResolver->getAlias($filter);
         if (is_array($filter->getValue())) {
             $value = sprintf(
                 '%s IN (%s)',
@@ -224,9 +247,31 @@ class Preprocessor implements PreprocessorInterface
             $value
         );
 
+        if ($this->isAddStockFilter()) {
+            $resultQuery = sprintf(
+                '%1$s AND %2$s%3$s.stock_status = %4$s',
+                $resultQuery,
+                $alias,
+                AliasResolver::STOCK_FILTER_SUFFIX,
+                Stock::STOCK_IN_STOCK
+            );
+        }
+
         return $resultQuery;
     }
 
+    /**
+     * @return bool
+     */
+    private function isAddStockFilter()
+    {
+        $isShowOutOfStock = $this->scopeConfig->isSetFlag(
+            'cataloginventory/options/show_out_of_stock',
+            ScopeInterface::SCOPE_STORE
+        );
+        return false === $isShowOutOfStock;
+    }
+
     /**
      * Get product metadata pool
      *
diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php
new file mode 100644
index 0000000000000000000000000000000000000000..8626b2ea15b077fc42380afaba82b245e7387937
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\FilterMapper;
+
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+
+/**
+ * Strategy which processes exclusions from general rules
+ */
+class ExclusionStrategy implements FilterStrategyInterface
+{
+    /**
+     * @var \Magento\Framework\App\ResourceConnection
+     */
+    private $resourceConnection;
+
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param \Magento\Framework\App\ResourceConnection $resourceConnection
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param AliasResolver $aliasResolver
+     */
+    public function __construct(
+        \Magento\Framework\App\ResourceConnection $resourceConnection,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        AliasResolver $aliasResolver
+    ) {
+        $this->resourceConnection = $resourceConnection;
+        $this->storeManager = $storeManager;
+        $this->aliasResolver = $aliasResolver;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function apply(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        \Magento\Framework\DB\Select $select
+    ) {
+        $isApplied = false;
+        $field = $filter->getField();
+        if ('price' === $field) {
+            $alias = $this->aliasResolver->getAlias($filter);
+            $tableName = $this->resourceConnection->getTableName('catalog_product_index_price');
+            $select->joinInner(
+                [
+                    $alias => $tableName
+                ],
+                $this->resourceConnection->getConnection()->quoteInto(
+                    'search_index.entity_id = price_index.entity_id AND price_index.website_id = ?',
+                    $this->storeManager->getWebsite()->getId()
+                ),
+                []
+            );
+            $isApplied = true;
+        } elseif ('category_ids' === $field) {
+            $alias = $this->aliasResolver->getAlias($filter);
+            $tableName = $this->resourceConnection->getTableName('catalog_category_product_index');
+            $select->joinInner(
+                [
+                    $alias => $tableName
+                ],
+                'search_index.entity_id = category_ids_index.product_id',
+                []
+            );
+            $isApplied = true;
+        }
+        return $isApplied;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php
new file mode 100644
index 0000000000000000000000000000000000000000..d244e3d5f754893fb671a3b6c81565eb5c920ff7
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\FilterMapper;
+
+
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+use Magento\Eav\Model\Config as EavConfig;
+use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+
+/**
+ * FilterContext represents a Context of the Strategy pattern
+ * Its responsibility is to choose appropriate strategy to apply passed filter to the Select
+ */
+class FilterContext implements FilterStrategyInterface
+{
+    /**
+     * @var ExclusionStrategy
+     */
+    private $exclusionStrategy;
+
+    /**
+     * @var EavConfig
+     */
+    private $eavConfig;
+
+    /**
+     * @var TermDropdownStrategy
+     */
+    private $termDropdownStrategy;
+
+    /**
+     * @var StaticAttributeStrategy
+     */
+    private $staticAttributeStrategy;
+
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
+
+    /**
+     * @param EavConfig $eavConfig
+     * @param AliasResolver $aliasResolver
+     * @param ExclusionStrategy $exclusionStrategy
+     * @param TermDropdownStrategy $termDropdownStrategy
+     * @param StaticAttributeStrategy $staticAttributeStrategy
+     */
+    public function __construct(
+        EavConfig $eavConfig,
+        AliasResolver $aliasResolver,
+        ExclusionStrategy $exclusionStrategy,
+        TermDropdownStrategy $termDropdownStrategy,
+        StaticAttributeStrategy $staticAttributeStrategy
+    ) {
+        $this->eavConfig = $eavConfig;
+        $this->aliasResolver = $aliasResolver;
+        $this->exclusionStrategy = $exclusionStrategy;
+        $this->termDropdownStrategy = $termDropdownStrategy;
+        $this->staticAttributeStrategy = $staticAttributeStrategy;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function apply(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        \Magento\Framework\DB\Select $select
+    ) {
+        $isApplied = $this->exclusionStrategy->apply($filter, $select);
+
+        if (!$isApplied) {
+            $attribute = $this->getAttributeByCode($filter->getField());
+            if ($attribute) {
+                if ($filter->getType() === \Magento\Framework\Search\Request\FilterInterface::TYPE_TERM
+                    && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true)
+                ) {
+                    $isApplied = $this->termDropdownStrategy->apply($filter, $select);
+                } elseif ($attribute->getBackendType() === AbstractAttribute::TYPE_STATIC) {
+                    $isApplied = $this->staticAttributeStrategy->apply($filter, $select);
+                }
+            }
+        }
+
+        return $isApplied;
+    }
+
+    /**
+     * @param string $field
+     * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    private function getAttributeByCode($field)
+    {
+        return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf17f7d5132efbf8246af0de674d7c789551aa3e
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\FilterMapper;
+
+/**
+ * FilterStrategyInterface provides the interface to work with strategies
+ */
+interface FilterStrategyInterface
+{
+    /**
+     * @param \Magento\Framework\Search\Request\FilterInterface $filter
+     * @param \Magento\Framework\DB\Select $select
+     * @return bool is filter was applied
+     */
+    public function apply(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        \Magento\Framework\DB\Select $select
+    );
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb9d61b5a7f4c352d23096050a5acd292dc80d54
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\FilterMapper;
+
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+use Magento\Eav\Model\Config as EavConfig;
+
+/**
+ * This strategy handles static attributes
+ */
+class StaticAttributeStrategy implements FilterStrategyInterface
+{
+    /**
+     * @var \Magento\Framework\App\ResourceConnection
+     */
+    private $resourceConnection;
+
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
+
+    /**
+     * @var EavConfig
+     */
+    private $eavConfig;
+
+    /**
+     * @param \Magento\Framework\App\ResourceConnection $resourceConnection
+     * @param EavConfig $eavConfig
+     * @param AliasResolver $aliasResolver
+     */
+    public function __construct(
+        \Magento\Framework\App\ResourceConnection $resourceConnection,
+        EavConfig $eavConfig,
+        AliasResolver $aliasResolver
+    ) {
+        $this->resourceConnection = $resourceConnection;
+        $this->eavConfig = $eavConfig;
+        $this->aliasResolver = $aliasResolver;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function apply(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        \Magento\Framework\DB\Select $select
+    ) {
+        $attribute = $this->getAttributeByCode($filter->getField());
+        $alias = $this->aliasResolver->getAlias($filter);
+        $select->joinInner(
+            [$alias => $attribute->getBackendTable()],
+            'search_index.entity_id = '
+            . $this->resourceConnection->getConnection()->quoteIdentifier("$alias.entity_id"),
+            []
+        );
+        return true;
+    }
+
+    /**
+     * @param string $field
+     * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    private function getAttributeByCode($field)
+    {
+        return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php
new file mode 100644
index 0000000000000000000000000000000000000000..76828fe28f4348c8b90c9f1bf695906242c77222
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\FilterMapper;
+
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+use Magento\Eav\Model\Config as EavConfig;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+/**
+ * This strategy handles attributes which comply with two criteria:
+ *   - The filter for dropdown or multi-select attribute
+ *   - The filter is Term filter
+ *
+ */
+class TermDropdownStrategy implements FilterStrategyInterface
+{
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var EavConfig
+     */
+    private $eavConfig;
+
+    /**
+     * @var ResourceConnection
+     */
+    private $resourceConnection;
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     * @param ResourceConnection $resourceConnection
+     * @param EavConfig $eavConfig
+     * @param ScopeConfigInterface $scopeConfig
+     * @param AliasResolver $aliasResolver
+     */
+    public function __construct(
+        StoreManagerInterface $storeManager,
+        ResourceConnection $resourceConnection,
+        EavConfig $eavConfig,
+        ScopeConfigInterface $scopeConfig,
+        AliasResolver $aliasResolver
+    ) {
+        $this->storeManager = $storeManager;
+        $this->resourceConnection = $resourceConnection;
+        $this->eavConfig = $eavConfig;
+        $this->scopeConfig = $scopeConfig;
+        $this->aliasResolver = $aliasResolver;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function apply(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        \Magento\Framework\DB\Select $select
+    ) {
+        $alias = $this->aliasResolver->getAlias($filter);
+        $attribute = $this->getAttributeByCode($filter->getField());
+        $joinCondition = sprintf(
+            'search_index.entity_id = %1$s.entity_id AND %1$s.attribute_id = %2$d AND %1$s.store_id = %3$d',
+            $alias,
+            $attribute->getId(),
+            $this->storeManager->getWebsite()->getId()
+        );
+        $select->joinLeft(
+            [$alias => $this->resourceConnection->getTableName('catalog_product_index_eav')],
+            $joinCondition,
+            []
+        );
+        if ($this->isAddStockFilter()) {
+            $stockAlias = $alias . AliasResolver::STOCK_FILTER_SUFFIX;
+            $select->joinLeft(
+                [
+                    $stockAlias => $this->resourceConnection->getTableName('cataloginventory_stock_status'),
+                ],
+                sprintf('%2$s.product_id = %1$s.source_id', $alias, $stockAlias),
+                []
+            );
+        }
+
+        return true;
+    }
+
+    /**
+     * @param string $field
+     * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    private function getAttributeByCode($field)
+    {
+        return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field);
+    }
+
+    /**
+     * @return bool
+     */
+    private function isAddStockFilter()
+    {
+        $isShowOutOfStock = $this->scopeConfig->isSetFlag(
+            'cataloginventory/options/show_out_of_stock',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        return false === $isShowOutOfStock;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
index 1d30bb4a14d23a94d79a2faa5bc20823df220d8d..0e96e4de700259c9dc48c8f876983e2642316a86 100644
--- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
+++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
@@ -99,6 +99,7 @@ class IndexBuilder implements IndexBuilderInterface
      *
      * @param RequestInterface $request
      * @return Select
+     * @throws \LogicException
      */
     public function build(RequestInterface $request)
     {
@@ -132,7 +133,7 @@ class IndexBuilder implements IndexBuilderInterface
                 ),
                 []
             );
-            $select->where('stock_index.stock_status = ?', Stock::DEFAULT_STOCK_ID);
+            $select->where('stock_index.stock_status = ?', Stock::STOCK_IN_STOCK);
         }
 
         return $select;
diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php
index ca7298e1beaac560ee66427f2b9d57db7ce21508..ac726192856a5fa555eae6757cd83b16930565ee 100644
--- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php
+++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php
@@ -6,10 +6,11 @@
 
 namespace Magento\CatalogSearch\Model\Search;
 
-use Magento\Catalog\Model\Product;
 use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+use Magento\CatalogSearch\Model\Search\FilterMapper\FilterStrategyInterface;
 use Magento\Eav\Model\Config as EavConfig;
-use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\ObjectManager;
 use Magento\Framework\App\ResourceConnection as AppResource;
 use Magento\Framework\DB\Select;
@@ -21,12 +22,15 @@ use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
 use Magento\Store\Model\StoreManagerInterface;
 
 /**
+ * Responsibility of the TableMapper is to collect all filters from the search query
+ * and pass them one by one for processing in the FilterContext,
+ * which will apply them to the Select
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class TableMapper
 {
     /**
-     * @var Resource
+     * @var AppResource
      */
     private $resource;
 
@@ -40,22 +44,59 @@ class TableMapper
      */
     private $eavConfig;
 
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
+    /**
+     * @var FilterStrategyInterface
+     */
+    private $filterStrategy;
+
+    /**
+     * @var AliasResolver
+     */
+    private $aliasResolver;
+
     /**
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @param AppResource $resource
      * @param StoreManagerInterface $storeManager
      * @param CollectionFactory $attributeCollectionFactory
      * @param EavConfig $eavConfig
+     * @param ScopeConfigInterface $scopeConfig
+     * @param FilterStrategyInterface $filterStrategy
+     * @param AliasResolver $aliasResolver
      */
     public function __construct(
         AppResource $resource,
         StoreManagerInterface $storeManager,
         CollectionFactory $attributeCollectionFactory,
-        EavConfig $eavConfig = null
+        EavConfig $eavConfig = null,
+        ScopeConfigInterface $scopeConfig = null,
+        FilterStrategyInterface $filterStrategy = null,
+        AliasResolver $aliasResolver = null
     ) {
         $this->resource = $resource;
         $this->storeManager = $storeManager;
-        $this->eavConfig = $eavConfig !== null ? $eavConfig : ObjectManager::getInstance()->get(EavConfig::class);
+
+        if (null === $eavConfig) {
+            $eavConfig = ObjectManager::getInstance()->get(EavConfig::class);
+        }
+        if (null === $scopeConfig) {
+            $scopeConfig = ObjectManager::getInstance()->get(ScopeConfigInterface::class);
+        }
+        if (null === $filterStrategy) {
+            $filterStrategy = ObjectManager::getInstance()->get(FilterStrategyInterface::class);
+        }
+        if (null === $aliasResolver) {
+            $aliasResolver = ObjectManager::getInstance()->get(AliasResolver::class);
+        }
+        $this->eavConfig = $eavConfig;
+        $this->scopeConfig = $scopeConfig;
+        $this->filterStrategy = $filterStrategy;
+        $this->aliasResolver = $aliasResolver;
     }
 
     /**
@@ -66,111 +107,53 @@ class TableMapper
      */
     public function addTables(Select $select, RequestInterface $request)
     {
-        $mappedTables = [];
-        $filters = $this->getFilters($request->getQuery());
+        $appliedFilters = [];
+        $filters = $this->getFiltersFromQuery($request->getQuery());
         foreach ($filters as $filter) {
-            list($alias, $table, $mapOn, $mappedFields, $joinType) = $this->getMappingData($filter);
-            if (!array_key_exists($alias, $mappedTables)) {
-                switch ($joinType) {
-                    case \Magento\Framework\DB\Select::INNER_JOIN:
-                        $select->joinInner(
-                            [$alias => $table],
-                            $mapOn,
-                            $mappedFields
-                        );
-                        break;
-                    case \Magento\Framework\DB\Select::LEFT_JOIN:
-                        $select->joinLeft(
-                            [$alias => $table],
-                            $mapOn,
-                            $mappedFields
-                        );
-                        break;
-                    default:
-                        throw new \LogicException(__('Unsupported join type: %1', $joinType));
+            $alias = $this->aliasResolver->getAlias($filter);
+            if (!array_key_exists($alias, $appliedFilters)) {
+                $isApplied = $this->filterStrategy->apply($filter, $select);
+                if ($isApplied) {
+                    $appliedFilters[$alias] = true;
                 }
-                $mappedTables[$alias] = $table;
             }
         }
         return $select;
     }
 
     /**
+     * This method is deprecated.
+     * Please use \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver::getAlias() instead.
+     *
+     * @deprecated
+     * @see AliasResolver::getAlias()
+     *
      * @param FilterInterface $filter
      * @return string
      */
     public function getMappingAlias(FilterInterface $filter)
     {
-        list($alias) = $this->getMappingData($filter);
-        return $alias;
-    }
-
-    /**
-     * Returns mapping data for field in format: [
-     *  'table_alias',
-     *  'table',
-     *  'join_condition',
-     *  ['fields'],
-     *  'joinType'
-     * ]
-     * @param FilterInterface $filter
-     * @return array
-     */
-    private function getMappingData(FilterInterface $filter)
-    {
-        $alias = null;
-        $table = null;
-        $mapOn = null;
-        $mappedFields = null;
-        $field = $filter->getField();
-        $joinType = \Magento\Framework\DB\Select::INNER_JOIN;
-        $fieldToTableMap = $this->getFieldToTableMap($field);
-        if ($fieldToTableMap) {
-            list($alias, $table, $mapOn, $mappedFields) = $fieldToTableMap;
-            $table = $this->resource->getTableName($table);
-        } elseif ($attribute = $this->getAttributeByCode($field)) {
-            if ($filter->getType() === FilterInterface::TYPE_TERM
-                && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true)
-            ) {
-                $joinType = \Magento\Framework\DB\Select::LEFT_JOIN;
-                $table = $this->resource->getTableName('catalog_product_index_eav');
-                $alias = $field . RequestGenerator::FILTER_SUFFIX;
-                $mapOn = sprintf(
-                    'search_index.entity_id = %1$s.entity_id AND %1$s.attribute_id = %2$d AND %1$s.store_id = %3$d',
-                    $alias,
-                    $attribute->getId(),
-                    $this->getStoreId()
-                );
-                $mappedFields = [];
-            } elseif ($attribute->getBackendType() === AbstractAttribute::TYPE_STATIC) {
-                $table = $attribute->getBackendTable();
-                $alias = $field . RequestGenerator::FILTER_SUFFIX;
-                $mapOn = 'search_index.entity_id = ' . $alias . '.entity_id';
-                $mappedFields = null;
-            }
-        }
-
-        return [$alias, $table, $mapOn, $mappedFields, $joinType];
+        return $this->aliasResolver->getAlias($filter);
     }
 
     /**
      * @param RequestQueryInterface $query
      * @return FilterInterface[]
      */
-    private function getFilters($query)
+    private function getFiltersFromQuery(RequestQueryInterface $query)
     {
         $filters = [];
         switch ($query->getType()) {
             case RequestQueryInterface::TYPE_BOOL:
                 /** @var \Magento\Framework\Search\Request\Query\BoolExpression $query */
                 foreach ($query->getMust() as $subQuery) {
-                    $filters = array_merge($filters, $this->getFilters($subQuery));
+                    $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery));
                 }
                 foreach ($query->getShould() as $subQuery) {
-                    $filters = array_merge($filters, $this->getFilters($subQuery));
+                    $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery));
                 }
                 foreach ($query->getMustNot() as $subQuery) {
-                    $filters = array_merge($filters, $this->getFilters($subQuery));
+                    $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery));
                 }
                 break;
             case RequestQueryInterface::TYPE_FILTER:
@@ -219,57 +202,4 @@ class TableMapper
         }
         return $filters;
     }
-
-    /**
-     * @return int
-     */
-    private function getWebsiteId()
-    {
-        return $this->storeManager->getWebsite()->getId();
-    }
-
-    /**
-     * @return int
-     */
-    private function getStoreId()
-    {
-        return $this->storeManager->getStore()->getId();
-    }
-
-    /**
-     * @param string $field
-     * @return array|null
-     */
-    private function getFieldToTableMap($field)
-    {
-        $fieldToTableMap = [
-            'price' => [
-                'price_index',
-                'catalog_product_index_price',
-                $this->resource->getConnection()->quoteInto(
-                    'search_index.entity_id = price_index.entity_id AND price_index.website_id = ?',
-                    $this->getWebsiteId()
-                ),
-                []
-            ],
-            'category_ids' => [
-                'category_ids_index',
-                'catalog_category_product_index',
-                'search_index.entity_id = category_ids_index.product_id',
-                []
-            ]
-        ];
-        return array_key_exists($field, $fieldToTableMap) ? $fieldToTableMap[$field] : null;
-    }
-
-    /**
-     * @param string $field
-     * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
-     * @throws \Magento\Framework\Exception\LocalizedException
-     */
-    private function getAttributeByCode($field)
-    {
-        $attribute = $this->eavConfig->getAttribute(Product::ENTITY, $field);
-        return $attribute;
-    }
 }
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab01d2553a3edcebde8a564a8ca8b8bb8cf2c7dd
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Test\Unit\Model\Adapter\Mysql\Filter;
+
+use Magento\CatalogSearch\Model\Search\RequestGenerator;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class AliasResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver
+     */
+    private $aliasResolver;
+
+    /**
+     * @inheritDoc
+     */
+    protected function setUp()
+    {
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->aliasResolver = $objectManagerHelper->getObject(
+            \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver::class,
+            []
+        );
+    }
+
+    /**
+     * @param string $field
+     * @param string $expectedAlias
+     * @dataProvider aliasDataProvider
+     */
+    public function testGetFilterAlias($field, $expectedAlias)
+    {
+        $filter = $this->getMockBuilder(\Magento\Framework\Search\Request\Filter\Term::class)
+            ->setMethods(['getField'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filter->expects($this->once())
+            ->method('getField')
+            ->willReturn($field);
+        $this->assertSame($expectedAlias, $this->aliasResolver->getAlias($filter));
+    }
+
+    /**
+     * @return array
+     */
+    public function aliasDataProvider()
+    {
+        return [
+            'general' => [
+                'field' => 'general',
+                'alias' => 'general' . RequestGenerator::FILTER_SUFFIX,
+            ],
+            'price' => [
+                'field' => 'price',
+                'alias' => 'price_index',
+            ],
+            'category_ids' => [
+                'field' => 'category_ids',
+                'alias' => 'category_ids_index',
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php
index 0949bf6469be92611fbefa4c45962d8255570892..2cd6935586bd816bcc8c1e444b242c3b3f7a1472 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php
@@ -6,6 +6,7 @@
 
 namespace Magento\CatalogSearch\Test\Unit\Model\Adapter\Mysql\Filter;
 
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
 use Magento\Framework\DB\Select;
 use Magento\Framework\EntityManager\EntityMetadata;
 use Magento\Framework\Search\Request\FilterInterface;
@@ -18,9 +19,9 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject;
 class PreprocessorTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\CatalogSearch\Model\Search\TableMapper|\PHPUnit_Framework_MockObject_MockObject
+     * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $tableMapper;
+    private $aliasResolver;
 
     /**
      * @var \Magento\Framework\DB\Adapter\AdapterInterface|MockObject
@@ -141,7 +142,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase
                 )
             );
 
-        $this->tableMapper = $this->getMockBuilder(\Magento\CatalogSearch\Model\Search\TableMapper::class)
+        $this->aliasResolver = $this->getMockBuilder(AliasResolver::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->metadataPoolMock = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class)
@@ -164,7 +165,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase
                 'resource' => $resource,
                 'attributePrefix' => 'attr_',
                 'metadataPool' => $this->metadataPoolMock,
-                'tableMapper' => $this->tableMapper,
+                'aliasResolver' => $this->aliasResolver,
             ]
         );
     }
@@ -234,7 +235,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase
 
         $this->attribute->method('getAttributeCode')
             ->willReturn('static_attribute');
-        $this->tableMapper->expects($this->once())->method('getMappingAlias')
+        $this->aliasResolver->expects($this->once())->method('getAlias')
             ->willReturn('attr_table_alias');
         $this->filter->expects($this->exactly(3))
             ->method('getField')
@@ -272,7 +273,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase
             ->method('getFrontendInput')
             ->willReturn($frontendInput);
 
-        $this->tableMapper->expects($this->once())->method('getMappingAlias')
+        $this->aliasResolver->expects($this->once())->method('getAlias')
             ->willReturn('termAttrAlias');
 
         $this->filter->expects($this->exactly(3))
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f133b763889bafb4843f7f9f868a3995a842eed
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Test\Unit\Model\Search\FilterMapper;
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
+use Magento\CatalogSearch\Model\Search\FilterMapper\ExclusionStrategy;
+use Magento\CatalogSearch\Model\Search\FilterMapper\FilterContext;
+use Magento\CatalogSearch\Model\Search\FilterMapper\StaticAttributeStrategy;
+use Magento\CatalogSearch\Model\Search\FilterMapper\TermDropdownStrategy;
+use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+use Magento\Framework\Search\Request\FilterInterface;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class FilterContextTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var FilterContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filterContext;
+
+    /**
+     * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $aliasResolver;
+
+    /**
+     * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eavConfig;
+
+    /**
+     * @var ExclusionStrategy|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $exclusionStrategy;
+
+    /**
+     * @var TermDropdownStrategy|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $termDropdownStrategy;
+
+    /**
+     * @var StaticAttributeStrategy|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $staticAttributeStrategy;
+
+    /**
+     * @var \Magento\Framework\DB\Select
+     */
+    private $select;
+
+    /**
+     * @inheritDoc
+     */
+    protected function setUp()
+    {
+        $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttribute'])
+            ->getMock();
+        $this->aliasResolver = $this->getMockBuilder(
+            AliasResolver::class
+        )
+            ->disableOriginalConstructor()
+            ->setMethods(['getAlias'])
+            ->getMock();
+        $this->exclusionStrategy = $this->getMockBuilder(ExclusionStrategy::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['apply'])
+            ->getMock();
+        $this->termDropdownStrategy = $this->getMockBuilder(TermDropdownStrategy::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['apply'])
+            ->getMock();
+        $this->staticAttributeStrategy = $this->getMockBuilder(StaticAttributeStrategy::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['apply'])
+            ->getMock();
+        $this->select = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
+            ->disableOriginalConstructor()
+            ->setMethods([])
+            ->getMock();
+        $objectManager = new ObjectManager($this);
+        $this->filterContext = $objectManager->getObject(
+            FilterContext::class,
+            [
+                'eavConfig' => $this->eavConfig,
+                'aliasResolver' => $this->aliasResolver,
+                'exclusionStrategy' => $this->exclusionStrategy,
+                'termDropdownStrategy' => $this->termDropdownStrategy,
+                'staticAttributeStrategy' => $this->staticAttributeStrategy,
+            ]
+        );
+    }
+
+    public function testApplyOnExclusionFilter()
+    {
+        $filter = $this->createFilterMock();
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(true);
+        $this->eavConfig->expects($this->never())->method('getAttribute');
+        $this->assertTrue($this->filterContext->apply($filter, $this->select));
+    }
+
+    public function testApplyFilterWithoutAttribute()
+    {
+        $filter = $this->createFilterMock('some_field');
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(false);
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(\Magento\Catalog\Model\Product::ENTITY, 'some_field')
+            ->willReturn(null);
+        $this->assertFalse($this->filterContext->apply($filter, $this->select));
+    }
+
+    public function testApplyOnTermFilterBySelect()
+    {
+        $filter = $this->createFilterMock('select_field', FilterInterface::TYPE_TERM);
+        $attribute = $this->createAttributeMock('select');
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(\Magento\Catalog\Model\Product::ENTITY, 'select_field')
+            ->willReturn($attribute);
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(false);
+        $this->termDropdownStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(true);
+        $this->assertTrue($this->filterContext->apply($filter, $this->select));
+    }
+
+    public function testApplyOnTermFilterByMultiSelect()
+    {
+        $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM);
+        $attribute = $this->createAttributeMock('multiselect');
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field')
+            ->willReturn($attribute);
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(false);
+        $this->termDropdownStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(true);
+        $this->assertTrue($this->filterContext->apply($filter, $this->select));
+    }
+
+    public function testApplyOnTermFilterByStaticAttribute()
+    {
+        $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM);
+        $attribute = $this->createAttributeMock('text', AbstractAttribute::TYPE_STATIC);
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field')
+            ->willReturn($attribute);
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(false);
+        $this->staticAttributeStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(true);
+        $this->assertTrue($this->filterContext->apply($filter, $this->select));
+    }
+
+    public function testApplyOnTermFilterByUnknownAttributeType()
+    {
+        $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM);
+        $attribute = $this->createAttributeMock('text', 'text');
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field')
+            ->willReturn($attribute);
+        $this->exclusionStrategy->expects($this->once())
+            ->method('apply')
+            ->with($filter, $this->select)
+            ->willReturn(false);
+        $this->assertFalse($this->filterContext->apply($filter, $this->select));
+    }
+
+    /**
+     * @param string $field
+     * @param string $type
+     * @return FilterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private function createFilterMock($field = null, $type = null)
+    {
+        $filter = $this->getMockBuilder(FilterInterface::class)
+            ->setMethods(['getField', 'getType'])
+            ->getMockForAbstractClass();
+        $filter->expects($this->any())
+            ->method('getField')
+            ->willReturn($field);
+        $filter->expects($this->any())
+            ->method('getType')
+            ->willReturn($type);
+
+        return $filter;
+    }
+
+    /**
+     * @param string|null $frontendInput
+     * @param string|null $backendType
+     * @return Attribute|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private function createAttributeMock($frontendInput = null, $backendType = null)
+    {
+        $attribute = $this->getMockBuilder(Attribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getFrontendInput', 'getBackendType'])
+            ->getMock();
+        $attribute->expects($this->any())
+            ->method('getFrontendInput')
+            ->willReturn($frontendInput);
+        $attribute->expects($this->any())
+            ->method('getBackendType')
+            ->willReturn($backendType);
+        return $attribute;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php
index dd9a556146ab3e40e4e1182f44c959c8260d9c8d..dad4ad8095f5af27fa3ce7cd48b1803c706d80a6 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php
@@ -6,6 +6,9 @@
 
 namespace Magento\CatalogSearch\Test\Unit\Model\Search;
 
+use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection;
+use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
+use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
 use Magento\Framework\Search\Request\FilterInterface;
 use Magento\Framework\Search\Request\QueryInterface;
 use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -16,8 +19,10 @@ use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  */
 class TableMapperTest extends \PHPUnit_Framework_TestCase
 {
-    const WEBSITE_ID = 4512;
-    const STORE_ID = 2514;
+    /**
+     * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $aliasResolver;
 
     /**
      * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
@@ -25,7 +30,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
     private $eavConfig;
 
     /**
-     * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection|\PHPUnit_Framework_MockObject_MockObject
+     * @var Collection|\PHPUnit_Framework_MockObject_MockObject
      */
     private $attributeCollection;
 
@@ -59,11 +64,6 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
      */
     private $resource;
 
-    /**
-     * @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $store;
-
     /**
      * @var \Magento\CatalogSearch\Model\Search\TableMapper
      */
@@ -76,65 +76,49 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->connection = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->connection->expects($this->any())
-            ->method('quoteInto')
-            ->willReturnCallback(
-                function ($query, $expression) {
-                    return str_replace('?', $expression, $query);
-                }
-            );
+        $this->connection->expects($this->never())->method('quoteInto');
 
         $this->resource = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->resource->method('getTableName')
-            ->willReturnCallback(
-                function ($table) {
-                    return 'prefix_' . $table;
-                }
-            );
-        $this->resource->expects($this->any())
-            ->method('getConnection')
-            ->willReturn($this->connection);
+        $this->resource->expects($this->never())->method('getTableName');
+        $this->resource->expects($this->never())->method('getConnection');
 
         $this->website = $this->getMockBuilder(\Magento\Store\Api\Data\WebsiteInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-        $this->website->expects($this->any())
-            ->method('getId')
-            ->willReturn(self::WEBSITE_ID);
-        $this->store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-        $this->store->expects($this->any())
-            ->method('getId')
-            ->willReturn(self::STORE_ID);
+        $this->website->expects($this->never())->method('getId');
+
         $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->storeManager->expects($this->any())
-            ->method('getWebsite')
-            ->willReturn($this->website);
-        $this->storeManager->expects($this->any())
-            ->method('getStore')
-            ->willReturn($this->store);
-        $this->attributeCollection = $this->getMockBuilder(
-            \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class
-        )
+        $this->storeManager->expects($this->never())->method('getWebsite');
+        $this->storeManager->expects($this->never())->method('getStore');
+
+        $this->attributeCollection = $this->getMockBuilder(Collection::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $attributeCollectionFactory = $this->getMockBuilder(
-            \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory::class
-        )
+        $attributeCollectionFactory = $this->getMockBuilder(CollectionFactory::class)
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
         $attributeCollectionFactory->expects($this->never())
             ->method('create');
+
         $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class)
             ->setMethods(['getAttribute'])
             ->disableOriginalConstructor()
             ->getMock();
+
+        $this->aliasResolver = $this->getMockBuilder(AliasResolver::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->aliasResolver->expects($this->any())
+            ->method('getAlias')
+            ->willReturnCallback(function (FilterInterface $filter) {
+                return $filter->getField() . '_alias';
+            });
+
         $this->target = $objectManager->getObject(
             \Magento\CatalogSearch\Model\Search\TableMapper::class,
             [
@@ -142,6 +126,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
                 'storeManager' => $this->storeManager,
                 'attributeCollectionFactory' => $attributeCollectionFactory,
                 'eavConfig' => $this->eavConfig,
+                'aliasResolver' => $this->aliasResolver,
             ]
         );
 
@@ -160,14 +145,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->once())
-            ->method('joinInner')
-            ->with(
-                ['price_index' => 'prefix_catalog_product_index_price'],
-                'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID,
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
@@ -176,18 +154,10 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
     {
         $priceFilter = $this->createRangeFilter('static');
         $query = $this->createFilterQuery($priceFilter);
-        $this->createAttributeMock('static', 'static', 'backend_table', 0, 'select');
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->once())
-            ->method('joinInner')
-            ->with(
-                ['static_filter' => 'backend_table'],
-                'search_index.entity_id = static_filter.entity_id',
-                null
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
@@ -199,46 +169,25 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->once())
-            ->method('joinInner')
-            ->with(
-                ['category_ids_index' => 'prefix_catalog_category_product_index'],
-                'search_index.entity_id = category_ids_index.product_id',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
 
     public function testAddTermFilter()
     {
-        $this->createAttributeMock('color', null, null, 132, 'select', 0);
         $categoryIdsFilter = $this->createTermFilter('color');
         $query = $this->createFilterQuery($categoryIdsFilter);
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->once())
-            ->method('joinLeft')
-            ->with(
-                ['color_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = color_filter.entity_id'
-                . ' AND color_filter.attribute_id = 132'
-                . ' AND color_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
 
     public function testAddBoolQueryWithTermFiltersInside()
     {
-        $this->createAttributeMock('must1', null, null, 101, 'select', 0);
-        $this->createAttributeMock('should1', null, null, 102, 'select', 1);
-        $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2);
-
         $query = $this->createBoolQuery(
             [
                 $this->createFilterQuery($this->createTermFilter('must1')),
@@ -253,45 +202,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->at(0))
-            ->method('joinLeft')
-            ->with(
-                ['must1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = must1_filter.entity_id'
-                . ' AND must1_filter.attribute_id = 101'
-                . ' AND must1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(1))
-            ->method('joinLeft')
-            ->with(
-                ['should1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = should1_filter.entity_id'
-                . ' AND should1_filter.attribute_id = 102'
-                . ' AND should1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(2))
-            ->method('joinLeft')
-            ->with(
-                ['mustNot1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = mustNot1_filter.entity_id'
-                . ' AND mustNot1_filter.attribute_id = 103'
-                . ' AND mustNot1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
 
     public function testAddBoolQueryWithTermAndPriceFiltersInside()
     {
-        $this->createAttributeMock('must1', null, null, 101, 'select', 0);
-        $this->createAttributeMock('should1', null, null, 102, 'select', 1);
-        $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2);
         $query = $this->createBoolQuery(
             [
                 $this->createFilterQuery($this->createTermFilter('must1')),
@@ -307,53 +224,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->at(0))
-            ->method('joinLeft')
-            ->with(
-                ['must1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = must1_filter.entity_id'
-                . ' AND must1_filter.attribute_id = 101'
-                . ' AND must1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(1))
-            ->method('joinInner')
-            ->with(
-                ['price_index' => 'prefix_catalog_product_index_price'],
-                'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID,
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(2))
-            ->method('joinLeft')
-            ->with(
-                ['should1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = should1_filter.entity_id'
-                . ' AND should1_filter.attribute_id = 102'
-                . ' AND should1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(3))
-            ->method('joinLeft')
-            ->with(
-                ['mustNot1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = mustNot1_filter.entity_id'
-                . ' AND mustNot1_filter.attribute_id = 103'
-                . ' AND mustNot1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
 
     public function testAddBoolFilterWithTermFiltersInside()
     {
-        $this->createAttributeMock('must1', null, null, 101, 'select', 0);
-        $this->createAttributeMock('should1', null, null, 102, 'select', 1);
-        $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2);
         $query = $this->createFilterQuery(
             $this->createBoolFilter(
                 [
@@ -370,45 +247,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->at(0))
-            ->method('joinLeft')
-            ->with(
-                ['must1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = must1_filter.entity_id'
-                . ' AND must1_filter.attribute_id = 101'
-                . ' AND must1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(1))
-            ->method('joinLeft')
-            ->with(
-                ['should1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = should1_filter.entity_id'
-                . ' AND should1_filter.attribute_id = 102'
-                . ' AND should1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(2))
-            ->method('joinLeft')
-            ->with(
-                ['mustNot1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = mustNot1_filter.entity_id'
-                . ' AND mustNot1_filter.attribute_id = 103'
-                . ' AND mustNot1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
 
     public function testAddBoolFilterWithBoolFiltersInside()
     {
-        $this->createAttributeMock('must1', null, null, 101, 'select', 0);
-        $this->createAttributeMock('should1', null, null, 102, 'select', 1);
-        $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2);
         $query = $this->createFilterQuery(
             $this->createBoolFilter(
                 [
@@ -425,36 +270,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())
             ->method('getQuery')
             ->willReturn($query);
-        $this->select->expects($this->at(0))
-            ->method('joinLeft')
-            ->with(
-                ['must1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = must1_filter.entity_id'
-                . ' AND must1_filter.attribute_id = 101'
-                . ' AND must1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(1))
-            ->method('joinLeft')
-            ->with(
-                ['should1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = should1_filter.entity_id'
-                . ' AND should1_filter.attribute_id = 102'
-                . ' AND should1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
-        $this->select->expects($this->at(2))
-            ->method('joinLeft')
-            ->with(
-                ['mustNot1_filter' => 'prefix_catalog_product_index_eav'],
-                'search_index.entity_id = mustNot1_filter.entity_id'
-                . ' AND mustNot1_filter.attribute_id = 103'
-                . ' AND mustNot1_filter.store_id = 2514',
-                []
-            )
-            ->willReturnSelf();
+
         $select = $this->target->addTables($this->select, $this->request);
         $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select');
     }
@@ -472,6 +288,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             ->willReturn(QueryInterface::TYPE_FILTER);
         $query->method('getReference')
             ->willReturn($filter);
+
         return $query;
     }
 
@@ -495,6 +312,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             ->willReturn($should);
         $query->method('getMustNot')
             ->willReturn($mustNot);
+
         return $query;
     }
 
@@ -518,6 +336,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             ->willReturn($should);
         $query->method('getMustNot')
             ->willReturn($mustNot);
+
         return $query;
     }
 
@@ -532,6 +351,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             FilterInterface::TYPE_RANGE,
             $field
         );
+
         return $filter;
     }
 
@@ -546,6 +366,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             FilterInterface::TYPE_TERM,
             $field
         );
+
         return $filter;
     }
 
@@ -564,40 +385,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase
             ->willReturn($type);
         $filter->method('getField')
             ->willReturn($field);
-        return $filter;
-    }
 
-    /**
-     * @param string $code
-     * @param string $backendType
-     * @param string $backendTable
-     * @param int $attributeId
-     * @param string $frontendInput
-     * @param int $positionInCollection
-     */
-    private function createAttributeMock(
-        $code,
-        $backendType = null,
-        $backendTable = null,
-        $attributeId = 120,
-        $frontendInput = 'select',
-        $positionInCollection = 0
-    ) {
-        $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
-            ->setMethods(['getBackendType', 'getBackendTable', 'getId', 'getFrontendInput'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $attribute->method('getId')
-            ->willReturn($attributeId);
-        $attribute->method('getBackendType')
-            ->willReturn($backendType);
-        $attribute->method('getBackendTable')
-            ->willReturn($backendTable);
-        $attribute->method('getFrontendInput')
-            ->willReturn($frontendInput);
-        $this->eavConfig->expects($this->at($positionInCollection))
-            ->method('getAttribute')
-            ->with(\Magento\Catalog\Model\Product::ENTITY, $code)
-            ->willReturn($attribute);
+        return $filter;
     }
 }
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 49756420bd2308cd1f8326f474395b6209c7450c..313cc99881a318799c15488fa742151e26db18ec 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-search",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-search": "100.2.*",
diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml
index f62b4e47767a25230c5c2ad8372f99acc6bda2eb..7e9451f9b83e7ada30455509b8fd686a0c251705 100644
--- a/app/code/Magento/CatalogSearch/etc/di.xml
+++ b/app/code/Magento/CatalogSearch/etc/di.xml
@@ -11,6 +11,7 @@
     <preference for="Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface" type="Magento\CatalogSearch\Model\Adapter\Mysql\Filter\Preprocessor" />
     <preference for="Magento\Framework\Search\Dynamic\DataProviderInterface" type="Magento\CatalogSearch\Model\Adapter\Mysql\Dynamic\DataProvider" />
     <preference for="Magento\Framework\Search\Adapter\OptionsInterface" type="Magento\CatalogSearch\Model\Adapter\Options" />
+    <preference for="Magento\CatalogSearch\Model\Search\FilterMapper\FilterStrategyInterface" type="Magento\CatalogSearch\Model\Search\FilterMapper\FilterContext"/>
     <type name="Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory">
         <arguments>
             <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json
index 8fd54cbc8ee8319f625cd6320954a0c821bf9a52..a5f66cd09dda49086434a4dc73b073fe7f0ee9c3 100644
--- a/app/code/Magento/CatalogUrlRewrite/composer.json
+++ b/app/code/Magento/CatalogUrlRewrite/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-url-rewrite",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-import-export": "100.2.*",
diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json
index 330f46176286c70822a32762dccfed157a2ce358..198e54db32d888dfc32eafd33f5c6b3ca45da870 100644
--- a/app/code/Magento/CatalogWidget/composer.json
+++ b/app/code/Magento/CatalogWidget/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-catalog-widget",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-widget": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml
index 080714bd228de24f0aa69cae014cb554ef814c53..212846aaa01d7efd067eb14a546b8dcb3467fc1f 100644
--- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml
+++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml
@@ -15,7 +15,6 @@
     $mode = 'grid';
 
     $image = 'new_products_content_widget_grid';
-    $title = $block->getTitle() ? __($block->getTitle()) : '';
     $items = $block->getProductCollection()->getItems();
 
     $showWishlist = true;
@@ -25,9 +24,9 @@
     $description = false;
 ?>
     <div class="block widget block-products-list <?php /* @noEscape */ echo $mode; ?>">
-        <?php if ($title): ?>
+        <?php if ($block->getTitle()): ?>
         <div class="block-title">
-            <strong><?php echo $block->escapeHtml($title); ?></strong>
+            <strong><?php echo $block->escapeHtml(__($block->getTitle())); ?></strong>
         </div>
         <?php endif ?>
         <div class="block-content">
@@ -64,27 +63,23 @@
                                             <div class="actions-primary">
                                                 <?php if ($_item->isSaleable()): ?>
                                                     <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?>
-                                                        <button class="action tocart primary"
-                                                                data-mage-init='{"redirectUrl":{"url":"<?php echo $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}'
-                                                                type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>">
-                                                            <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span>
+                                                        <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?php echo $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>">
+                                                            <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span>
                                                         </button>
                                                     <?php else: ?>
                                                         <?php
                                                             $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper');
                                                             $postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()])
                                                         ?>
-                                                        <button class="action tocart primary"
-                                                                data-post='<?php /* @noEscape */ echo $postData; ?>'
-                                                                type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>">
-                                                            <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span>
+                                                        <button class="action tocart primary" data-post='<?php /* @noEscape */ echo $postData; ?>' type="button" title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>">
+                                                            <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span>
                                                         </button>
                                                     <?php endif; ?>
                                                 <?php else: ?>
                                                     <?php if ($_item->getIsSalable()): ?>
-                                                        <div class="stock available"><span><?php /* @escapeNotVerified */ echo __('In stock') ?></span></div>
+                                                        <div class="stock available"><span><?php echo $block->escapeHtml(__('In stock')) ?></span></div>
                                                     <?php else: ?>
-                                                        <div class="stock unavailable"><span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span></div>
+                                                        <div class="stock unavailable"><span><?php echo $block->escapeHtml(__('Out of stock')) ?></span></div>
                                                     <?php endif; ?>
                                                 <?php endif; ?>
                                             </div>
@@ -93,18 +88,14 @@
                                             <div class="actions-secondary" data-role="add-to-links">
                                                 <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?>
                                                     <a href="#"
-                                                       data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($_item); ?>'
-                                                       class="action towishlist" data-action="add-to-wishlist"
-                                                       title="<?php /* @escapeNotVerified */ echo __('Add to Wish List') ?>">
-                                                        <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span>
+                                                       data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($_item); ?>' class="action towishlist" data-action="add-to-wishlist" title="<?php echo $block->escapeHtmlAttr(__('Add to Wish List')) ?>">
+                                                        <span><?php echo $block->escapeHtml(__('Add to Wish List')) ?></span>
                                                     </a>
                                                 <?php endif; ?>
                                                 <?php if ($block->getAddToCompareUrl() && $showCompare): ?>
                                                     <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?>
-                                                    <a href="#" class="action tocompare"
-                                                       data-post='<?php /* @noEscape */ echo $compareHelper->getPostDataParams($_item);?>'
-                                                       title="<?php /* @escapeNotVerified */ echo __('Add to Compare') ?>">
-                                                        <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span>
+                                                    <a href="#" class="action tocompare" data-post='<?php /* @noEscape */ echo $compareHelper->getPostDataParams($_item);?>' title="<?php echo $block->escapeHtmlAttr(__('Add to Compare')) ?>">
+                                                        <span><?php echo $block->escapeHtml(__('Add to Compare')) ?></span>
                                                     </a>
                                                 <?php endif; ?>
                                             </div>
diff --git a/app/code/Magento/Checkout/Controller/Cart/Add.php b/app/code/Magento/Checkout/Controller/Cart/Add.php
index fddfa63b5983e5f508f5211c19f8980d56aafc34..bfbf0008bf5892067aaa7b0ba53ca1bbb7632339 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Add.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Add.php
@@ -84,6 +84,7 @@ class Add extends \Magento\Checkout\Controller\Cart
         }
 
         $params = $this->getRequest()->getParams();
+
         try {
             if (isset($params['qty'])) {
                 $filter = new \Zend_Filter_LocalizedToNormalized(
diff --git a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
index 2b3f65728068bee22560f06943f88eea69e36d79..0498b22d550e7f8c78cc2af53819a31aebeb3d47 100644
--- a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
+++ b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
@@ -90,26 +90,17 @@ class CouponPost extends \Magento\Checkout\Controller\Cart
 
             if ($codeLength) {
                 $escaper = $this->_objectManager->get(\Magento\Framework\Escaper::class);
+                $coupon = $this->couponFactory->create();
+                $coupon->load($couponCode, 'code');
                 if (!$itemsCount) {
-                    if ($isCodeLengthValid) {
-                        $coupon = $this->couponFactory->create();
-                        $coupon->load($couponCode, 'code');
-                        if ($coupon->getId()) {
-                            $this->_checkoutSession->getQuote()->setCouponCode($couponCode)->save();
-                            $this->messageManager->addSuccess(
-                                __(
-                                    'You used coupon code "%1".',
-                                    $escaper->escapeHtml($couponCode)
-                                )
-                            );
-                        } else {
-                            $this->messageManager->addError(
-                                __(
-                                    'The coupon code "%1" is not valid.',
-                                    $escaper->escapeHtml($couponCode)
-                                )
-                            );
-                        }
+                    if ($isCodeLengthValid && $coupon->getId()) {
+                        $this->_checkoutSession->getQuote()->setCouponCode($couponCode)->save();
+                        $this->messageManager->addSuccess(
+                            __(
+                                'You used coupon code "%1".',
+                                $escaper->escapeHtml($couponCode)
+                            )
+                        );
                     } else {
                         $this->messageManager->addError(
                             __(
@@ -119,7 +110,7 @@ class CouponPost extends \Magento\Checkout\Controller\Cart
                         );
                     }
                 } else {
-                    if ($isCodeLengthValid && $couponCode == $cartQuote->getCouponCode()) {
+                    if ($isCodeLengthValid && $coupon->getId() && $couponCode == $cartQuote->getCouponCode()) {
                         $this->messageManager->addSuccess(
                             __(
                                 'You used coupon code "%1".',
diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php
index 4ce23c9c7f7090980d48f4c3bb231d4214a7e893..236c716f572d91e4bd4b88366414480567ccabc0 100644
--- a/app/code/Magento/Checkout/Model/Cart.php
+++ b/app/code/Magento/Checkout/Model/Cart.php
@@ -91,6 +91,11 @@ class Cart extends DataObject implements CartInterface
      */
     protected $productRepository;
 
+    /**
+     * @var \Magento\Checkout\Model\Cart\RequestInfoFilterInterface
+     */
+    private $requestInfoFilter;
+
     /**
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -315,6 +320,7 @@ class Cart extends DataObject implements CartInterface
      *
      * @param   \Magento\Framework\DataObject|int|array $requestInfo
      * @return  \Magento\Framework\DataObject
+     * @throws \Magento\Framework\Exception\LocalizedException
      */
     protected function _getProductRequest($requestInfo)
     {
@@ -322,11 +328,14 @@ class Cart extends DataObject implements CartInterface
             $request = $requestInfo;
         } elseif (is_numeric($requestInfo)) {
             $request = new \Magento\Framework\DataObject(['qty' => $requestInfo]);
-        } else {
+        } elseif (is_array($requestInfo)) {
             $request = new \Magento\Framework\DataObject($requestInfo);
+        } else {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                __('We found an invalid request for adding product to quote.')
+            );
         }
-
-        !$request->hasFormKey() ?: $request->unsFormKey();
+        $this->getRequestInfoFilter()->filter($request);
 
         return $request;
     }
@@ -722,4 +731,19 @@ class Cart extends DataObject implements CartInterface
         $this->_checkoutSession->setLastAddedProductId($productId);
         return $result;
     }
+
+    /**
+     * Getter for RequestInfoFilter
+     *
+     * @deprecated
+     * @return \Magento\Checkout\Model\Cart\RequestInfoFilterInterface
+     */
+    private function getRequestInfoFilter()
+    {
+        if ($this->requestInfoFilter === null) {
+            $this->requestInfoFilter = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Checkout\Model\Cart\RequestInfoFilterInterface::class);
+        }
+        return $this->requestInfoFilter;
+    }
 }
diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..10f3b81386b8febcee8f2b49ee4acd6242d1e5e8
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model\Cart;
+
+/**
+ * Class RequestInfoFilter used for filtering data from a request
+ */
+class RequestInfoFilter implements RequestInfoFilterInterface
+{
+    /**
+     * @var array $params
+     */
+    private $filterList;
+
+    /**
+     * @param array $filterList
+     */
+    public function __construct(
+        array $filterList = []
+    ) {
+        $this->filterList = $filterList;
+    }
+
+    /**
+     * Filters the data with values from filterList
+     *
+     * @param \Magento\Framework\DataObject $params
+     * @return $this
+     */
+    public function filter(\Magento\Framework\DataObject $params)
+    {
+        foreach ($this->filterList as $filterKey) {
+            /** @var string $filterKey */
+            if ($params->hasData($filterKey)) {
+                $params->unsetData($filterKey);
+            }
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ef24c0a5f28a198be28cbb4fc0ba212ebbd9097
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model\Cart;
+
+/**
+ * Class RequestInfoFilterComposite
+ */
+class RequestInfoFilterComposite implements RequestInfoFilterInterface
+{
+    /**
+     * @var RequestInfoFilter[] $params
+     */
+    private $filters = [];
+
+    /**
+     * @param RequestInfoFilter[] $filters
+     */
+    public function __construct(
+        $filters = []
+    ) {
+        $this->filters = $filters;
+    }
+
+    /**
+     * Loops through all leafs of the composite and calls filter method
+     *
+     * @param \Magento\Framework\DataObject $params
+     * @return $this
+     */
+    public function filter(\Magento\Framework\DataObject $params)
+    {
+        foreach ($this->filters as $filter) {
+            $filter->filter($params);
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bd268f6c896e149bf042ccdbaaa85e411ec6153
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model\Cart;
+
+/**
+ * Interface RequestInfoFilterInterface used by composite and leafs to implement filtering
+ */
+interface RequestInfoFilterInterface
+{
+    /**
+     * Filters the data object by an array of parameters
+     *
+     * @param \Magento\Framework\DataObject $params
+     * @return RequestInfoFilterInterface
+     */
+    public function filter(\Magento\Framework\DataObject $params);
+}
diff --git a/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php
index b07e90384c1647b51d59405022bb63a0b8e108d3..f2ad294d06cbe45d0b5d77ebe8658d546d27efd3 100644
--- a/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php
@@ -9,6 +9,9 @@ namespace Magento\Checkout\Model;
 use Magento\Quote\Api\CartRepositoryInterface;
 use Magento\Framework\Exception\CouldNotSaveException;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPaymentInformationManagementInterface
 {
 
@@ -42,6 +45,11 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa
      */
     protected $cartRepository;
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    private $logger;
+
     /**
      * @param \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement
      * @param \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement
@@ -79,7 +87,13 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa
         $this->savePaymentInformation($cartId, $email, $paymentMethod, $billingAddress);
         try {
             $orderId = $this->cartManagement->placeOrder($cartId);
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            throw new CouldNotSaveException(
+                __($e->getMessage()),
+                $e
+            );
         } catch (\Exception $e) {
+            $this->getLogger()->critical($e);
             throw new CouldNotSaveException(
                 __('An error occurred on the server. Please try to place the order again.'),
                 $e
@@ -117,4 +131,18 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa
         $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
         return $this->paymentInformationManagement->getPaymentInformation($quoteIdMask->getQuoteId());
     }
+
+    /**
+     * Get logger instance
+     *
+     * @return \Psr\Log\LoggerInterface
+     * @deprecated
+     */
+    private function getLogger()
+    {
+        if (!$this->logger) {
+            $this->logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
+        }
+        return $this->logger;
+    }
 }
diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php
index 140917dcdfeff22eaa73b9a1dc928d5d83f6ccd5..79e76feb4366190cb1d81389e7c54ac4f97cca9e 100644
--- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php
@@ -7,6 +7,9 @@ namespace Magento\Checkout\Model;
 
 use Magento\Framework\Exception\CouldNotSaveException;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInformationManagementInterface
 {
     /**
@@ -34,6 +37,11 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
      */
     protected $cartTotalsRepository;
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    private $logger;
+
     /**
      * @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement
      * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
@@ -67,7 +75,13 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
         $this->savePaymentInformation($cartId, $paymentMethod, $billingAddress);
         try {
             $orderId = $this->cartManagement->placeOrder($cartId);
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            throw new CouldNotSaveException(
+                __($e->getMessage()),
+                $e
+            );
         } catch (\Exception $e) {
+            $this->getLogger()->critical($e);
             throw new CouldNotSaveException(
                 __('An error occurred on the server. Please try to place the order again.'),
                 $e
@@ -102,4 +116,18 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor
         $paymentDetails->setTotals($this->cartTotalsRepository->get($cartId));
         return $paymentDetails;
     }
+
+    /**
+     * Get logger instance
+     *
+     * @return \Psr\Log\LoggerInterface
+     * @deprecated
+     */
+    private function getLogger()
+    {
+        if (!$this->logger) {
+            $this->logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
+        }
+        return $this->logger;
+    }
 }
diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php
index 16ffb7c2b1437da5e7ffadcc6ebe2fc4b3c479d3..93100df3d8c32182912d59f96f9149200f5f0139 100644
--- a/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php
@@ -69,6 +69,16 @@ class CouponPostTest extends \PHPUnit_Framework_TestCase
      */
     protected $quoteRepository;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $redirect;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $redirectFactory;
+
     /**
      * @return void
      */
@@ -204,6 +214,12 @@ class CouponPostTest extends \PHPUnit_Framework_TestCase
             ->method('getCouponCode')
             ->willReturn('OLDCODE');
 
+        $coupon = $this->getMock(\Magento\SalesRule\Model\Coupon::class, [], [], '', false);
+        $this->couponFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($coupon);
+        $coupon->expects($this->once())->method('load')->willReturnSelf();
+        $coupon->expects($this->once())->method('getId')->willReturn(1);
         $this->quote->expects($this->any())
             ->method('getItemsCount')
             ->willReturn(1);
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c758cf4661fdab253a58b04f70969dc845e89d1
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Model\Cart;
+
+/**
+ * Class RequestInfoFilterTest
+ */
+class RequestInfoFilterCompositeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Checkout\Model\Cart\RequestInfoFilterComposite
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Setup the test
+     */
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $requestInfoFilterMock1  = $this->getMock(
+            \Magento\Checkout\Model\Cart\RequestInfoFilter::class,
+            ['filter'],
+            [],
+            '',
+            false
+        );
+        $requestInfoFilterMock2  = $this->getMock(
+            \Magento\Checkout\Model\Cart\RequestInfoFilter::class,
+            ['filter'],
+            [],
+            '',
+            false
+        );
+
+        $requestInfoFilterMock1->expects($this->atLeastOnce())
+            ->method('filter');
+        $requestInfoFilterMock2->expects($this->atLeastOnce())
+            ->method('filter');
+
+        $filterList = [ $requestInfoFilterMock1, $requestInfoFilterMock2];
+
+        $this->model = $this->objectManager->getObject(
+            \Magento\Checkout\Model\Cart\RequestInfoFilterComposite::class,
+            [
+                'filters' => $filterList,
+            ]
+        );
+    }
+
+    /**
+     * Test Filter method
+     */
+    public function testFilter()
+    {
+        /** @var \Magento\Framework\DataObject $params */
+        $params = $this->objectManager->getObject(
+            \Magento\Framework\DataObject::class,
+            ['data' => ['abc' => 1, 'efg' => 1, 'xyz' => 1]]
+        );
+        $result = $this->model->filter($params);
+        $this->assertEquals($this->model, $result);
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd6ca330da1b2d7252b8911f1820d7bc217d3561
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Model\Cart;
+
+/**
+ * Class RequestInfoFilterTest
+ */
+class RequestInfoFilterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Checkout\Model\Cart\RequestInfoFilter
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Setup the test
+     */
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->model = $this->objectManager->getObject(
+            \Magento\Checkout\Model\Cart\RequestInfoFilter::class,
+            [
+                'filterList' => ['efg', 'xyz'],
+            ]
+        );
+    }
+
+    /**
+     * Test Filter method
+     */
+    public function testFilter()
+    {
+        /** @var \Magento\Framework\DataObject $params */
+        $params = $this->objectManager->getObject(
+            \Magento\Framework\DataObject::class,
+            ['data' => ['abc' => 1, 'efg' => 1, 'xyz' => 1]]
+        );
+        $result = $this->model->filter($params);
+        $this->assertEquals($this->model, $result);
+        $this->assertEquals(['abc' => 1], $params->convertToArray());
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php
index 199e6692e68d1777c382c8125391cac88326a549..9984fe12d3792e95f0b29d0d2c71ff36b37a5897 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php
@@ -29,7 +29,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
      */
     protected $customerSessionMock;
 
-    /** @var \Magento\CatalogInventory\Api\StockItem|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\CatalogInventory\Api\Data\StockItemInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $stockItemMock;
 
     /**
@@ -57,16 +57,39 @@ class CartTest extends \PHPUnit_Framework_TestCase
      */
     protected $stockState;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $productRepository;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $requestInfoFilterMock;
+
     protected function setUp()
     {
         $this->checkoutSessionMock = $this->getMock(\Magento\Checkout\Model\Session::class, [], [], '', false);
         $this->customerSessionMock = $this->getMock(\Magento\Customer\Model\Session::class, [], [], '', false);
         $this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class);
+        $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
+        $this->eventManagerMock = $this->getMock(\Magento\Framework\Event\ManagerInterface::class);
+        $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class);
+        $this->productRepository = $this->getMock(\Magento\Catalog\Api\ProductRepositoryInterface::class);
         $this->stockRegistry = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockRegistry::class)
             ->disableOriginalConstructor()
             ->setMethods(['getStockItem', '__wakeup'])
             ->getMock();
-
         $this->stockItemMock = $this->getMock(
             \Magento\CatalogInventory\Model\Stock\Item::class,
             ['getMinSaleQty', '__wakeup'],
@@ -74,7 +97,6 @@ class CartTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-
         $this->stockState = $this->getMock(
             \Magento\CatalogInventory\Model\StockState::class,
             ['suggestQty', '__wakeup'],
@@ -82,12 +104,22 @@ class CartTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->storeMock =
+            $this->getMock(\Magento\Store\Model\Store::class, ['getWebsiteId', 'getId', '__wakeup'], [], '', false);
+        $this->requestInfoFilterMock = $this->getMock(\Magento\Checkout\Model\Cart\RequestInfoFilterInterface::class);
 
         $this->stockRegistry->expects($this->any())
             ->method('getStockItem')
             ->will($this->returnValue($this->stockItemMock));
-        $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
-        $this->eventManagerMock = $this->getMock(\Magento\Framework\Event\ManagerInterface::class);
+        $this->storeMock->expects($this->any())
+            ->method('getWebsiteId')
+            ->will($this->returnValue(10));
+        $this->storeMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(10));
+        $this->storeManagerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
 
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->cart = $this->objectManagerHelper->getObject(
@@ -98,9 +130,14 @@ class CartTest extends \PHPUnit_Framework_TestCase
                 'stockRegistry' => $this->stockRegistry,
                 'stockState' => $this->stockState,
                 'customerSession' => $this->customerSessionMock,
-                'eventManager' => $this->eventManagerMock
+                'eventManager' => $this->eventManagerMock,
+                'storeManager' => $this->storeManagerMock,
+                'productRepository' => $this->productRepository
             ]
         );
+
+        $this->objectManagerHelper
+            ->setBackwardCompatibleProperty($this->cart, 'requestInfoFilter', $this->requestInfoFilterMock);
     }
 
     public function testSuggestItemsQty()
@@ -169,10 +206,17 @@ class CartTest extends \PHPUnit_Framework_TestCase
      */
     public function prepareQuoteItemMock($itemId)
     {
-        $store = $this->getMock(\Magento\Store\Model\Store::class, ['getWebsiteId', '__wakeup'], [], '', false);
+        $store = $this->getMock(\Magento\Store\Model\Store::class, ['getId', '__wakeup'], [], '', false);
         $store->expects($this->any())
             ->method('getWebsiteId')
             ->will($this->returnValue(10));
+        $store->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(10));
+        $this->storeManagerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
         switch ($itemId) {
             case 2:
                 $product = $this->getMock(
@@ -255,4 +299,162 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ['useQty' => false]
         ];
     }
+
+    /**
+     * Test successful scenarios for AddProduct
+     *
+     * @param int|\Magento\Catalog\Model\Product $productInfo
+     * @param \Magento\Framework\DataObject|int|array $requestInfo
+     * @dataProvider addProductDataProvider
+     */
+    public function testAddProduct($productInfo, $requestInfo)
+    {
+        $product = $this->getMock(
+            \Magento\Catalog\Model\Product::class,
+            ['getStore', 'getWebsiteIds', 'getProductUrl', 'getId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $product->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(4));
+        $product->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+        $product->expects($this->any())
+            ->method('getWebsiteIds')
+            ->will($this->returnValue([10]));
+        $product->expects($this->any())
+            ->method('getProductUrl')
+            ->will($this->returnValue('url'));
+        $this->productRepository->expects($this->any())
+            ->method('getById')
+            ->will($this->returnValue($product));
+        $this->quoteMock->expects($this->once())
+        ->method('addProduct')
+        ->will($this->returnValue(1));
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->will($this->returnValue($this->quoteMock));
+
+        $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with(
+            'checkout_cart_product_add_after',
+            ['quote_item' => 1, 'product' => $product]
+        );
+
+        if (!$productInfo) {
+            $productInfo = $product;
+        }
+        $result = $this->cart->addProduct($productInfo, $requestInfo);
+        $this->assertSame($this->cart, $result);
+    }
+
+    /**
+     * Test exception on adding product for AddProduct
+     *
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function testAddProductException()
+    {
+        $product = $this->getMock(
+            \Magento\Catalog\Model\Product::class,
+            ['getStore', 'getWebsiteIds', 'getProductUrl', 'getId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $product->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(4));
+        $product->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+        $product->expects($this->any())
+            ->method('getWebsiteIds')
+            ->will($this->returnValue([10]));
+        $product->expects($this->any())
+            ->method('getProductUrl')
+            ->will($this->returnValue('url'));
+        $this->productRepository->expects($this->any())
+            ->method('getById')
+            ->will($this->returnValue($product));
+        $this->quoteMock->expects($this->once())
+            ->method('addProduct')
+            ->will($this->returnValue('error'));
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->will($this->returnValue($this->quoteMock));
+
+        $this->eventManagerMock->expects($this->never())->method('dispatch')->with(
+            'checkout_cart_product_add_after',
+            ['quote_item' => 1, 'product' => $product]
+        );
+        $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class);
+        $this->cart->addProduct(4, 4);
+    }
+
+    /**
+     * Test bad parameters on adding product for AddProduct
+     *
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function testAddProductExceptionBadParams()
+    {
+        $product = $this->getMock(
+            \Magento\Catalog\Model\Product::class,
+            ['getWebsiteIds', 'getId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $product->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(4));
+        $product->expects($this->any())
+            ->method('getWebsiteIds')
+            ->will($this->returnValue([10]));
+        $this->productRepository->expects($this->any())
+            ->method('getById')
+            ->will($this->returnValue($product));
+
+        $this->eventManagerMock->expects($this->never())->method('dispatch')->with(
+            'checkout_cart_product_add_after',
+            ['quote_item' => 1, 'product' => $product]
+        );
+        $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class);
+        $this->cart->addProduct(4, 'bad');
+    }
+
+    /**
+     * Data provider for testAddProduct
+     *
+     * @return array
+     */
+    public function addProductDataProvider()
+    {
+        $obj = new ObjectManagerHelper($this) ;
+        $data = ['qty' => 5.5, 'sku' => 'prod'];
+
+        return [
+            'prod_int_info_int' => [4, 4],
+            'prod_int_info_array' => [ 4, $data],
+            'prod_int_info_object' => [
+                4,
+                $obj->getObject(
+                    \Magento\Framework\DataObject::class,
+                    ['data' => $data]
+                )
+            ],
+            'prod_obj_info_int' => [null, 4],
+            'prod_obj_info_array' => [ null, $data],
+            'prod_obj_info_object' => [
+                null,
+                $obj->getObject(
+                    \Magento\Framework\DataObject::class,
+                    ['data' => $data]
+                )
+            ]
+        ];
+    }
 }
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php
index 093bbf4a5accc66bdd5c00fa4f30660409e09f79..76cbafb48ebd47e4fd83d01ef1361ef29df2f3be 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php
@@ -42,6 +42,11 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $model;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $loggerMock;
+
     protected function setUp()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -61,6 +66,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class);
         $this->model = $objectManager->getObject(
             \Magento\Checkout\Model\GuestPaymentInformationManagement::class,
             [
@@ -71,6 +77,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
                 'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock
             ]
         );
+        $objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock);
     }
 
     public function testSavePaymentInformationAndPlaceOrder()
@@ -112,7 +119,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
             ->method('assign')
             ->with($cartId, $billingAddressMock);
         $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock);
-        $exception = new CouldNotSaveException(__('DB exception'));
+        $exception = new \Exception(__('DB exception'));
         $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception);
 
         $this->model->savePaymentInformationAndPlaceOrder($cartId, $email, $paymentMock, $billingAddressMock);
@@ -161,4 +168,29 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
         $billingAddressMock->expects($this->once())->method('setEmail')->with($email);
         $this->assertTrue($this->model->savePaymentInformation($cartId, $email, $paymentMock));
     }
+
+    /**
+     * @expectedExceptionMessage DB exception
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function testSavePaymentInformationAndPlaceOrderWithLocolizedException()
+    {
+        $cartId = 100;
+        $email = 'email@magento.com';
+        $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class);
+        $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+
+        $billingAddressMock->expects($this->once())->method('setEmail')->with($email)->willReturnSelf();
+
+        $this->billingAddressManagementMock->expects($this->once())
+            ->method('assign')
+            ->with($cartId, $billingAddressMock);
+        $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock);
+        $phrase = new \Magento\Framework\Phrase(__('DB exception'));
+        $exception = new \Magento\Framework\Exception\LocalizedException($phrase);
+        $this->loggerMock->expects($this->never())->method('critical');
+        $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception);
+
+        $this->model->savePaymentInformationAndPlaceOrder($cartId, $email, $paymentMock, $billingAddressMock);
+    }
 }
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php
index 496054b2c7b1e0a0b9e60c119a8c25d322832a26..8da67a1fcb71512dd218a2c62d51b7922bb36c25 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php
@@ -29,6 +29,11 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $model;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $loggerMock;
+
     protected function setUp()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -40,6 +45,8 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
         );
         $this->cartManagementMock = $this->getMock(\Magento\Quote\Api\CartManagementInterface::class);
 
+        $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class);
+
         $this->model = $objectManager->getObject(
             \Magento\Checkout\Model\PaymentInformationManagement::class,
             [
@@ -48,6 +55,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
                 'cartManagement' => $this->cartManagementMock
             ]
         );
+        $objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock);
     }
 
     public function testSavePaymentInformationAndPlaceOrder()
@@ -83,7 +91,8 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
             ->method('assign')
             ->with($cartId, $billingAddressMock);
         $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock);
-        $exception = new CouldNotSaveException(__('DB exception'));
+        $exception = new \Exception(__('DB exception'));
+        $this->loggerMock->expects($this->once())->method('critical');
         $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception);
 
         $this->model->savePaymentInformationAndPlaceOrder($cartId, $paymentMock, $billingAddressMock);
@@ -129,4 +138,26 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase
 
         $this->assertTrue($this->model->savePaymentInformation($cartId, $paymentMock));
     }
+
+    /**
+     * @expectedExceptionMessage DB exception
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function testSavePaymentInformationAndPlaceOrderWithLocolizedException()
+    {
+        $cartId = 100;
+        $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class);
+        $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+
+        $this->billingAddressManagementMock->expects($this->once())
+            ->method('assign')
+            ->with($cartId, $billingAddressMock);
+        $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock);
+        $phrase = new \Magento\Framework\Phrase(__('DB exception'));
+        $exception = new \Magento\Framework\Exception\LocalizedException($phrase);
+        $this->loggerMock->expects($this->never())->method('critical');
+        $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception);
+
+        $this->model->savePaymentInformationAndPlaceOrder($cartId, $paymentMock, $billingAddressMock);
+    }
 }
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index 5545e409b65abb3fb381e593c4ec34298dba6b80..60919d9fa2ca949817641c43328ad3be88edc8be 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-checkout",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-sales": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml
index c55598fdff5e792dd7404967d12f9fcc5e78e828..a2243b33a04edc0af4dc71ed79b802eac68f4cc2 100644
--- a/app/code/Magento/Checkout/etc/di.xml
+++ b/app/code/Magento/Checkout/etc/di.xml
@@ -26,4 +26,20 @@
     <preference for="Magento\Checkout\Api\GuestTotalsInformationManagementInterface" type="Magento\Checkout\Model\GuestTotalsInformationManagement" />
     <preference for="Magento\Checkout\Api\TotalsInformationManagementInterface" type="Magento\Checkout\Model\TotalsInformationManagement" />
     <preference for="Magento\Checkout\Api\AgreementsValidatorInterface" type="Magento\Checkout\Model\AgreementsValidator" />
+    <preference for="Magento\Checkout\Model\Cart\RequestInfoFilterInterface"
+                type="Magento\Checkout\Model\Cart\RequestInfoFilterComposite"/>
+    <type name="Magento\Checkout\Model\Cart\RequestInfoFilter">
+        <arguments>
+            <argument name="filterList" xsi:type="array">
+                <item name="form_key" xsi:type="string">form_key</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Checkout\Model\Cart\RequestInfoFilterComposite">
+        <arguments>
+            <argument name="filters" xsi:type="array">
+                <item name="filter" xsi:type="object">Magento\Checkout\Model\Cart\RequestInfoFilter</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Checkout/etc/frontend/di.xml b/app/code/Magento/Checkout/etc/frontend/di.xml
index bccf81bcb6ee81c97bd6bef98d3c5f08ec33b9cc..6fb9058c3b7681c8905a40a5eace5d88d8566b6f 100644
--- a/app/code/Magento/Checkout/etc/frontend/di.xml
+++ b/app/code/Magento/Checkout/etc/frontend/di.xml
@@ -72,4 +72,12 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Checkout\Model\Cart\RequestInfoFilter">
+        <arguments>
+            <argument name="filterList" xsi:type="array">
+                <item name="form_key" xsi:type="string">form_key</item>
+                <item name="custom_price" xsi:type="string">custom_price</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js b/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js
index ca9d6493a16740f1a43555d84459df4403bd3c88..9005015d2460e12c5462551aecce97f1bd31c003 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js
@@ -24,7 +24,7 @@ define([
             /**
              * Stop full page loader action
              *
-             * @param {Boolean} forceStop
+             * @param {Boolean} [forceStop]
              */
             stopLoader: function (forceStop) {
                 var $elem = $(containerId),
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
index e06b8922b2252fd497db66a79db35af8c543db09..eba77927be79ea6189884f412be03be7ec7a76be 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
@@ -7,9 +7,10 @@
 define([
     'jquery',
     'mage/template',
+    'underscore',
     'jquery/ui',
     'mage/validation'
-], function ($, mageTemplate) {
+], function ($, mageTemplate, _) {
     'use strict';
 
     $.widget('mage.regionUpdater', {
@@ -124,6 +125,8 @@ define([
          * @private
          */
         _clearError: function () {
+            var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId];
+
             if (this.options.clearError && typeof this.options.clearError === 'function') {
                 this.options.clearError.call(this);
             } else {
@@ -133,8 +136,8 @@ define([
 
                 this.options.form = $(this.options.form);
 
-                this.options.form && this.options.form.data('validator') && this.options.form.validation('clearError',
-                    this.options.regionListId, this.options.regionInputId, this.options.postcodeId);
+                this.options.form && this.options.form.data('validator') &&
+                    this.options.form.validation.apply(this.options.form, _.compact(args));
 
                 // Clean up errors on region & zip fix
                 $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove();
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index afb706a39a25ec97915abfe0bc6bfcb99c95f6d4..56a2b567745c2dd81fa3ca691309c4a76fe05aed 100644
--- a/app/code/Magento/CheckoutAgreements/composer.json
+++ b/app/code/Magento/CheckoutAgreements/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-checkout-agreements",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-checkout": "100.2.*",
         "magento/module-quote": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js
index 3d030a62eb425cdb0365331c8fac5325a5dbc91d..2fa3c2cddd3d5af870f02db0e189cae8456c51aa 100644
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js
@@ -12,9 +12,8 @@ define(
     function ($) {
         'use strict';
         var checkoutConfig = window.checkoutConfig,
-            agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {};
-
-        var agreementsInputPath = '.payment-method._active div.checkout-agreements input';
+            agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {},
+            agreementsInputPath = '.payment-method._active div.checkout-agreements input';
 
         return {
             /**
@@ -23,26 +22,11 @@ define(
              * @returns {boolean}
              */
             validate: function() {
-                if (!agreementsConfig.isEnabled) {
-                    return true;
-                }
-
-                if ($(agreementsInputPath).length == 0) {
+                if (!agreementsConfig.isEnabled || $(agreementsInputPath).length == 0) {
                     return true;
                 }
 
-                return $('#co-payment-form').validate({
-                    errorClass: 'mage-error',
-                    errorElement: 'div',
-                    meta: 'validate',
-                    errorPlacement: function (error, element) {
-                        var errorPlacement = element;
-                        if (element.is(':checkbox') || element.is(':radio')) {
-                            errorPlacement = element.siblings('label').last();
-                        }
-                        errorPlacement.after(error);
-                    }
-                }).element(agreementsInputPath);
+                return $.validator.validateSingleElement(agreementsInputPath, {errorElement: 'div'});
             }
         }
     }
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
index bb7d5de636ce5fd98b5f98943500910603d56267..7d8ef43084f3264c09bb65d2939f6660fa343f7f 100644
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
@@ -8,14 +8,13 @@
     <div class="checkout-agreements" data-bind="visible: isVisible">
         <!-- ko foreach: agreements -->
             <!-- ko if: ($parent.isAgreementRequired($data)) -->
-            <div class="checkout-agreement">
-                <input type="checkbox"
+            <div class="checkout-agreement required">
+                <input type="checkbox" class="required-entry"
                        data-bind="attr: {
                                     'id': 'agreement_' + agreementId,
                                     'name': 'agreement[' + agreementId + ']',
                                     'value': agreementId
-                                    }"
-                       data-validate="{required:true}" />
+                                    }"/>
                 <label data-bind="attr: {'for': 'agreement_' + agreementId}">
                     <button type="button"
                             class="action action-show"
diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
index ec5a438247e5cddc205d2f49c8d49ea746943e34..1bd96eff4dceef562040df73978679cc236a00bb 100644
--- a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
+++ b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
@@ -41,6 +41,7 @@ class Collection extends AbstractCollection
     {
         $this->_init(\Magento\Cms\Model\Block::class, \Magento\Cms\Model\ResourceModel\Block::class);
         $this->_map['fields']['store'] = 'store_table.store_id';
+        $this->_map['fields']['block_id'] = 'main_table.block_id';
     }
 
     /**
diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e1de289e5ef0e004a34d70dd793c1715a8bf292
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Test\Unit\Ui\Component\Listing\Column;
+
+use Magento\Cms\Ui\Component\Listing\Column\BlockActions;
+use Magento\Framework\Escaper;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\UrlInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponent\Processor;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+/**
+ * BlockActionsTest contains unit tests for \Magento\Cms\Ui\Component\Listing\Column\BlockActions class
+ */
+class BlockActionsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var BlockActions
+     */
+    private $blockActions;
+
+    /**
+     * @var Escaper|MockObject
+     */
+    private $escaper;
+
+    /**
+     * @var UrlInterface|MockObject
+     */
+    private $urlBuilder;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $context = $this->getMock(ContextInterface::class);
+
+        $processor = $this->getMockBuilder(Processor::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $context->expects(static::once())
+            ->method('getProcessor')
+            ->willReturn($processor);
+
+        $this->urlBuilder = $this->getMock(UrlInterface::class);
+
+        $this->escaper = $this->getMockBuilder(Escaper::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['escapeHtml'])
+            ->getMock();
+
+        $this->blockActions = $objectManager->getObject(BlockActions::class, [
+            'context' => $context,
+            'urlBuilder' => $this->urlBuilder
+        ]);
+
+        $objectManager->setBackwardCompatibleProperty($this->blockActions, 'escaper', $this->escaper);
+    }
+
+    /**
+     * @covers \Magento\Cms\Ui\Component\Listing\Column\BlockActions::prepareDataSource
+     */
+    public function testPrepareDataSource()
+    {
+        $blockId = 1;
+        $title = 'block title';
+        $items = [
+            'data' => [
+                'items' => [
+                    [
+                        'block_id' => $blockId,
+                        'title' => $title
+                    ]
+                ]
+            ]
+        ];
+        $name = 'item_name';
+        $expectedItems = [
+            [
+                'block_id' => $blockId,
+                'title' => $title,
+                $name => [
+                    'edit' => [
+                        'href' => 'test/url/edit',
+                        'label' => __('Edit'),
+                    ],
+                    'delete' => [
+                        'href' => 'test/url/delete',
+                        'label' => __('Delete'),
+                        'confirm' => [
+                            'title' => __('Delete %1', $title),
+                            'message' => __('Are you sure you wan\'t to delete a %1 record?', $title)
+                        ],
+                    ]
+                ],
+            ]
+        ];
+
+        $this->escaper->expects(static::once())
+            ->method('escapeHtml')
+            ->with($title)
+            ->willReturn($title);
+
+        $this->urlBuilder->expects(static::exactly(2))
+            ->method('getUrl')
+            ->willReturnMap(
+                [
+                    [
+                        BlockActions::URL_PATH_EDIT,
+                        [
+                            'block_id' => $blockId
+                        ],
+                        'test/url/edit',
+                    ],
+                    [
+                        BlockActions::URL_PATH_DELETE,
+                        [
+                            'block_id' => $blockId
+                        ],
+                        'test/url/delete',
+                    ],
+                ]
+            );
+
+        $this->blockActions->setData('name', $name);
+
+        $actual = $this->blockActions->prepareDataSource($items);
+        static::assertEquals($expectedItems, $actual['data']['items']);
+    }
+}
diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php
index 4b6ce1ae2ff42d39bf53a9e57bd3b9f6aa639f89..731c08fbc64dd59a967b4d74ea52ba188336d0a9 100644
--- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php
@@ -6,6 +6,7 @@
 namespace Magento\Cms\Test\Unit\Ui\Component\Listing\Column;
 
 use Magento\Cms\Ui\Component\Listing\Column\PageActions;
+use Magento\Framework\Escaper;
 
 class PageActionsTest extends \PHPUnit_Framework_TestCase
 {
@@ -34,12 +35,20 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase
             ]
         );
 
+        $escaper = $this->getMockBuilder(Escaper::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['escapeHtml'])
+            ->getMock();
+        $objectManager->setBackwardCompatibleProperty($model, 'escaper', $escaper);
+
         // Define test input and expectations
+        $title = 'page title';
         $items = [
             'data' => [
                 'items' => [
                     [
-                        'page_id' => $pageId
+                        'page_id' => $pageId,
+                        'title' => $title
                     ]
                 ]
             ]
@@ -48,6 +57,7 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase
         $expectedItems = [
             [
                 'page_id' => $pageId,
+                'title' => $title,
                 $name => [
                     'edit' => [
                         'href' => 'test/url/edit',
@@ -57,14 +67,19 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase
                         'href' => 'test/url/delete',
                         'label' => __('Delete'),
                         'confirm' => [
-                            'title' => __('Delete ${ $.$data.title }'),
-                            'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?')
+                            'title' => __('Delete %1', $title),
+                            'message' => __('Are you sure you wan\'t to delete a %1 record?', $title)
                         ],
                     ]
                 ],
             ]
         ];
 
+        $escaper->expects(static::once())
+            ->method('escapeHtml')
+            ->with($title)
+            ->willReturn($title);
+
         // Configure mocks and object data
         $urlBuilderMock->expects($this->any())
             ->method('getUrl')
diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php
index e71352c465333396312cc0bd0242cbe45f62bd17..f0a1fe7981f8c3007055973eb4e296c23afe5ab8 100644
--- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php
+++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php
@@ -9,6 +9,8 @@ use Magento\Framework\UrlInterface;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
 use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Ui\Component\Listing\Columns\Column;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Escaper;
 
 /**
  * Class BlockActions
@@ -27,6 +29,11 @@ class BlockActions extends Column
      */
     protected $urlBuilder;
 
+    /**
+     * @var Escaper
+     */
+    private $escaper;
+
     /**
      * Constructor
      *
@@ -47,10 +54,6 @@ class BlockActions extends Column
         parent::__construct($context, $uiComponentFactory, $components, $data);
     }
 
-    /**
-     * @param array $items
-     * @return array
-     */
     /**
      * Prepare Data Source
      *
@@ -62,6 +65,7 @@ class BlockActions extends Column
         if (isset($dataSource['data']['items'])) {
             foreach ($dataSource['data']['items'] as & $item) {
                 if (isset($item['block_id'])) {
+                    $title = $this->getEscaper()->escapeHtml($item['title']);
                     $item[$this->getData('name')] = [
                         'edit' => [
                             'href' => $this->urlBuilder->getUrl(
@@ -81,8 +85,8 @@ class BlockActions extends Column
                             ),
                             'label' => __('Delete'),
                             'confirm' => [
-                                'title' => __('Delete "${ $.$data.title }"'),
-                                'message' => __('Are you sure you wan\'t to delete a "${ $.$data.title }" record?')
+                                'title' => __('Delete %1', $title),
+                                'message' => __('Are you sure you wan\'t to delete a %1 record?', $title)
                             ]
                         ]
                     ];
@@ -92,4 +96,17 @@ class BlockActions extends Column
 
         return $dataSource;
     }
+
+    /**
+     * Get instance of escaper
+     * @return Escaper
+     * @deprecated
+     */
+    private function getEscaper()
+    {
+        if (!$this->escaper) {
+            $this->escaper = ObjectManager::getInstance()->get(Escaper::class);
+        }
+        return $this->escaper;
+    }
 }
diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
index fe85fd0ef314070c5c6cdb6f34435e72af3e152b..f23afbffa792e6b5b92166b5268e3942735bd21f 100644
--- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
+++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
@@ -5,11 +5,13 @@
  */
 namespace Magento\Cms\Ui\Component\Listing\Column;
 
+use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Escaper;
+use Magento\Framework\UrlInterface;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
 use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Ui\Component\Listing\Columns\Column;
-use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder;
-use Magento\Framework\UrlInterface;
 
 /**
  * Class PageActions
@@ -31,6 +33,11 @@ class PageActions extends Column
      */
     private $editUrl;
 
+    /**
+     * @var Escaper
+     */
+    private $escaper;
+
     /**
      * @param ContextInterface $context
      * @param UiComponentFactory $uiComponentFactory
@@ -71,12 +78,13 @@ class PageActions extends Column
                         'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]),
                         'label' => __('Edit')
                     ];
+                    $title = $this->getEscaper()->escapeHtml($item['title']);
                     $item[$name]['delete'] = [
                         'href' => $this->urlBuilder->getUrl(self::CMS_URL_PATH_DELETE, ['page_id' => $item['page_id']]),
                         'label' => __('Delete'),
                         'confirm' => [
-                            'title' => __('Delete ${ $.$data.title }'),
-                            'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?')
+                            'title' => __('Delete %1', $title),
+                            'message' => __('Are you sure you wan\'t to delete a %1 record?', $title)
                         ]
                     ];
                 }
@@ -95,4 +103,17 @@ class PageActions extends Column
 
         return $dataSource;
     }
+
+    /**
+     * Get instance of escaper
+     * @return Escaper
+     * @deprecated
+     */
+    private function getEscaper()
+    {
+        if (!$this->escaper) {
+            $this->escaper = ObjectManager::getInstance()->get(Escaper::class);
+        }
+        return $this->escaper;
+    }
 }
diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json
index 66f6da042e6c9a77e25eb5c9e8f1595c16e3e5f6..7f2ed4d7a7dcdc59916c34c796f7f3fc05ec6cc9 100644
--- a/app/code/Magento/Cms/composer.json
+++ b/app/code/Magento/Cms/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-cms",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-theme": "100.2.*",
         "magento/module-widget": "100.2.*",
diff --git a/app/code/Magento/Cms/i18n/en_US.csv b/app/code/Magento/Cms/i18n/en_US.csv
index 6f3a2955a5c65b5cf1760519741fd60d49133123..9a9f6ac4c6888e386d44c679c94a87533844342d 100644
--- a/app/code/Magento/Cms/i18n/en_US.csv
+++ b/app/code/Magento/Cms/i18n/en_US.csv
@@ -84,10 +84,8 @@ Exception,Exception
 "All Store Views","All Store Views"
 Edit,Edit
 Delete,Delete
-"Delete ${ $.$data.title }","Delete ${ $.$data.title }"
-"Are you sure you wan\'t to delete a ${ $.$data.title } record?","Are you sure you wan\'t to delete a ${ $.$data.title } record?"
-"Delete ""${ $.$data.title }""","Delete ""${ $.$data.title }"""
-"Are you sure you wan\'t to delete a ""${ $.$data.title }"" record?","Are you sure you wan\'t to delete a ""${ $.$data.title }"" record?"
+"Delete %1","Delete %1"
+"Are you sure you wan\'t to delete a %1 record?","Are you sure you wan\'t to delete a %1 record?"
 View,View
 px.,px.
 "No files found","No files found"
diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml
index a6185c454189770f39d00ae0c54c95086dc1fcf1..827f2ee938e41378a158090c16a383e62fa9e74e 100644
--- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml
+++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml
@@ -21,11 +21,11 @@ $_height = $block->getImagesHeight();
         <?php endif; ?>
         </p>
         <?php if ($block->getFileWidth($file)): ?>
-            <small><?php echo $block->escapeHtml($block->getFileWidth($file)) ?>x<?php echo $block->escapeHtml($block->getFileHeight($file)) ?> <?php /* @escapeNotVerified */ echo __('px.') ?></small><br/>
+            <small><?php echo $block->escapeHtml($block->getFileWidth($file)) ?>x<?php echo $block->escapeHtml($block->getFileHeight($file)) ?> <?php echo $block->escapeHtml(__('px.')) ?></small><br/>
         <?php endif; ?>
         <small><?php echo $block->escapeHtml($block->getFileShortName($file)); ?></small>
     </div>
     <?php endforeach; ?>
 <?php else: ?>
-    <div class="empty"><?php /* @escapeNotVerified */ echo __('No files found') ?></div>
+    <div class="empty"><?php echo $block->escapeHtml(__('No files found')) ?></div>
 <?php endif; ?>
diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
index 6a29cb1497175d418723af26a041c6bb80a990f8..3233bb17c09a319f27a987e47cb4cdd16661c20d 100644
--- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
+++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
@@ -11,7 +11,7 @@
 
 <div id="<?php echo $block->getHtmlId() ?>" class="uploader">
     <span class="fileinput-button form-buttons">
-        <span><?php /* @escapeNotVerified */ echo __('Browse Files...') ?></span>
+        <span><?php echo $block->escapeHtml(__('Browse Files...')) ?></span>
         <input class="fileupload" type="file" name="<?php echo $block->escapeHtmlAttr($block->getConfig()->getFileField()) ?>" data-url="<?php echo $block->escapeUrl($block->getConfig()->getUrl()) ?>" multiple>
     </span>
     <div class="clear"></div>
diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml
index 90a00c32015b7733b54e08cda63217c897f0bf58..2e6204496eba453a40c8288ed041db7781ec27e7 100644
--- a/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml
+++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml
@@ -11,9 +11,9 @@
 <div class="tree-panel" >
     <div class="categories-side-col">
         <div class="tree-actions">
-            <a onclick="jQuery('[data-role=tree]').jstree('close_all');"><?php /* @escapeNotVerified */ echo __('Collapse All'); ?></a>
+            <a onclick="jQuery('[data-role=tree]').jstree('close_all');"><?php echo $block->escapeHtml(__('Collapse All')) ?></a>
             <span class="separator">|</span>
-            <a onclick="jQuery('[data-role=tree]').jstree('open_all');"><?php /* @escapeNotVerified */ echo __('Expand All'); ?></a>
+            <a onclick="jQuery('[data-role=tree]').jstree('open_all');"><?php echo $block->escapeHtml(__('Expand All')) ?></a>
         </div>
     </div>
     <div data-role="tree" data-mage-init='<?php echo $block->escapeHtml($this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getTreeWidgetOptions())); ?>'>
diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml
index 55c1b02be8797a45a9f4b27914e3195d7695da61..82a27c7aa0d78f1b44f44c9ca9f108d8df1ae586 100644
--- a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml
+++ b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml
@@ -3,9 +3,13 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+/**
+ * @var \Magento\Cms\Block\Widget\Page\Link $block
+ */
 ?>
 <div class="widget block block-cms-link">
-    <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>>
+    <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>>
         <span><?php echo $block->escapeHtml($block->getLabel()) ?></span>
     </a>
 </div>
diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml
index 382b492db3da5c815530d87f13ee959d82e2c083..d906826507d73b50f1c8cbf50a85f8ae2e09c5c8 100644
--- a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml
+++ b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml
@@ -3,9 +3,13 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+/**
+ * @var \Magento\Cms\Block\Widget\Page\Link $block
+ */
 ?>
 <span class="widget block block-cms-link-inline">
-    <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>>
+    <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>>
         <span><?php echo $block->escapeHtml($block->getLabel()) ?></span>
     </a>
 </span>
diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json
index 1ae1efd9350a760846e76fcac8939ef574194361..1d2e70c74eb4f9fd0876f92c37b30b5e9387d2cd 100644
--- a/app/code/Magento/CmsUrlRewrite/composer.json
+++ b/app/code/Magento/CmsUrlRewrite/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-cms-url-rewrite",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-cms": "101.1.*",
         "magento/module-url-rewrite": "100.2.*",
diff --git a/app/code/Magento/Config/Model/Config/Backend/Baseurl.php b/app/code/Magento/Config/Model/Config/Backend/Baseurl.php
index 09fd99773813117a71b43240eaafc5b96bf967ca..f08c2f8e04434c7a26645669ff3a4c1c8d1840c7 100644
--- a/app/code/Magento/Config/Model/Config/Backend/Baseurl.php
+++ b/app/code/Magento/Config/Model/Config/Backend/Baseurl.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Config\Model\Config\Backend;
 
+use Magento\Framework\Validator\Url as UrlValidator;
+use Magento\Framework\App\ObjectManager;
+
 class Baseurl extends \Magento\Framework\App\Config\Value
 {
     /**
@@ -12,6 +15,11 @@ class Baseurl extends \Magento\Framework\App\Config\Value
      */
     protected $_mergeService;
 
+    /**
+     * @var UrlValidator
+     */
+    private $urlValidator;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -193,8 +201,7 @@ class Baseurl extends \Magento\Framework\App\Config\Value
      */
     private function _isFullyQualifiedUrl($value)
     {
-        $url = parse_url($value);
-        return isset($url['scheme']) && isset($url['host']) && preg_match('/\/$/', $value);
+        return preg_match('/\/$/', $value) && $this->getUrlValidator()->isValid($value, ['http', 'https']);
     }
 
     /**
@@ -216,4 +223,18 @@ class Baseurl extends \Magento\Framework\App\Config\Value
         }
         return parent::afterSave();
     }
+
+    /**
+     * Get URL Validator
+     *
+     * @deprecated
+     * @return UrlValidator
+     */
+    private function getUrlValidator()
+    {
+        if (!$this->urlValidator) {
+            $this->urlValidator = ObjectManager::getInstance()->get(UrlValidator::class);
+        }
+        return $this->urlValidator;
+    }
 }
diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json
index bdd1a9c14ae6894d052f6e7e2994f2c87c6554b0..b14dd825b0d12d819fd511222e80de12a7cf8c3a 100644
--- a/app/code/Magento/Config/composer.json
+++ b/app/code/Magento/Config/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-config",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-cron": "100.2.*",
diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json
index 6c249134d28626b4c8846fd7491cf25b2e278638..d292e73198435431015dff6bcfe1a69d516debc9 100644
--- a/app/code/Magento/ConfigurableImportExport/composer.json
+++ b/app/code/Magento/ConfigurableImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-configurable-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-import-export": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
index 0fdfbd3bfa172ee597414ed3ab4c46bbac2a9549..5575d6f7ef56fa4f7f2fed433299c01eaa4ba98d 100644
--- a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
+++ b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
@@ -32,6 +32,16 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
      */
     private $dataObjectHelper;
 
+    /**
+     * @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory;
+     */
+    private $optionsFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory
+     */
+    private $attributeFactory;
+
     /**
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory
@@ -102,9 +112,28 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
             throw new StateException(__('Product has been already attached'));
         }
 
+        $configurableProductOptions = $product->getExtensionAttributes()->getConfigurableProductOptions();
+        if (empty($configurableProductOptions)) {
+            throw new StateException(__('Parent product does not have configurable product options'));
+        }
+
+        $attributeIds = [];
+        foreach ($configurableProductOptions as $configurableProductOption) {
+            $attributeCode = $configurableProductOption->getProductAttribute()->getAttributeCode();
+            if (!$child->getData($attributeCode)) {
+                throw new StateException(__('Child product does not have attribute value %1', $attributeCode));
+            }
+            $attributeIds[] = $configurableProductOption->getAttributeId();
+        }
+        $configurableOptionData = $this->getConfigurableAttributesData($attributeIds);
+
+        /** @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory $optionFactory */
+        $optionFactory = $this->getOptionsFactory();
+        $options = $optionFactory->create($configurableOptionData);
         $childrenIds[] = $child->getId();
+        $product->getExtensionAttributes()->setConfigurableProductOptions($options);
         $product->getExtensionAttributes()->setConfigurableProductLinks($childrenIds);
-        $product->save();
+        $this->productRepository->save($product);
         return true;
     }
 
@@ -133,7 +162,75 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
             throw new NoSuchEntityException(__('Requested option doesn\'t exist'));
         }
         $product->getExtensionAttributes()->setConfigurableProductLinks($ids);
-        $product->save();
+        $this->productRepository->save($product);
         return true;
     }
+
+    /**
+     * Get Options Factory
+     *
+     * @return \Magento\ConfigurableProduct\Helper\Product\Options\Factory
+     *
+     * @deprecated
+     */
+    private function getOptionsFactory()
+    {
+        if (!$this->optionsFactory) {
+            $this->optionsFactory = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class);
+        }
+        return $this->optionsFactory;
+    }
+
+    /**
+     * Get Attribute Factory
+     *
+     * @return \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory
+     *
+     * @deprecated
+     */
+    private function getAttributeFactory()
+    {
+        if (!$this->attributeFactory) {
+            $this->attributeFactory = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class);
+        }
+        return $this->attributeFactory;
+    }
+
+    /**
+     * Get Configurable Attribute Data
+     *
+     * @param int[] $attributeIds
+     * @return array
+     */
+    private function getConfigurableAttributesData($attributeIds)
+    {
+        $configurableAttributesData = [];
+        $attributeValues = [];
+        $attributes = $this->getAttributeFactory()->create()
+            ->getCollection()
+            ->addFieldToFilter('attribute_id', $attributeIds)
+            ->getItems();
+        foreach ($attributes as $attribute) {
+            foreach ($attribute->getOptions() as $option) {
+                if ($option->getValue()) {
+                    $attributeValues[] = [
+                        'label' => $option->getLabel(),
+                        'attribute_id' => $attribute->getId(),
+                        'value_index' => $option->getValue(),
+                    ];
+                }
+            }
+            $configurableAttributesData[] =
+                [
+                    'attribute_id' => $attribute->getId(),
+                    'code' => $attribute->getAttributeCode(),
+                    'label' => $attribute->getStoreLabel(),
+                    'values' => $attributeValues,
+                ];
+        }
+
+        return $configurableAttributesData;
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 0b8a4aee9feced6e4f104208b7563bda16b6305c..0bd2f23418221770d4562eb67d6af9d3e8bd4646 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -1287,4 +1287,19 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
         }
         return $this->catalogConfig;
     }
+
+    /**
+     * @inheritdoc
+     */
+    public function isPossibleBuyFromList($product)
+    {
+        $isAllCustomOptionsDisplayed = true;
+        foreach ($this->getConfigurableAttributes($product) as $attribute) {
+            $eavAttribute = $attribute->getProductAttribute();
+
+            $isAllCustomOptionsDisplayed = ($isAllCustomOptionsDisplayed && $eavAttribute->getUsedInProductListing());
+        }
+
+        return $isAllCustomOptionsDisplayed;
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php
index 4e6fa8ae5210d77726b393047a7433ca03d69c7d..fbb69798ff94fbdf8caafc7486e564da662cf655 100644
--- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php
@@ -8,6 +8,7 @@
 namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
 
 use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
 
 class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice
 {
@@ -166,6 +167,9 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\
         $this->_prepareConfigurableOptionAggregateTable();
         $this->_prepareConfigurableOptionPriceTable();
 
+        $statusAttribute = $this->_getAttribute(ProductInterface::STATUS);
+        $linkField = $metadata->getLinkField();
+
         $select = $connection->select()->from(
             ['i' => $this->_getDefaultFinalPriceTable()],
             []
@@ -175,7 +179,7 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\
             ['parent_id' => 'e.entity_id']
         )->join(
             ['l' => $this->getTable('catalog_product_super_link')],
-            'l.parent_id = e.' . $metadata->getLinkField(),
+            'l.parent_id = e.' . $linkField,
             ['product_id']
         )->columns(
             ['customer_group_id', 'website_id'],
@@ -186,11 +190,21 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\
             []
         )->where(
             'le.required_options=0'
+        )->join(
+            ['product_status' => $this->getTable($statusAttribute->getBackend()->getTable())],
+            sprintf(
+                'le.%1$s = product_status.%1$s AND product_status.attribute_id = %2$s',
+                $linkField,
+                $statusAttribute->getAttributeId()
+            ),
+            []
+        )->where(
+            'product_status.value=' . ProductStatus::STATUS_ENABLED
         )->group(
-            ['parent_id', 'i.customer_group_id', 'i.website_id', 'l.product_id']
+            ['e.entity_id', 'i.customer_group_id', 'i.website_id', 'l.product_id']
         );
-        $priceColumn = $this->_addAttributeToSelect($select, 'price', 'l.product_id', 0, null, true);
-        $tierPriceColumn = $connection->getCheckSql("MIN(i.tier_price) IS NOT NULL", "i.tier_price", 'NULL');
+        $priceColumn = $this->_addAttributeToSelect($select, 'price', 'le.' . $linkField, 0, null, true);
+        $tierPriceColumn = $connection->getIfNullSql('MIN(i.tier_price)', 'NULL');
 
         $select->columns(
             ['price' => $priceColumn, 'tier_price' => $tierPriceColumn]
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
index 6b69888e6dd0924cf6e090bdb1eb0af2daddaab1..5a7886ea3ea640c2f276ffb7eedeaa243ff9e790 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
@@ -6,8 +6,8 @@
 
 namespace Magento\ConfigurableProduct\Test\Unit\Model;
 
+use Magento\ConfigurableProduct\Model\LinkManagement;
 use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
-use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -146,15 +146,59 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
 
         $configurable = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
             ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getExtensionAttributes'])
+            ->getMock();
+        $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getData'])
             ->getMock();
 
-        $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
+        $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtension::class)
+            ->disableOriginalConstructor()
+            ->setMethods([
+                'getConfigurableProductOptions', 'setConfigurableProductOptions', 'setConfigurableProductLinks'
+            ])
+            ->getMock();
+        $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\Option::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getProductAttribute', 'getAttributeId'])
+            ->getMock();
+        $productAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributeCode'])
+            ->getMock();
+        $optionsFactoryMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $reflectionClass = new \ReflectionClass(\Magento\ConfigurableProduct\Model\LinkManagement::class);
+        $optionsFactoryReflectionProperty = $reflectionClass->getProperty('optionsFactory');
+        $optionsFactoryReflectionProperty->setAccessible(true);
+        $optionsFactoryReflectionProperty->setValue($this->object, $optionsFactoryMock);
 
-        $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+        $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class)
             ->disableOriginalConstructor()
+            ->setMethods(['create'])
             ->getMock();
+        $attributeFactoryReflectionProperty = $reflectionClass->getProperty('attributeFactory');
+        $attributeFactoryReflectionProperty->setAccessible(true);
+        $attributeFactoryReflectionProperty->setValue($this->object, $attributeFactoryMock);
 
-        $simple->expects($this->any())->method('getId')->will($this->returnValue(999));
+        $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getCollection', 'getOptions', 'getId', 'getAttributeCode', 'getStoreLabel'])
+            ->getMock();
+        $attributeOptionMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Option::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getValue', 'getLabel'])
+            ->getMock();
+
+        $attributeCollectionMock = $this->getMockBuilder(
+            \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection::class
+        )
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getItems'])
+            ->getMock();
 
         $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->willReturn($configurable);
         $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->willReturn($simple);
@@ -164,15 +208,30 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
                 $this->returnValue([0 => [1, 2, 3]])
             );
 
-        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
-            ->setMethods(['setConfigurableProductLinks'])
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
+        $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
+        $simple->expects($this->any())->method('getId')->will($this->returnValue(999));
+
+        $configurable->expects($this->any())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
+        $extensionAttributesMock->expects($this->any())
+            ->method('getConfigurableProductOptions')
+            ->willReturn([$optionMock]);
+        $optionMock->expects($this->any())->method('getProductAttribute')->willReturn($productAttributeMock);
+        $productAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn('color');
+        $simple->expects($this->any())->method('getData')->willReturn('color');
+        $optionMock->expects($this->any())->method('getAttributeId')->willReturn('1');
 
-        $configurable->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
-        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
+        $optionsFactoryMock->expects($this->any())->method('create')->willReturn([$optionMock]);
+        $attributeFactoryMock->expects($this->any())->method('create')->willReturn($attributeMock);
+        $attributeMock->expects($this->any())->method('getCollection')->willReturn($attributeCollectionMock);
+        $attributeCollectionMock->expects($this->any())->method('addFieldToFilter')->willReturnSelf();
+        $attributeCollectionMock->expects($this->any())->method('getItems')->willReturn([$attributeMock]);
 
-        $configurable->expects($this->once())->method('save');
+        $attributeMock->expects($this->any())->method('getOptions')->willReturn([$attributeOptionMock]);
+
+        $extensionAttributesMock->expects($this->any())->method('setConfigurableProductOptions');
+        $extensionAttributesMock->expects($this->any())->method('setConfigurableProductLinks');
+
+        $this->productRepository->expects($this->once())->method('save');
 
         $this->assertTrue(true, $this->object->addChild($productSku, $childSku));
     }
@@ -243,15 +302,13 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
         $productType->expects($this->once())->method('getUsedProducts')
             ->will($this->returnValue([$option]));
 
-        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
+        $extensionAttributesMock = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class)
             ->setMethods(['setConfigurableProductLinks'])
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
 
-        $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
-        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
-
-        $product->expects($this->once())->method('save');
+        $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
+        $this->productRepository->expects($this->once())->method('save');
         $this->assertTrue($this->object->removeChild($productSku, $childSku));
     }
 
diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json
index 8dda841250ff126d0fed90a03dd4272169266392..755b94a600a099a0ada188d435f3682cf6736e69 100644
--- a/app/code/Magento/ConfigurableProduct/composer.json
+++ b/app/code/Magento/ConfigurableProduct/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-configurable-product",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-inventory": "100.2.*",
diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json
index b541f1e7a0ed3afe8f8bfb8c25b7f27282bc9372..377e46256c0886c5479cbe256451310bac14b896 100644
--- a/app/code/Magento/Contact/composer.json
+++ b/app/code/Magento/Contact/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-contact",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json
index 5222975723385a48adf043f695c08e319f11d57b..96a050f2ad20dfa94958fd11f7a24cfb73010642 100644
--- a/app/code/Magento/Cookie/composer.json
+++ b/app/code/Magento/Cookie/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-cookie",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json
index b1155c028f91971b5508269a06ebef675032e5b5..75a7ce27a2aa110d55398a0588ae4f4907c724c2 100644
--- a/app/code/Magento/Cron/composer.json
+++ b/app/code/Magento/Cron/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-cron",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json
index 2cdfedadf7a38c7c792a27de4498772cc59c692b..29f0bd7435eef99279f54273163f17041d64a351 100644
--- a/app/code/Magento/CurrencySymbol/composer.json
+++ b/app/code/Magento/CurrencySymbol/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-currency-symbol",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-page-cache": "100.2.*",
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
index 77bf7af2a4031ac71488b7644225a6c13dc520f2..fd2ceaf09695bfb4a413bc6f680f254ca4edca4c 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
@@ -72,6 +72,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
     ) {
         $metadataForm = $this->getMetadataForm($entityType, $formCode, $scope);
         $formData = $metadataForm->extractData($this->getRequest(), $scope);
+        $formData = $metadataForm->compactData($formData);
 
         // Initialize additional attributes
         /** @var \Magento\Framework\DataObject $object */
@@ -81,11 +82,6 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
             $formData[$attributeCode] = isset($requestData[$attributeCode]) ? $requestData[$attributeCode] : false;
         }
 
-        $result = $metadataForm->compactData($formData);
-
-        // Re-initialize additional attributes
-        $formData = array_replace($formData, $result);
-
         // Unset unused attributes
         $formAttributes = $metadataForm->getAttributes();
         foreach ($formAttributes as $attribute) {
diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php
index 19b361b2c830d763681184b5055f0d477c4641ae..c1ec593e4a7aeec51a53323052aeae62cb7036ff 100644
--- a/app/code/Magento/Customer/Controller/Section/Load.php
+++ b/app/code/Magento/Customer/Controller/Section/Load.php
@@ -5,10 +5,10 @@
  */
 namespace Magento\Customer\Controller\Section;
 
+use Magento\Customer\CustomerData\Section\Identifier;
 use Magento\Customer\CustomerData\SectionPoolInterface;
 use Magento\Framework\App\Action\Context;
 use Magento\Framework\Controller\Result\JsonFactory;
-use Magento\Framework\Exception\LocalizedException;
 
 /**
  * Customer section controller
@@ -22,6 +22,7 @@ class Load extends \Magento\Framework\App\Action\Action
 
     /**
      * @var Identifier
+     * @deprecated
      */
     protected $sectionIdentifier;
 
@@ -30,26 +31,34 @@ class Load extends \Magento\Framework\App\Action\Action
      */
     protected $sectionPool;
 
+    /**
+     * @var \Magento\Framework\Escaper
+     */
+    private $escaper;
+
     /**
      * @param Context $context
      * @param JsonFactory $resultJsonFactory
-     * @param \Magento\Customer\CustomerData\Section\Identifier $sectionIdentifier
+     * @param Identifier $sectionIdentifier
      * @param SectionPoolInterface $sectionPool
+     * @param Escaper $escaper
      */
     public function __construct(
         Context $context,
         JsonFactory $resultJsonFactory,
-        \Magento\Customer\CustomerData\Section\Identifier $sectionIdentifier,
-        SectionPoolInterface $sectionPool
+        Identifier $sectionIdentifier,
+        SectionPoolInterface $sectionPool,
+        \Magento\Framework\Escaper $escaper = null
     ) {
         parent::__construct($context);
         $this->resultJsonFactory = $resultJsonFactory;
         $this->sectionIdentifier = $sectionIdentifier;
         $this->sectionPool = $sectionPool;
+        $this->escaper = $escaper ?: $this->_objectManager->get(\Magento\Framework\Escaper::class);
     }
 
     /**
-     * @return \Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\Result\Redirect
+     * @return \Magento\Framework\Controller\Result\Json
      */
     public function execute()
     {
@@ -60,7 +69,7 @@ class Load extends \Magento\Framework\App\Action\Action
             $sectionNames = $sectionNames ? array_unique(\explode(',', $sectionNames)) : null;
 
             $updateSectionId = $this->getRequest()->getParam('update_section_id');
-            if ('false' == $updateSectionId) {
+            if ('false' === $updateSectionId) {
                 $updateSectionId = false;
             }
             $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$updateSectionId);
@@ -70,7 +79,7 @@ class Load extends \Magento\Framework\App\Action\Action
                 \Zend\Http\AbstractMessage::VERSION_11,
                 'Bad Request'
             );
-            $response = ['message' => $e->getMessage()];
+            $response = ['message' => $this->escaper->escapeHtml($e->getMessage())];
         }
 
         return $resultJson->setData($response);
diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php
index 8fb48fe9f87e76dcf4f5d489a830bb15bf910c79..11fd1b5a7fc3356f54cc1e72b76e111b22446383 100644
--- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php
@@ -304,33 +304,28 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ],
             'subscription' => $subscription,
         ];
-        $filteredData = [
+        $extractedData = [
             'entity_id' => $customerId,
             'code' => 'value',
             'coolness' => false,
             'disable_auto_group_change' => 'false',
         ];
-        $dataToCompact = [
+        $compactedData = [
             'entity_id' => $customerId,
             'code' => 'value',
             'coolness' => false,
             'disable_auto_group_change' => 'false',
-            CustomerInterface::DEFAULT_BILLING => false,
-            CustomerInterface::DEFAULT_SHIPPING => false,
-            'confirmation' => false,
-            'sendemail_store_id' => false,
-            'extension_attributes' => false,
+            CustomerInterface::DEFAULT_BILLING => 2,
+            CustomerInterface::DEFAULT_SHIPPING => 2
         ];
-        $addressFilteredData = [
+        $addressExtractedData = [
             'entity_id' => $addressId,
-            'default_billing' => 'true',
-            'default_shipping' => 'true',
             'code' => 'value',
             'coolness' => false,
             'region' => 'region',
             'region_id' => 'region_id',
         ];
-        $addressDataToCompact = [
+        $addressCompactedData = [
             'entity_id' => $addressId,
             'default_billing' => 'true',
             'default_shipping' => 'true',
@@ -430,11 +425,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'customer')
-            ->willReturn($filteredData);
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('compactData')
-            ->with($dataToCompact)
-            ->willReturn($filteredData);
+            ->with($extractedData)
+            ->willReturn($compactedData);
         $customerFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -445,11 +440,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerAddressFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'address/' . $addressId)
-            ->willReturn($addressFilteredData);
+            ->willReturn($addressExtractedData);
         $customerAddressFormMock->expects($this->once())
             ->method('compactData')
-            ->with($addressDataToCompact)
-            ->willReturn($addressFilteredData);
+            ->with($addressExtractedData)
+            ->willReturn($addressCompactedData);
         $customerAddressFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -625,8 +620,6 @@ class SaveTest extends \PHPUnit_Framework_TestCase
                 '_template_' => '_template_',
                 $addressId => [
                     'entity_id' => $addressId,
-                    'default_billing' => 'false',
-                    'default_shipping' => 'false',
                     'code' => 'value',
                     'coolness' => false,
                     'region' => 'region',
@@ -635,32 +628,12 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ],
             'subscription' => $subscription,
         ];
-        $filteredData = [
+        $extractedData = [
             'coolness' => false,
             'disable_auto_group_change' => 'false',
         ];
-        $dataToCompact = [
-            'coolness' => false,
-            'disable_auto_group_change' => 'false',
-            CustomerInterface::DEFAULT_BILLING => false,
-            CustomerInterface::DEFAULT_SHIPPING => false,
-            'confirmation' => false,
-            'sendemail_store_id' => false,
-            'extension_attributes' => false,
-        ];
-        $addressFilteredData = [
+        $addressExtractedData = [
             'entity_id' => $addressId,
-            'default_billing' => 'false',
-            'default_shipping' => 'false',
-            'code' => 'value',
-            'coolness' => false,
-            'region' => 'region',
-            'region_id' => 'region_id',
-        ];
-        $addressDataToCompact = [
-            'entity_id' => $addressId,
-            'default_billing' => 'false',
-            'default_shipping' => 'false',
             'code' => 'value',
             'coolness' => false,
             'region' => 'region',
@@ -739,11 +712,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'customer')
-            ->willReturn($filteredData);
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('compactData')
-            ->with($dataToCompact)
-            ->willReturn($filteredData);
+            ->with($extractedData)
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -754,11 +727,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerAddressFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'address/' . $addressId)
-            ->willReturn($addressFilteredData);
+            ->willReturn($addressExtractedData);
         $customerAddressFormMock->expects($this->once())
             ->method('compactData')
-            ->with($addressDataToCompact)
-            ->willReturn($addressFilteredData);
+            ->with($addressExtractedData)
+            ->willReturn($addressExtractedData);
         $customerAddressFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -910,19 +883,10 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ],
             'subscription' => $subscription,
         ];
-        $filteredData = [
+        $extractedData = [
             'coolness' => false,
             'disable_auto_group_change' => 'false',
         ];
-        $dataToCompact = [
-            'coolness' => false,
-            'disable_auto_group_change' => 'false',
-            CustomerInterface::DEFAULT_BILLING => false,
-            CustomerInterface::DEFAULT_SHIPPING => false,
-            'confirmation' => false,
-            'sendemail_store_id' => false,
-            'extension_attributes' => false,
-        ];
 
         /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */
         $attributeMock = $this->getMockBuilder(
@@ -971,11 +935,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'customer')
-            ->willReturn($filteredData);
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('compactData')
-            ->with($dataToCompact)
-            ->willReturn($filteredData);
+            ->with($extractedData)
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -1062,19 +1026,10 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ],
             'subscription' => $subscription,
         ];
-        $filteredData = [
+        $extractedData = [
             'coolness' => false,
             'disable_auto_group_change' => 'false',
         ];
-        $dataToCompact = [
-            'coolness' => false,
-            'disable_auto_group_change' => 'false',
-            CustomerInterface::DEFAULT_BILLING => false,
-            CustomerInterface::DEFAULT_SHIPPING => false,
-            'confirmation' => false,
-            'sendemail_store_id' => false,
-            'extension_attributes' => false,
-        ];
 
         /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */
         $attributeMock = $this->getMockBuilder(
@@ -1124,11 +1079,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'customer')
-            ->willReturn($filteredData);
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('compactData')
-            ->with($dataToCompact)
-            ->willReturn($filteredData);
+            ->with($extractedData)
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
@@ -1214,18 +1169,9 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ],
             'subscription' => $subscription,
         ];
-        $filteredData = [
-            'coolness' => false,
-            'disable_auto_group_change' => 'false',
-        ];
-        $dataToCompact = [
+        $extractedData = [
             'coolness' => false,
             'disable_auto_group_change' => 'false',
-            CustomerInterface::DEFAULT_BILLING => false,
-            CustomerInterface::DEFAULT_SHIPPING => false,
-            'confirmation' => false,
-            'sendemail_store_id' => false,
-            'extension_attributes' => false,
         ];
 
         /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */
@@ -1275,11 +1221,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $customerFormMock->expects($this->once())
             ->method('extractData')
             ->with($this->requestMock, 'customer')
-            ->willReturn($filteredData);
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('compactData')
-            ->with($dataToCompact)
-            ->willReturn($filteredData);
+            ->with($extractedData)
+            ->willReturn($extractedData);
         $customerFormMock->expects($this->once())
             ->method('getAttributes')
             ->willReturn($attributes);
diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
index 9eed3d2b044ca166d35703d35e1fd1995e181108..28697fa5cf85faf8bb33dd61c9f5816fc0b60eed 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
@@ -1146,7 +1146,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase
 
         $storeId = 1;
 
-        mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX);
+        mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX);
         $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true));
 
         $this->emailNotificationMock->expects($this->once())
@@ -1168,7 +1168,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase
         $templateIdentifier = 'Template Identifier';
         $sender = 'Sender';
 
-        mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX);
+        mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX);
         $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true));
 
         $this->emailNotificationMock->expects($this->once())
@@ -1194,7 +1194,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase
         $templateIdentifier = 'Template Identifier';
         $sender = 'Sender';
 
-        mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX);
+        mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX);
         $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true));
 
         $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash);
diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json
index 74f0ebc2b5e0026acbdc5061949c10ad04aa8d9c..53e1a270fb3b04a791a368a375ce7e8b1ef62d8d 100644
--- a/app/code/Magento/Customer/composer.json
+++ b/app/code/Magento/Customer/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-customer",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-eav": "100.2.*",
         "magento/module-directory": "100.2.*",
diff --git a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
index 1ff64fffe20369a5675afcc573c99b9f926ba30a..9ad2cf5265043b4fd1850514258d99276d500ff3 100644
--- a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
+++ b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
@@ -78,7 +78,6 @@
                     <!-- ko foreach: getRegion('additional-login-form-fields') -->
                     <!-- ko template: getTemplate() --><!-- /ko -->
                     <!-- /ko -->
-                    </div>
                     <div class="actions-toolbar">
                         <input name="context" type="hidden" value="checkout" />
                         <div class="primary">
diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json
index 533f40c7688e4aa8269bedfe84f5331a772b0b2a..cd02f6dbfb38b46bda32ebdcb87720124eab37e4 100644
--- a/app/code/Magento/CustomerImportExport/composer.json
+++ b/app/code/Magento/CustomerImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-customer-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json
index 856e0d8b3e542a37cdd7fcf7554b9e4e158de245..ed0b8520ca645afa8af2506616f9dccde6965f08 100644
--- a/app/code/Magento/Deploy/composer.json
+++ b/app/code/Magento/Deploy/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-deploy",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-require-js": "100.2.*",
diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json
index 23f6d20c2aab74dc0f23c03f5727aa99379fbf54..73fd1c17750c6749bd0f89cd9fe55939fbe2d419 100644
--- a/app/code/Magento/Developer/composer.json
+++ b/app/code/Magento/Developer/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-developer",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/framework": "100.2.*",
         "magento/module-config": "100.2.*"
diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json
index e88cd535952d628628bbc984137430d5370a6ecd..15ca7882331a145ba1993ded371bd084bc8c83b3 100644
--- a/app/code/Magento/Dhl/composer.json
+++ b/app/code/Magento/Dhl/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-dhl",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-shipping": "100.2.*",
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php
index 9ea0babbfd9982c3e9c5657e218668c384b47501..ed36ad3ace22b232c8071bbb195184066a2ebd50 100644
--- a/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php
@@ -12,7 +12,10 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem
      *
      * @var array
      */
-    protected $_idAttributes = ['/config/zip' => 'countryCode'];
+    protected $_idAttributes = [
+        '/config/zip' => 'countryCode',
+        '/config/zip/codes/code' => 'id',
+    ];
 
     /**
      * Construct the FileSystem Reader Class
diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json
index 9b3b253c26a35ed14c4de51c77624a10750ce5f2..82d8bca34da840e57511bb3912c9b531297d9e86 100644
--- a/app/code/Magento/Directory/composer.json
+++ b/app/code/Magento/Directory/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-directory",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json
index 8d8814740ccd13248b1e7ab903052ca429567ead..ea8eef6436ef9174e9643c742684f29d1129799f 100644
--- a/app/code/Magento/Downloadable/composer.json
+++ b/app/code/Magento/Downloadable/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-downloadable",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/DownloadableImportExport/composer.json b/app/code/Magento/DownloadableImportExport/composer.json
index c99a0d6d05b822e792e24a27a69f68f240f8b002..4f95711b279d0f907934fc4cf2bc4b8056ff4817 100644
--- a/app/code/Magento/DownloadableImportExport/composer.json
+++ b/app/code/Magento/DownloadableImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-downloadable-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-import-export": "100.2.*",
         "magento/module-catalog-import-export": "100.2.*",
diff --git a/app/code/Magento/Eav/Model/AttributeManagement.php b/app/code/Magento/Eav/Model/AttributeManagement.php
index 8d8674bcca0e7886d4a174840a7d55dea5bef8a4..102aafbd39fb1ba473dc1a346a857ccf695a5dab 100644
--- a/app/code/Magento/Eav/Model/AttributeManagement.php
+++ b/app/code/Magento/Eav/Model/AttributeManagement.php
@@ -6,10 +6,14 @@
  */
 namespace Magento\Eav\Model;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\StateException;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterface
 {
     /**
@@ -19,6 +23,7 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa
 
     /**
      * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection
+     * @deprecated please use instead \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory
      */
     protected $attributeCollection;
 
@@ -47,6 +52,11 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa
      */
     protected $attributeResource;
 
+    /**
+     * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory
+     */
+    private $attributeCollectionFactory;
+
     /**
      * @param \Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository
      * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributeCollection
@@ -154,11 +164,26 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa
         if (!$attributeSet->getAttributeSetId() || $attributeSet->getEntityTypeId() != $requiredEntityTypeId) {
             throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId);
         }
-
-        $attributeCollection = $this->attributeCollection
-            ->setAttributeSetFilter($attributeSet->getAttributeSetId())
-            ->load();
+        /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributeCollection */
+        $attributeCollection = $this->getCollectionFactory()->create();
+        $attributeCollection->setAttributeSetFilter($attributeSet->getAttributeSetId())->load();
 
         return $attributeCollection->getItems();
     }
+
+    /**
+     * Retrieve collection factory
+     *
+     * @deprecated
+     * @return \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory
+     */
+    private function getCollectionFactory()
+    {
+        if ($this->attributeCollectionFactory === null) {
+            $this->attributeCollectionFactory = ObjectManager::getInstance()->create(
+                \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory::class
+            );
+        }
+        return $this->attributeCollectionFactory;
+    }
 }
diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php
index 88118e0b0f70fc54241d76b3895c644c5bd4a616..c45c575dffc2fa9fd87cf9e226ef06ceaa0ce2e2 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php
@@ -371,6 +371,24 @@ class AttributeManagementTest extends \PHPUnit_Framework_TestCase
         $entityType = 'type';
         $attributeSetId = 148;
 
+        $attributeCollectionFactoryMock = $this->getMock(
+            \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory::class,
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $attributeCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->attributeCollectionMock);
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $objectManager->setBackwardCompatibleProperty(
+            $this->model,
+            'attributeCollectionFactory',
+            $attributeCollectionFactoryMock
+        );
+
         $attributeSetMock = $this->getMock(\Magento\Eav\Api\Data\AttributeSetInterface::class, [], [], '', false);
         $this->setRepositoryMock->expects($this->once())
             ->method('get')
diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php
index bcad34654b98aa2d6d3844d1a780d585713c8d86..c18af6380a3b71ca7adfd6af5146f853926b419d 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php
@@ -29,7 +29,7 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
     {
         $this->contextMock = $this->getMock(
             \Magento\Framework\Model\Context::class,
-            ['getCacheManager', 'getEventDispatcher', 'getLogger', 'getAppState', 'getActionValidator'],
+            [],
             [],
             '',
             false
diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json
index 16e62a6434a26aa358a3491d697ce7cd3bb54ad7..9863a89fff5d3d64ccbf8eaa4b3f5691168e0155 100644
--- a/app/code/Magento/Eav/composer.json
+++ b/app/code/Magento/Eav/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-eav",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json
index 33d04b921278d3c57ce0107792c6deef458c73ab..648c984de0bbb6e93d16f84110075dc36909cfda 100644
--- a/app/code/Magento/Email/composer.json
+++ b/app/code/Magento/Email/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-email",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-theme": "100.2.*",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/EncryptionKey/composer.json b/app/code/Magento/EncryptionKey/composer.json
index 6d7ff5558734ab1952b59b2e02db4cc5093f9984..11b1c034a76a792cd782be06db484e494764553f 100644
--- a/app/code/Magento/EncryptionKey/composer.json
+++ b/app/code/Magento/EncryptionKey/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-encryption-key",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/framework": "100.2.*"
diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json
index d27d5c1c60d407ce4d1d5b3781b0209c5955a0d4..8d487485c0d210824949657ab7444ba937ef9996 100644
--- a/app/code/Magento/Fedex/composer.json
+++ b/app/code/Magento/Fedex/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-fedex",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-shipping": "100.2.*",
         "magento/module-directory": "100.2.*",
diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json
index 04c620dc36db5829f9c8c6aa8a6aec620d211e95..067bf16017b231977183491ff6a4e8cdf91dfe68 100644
--- a/app/code/Magento/GiftMessage/composer.json
+++ b/app/code/Magento/GiftMessage/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-gift-message",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-checkout": "100.2.*",
diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json
index ad3df5c0b8b2621f395acbfe81bfde3c6b7bae27..cacbbe2088c778ff4a3777f129aea263cf9dee79 100644
--- a/app/code/Magento/GoogleAdwords/composer.json
+++ b/app/code/Magento/GoogleAdwords/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-google-adwords",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-sales": "100.2.*",
         "magento/framework": "100.2.*"
diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json
index 4cccc7bd0cbff69369ae852138045ed06a0dbf4a..8653e93d7a98338160895c65011cdc2f7471270f 100644
--- a/app/code/Magento/GoogleAnalytics/composer.json
+++ b/app/code/Magento/GoogleAnalytics/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-google-analytics",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-sales": "100.2.*",
         "magento/framework": "100.2.*",
diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json
index 20a48fc78060b53fb144aa5da405b343ce696063..8c61e9f068ea122b74a7dea02ed5c110d26629b6 100644
--- a/app/code/Magento/GoogleOptimizer/composer.json
+++ b/app/code/Magento/GoogleOptimizer/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-google-optimizer",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-google-analytics": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json
index b036a8d5d528bd3959ea66b294d7b51736f7ba2c..50c061e5b56da30c1faf2bfab9439460be6908a3 100644
--- a/app/code/Magento/GroupedImportExport/composer.json
+++ b/app/code/Magento/GroupedImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-grouped-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-import-export": "100.2.*",
         "magento/module-catalog-import-export": "100.2.*",
diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json
index 69aed214284454722708703068de37e3134393f0..0f207eb414789becda0c4e57846f0a48ced13d7a 100644
--- a/app/code/Magento/GroupedProduct/composer.json
+++ b/app/code/Magento/GroupedProduct/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-grouped-product",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-catalog-inventory": "100.2.*",
diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json
index 35a088cbd9c91907c3f9f2c434f16cfb86ed57a8..5e403d2180652a6f3565bf03b573abf75310f19f 100644
--- a/app/code/Magento/ImportExport/composer.json
+++ b/app/code/Magento/ImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index cbaab12f6ee285ac1207f8c01d5ed5ff5af42c07..e80d8a9f7bc90d63dfbbced39431571d73fdc937 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-indexer",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/Integration/Model/Config.php b/app/code/Magento/Integration/Model/Config.php
index 70795cae0035034a7801c6a21cc3bb90ab566e1f..3cea4d33743198988c44d8c8aae9bf6e9f247efa 100644
--- a/app/code/Magento/Integration/Model/Config.php
+++ b/app/code/Magento/Integration/Model/Config.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\Type;
 
 /**
@@ -34,14 +36,24 @@ class Config
      */
     protected $_integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param Cache\Type $configCacheType
      * @param Config\Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(Cache\Type $configCacheType, Config\Reader $configReader)
-    {
+    public function __construct(
+        Cache\Type $configCacheType,
+        Config\Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->_configCacheType = $configCacheType;
         $this->_configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -55,10 +67,14 @@ class Config
         if (null === $this->_integrations) {
             $integrations = $this->_configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->_integrations = unserialize($integrations);
+                $this->_integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->_integrations = $this->_configReader->read();
-                $this->_configCacheType->save(serialize($this->_integrations), self::CACHE_ID, [Type::CACHE_TAG]);
+                $this->_configCacheType->save(
+                    $this->serializer->serialize($this->_integrations),
+                    self::CACHE_ID,
+                    [Type::CACHE_TAG]
+                );
             }
         }
         return $this->_integrations;
diff --git a/app/code/Magento/Integration/Model/ConsolidatedConfig.php b/app/code/Magento/Integration/Model/ConsolidatedConfig.php
index 9027bf774bc30a9a5b7cb6a427057efc45971742..9208d19e7028f8f753d6e20c2d43765163cb9bec 100644
--- a/app/code/Magento/Integration/Model/ConsolidatedConfig.php
+++ b/app/code/Magento/Integration/Model/ConsolidatedConfig.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\TypeConsolidated;
 
 /**
@@ -31,14 +33,24 @@ class ConsolidatedConfig
      */
     protected $integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param Cache\TypeConsolidated $configCacheType
      * @param Config\Consolidated\Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(Cache\TypeConsolidated $configCacheType, Config\Consolidated\Reader $configReader)
-    {
+    public function __construct(
+        Cache\TypeConsolidated $configCacheType,
+        Config\Consolidated\Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->configCacheType = $configCacheType;
         $this->configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -51,11 +63,11 @@ class ConsolidatedConfig
         if (null === $this->integrations) {
             $integrations = $this->configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->integrations = unserialize($integrations);
+                $this->integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->integrations = $this->configReader->read();
                 $this->configCacheType->save(
-                    serialize($this->integrations),
+                    $this->serializer->serialize($this->integrations),
                     self::CACHE_ID,
                     [TypeConsolidated::CACHE_TAG]
                 );
diff --git a/app/code/Magento/Integration/Model/IntegrationConfig.php b/app/code/Magento/Integration/Model/IntegrationConfig.php
index 647bff70efe4afdffd35e5294251e0fe9e98aa98..cde4fc20d22351ff4b9dedd9d93254f8d838438a 100644
--- a/app/code/Magento/Integration/Model/IntegrationConfig.php
+++ b/app/code/Magento/Integration/Model/IntegrationConfig.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\TypeIntegration;
 use Magento\Integration\Model\Config\Integration\Reader;
 
@@ -36,14 +38,24 @@ class IntegrationConfig
      */
     protected $_integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param TypeIntegration $configCacheType
      * @param Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(TypeIntegration $configCacheType, Reader $configReader)
-    {
+    public function __construct(
+        TypeIntegration $configCacheType,
+        Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->_configCacheType = $configCacheType;
         $this->_configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -57,11 +69,11 @@ class IntegrationConfig
         if (null === $this->_integrations) {
             $integrations = $this->_configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->_integrations = unserialize($integrations);
+                $this->_integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->_integrations = $this->_configReader->read();
                 $this->_configCacheType->save(
-                    serialize($this->_integrations),
+                    $this->serializer->serialize($this->_integrations),
                     self::CACHE_ID,
                     [TypeIntegration::CACHE_TAG]
                 );
diff --git a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
index 0b75592782773d504061e4e6f9a56c67ebe5982e..22b50a8aef8d070c479ca2a28b499308a6a95c80 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Integration\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\ConsolidatedConfig as Config;
 use Magento\Integration\Model\Cache\TypeConsolidated as Type;
 
@@ -18,17 +19,22 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
      *
      * @var Config
      */
-    protected $configModel;
+    private $configModel;
 
     /**
      * @var Type|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configCacheTypeMock;
+    private $configCacheTypeMock;
 
     /**
      * @var  \Magento\Integration\Model\Config\Consolidated\Reader|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configReaderMock;
+    private $configReaderMock;
+
+    /**
+     * @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
@@ -38,12 +44,16 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
         $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Consolidated\Reader::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $this->serializer = $this->getMockBuilder(SerializerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->configModel = $objectManagerHelper->getObject(
             \Magento\Integration\Model\ConsolidatedConfig::class,
             [
                 'configCacheType' => $this->configCacheTypeMock,
-                'configReader' => $this->configReaderMock
+                'configReader' => $this->configReaderMock,
+                'serializer' => $this->serializer,
             ]
         );
     }
@@ -51,10 +61,15 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigCacheType()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(Config::CACHE_ID)
-            ->will($this->returnValue(serialize($integrations)));
+            ->will($this->returnValue($serializedIntegrations));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedIntegrations)
+            ->willReturn($integrations);
 
         $this->assertEquals($integrations, $this->configModel->getIntegrations());
     }
@@ -62,17 +77,21 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigReader()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(Config::CACHE_ID)
             ->will($this->returnValue(null));
-        $this->configCacheTypeMock->expects($this->once())
-            ->method('save')
-            ->with(serialize($integrations), Config::CACHE_ID, [Type::CACHE_TAG])
-            ->will($this->returnValue(null));
         $this->configReaderMock->expects($this->once())
             ->method('read')
             ->will($this->returnValue($integrations));
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($integrations)
+            ->willReturn($serializedIntegrations);
+        $this->configCacheTypeMock->expects($this->once())
+            ->method('save')
+            ->with($serializedIntegrations, Config::CACHE_ID, [Type::CACHE_TAG]);
 
         $this->assertEquals($integrations, $this->configModel->getIntegrations());
     }
diff --git a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
index aed4e02453dc435fa5ff87f30931560bace8721e..14871420a621aceec2d5dcb79f209c60fac1f9f6 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Integration\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\IntegrationConfig;
 use Magento\Integration\Model\Cache\TypeIntegration;
 
@@ -16,17 +17,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
     /**
      * @var IntegrationConfig
      */
-    protected $integrationConfigModel;
+    private $integrationConfigModel;
 
     /**
      * @var TypeIntegration|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configCacheTypeMock;
+    private $configCacheTypeMock;
 
     /**
      * @var  \Magento\Integration\Model\Config\Integration\Reader|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configReaderMock;
+    private $configReaderMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
@@ -36,19 +42,28 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
         $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Integration\Reader::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $this->serializer = $this->getMockBuilder(SerializerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->integrationConfigModel = new IntegrationConfig(
             $this->configCacheTypeMock,
-            $this->configReaderMock
+            $this->configReaderMock,
+            $this->serializer
         );
     }
 
     public function testGetIntegrationsFromConfigCacheType()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(IntegrationConfig::CACHE_ID)
-            ->will($this->returnValue(serialize($integrations)));
+            ->will($this->returnValue($serializedIntegrations));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedIntegrations)
+            ->willReturn($integrations);
 
         $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations());
     }
@@ -56,17 +71,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigReader()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(IntegrationConfig::CACHE_ID)
             ->will($this->returnValue(null));
-        $this->configCacheTypeMock->expects($this->once())
-            ->method('save')
-            ->with(serialize($integrations), IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG])
-            ->will($this->returnValue(null));
         $this->configReaderMock->expects($this->once())
             ->method('read')
             ->will($this->returnValue($integrations));
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($integrations)
+            ->willReturn($serializedIntegrations);
+        $this->configCacheTypeMock->expects($this->once())
+            ->method('save')
+            ->with($serializedIntegrations, IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG])
+            ->will($this->returnValue(null));
 
         $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations());
     }
diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json
index 028e56472268abc0e0fcc612107a5bd8072da806..f76d60c957c87d828cc773e96a5edf10266293c9 100644
--- a/app/code/Magento/Integration/composer.json
+++ b/app/code/Magento/Integration/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-integration",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json
index 99299c3e4a32cccd465af4131bc549b033142545..d1d82781bb5c881cceaaf0b8ccdf85fa02c54e86 100644
--- a/app/code/Magento/LayeredNavigation/composer.json
+++ b/app/code/Magento/LayeredNavigation/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-layered-navigation",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/framework": "100.2.*"
diff --git a/app/code/Magento/Marketplace/Helper/Cache.php b/app/code/Magento/Marketplace/Helper/Cache.php
index 1cb5fb9c710e67885f0e7266d57873ca29cb3e21..a0a4ce73e0373ac7d057777160c7ac5028321e8c 100644
--- a/app/code/Magento/Marketplace/Helper/Cache.php
+++ b/app/code/Magento/Marketplace/Helper/Cache.php
@@ -6,7 +6,8 @@
 
 namespace Magento\Marketplace\Helper;
 
-use Magento\Framework\Filesystem;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Cache helper
@@ -25,15 +26,23 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $cache;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Framework\Config\CacheInterface $cache
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
-        \Magento\Framework\Config\CacheInterface $cache
+        \Magento\Framework\Config\CacheInterface $cache,
+        SerializerInterface $serializer = null
     ) {
         $this->cache = $cache;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
         parent::__construct($context);
     }
 
@@ -46,7 +55,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
     {
         $data = $this->getCache()->load($this->pathToCacheFile);
         if (false !== $data) {
-            $data = unserialize($data);
+            $data = $this->serializer->unserialize($data);
         }
         return $data;
     }
@@ -59,7 +68,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function savePartnersToCache($partners)
     {
-        return $this->getCache()->save(serialize($partners), $this->pathToCacheFile);
+        return $this->getCache()->save($this->serializer->serialize($partners), $this->pathToCacheFile);
     }
 
     /**
diff --git a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
index 75c6e6110389c5a920c3053aa451a6d0deab3775..00b78a47eb4b0be4c5b89cf3383dac80028dc899 100644
--- a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
+++ b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
@@ -6,70 +6,79 @@
 
 namespace Magento\Marketplace\Test\Unit\Helper;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 class CacheTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache
+     * @var \Magento\Framework\Config\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cache;
+
+    /**
+     * @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $cacheHelperMock;
+    private $serializer;
+
+    /**
+     * @var \Magento\Marketplace\Helper\Cache
+     */
+    private $cacheHelper;
 
     protected function setUp()
     {
-        $this->cacheHelperMock = $this->getCacheHelperMock(['getCache']);
+        $this->cache = $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->cacheHelper = $objectManagerHelper->getObject(
+            \Magento\Marketplace\Helper\Cache::class,
+            [
+                'cache' => $this->cache,
+                'serializer' => $this->serializer,
+            ]
+        );
     }
 
-    /**
-     * @covers \Magento\Marketplace\Helper\Cache::loadPartnersFromCache
-     */
     public function testLoadPartnersFromCache()
     {
-        $cache = $this->getCacheMock();
-        $this->cacheHelperMock
-            ->expects($this->once())
-            ->method('getCache')
-            ->will($this->returnValue($cache));
-        $cache->expects($this->once())
+        $partners = ['partner1', 'partner2'];
+        $serializedPartners = '["partner1", "partner2"]';
+        $this->cache->expects($this->once())
             ->method('load')
-            ->will($this->returnValue(''));
+            ->with('partners')
+            ->willReturn($serializedPartners);
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedPartners)
+            ->willReturn($partners);
 
-        $this->cacheHelperMock->loadPartnersFromCache();
+        $this->assertSame($partners, $this->cacheHelper->loadPartnersFromCache());
     }
 
-    /**
-     * @covers \Magento\Marketplace\Helper\Cache::savePartnersToCache
-     */
-    public function testSavePartnersToCache()
+    public function testLoadPartnersFromCacheNoCachedData()
     {
-        $cache = $this->getCacheMock();
-        $this->cacheHelperMock
-            ->expects($this->once())
-            ->method('getCache')
-            ->will($this->returnValue($cache));
-        $cache->expects($this->once())
-            ->method('save')
-            ->will($this->returnValue(true));
+        $this->cache->expects($this->once())
+            ->method('load')
+            ->with('partners')
+            ->willReturn(false);
+        $this->serializer->expects($this->never())
+            ->method('unserialize');
 
-        $this->cacheHelperMock->savePartnersToCache([]);
+        $this->assertSame(false, $this->cacheHelper->loadPartnersFromCache());
     }
 
-    /**
-     * Gets cache helper mock
-     *
-     * @param null $methods
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache
-     */
-    public function getCacheHelperMock($methods = null)
+    public function testSavePartnersToCache()
     {
-        return $this->getMock(\Magento\Marketplace\Helper\Cache::class, $methods, [], '', false);
-    }
+        $partners = ['partner1', 'partner2'];
+        $serializedPartners = '["partner1", "partner2"]';
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($partners)
+            ->willReturn($serializedPartners);
+        $this->cache->expects($this->once())
+            ->method('save')
+            ->with($serializedPartners);
 
-    /**
-     * Gets Filesystem mock
-     *
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Config\CacheInterface
-     */
-    public function getCacheMock()
-    {
-        return $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class);
+        $this->cacheHelper->savePartnersToCache($partners);
     }
 }
diff --git a/app/code/Magento/Marketplace/composer.json b/app/code/Magento/Marketplace/composer.json
index 2916ff94544bcc46cd59a9e48e9385e89ea6283b..ed79a80bc0c35d81efa3f27867b33846e3a19007 100644
--- a/app/code/Magento/Marketplace/composer.json
+++ b/app/code/Magento/Marketplace/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-marketplace",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/module-backend": "100.2.*"
     },
diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json
index fa7858d5b0aff32de7d37f2756aca1891cb15cf7..141e1c19c532cc67f8152459de7e12d50fb0b9d8 100644
--- a/app/code/Magento/MediaStorage/composer.json
+++ b/app/code/Magento/MediaStorage/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-media-storage",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-config": "100.2.*",
diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json
index b86374e6be2779d14fd3d2b3e8a4d5b46b1b881f..422aac99869919aa08c31e7ac4edd39d9e0a6f2e 100644
--- a/app/code/Magento/Msrp/composer.json
+++ b/app/code/Magento/Msrp/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-msrp",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-downloadable": "100.2.*",
diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json
index 8d9ac91cd05a07b78c19588cbcd34ce3a110cc9f..970c7ea0569a28d226f8f50c419b3d5ee998a17f 100644
--- a/app/code/Magento/Multishipping/composer.json
+++ b/app/code/Magento/Multishipping/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-multishipping",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-checkout": "100.2.*",
         "magento/module-sales": "100.2.*",
diff --git a/app/code/Magento/NewRelicReporting/composer.json b/app/code/Magento/NewRelicReporting/composer.json
index 9faa17d454e5072f7dc9ec5473057bfad1533dce..097de6bea926c60644bedefec56adde409f5aa04 100644
--- a/app/code/Magento/NewRelicReporting/composer.json
+++ b/app/code/Magento/NewRelicReporting/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-new-relic-reporting",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json
index 06a278aef6d48692c856f56daf213e4bab162db8..ab5cdd1510a35285d42698ee999737a74b699d54 100644
--- a/app/code/Magento/Newsletter/composer.json
+++ b/app/code/Magento/Newsletter/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-newsletter",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-customer": "100.2.*",
         "magento/module-widget": "100.2.*",
diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml
index fb6989716cd2dfc64d1e97c487e77f3b47afeb35..0ee371c32817649669fe2bc20d88b08e132a9a11 100644
--- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml
+++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml
@@ -10,7 +10,7 @@
 
 ?>
 <div class="block newsletter">
-    <div class="title"><strong>Newsletter</strong></div>
+    <div class="title"><strong><?php /* @escapeNotVerified */ echo __('Newsletter') ?></strong></div>
     <div class="content">
         <form class="form subscribe"
             novalidate
diff --git a/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php b/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php
index 84b6e554d4cfb193e1418f3d9460f9fcc44f6a7d..8616c186555e3e71db0a13a13c648b5c20ff3e0c 100644
--- a/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php
+++ b/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php
@@ -49,20 +49,13 @@ class Checkmo extends \Magento\Payment\Block\Info
     }
 
     /**
-     * Enter description here...
-     *
+     * @deprecated
      * @return $this
      */
     protected function _convertAdditionalData()
     {
-        $details = @unserialize($this->getInfo()->getAdditionalData());
-        if (is_array($details)) {
-            $this->_payableTo = isset($details['payable_to']) ? (string)$details['payable_to'] : '';
-            $this->_mailingAddress = isset($details['mailing_address']) ? (string)$details['mailing_address'] : '';
-        } else {
-            $this->_payableTo = '';
-            $this->_mailingAddress = '';
-        }
+        $this->_payableTo = $this->getInfo()->getAdditionalInformation('payable_to');
+        $this->_mailingAddress = $this->getInfo()->getAdditionalInformation('mailing_address');
         return $this;
     }
 
diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php
index 848cfbae52b25a0b4b202b296f43ae4b79c5c19a..27209fc8d3538a1465e985929ef6adb52408de93 100644
--- a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php
+++ b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php
@@ -5,81 +5,118 @@
  */
 namespace Magento\OfflinePayments\Test\Unit\Block\Info;
 
+use Magento\Framework\View\Element\Template\Context;
+use Magento\OfflinePayments\Block\Info\Checkmo;
+use Magento\Payment\Model\Info;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+/**
+ * CheckmoTest contains list of test for block methods testing
+ */
 class CheckmoTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\OfflinePayments\Block\Info\Checkmo
+     * @var Info|MockObject
+     */
+    private $info;
+
+    /**
+     * @var Checkmo
      */
-    protected $_model;
+    private $block;
 
+    /**
+     * @inheritdoc
+     */
     protected function setUp()
     {
-        $context = $this->getMock(\Magento\Framework\View\Element\Template\Context::class, [], [], '', false);
-        $this->_model = new \Magento\OfflinePayments\Block\Info\Checkmo($context);
+        $context = $this->getMockBuilder(Context::class)
+            ->disableOriginalConstructor()
+            ->setMethods([])
+            ->getMock();
+
+        $this->info = $this->getMockBuilder(Info::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAdditionalInformation'])
+            ->getMock();
+
+        $this->block = new Checkmo($context);
     }
 
     /**
+     * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getPayableTo
+     * @param array $details
+     * @param string|null $expected
      * @dataProvider getPayableToDataProvider
      */
     public function testGetPayableTo($details, $expected)
     {
-        $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false);
-        $info->expects($this->once())
-            ->method('getAdditionalData')
-            ->willReturn(serialize($details));
-        $this->_model->setData('info', $info);
+        $this->info->expects(static::at(0))
+            ->method('getAdditionalInformation')
+            ->with('payable_to')
+            ->willReturn($details);
+        $this->block->setData('info', $this->info);
 
-        $this->assertEquals($expected, $this->_model->getPayableTo());
+        static::assertEquals($expected, $this->block->getPayableTo());
     }
 
     /**
+     * Get list of variations for payable configuration option testing
      * @return array
      */
     public function getPayableToDataProvider()
     {
         return [
-            [['payable_to' => 'payable'], 'payable'],
-            ['', '']
+            ['payable_to' => 'payable', 'payable'],
+            ['', null]
         ];
     }
 
     /**
+     * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getMailingAddress
+     * @param array $details
+     * @param string|null $expected
      * @dataProvider getMailingAddressDataProvider
      */
     public function testGetMailingAddress($details, $expected)
     {
-        $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false);
-        $info->expects($this->once())
-            ->method('getAdditionalData')
-            ->willReturn(serialize($details));
-        $this->_model->setData('info', $info);
+        $this->info->expects(static::at(1))
+            ->method('getAdditionalInformation')
+            ->with('mailing_address')
+            ->willReturn($details);
+        $this->block->setData('info', $this->info);
 
-        $this->assertEquals($expected, $this->_model->getMailingAddress());
+        static::assertEquals($expected, $this->block->getMailingAddress());
     }
 
     /**
+     * Get list of variations for mailing address testing
      * @return array
      */
     public function getMailingAddressDataProvider()
     {
         return [
-            [['mailing_address' => 'blah@blah.com'], 'blah@blah.com'],
-            ['', '']
+            ['mailing_address' => 'blah@blah.com', 'blah@blah.com'],
+            ['mailing_address' => '', null]
         ];
     }
 
+    /**
+     * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getMailingAddress
+     */
     public function testConvertAdditionalDataIsNeverCalled()
     {
-        $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false);
-        $info->expects($this->once())
-            ->method('getAdditionalData')
-            ->willReturn(serialize(['mailing_address' => 'blah@blah.com']));
-        $this->_model->setData('info', $info);
+        $mailingAddress = 'blah@blah.com';
+        $this->info->expects(static::at(1))
+            ->method('getAdditionalInformation')
+            ->with('mailing_address')
+            ->willReturn($mailingAddress);
+        $this->block->setData('info', $this->info);
 
         // First we set the property $this->_mailingAddress
-        $this->_model->getMailingAddress();
+        $this->block->getMailingAddress();
 
         // And now we get already setted property $this->_mailingAddress
-        $this->assertEquals('blah@blah.com', $this->_model->getMailingAddress());
+        static::assertEquals($mailingAddress, $this->block->getMailingAddress());
     }
 }
diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json
index 52deb08ba3d904a824faa762391ddf67ae29b026..cf728aaa1c5f6a7ea7c36163b021cb378d7df7f0 100644
--- a/app/code/Magento/OfflinePayments/composer.json
+++ b/app/code/Magento/OfflinePayments/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-offline-payments",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-checkout": "100.2.*",
         "magento/module-payment": "100.2.*",
         "magento/framework": "100.2.*"
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
index d5bff77e002d17d5ad8a80349ea646aee0135fa4..8c5cfd50cc110f2f8c61414c14ed2d48965929d6 100644
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
+++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml
@@ -10,7 +10,7 @@
  */
 ?>
 <?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?>
-<?php if ($block->getInfo()->getAdditionalData()): ?>
+<?php if ($block->getInfo()->getAdditionalInformation()): ?>
     <?php if ($block->getPayableTo()): ?>
         <br /><?php echo $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?>
     <?php endif; ?>
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
index 6195cdbd776548c229a6d1dfca03c8f4c1b2a61f..5587ac239d37e84a21348cfd994d9d0b73f0ba97 100644
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
+++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml
@@ -11,7 +11,7 @@
 ?>
 <?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?>
     {{pdf_row_separator}}
-<?php if ($block->getInfo()->getAdditionalData()): ?>
+<?php if ($block->getInfo()->getAdditionalInformation()): ?>
     {{pdf_row_separator}}
     <?php if ($block->getPayableTo()): ?>
         <?php echo $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?>
diff --git a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml
index f0dbff1add32b2fd7d49e3b6ca5f14c4038fc2ca..3c0b6bb23086a67b48de1134cdb245daffeab045 100644
--- a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml
+++ b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml
@@ -11,7 +11,7 @@
 ?>
 <dl class="payment-method checkmemo">
     <dt class="title"><?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?></dt>
-    <?php if ($block->getInfo()->getAdditionalData()): ?>
+    <?php if ($block->getInfo()->getAdditionalInformation()): ?>
         <?php if ($block->getPayableTo()): ?>
             <dd class="content">
                 <strong><?php echo $block->escapeHtml(__('Make Check payable to')) ?></strong>
diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json
index 3c959b4dec766fe09cf81df46571051b714ee4e1..b429376c6cd7adc0a70b133a633b4edf068d684e 100644
--- a/app/code/Magento/OfflineShipping/composer.json
+++ b/app/code/Magento/OfflineShipping/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-offline-shipping",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml b/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml
index 50ed4cdc9417833683a04e3a715ff828f04b9674..4a4f550588f5366668f4ceee0ff895964246172b 100644
--- a/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml
+++ b/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml
@@ -52,6 +52,7 @@
                 <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Show Method if Not Applicable</label>
                     <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                    <frontend_class>shipping-skip-hide</frontend_class>
                 </field>
                 <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                     <label>Displayed Error Message</label>
@@ -146,6 +147,7 @@
                 <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Show Method if Not Applicable</label>
                     <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                    <frontend_class>shipping-skip-hide</frontend_class>
                 </field>
                 <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                     <label>Displayed Error Message</label>
diff --git a/app/code/Magento/PageCache/Model/Config.php b/app/code/Magento/PageCache/Model/Config.php
index 222d9d57e467a31988fd6b6ac221f7ce640c06c5..786165728406f0162be0da04f869a10020d9d3bb 100644
--- a/app/code/Magento/PageCache/Model/Config.php
+++ b/app/code/Magento/PageCache/Model/Config.php
@@ -148,12 +148,17 @@ class Config
             ),
             '/* {{ ips }} */' => $this->_getAccessList(),
             '/* {{ design_exceptions_code }} */' => $this->_getDesignExceptions(),
-            // http headers get transformed by php `X-Forwarded-Proto: https` becomes $SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'
+            // http headers get transformed by php `X-Forwarded-Proto: https`
+            // becomes $SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'
             // Apache and Nginx drop all headers with underlines by default.
-            '/* {{ ssl_offloaded_header }} */' => str_replace('_', '-', $this->_scopeConfig->getValue(
-                \Magento\Framework\HTTP\PhpEnvironment\Request::XML_PATH_OFFLOADER_HEADER,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE))
-
+            '/* {{ ssl_offloaded_header }} */' => str_replace(
+                '_',
+                '-',
+                $this->_scopeConfig->getValue(
+                    \Magento\Framework\HTTP\PhpEnvironment\Request::XML_PATH_OFFLOADER_HEADER,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                )
+            )
         ];
     }
 
@@ -176,6 +181,7 @@ class Config
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         );
         if (!empty($accessList)) {
+            $result = [];
             $ips = explode(',', $accessList);
             foreach ($ips as $ip) {
                 $result[] = sprintf($tpl, trim($ip));
diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json
index 5c29e4fc3c97081626ae4a77243ccd6ac9843d38..f18eb7bbe94edd31a48c4796dc41b21cdef38a8b 100644
--- a/app/code/Magento/PageCache/composer.json
+++ b/app/code/Magento/PageCache/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-page-cache",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index 35ff326d916bd43f8ae2366d9b50f5b77fe46dc8..c8d7254ce9e002ced1ecfb1067d821c63dbeb5be 100644
--- a/app/code/Magento/Payment/composer.json
+++ b/app/code/Magento/Payment/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-payment",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-sales": "100.2.*",
diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json
index bddc5d91a94587f4d26532246d8c83f8de6ba7f7..7503db18f008ca76252f8687df6d52f88dc0e02d 100644
--- a/app/code/Magento/Paypal/composer.json
+++ b/app/code/Magento/Paypal/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-paypal",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-checkout": "100.2.*",
diff --git a/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml b/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml
index 1876f07830ba7b55df25230bc256b829f65b2fc3..90cb60186e34e3730ae6d068b34e4002add00a6c 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml
@@ -23,7 +23,8 @@
                 <label>Express Checkout</label>
                 <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
                 <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5">
-                    <label>Email Associated with PayPal Merchant Account</label>
+                    <label>Email Associated with PayPal Merchant Account (Optional)</label>
+                    <frontend_class>not-required</frontend_class>
                     <comment>
                         <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]>
                     </comment>
diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index 25cc9d76acd768fe970363628abad60945e418d9..61f77a104c016d23f3734433efd8646bd21b42f4 100644
--- a/app/code/Magento/Persistent/composer.json
+++ b/app/code/Magento/Persistent/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-persistent",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-checkout": "100.2.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json
index a43a52209740318e0f5adcc8bea03a8860c04037..9c63c6958a465852ea3148cab659102880b07630 100644
--- a/app/code/Magento/ProductAlert/composer.json
+++ b/app/code/Magento/ProductAlert/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-product-alert",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
index f0edccbaf812acbf8495d97817515395635af409..7a087f769877160a316635baf9017b8b37ebbd38 100644
--- a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
+++ b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
@@ -6,6 +6,7 @@
 namespace Magento\ProductVideo\Controller\Adminhtml\Product\Gallery;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\File\Uploader;
 
 /**
@@ -43,6 +44,13 @@ class RetrieveImage extends \Magento\Backend\App\Action
      */
     protected $fileUtility;
 
+    /**
+     * URI validator
+     *
+     * @var \Magento\Framework\Validator\ValidatorInterface
+     */
+    private $protocolValidator;
+
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
@@ -51,6 +59,7 @@ class RetrieveImage extends \Magento\Backend\App\Action
      * @param \Magento\Framework\Image\AdapterFactory $imageAdapterFactory
      * @param \Magento\Framework\HTTP\Adapter\Curl $curl
      * @param \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility
+     * @param \Magento\Framework\Validator\ValidatorInterface $protocolValidator
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
@@ -59,7 +68,8 @@ class RetrieveImage extends \Magento\Backend\App\Action
         \Magento\Framework\Filesystem $fileSystem,
         \Magento\Framework\Image\AdapterFactory $imageAdapterFactory,
         \Magento\Framework\HTTP\Adapter\Curl $curl,
-        \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility
+        \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility,
+        \Magento\Framework\Validator\ValidatorInterface $protocolValidator = null
     ) {
         parent::__construct($context);
         $this->resultRawFactory = $resultRawFactory;
@@ -68,6 +78,10 @@ class RetrieveImage extends \Magento\Backend\App\Action
         $this->imageAdapter = $imageAdapterFactory->create();
         $this->curl = $curl;
         $this->fileUtility = $fileUtility;
+
+        $this->protocolValidator = $protocolValidator ?:
+            \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\Validator\ValidatorInterface::class);
     }
 
     /**
@@ -78,15 +92,15 @@ class RetrieveImage extends \Magento\Backend\App\Action
         $baseTmpMediaPath = $this->mediaConfig->getBaseTmpMediaPath();
         try {
             $remoteFileUrl = $this->getRequest()->getParam('remote_image');
-            $originalFileName = basename($remoteFileUrl);
-            $localFileName = Uploader::getCorrectFileName($originalFileName);
+            $this->validateRemoteFile($remoteFileUrl);
+            $localFileName = Uploader::getCorrectFileName(basename($remoteFileUrl));
             $localTmpFileName = Uploader::getDispretionPath($localFileName) . DIRECTORY_SEPARATOR . $localFileName;
-            $localFileMediaPath = $baseTmpMediaPath . ($localTmpFileName);
-            $localUniqueFileMediaPath = $this->appendNewFileName($localFileMediaPath);
-            $this->retrieveRemoteImage($remoteFileUrl, $localUniqueFileMediaPath);
-            $localFileFullPath = $this->appendAbsoluteFileSystemPath($localUniqueFileMediaPath);
+            $localFilePath = $baseTmpMediaPath . ($localTmpFileName);
+            $localUniqFilePath = $this->appendNewFileName($localFilePath);
+            $this->retrieveRemoteImage($remoteFileUrl, $localUniqFilePath);
+            $localFileFullPath = $this->appendAbsoluteFileSystemPath($localUniqFilePath);
             $this->imageAdapter->validateUploadFile($localFileFullPath);
-            $result = $this->appendResultSaveRemoteImage($localUniqueFileMediaPath);
+            $result = $this->appendResultSaveRemoteImage($localUniqFilePath);
         } catch (\Exception $e) {
             $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
         }
@@ -98,6 +112,25 @@ class RetrieveImage extends \Magento\Backend\App\Action
         return $response;
     }
 
+    /**
+     * Validate remote file
+     *
+     * @param string $remoteFileUrl
+     * @throws LocalizedException
+     *
+     * @return $this
+     */
+    private function validateRemoteFile($remoteFileUrl)
+    {
+        if (!$this->protocolValidator->isValid($remoteFileUrl)) {
+            throw new LocalizedException(
+                __("Protocol isn't allowed")
+            );
+        }
+
+        return $this;
+    }
+
     /**
      * @param string $fileName
      * @return mixed
@@ -116,6 +149,8 @@ class RetrieveImage extends \Magento\Backend\App\Action
     }
 
     /**
+     * Trying to get remote image to save it locally
+     *
      * @param string $fileUrl
      * @param string $localFilePath
      * @return void
@@ -127,7 +162,7 @@ class RetrieveImage extends \Magento\Backend\App\Action
         $this->curl->write('GET', $fileUrl);
         $image = $this->curl->read();
         if (empty($image)) {
-            throw new \Magento\Framework\Exception\LocalizedException(
+            throw new LocalizedException(
                 __('Could not get preview image information. Please check your connection and try again.')
             );
         }
diff --git a/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php b/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php
index 79d83f38421bba1a2e582efc3bc90f261c8b79dc..64149d529e5ca8f993e300594279a7e0842f9b8b 100644
--- a/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php
+++ b/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php
@@ -73,17 +73,11 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->contextMock = $this->getMock(\Magento\Backend\App\Action\Context::class, [], [], '', false);
         $this->rawFactoryMock =
             $this->getMock(\Magento\Framework\Controller\Result\RawFactory::class, ['create'], [], '', false);
-        $response =
-            $this->getMock(
-                \Magento\Framework\Controller\Result\Raw::class,
-                [],
-                [],
-                '',
-                false
-            );
+        $response = new \Magento\Framework\DataObject();
         $this->rawFactoryMock->expects($this->once())->method('create')->willReturn($response);
         $this->configMock = $this->getMock(\Magento\Catalog\Model\Product\Media\Config::class, [], [], '', false);
         $this->filesystemMock = $this->getMock(\Magento\Framework\Filesystem::class, [], [], '', false);
@@ -101,11 +95,15 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase
         $this->adapterFactoryMock->expects($this->once())->method('create')->willReturn($this->abstractAdapter);
         $this->curlMock = $this->getMock(\Magento\Framework\HTTP\Adapter\Curl::class, [], [], '', false);
         $this->storageFileMock =
-            $this->getMock(\Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, [], [], '', false);
+        $this->getMock(\Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, [], [], '', false);
         $this->request = $this->getMock(\Magento\Framework\App\RequestInterface::class);
         $this->contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->request));
-
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $managerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['get'])
+            ->getMockForAbstractClass();
+        $this->contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->request));
+        $this->contextMock->expects($this->any())->method('getObjectManager')->willReturn($managerMock);
 
         $this->image = $objectManager->getObject(
             \Magento\ProductVideo\Controller\Adminhtml\Product\Gallery\RetrieveImage::class,
@@ -117,6 +115,7 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase
                 'imageAdapterFactory' => $this->adapterFactoryMock,
                 'curl' => $this->curlMock,
                 'fileUtility' => $this->storageFileMock,
+                'protocolValidator' => new \Magento\Framework\Validator\AllowedProtocols(),
             ]
         );
     }
diff --git a/app/code/Magento/ProductVideo/composer.json b/app/code/Magento/ProductVideo/composer.json
index 362fd006d2690c9f9b60b7be3abb71d5ce0b4da7..08d21e4c2abbfb167aed2ca24c0ba012d6b2e8c8 100644
--- a/app/code/Magento/ProductVideo/composer.json
+++ b/app/code/Magento/ProductVideo/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-product-video",
     "description": "Add Video to Products",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-backend": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/ProductVideo/etc/di.xml b/app/code/Magento/ProductVideo/etc/di.xml
index 09c15d8fccecc64d3dd183e7940aa26b6819d6df..7242a9d48ce1e3c0da66a3f4d5953cda705132cd 100644
--- a/app/code/Magento/ProductVideo/etc/di.xml
+++ b/app/code/Magento/ProductVideo/etc/di.xml
@@ -7,6 +7,7 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
     <preference for="Magento\Framework\Api\Data\VideoContentInterface" type="Magento\ProductVideo\Model\Product\Attribute\Media\VideoEntry" />
+    <preference for="Magento\Framework\Validator\ValidatorInterface" type="Magento\Framework\Validator\AllowedProtocols" />
     <type name="Magento\Catalog\Model\Product\Attribute\Backend\Media\EntryConverterPool">
         <arguments>
             <argument name="mediaGalleryEntryConvertersCollection" xsi:type="array">
diff --git a/app/code/Magento/ProductVideo/i18n/en_US.csv b/app/code/Magento/ProductVideo/i18n/en_US.csv
index 4cfabe1592dd2d0ce5c8072f0bdaafbc847689e6..64a08075c19548bc092f3918e7dabf606dd2052e 100644
--- a/app/code/Magento/ProductVideo/i18n/en_US.csv
+++ b/app/code/Magento/ProductVideo/i18n/en_US.csv
@@ -40,3 +40,4 @@ Delete,Delete
 "Show related video","Show related video"
 "Auto restart video","Auto restart video"
 "Images And Videos","Images And Videos"
+"Protocol isn't allowed", "Protocol isn't allowed"
diff --git a/app/code/Magento/Quote/Model/QueryResolver.php b/app/code/Magento/Quote/Model/QueryResolver.php
index cfc1480feb66386a122b21a6484107a205cad566..04d83bab85b2bf4b31c5d57e8c2b742614a4694b 100644
--- a/app/code/Magento/Quote/Model/QueryResolver.php
+++ b/app/code/Magento/Quote/Model/QueryResolver.php
@@ -5,8 +5,10 @@
  */
 namespace Magento\Quote\Model;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Config\CacheInterface;
 use Magento\Framework\App\ResourceConnection\ConfigInterface;
+use Magento\Framework\Serialize\SerializerInterface;
 
 class QueryResolver
 {
@@ -37,19 +39,27 @@ class QueryResolver
      */
     private $cacheTags = [];
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param ConfigInterface $config
      * @param CacheInterface $cache
      * @param string $cacheId
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         ConfigInterface $config,
         CacheInterface $cache,
-        $cacheId = 'connection_config_cache'
+        $cacheId = 'connection_config_cache',
+        SerializerInterface $serializer = null
     ) {
         $this->config = $config;
         $this->cache = $cache;
         $this->cacheId = $cacheId;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -75,9 +85,9 @@ class QueryResolver
         if (false === $data) {
             $singleQuery = $this->config->getConnectionName('checkout_setup') == 'default' ? true : false;
             $data['checkout'] = $singleQuery;
-            $this->cache->save(serialize($data), $this->cacheId, $this->cacheTags);
+            $this->cache->save($this->serializer->serialize($data), $this->cacheId, $this->cacheTags);
         } else {
-            $data = unserialize($data);
+            $data = $this->serializer->unserialize($data);
         }
         $this->merge($data);
     }
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
index 8e62d1b942f1e2a5808e76ac293c94abd9830cad..d430bf3acc6cd08d22b0f352efde6b9dc7774fed 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Quote\Model\Quote\Address\Total;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Address Total Collector model
  */
@@ -69,6 +71,7 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
      * @param \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory
      * @param mixed $sourceData
      * @param mixed $store
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
@@ -78,11 +81,12 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory,
         $sourceData = null,
-        $store = null
+        $store = null,
+        SerializerInterface $serializer = null
     ) {
         $this->_scopeConfig = $scopeConfig;
         $this->_totalFactory = $totalFactory;
-        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData);
+        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer);
         $this->_store = $store ?: $storeManager->getStore();
         $this->_initModels()->_initCollectors()->_initRetrievers();
     }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
index a2075b1161fc2a9cde83ba9af7bd2729244aa9a3..eb6828afff4edc79f0fb32bea383515ebacdcf86 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
@@ -6,83 +6,100 @@
 
 namespace Magento\Quote\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 class QueryResolverTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Quote\Model\QueryResolver
      */
-    protected $quoteResolver;
+    private $quoteResolver;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configMock;
+    private $configMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $cacheMock;
+    private $cacheMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
         $this->configMock = $this->getMock(\Magento\Framework\App\ResourceConnection\ConfigInterface::class);
         $this->cacheMock = $this->getMock(\Magento\Framework\Config\CacheInterface::class);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
         $this->quoteResolver = new \Magento\Quote\Model\QueryResolver(
             $this->configMock,
             $this->cacheMock,
-            'connection_config_cache'
+            'connection_config_cache',
+            $this->serializer
         );
-
     }
 
     public function testIsSingleQueryWhenDataWereCached()
     {
-        $queryData['checkout'] = true;
+        $serializedData = '{"checkout":true}';
+        $data = ['checkout' => true];
         $this->cacheMock
             ->expects($this->once())
             ->method('load')
             ->with('connection_config_cache')
-            ->willReturn(serialize($queryData));
+            ->willReturn($serializedData);
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedData)
+            ->willReturn($data);
         $this->assertTrue($this->quoteResolver->isSingleQuery());
     }
 
-    public function testIsSingleQueryWhenDataNotCached()
+    /**
+     * @param string $connectionName
+     * @param bool $isSingleQuery
+     *
+     * @dataProvider isSingleQueryWhenDataNotCachedDataProvider
+     */
+    public function testIsSingleQueryWhenDataNotCached($connectionName, $isSingleQuery)
     {
-        $queryData['checkout'] = true;
+        $data = ['checkout' => $isSingleQuery];
+        $serializedData = '{"checkout":true}';
         $this->cacheMock
             ->expects($this->once())
             ->method('load')
             ->with('connection_config_cache')
             ->willReturn(false);
+        $this->serializer->expects($this->never())
+            ->method('unserialize');
         $this->configMock
             ->expects($this->once())
             ->method('getConnectionName')
             ->with('checkout_setup')
-            ->willReturn('default');
+            ->willReturn($connectionName);
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($data)
+            ->willReturn($serializedData);
         $this->cacheMock
             ->expects($this->once())
             ->method('save')
-            ->with(serialize($queryData), 'connection_config_cache', []);
-        $this->assertTrue($this->quoteResolver->isSingleQuery());
+            ->with($serializedData, 'connection_config_cache', []);
+        $this->assertEquals($isSingleQuery, $this->quoteResolver->isSingleQuery());
     }
 
-    public function testIsSingleQueryWhenSeveralConnectionsExist()
+    /**
+     * @return array
+     */
+    public function isSingleQueryWhenDataNotCachedDataProvider()
     {
-        $queryData['checkout'] = false;
-        $this->cacheMock
-            ->expects($this->once())
-            ->method('load')
-            ->with('connection_config_cache')
-            ->willReturn(false);
-        $this->configMock
-            ->expects($this->once())
-            ->method('getConnectionName')
-            ->with('checkout_setup')
-            ->willReturn('checkout');
-        $this->cacheMock
-            ->expects($this->once())
-            ->method('save')
-            ->with(serialize($queryData), 'connection_config_cache', []);
-        $this->assertFalse($this->quoteResolver->isSingleQuery());
+        return [
+            ['default', true],
+            ['checkout', false],
+        ];
     }
 }
diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json
index 79c3a1aaa9d907cea1c505ece12a22e4ee3986f2..76063b177d46c2eb93626dea77a346aaaeb5c21d 100644
--- a/app/code/Magento/Quote/composer.json
+++ b/app/code/Magento/Quote/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-quote",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json
index 0bb989cb54ac8cb84e3da943a231634b6707f256..9c76abd07b9b35276f1f923138c9dd47031c289d 100644
--- a/app/code/Magento/Reports/composer.json
+++ b/app/code/Magento/Reports/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-reports",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json
index 8c9fed33ab730dd2431b222b2edd04aa2252e12f..68428caa867bf7108fc466ebfd1fa2829a2b75fa 100644
--- a/app/code/Magento/RequireJs/composer.json
+++ b/app/code/Magento/RequireJs/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-require-js",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json
index 09f5529feabdd97512839be2dacd00f791083c3c..3ec82943476088c3aa307de1b5a934a3cac8ca0d 100644
--- a/app/code/Magento/Review/composer.json
+++ b/app/code/Magento/Review/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-review",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml
index 7c89fd8740c5607ec83f0d0a4dda761de50d97ed..bcac1dbca059833749faf9db4d759f8a06a6f24a 100644
--- a/app/code/Magento/Review/view/frontend/templates/form.phtml
+++ b/app/code/Magento/Review/view/frontend/templates/form.phtml
@@ -20,7 +20,7 @@
         <?php if ($block->getRatings() && $block->getRatings()->getSize()): ?>
         <span id="input-message-box"></span>
         <fieldset class="field required review-field-ratings">
-            <legend class="label"><span><?php echo $block->escapeHtml(__('Your Rating')) ?><span></legend><br/>
+            <legend class="label"><span><?php echo $block->escapeHtml(__('Your Rating')) ?></span></legend><br/>
             <div class="control">
                 <div class="nested" id="product-review-table">
                     <?php foreach ($block->getRatings() as $_rating): ?>
diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json
index d35f0ee6ebecbf75af87566d776f172ab3d22c0d..fedd0ffeaacfe9577ea6e5971411540d4925fe4c 100644
--- a/app/code/Magento/Rss/composer.json
+++ b/app/code/Magento/Rss/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-rss",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/framework": "100.2.*",
diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json
index 95b8e6ffec2a682895b3459ca7bdcc7b4f001669..31ee3254d99b98a10ce9973e3a8a4adb1c5818da 100644
--- a/app/code/Magento/Rule/composer.json
+++ b/app/code/Magento/Rule/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-rule",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-eav": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php
index 36f1310079ed534d928fa03be511a64265f71dc5..ac3ffdc3d622c956074b3fc174df6c24e4cabff3 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php
@@ -217,9 +217,9 @@ class CreditmemoLoader extends DataObject
             foreach ($creditmemo->getAllItems() as $creditmemoItem) {
                 $orderItem = $creditmemoItem->getOrderItem();
                 $parentId = $orderItem->getParentItemId();
-                if (isset($backToStock[$orderItem->getId()])) {
+                if ($parentId && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
                     $creditmemoItem->setBackToStock(true);
-                } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
+                } elseif (isset($backToStock[$orderItem->getId()])) {
                     $creditmemoItem->setBackToStock(true);
                 } elseif (empty($savedData)) {
                     $creditmemoItem->setBackToStock(
diff --git a/app/code/Magento/Sales/Model/Config/Ordered.php b/app/code/Magento/Sales/Model/Config/Ordered.php
index 7ea7d1f8cc5fae05277754e033c9a4cb9fac37f6..806a7b522c189f495e080307981bf8fd95f3d420 100644
--- a/app/code/Magento/Sales/Model/Config/Ordered.php
+++ b/app/code/Magento/Sales/Model/Config/Ordered.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Sales\Model\Config;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Configuration class for ordered items
  *
@@ -69,22 +72,30 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
      */
     protected $_salesConfig;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Framework\Simplexml\Element $sourceData
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
-        $sourceData = null
+        $sourceData = null,
+        SerializerInterface $serializer = null
     ) {
         parent::__construct($sourceData);
         $this->_configCacheType = $configCacheType;
         $this->_logger = $logger;
         $this->_salesConfig = $salesConfig;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -179,11 +190,11 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
         $sortedCodes = [];
         $cachedData = $this->_configCacheType->load($this->_collectorsCacheKey);
         if ($cachedData) {
-            $sortedCodes = unserialize($cachedData);
+            $sortedCodes = $this->serializer->unserialize($cachedData);
         }
         if (!$sortedCodes) {
             $sortedCodes = $this->_getSortedCollectorCodes($this->_modelsConfig);
-            $this->_configCacheType->save(serialize($sortedCodes), $this->_collectorsCacheKey);
+            $this->_configCacheType->save($this->serializer->serialize($sortedCodes), $this->_collectorsCacheKey);
         }
         foreach ($sortedCodes as $code) {
             $this->_collectors[$code] = $this->_models[$code];
diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php
index 21104933a51d6d8fda5d225ff4b879a07def3d20..ff687074e4a66cc50c457c685fc1757d1529dcb6 100644
--- a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php
+++ b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php
@@ -3,7 +3,6 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Sales\Model\Order;
 
 /**
@@ -23,6 +22,11 @@ class CreditmemoFactory
      */
     protected $taxConfig;
 
+    /**
+     * @var \Magento\Framework\Unserialize\Unserialize
+     */
+    protected $unserialize;
+
     /**
      * Factory constructor
      *
@@ -57,7 +61,12 @@ class CreditmemoFactory
 
             $item = $this->convertor->itemToCreditmemoItem($orderItem);
             if ($orderItem->isDummy()) {
-                $qty = 1;
+                if (isset($data['qtys'][$orderItem->getParentItemId()])) {
+                    $parentQty = $data['qtys'][$orderItem->getParentItemId()];
+                } else {
+                    $parentQty = $orderItem->getParentItem() ? $orderItem->getParentItem()->getQtyToRefund() : 1;
+                }
+                $qty = $this->calculateProductOptions($orderItem, $parentQty);
                 $orderItem->setLockedDoShip(true);
             } else {
                 if (isset($qtys[$orderItem->getId()])) {
@@ -132,7 +141,12 @@ class CreditmemoFactory
 
             $item = $this->convertor->itemToCreditmemoItem($orderItem);
             if ($orderItem->isDummy()) {
-                $qty = 1;
+                if (isset($data['qtys'][$orderItem->getParentItemId()])) {
+                    $parentQty = $data['qtys'][$orderItem->getParentItemId()];
+                } else {
+                    $parentQty = $orderItem->getParentItem() ? $orderItem->getParentItem()->getQtyToRefund() : 1;
+                }
+                $qty = $this->calculateProductOptions($orderItem, $parentQty);
             } else {
                 if (isset($qtys[$orderItem->getId()])) {
                     $qty = (double)$qtys[$orderItem->getId()];
@@ -245,4 +259,38 @@ class CreditmemoFactory
             $creditmemo->setAdjustmentNegative($data['adjustment_negative']);
         }
     }
+
+    /**
+     * @param \Magento\Sales\Api\Data\OrderItemInterface $orderItem
+     * @param array $qtys
+     * @return int
+     */
+    private function calculateProductOptions(\Magento\Sales\Api\Data\OrderItemInterface $orderItem, $parentQty)
+    {
+        $qty = $parentQty;
+        $productOptions = $orderItem->getProductOptions();
+        if (isset($productOptions['bundle_selection_attributes'])) {
+            $bundleSelectionAttributes = $this->getUnserialize()
+                ->unserialize($productOptions['bundle_selection_attributes']);
+            if ($bundleSelectionAttributes) {
+                $qty = $bundleSelectionAttributes['qty'] * $parentQty;
+            }
+        }
+        return $qty;
+    }
+
+    /**
+     * Get Unserialize
+     *
+     * @return \Magento\Framework\Unserialize\Unserialize
+     * @deprecated
+     */
+    private function getUnserialize()
+    {
+        if (!$this->unserialize) {
+            $this->unserialize = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\Unserialize\Unserialize::class);
+        }
+        return $this->unserialize;
+    }
 }
diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php
index a0f56d6ea9a73ea02d4c852ef6ac4831be29b574..3cd5ecde21366c87d4ee746a0ddc1b453ec0bf95 100644
--- a/app/code/Magento/Sales/Model/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Order/Payment.php
@@ -1289,7 +1289,7 @@ class Payment extends Info implements OrderPaymentInterface
      */
     public function isCaptureFinal($amountToCapture)
     {
-        $total = $this->getOrder()->getTotalDue();
+        $total = $this->getOrder()->getBaseTotalDue();
         return $this->formatAmount($total, true) == $this->formatAmount($amountToCapture, true);
     }
 
diff --git a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
index 22c71f48b6f35189bf532362a8647e53069a39a5..d96591118b82296a937445256e01e75ee942a569 100644
--- a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
+++ b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Sales\Model\Order\Total\Config;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Configuration class for totals
  */
@@ -42,15 +44,17 @@ class Base extends \Magento\Sales\Model\Config\Ordered
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory
      * @param mixed $sourceData
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory,
-        $sourceData = null
+        $sourceData = null,
+        SerializerInterface $serializer = null
     ) {
-        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData);
+        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer);
         $this->_orderTotalFactory = $orderTotalFactory;
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
index f97e3be1dcb6dcb9ea6383efec081517751325b5..7f058b7c05053646af0272e5b4f206105b8b45aa 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
@@ -1548,7 +1548,7 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
         $partialAmount = 12.00;
 
         $this->orderMock->expects(static::exactly(2))
-            ->method('getTotalDue')
+            ->method('getBaseTotalDue')
             ->willReturn($amount);
 
         static::assertFalse($this->payment->isCaptureFinal($partialAmount));
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
index ed44331f577d06ebdbe4df00401f85f34c59284d..bd519e76585ba452bb066ccac2cfbd27c5d58d7f 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
@@ -5,24 +5,28 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Total\Config;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class BaseTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\Sales\Model\Order\Total\Config\Base */
-    protected $object;
+    private $object;
+
+    /** @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $serializer;
 
     /** @var \Magento\Framework\App\Cache\Type\Config|\PHPUnit_Framework_MockObject_MockObject */
-    protected $configCacheType;
+    private $configCacheType;
 
     /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $logger;
+    private $logger;
 
     /** @var \Magento\Sales\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
-    protected $salesConfig;
+    private $salesConfig;
 
     /** @var \Magento\Sales\Model\Order\TotalFactory|\PHPUnit_Framework_MockObject_MockObject */
-    protected $orderTotalFactory;
+    private $orderTotalFactory;
 
     protected function setUp()
     {
@@ -30,6 +34,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
         $this->logger = $this->getMock(\Psr\Log\LoggerInterface::class);
         $this->salesConfig = $this->getMock(\Magento\Sales\Model\Config::class, [], [], '', false);
         $this->orderTotalFactory = $this->getMock(\Magento\Sales\Model\Order\TotalFactory::class, [], [], '', false);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
 
         $objectManager = new ObjectManager($this);
         $this->object = $objectManager->getObject(
@@ -39,6 +44,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
                 'logger' => $this->logger,
                 'salesConfig' => $this->salesConfig,
                 'orderTotalFactory' => $this->orderTotalFactory,
+                'serializer' => $this->serializer,
             ]
         );
     }
@@ -59,8 +65,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class)
             ->will($this->returnValue($total));
 
+        $sortedCodes = ['other_code', 'some_code'];
+        $serializedCodes = '["other_code", "some_code"]';
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($sortedCodes)
+            ->willReturn($serializedCodes);
         $this->configCacheType->expects($this->once())->method('save')
-            ->with('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}', 'sorted_collectors');
+            ->with($serializedCodes, 'sorted_collectors');
 
         $this->assertSame(
             ['other_code' => $total, 'some_code' => $total],
@@ -106,8 +118,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class)
             ->will($this->returnValue($total));
 
+        $sortedCodes = ['other_code', 'some_code'];
+        $serializedCodes = '["other_code", "some_code"]';
         $this->configCacheType->expects($this->once())->method('load')->with('sorted_collectors')
-            ->will($this->returnValue('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}'));
+            ->will($this->returnValue($serializedCodes));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedCodes)
+            ->willReturn($sortedCodes);
         $this->configCacheType->expects($this->never())->method('save');
 
         $this->assertSame(
diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json
index 09d1a9d6b7dd41ea95a09b26c0f72276327fe245..6b5638455a1c5986fb487f7f9c948d9ddf19aad3 100644
--- a/app/code/Magento/Sales/composer.json
+++ b/app/code/Magento/Sales/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sales",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
index b2e779e330fe0582f855f17ee57e6f648f61a001..6acb23ab0910ea3e8dc1e8bd5e87c28900e19da5 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
@@ -16,7 +16,7 @@
 
         <referenceBlock name="page.title">
             <action method="setTitleId">
-                <argument translate="true" name="id" xsi:type="string">order-header</argument>
+                <argument translate="false" name="id" xsi:type="string">order-header</argument>
             </action>
         </referenceBlock>
         <referenceContainer name="after.body.start">
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
index 59bb31a94fa0cadadf177f695271c1efeaa69aa6..a8ccf82c5fe06030055381d9c13228661308e04e 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml
@@ -66,7 +66,13 @@
                         <?php endif; ?>
 
                         <?php if ($block->canDisplayPrice()): ?>
-                            <td class="col-price"><?php /* @noEscape */ echo $block->getItemPrice($_item) ?></td>
+                            <td class="col-price">
+                                <?php if ($block->getDataId() == 'cart'): ?>
+                                    <?php /* @noEscape */ echo $block->getItemPrice($_item->getProduct()) ?>
+                                <?php else: ?>
+                                    <?php /* @noEscape */ echo $block->getItemPrice($_item) ?>
+                                <?php endif; ?>
+                            </td>
                         <?php endif; ?>
 
                         <?php if ($block->canRemoveItems()): ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
index 775c7214c2f104771c79d5fd299229187595b167..20cfcdeadf22a0f18d81b262134058640c04877f 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml
@@ -38,10 +38,10 @@ $orderStoreDate = $block->formatDate(
             <div class="admin__page-section-item-title">
                 <span class="title">
                     <?php if ($block->getNoUseOrderLink()): ?>
-                        <?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php /* @escapeNotVerified */ echo $_email ?></span>)
+                        <?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php echo $block->escapeHtml($_email) ?></span>)
                     <?php else: ?>
                         <a href="<?php /* @escapeNotVerified */ echo $block->getViewUrl($_order->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?></a>
-                        <span>(<?php /* @escapeNotVerified */ echo $_email ?>)</span>
+                        <span>(<?php echo $block->escapeHtml($_email) ?>)</span>
                     <?php endif; ?>
                 </span>
             </div>
@@ -49,7 +49,7 @@ $orderStoreDate = $block->formatDate(
                 <table class="admin__table-secondary order-information-table">
                 <tr>
                     <th><?php /* @escapeNotVerified */ echo __('Order Date') ?></th>
-                    <td><?php /* @escapeNotVerified */ echo $orderAdminDate ?></td>
+                    <td><?php echo $block->escapeHtml($orderAdminDate) ?></td>
                 </tr>
                 <?php if ($orderAdminDate != $orderStoreDate):?>
                     <tr>
@@ -57,12 +57,12 @@ $orderStoreDate = $block->formatDate(
                                 'Order Date (%1)',
                                 $block->getTimezoneForStore($_order->getStore())
                             ) ?></th>
-                        <td><?php /* @escapeNotVerified */ echo $orderStoreDate ?></td>
+                        <td><?php echo $block->escapeHtml($orderStoreDate) ?></td>
                     </tr>
                 <?php endif;?>
                 <tr>
                     <th><?php /* @escapeNotVerified */ echo __('Order Status') ?></th>
-                    <td><span id="order_status"><?php /* @escapeNotVerified */ echo $_order->getStatusLabel() ?></span></td>
+                    <td><span id="order_status"><?php echo $block->escapeHtml($_order->getStatusLabel()) ?></span></td>
                 </tr>
                 <?php echo $block->getChildHtml(); ?>
                 <?php if ($block->isSingleStoreMode() == false):?>
@@ -136,13 +136,13 @@ $orderStoreDate = $block->formatDate(
                     <?php if ($_groupName = $block->getCustomerGroupName()) : ?>
                         <tr>
                             <th><?php /* @escapeNotVerified */ echo __('Customer Group') ?></th>
-                            <td><?php /* @escapeNotVerified */ echo $_groupName ?></td>
+                            <td><?php echo $block->escapeHtml($_groupName) ?></td>
                         </tr>
                     <?php endif; ?>
                     <?php foreach ($block->getCustomerAccountData() as $data):?>
                         <tr>
-                            <th><?php /* @escapeNotVerified */ echo $data['label'] ?></th>
-                            <td><?php /* @escapeNotVerified */ echo $data['value'] ?></td>
+                            <th><?php echo $block->escapeHtml($data['label']) ?></th>
+                            <td><?php echo $block->escapeHtml($data['value']) ?></td>
                         </tr>
                     <?php endforeach;?>
                 </table>
diff --git a/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php
index 7752d7131031cf0daa63f4c8b8bf49609e3090ed..3680bbb3a1eaefa3ee822eefd99b7b21b320a3f8 100644
--- a/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php
+++ b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php
@@ -6,7 +6,6 @@
 namespace Magento\SalesInventory\Model\Order;
 
 use Magento\Sales\Api\Data\CreditmemoInterface;
-use Magento\Sales\Api\Data\CreditmemoItemInterface;
 use Magento\Sales\Api\Data\OrderInterface;
 
 /**
@@ -29,52 +28,35 @@ class ReturnProcessor
      */
     private $priceIndexer;
 
-    /**
-     * @var \Magento\Sales\Api\CreditmemoRepositoryInterface
-     */
-    private $creditmemoRepository;
-
     /**
      * @var \Magento\Store\Model\StoreManagerInterface
      */
     private $storeManager;
 
-    /**
-     * @var \Magento\Sales\Api\OrderRepositoryInterface
-     */
-    private $orderRepository;
-
     /**
      * @var \Magento\Sales\Api\OrderItemRepositoryInterface
      */
     private $orderItemRepository;
 
     /**
-     * ReturnToStockPlugin constructor.
-     * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
+     * ReturnProcessor constructor.
      * @param \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement
      * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer
      * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer
-     * @param \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
      * @param \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository
      */
     public function __construct(
         \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement,
         \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer,
         \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer,
-        \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
         \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository
     ) {
         $this->stockManagement = $stockManagement;
         $this->stockIndexerProcessor = $stockIndexer;
         $this->priceIndexer = $priceIndexer;
-        $this->creditmemoRepository = $creditmemoRepository;
         $this->storeManager = $storeManager;
-        $this->orderRepository = $orderRepository;
         $this->orderItemRepository = $orderItemRepository;
     }
 
@@ -82,22 +64,22 @@ class ReturnProcessor
      * @param CreditmemoInterface $creditmemo
      * @param OrderInterface $order
      * @param array $returnToStockItems
+     * @param bool $isAutoReturn
      * @return void
      */
     public function execute(
         CreditmemoInterface $creditmemo,
         OrderInterface $order,
-        array $returnToStockItems = []
+        array $returnToStockItems = [],
+        $isAutoReturn = false
     ) {
         $itemsToUpdate = [];
         foreach ($creditmemo->getItems() as $item) {
-            $qty = $item->getQty();
             $productId = $item->getProductId();
             $orderItem = $this->orderItemRepository->get($item->getOrderItemId());
             $parentItemId = $orderItem->getParentItemId();
-            if ($this->canReturnItem($item, $qty, $parentItemId, $returnToStockItems)) {
-                $parentItem = $parentItemId ? $this->getItemByOrderId($creditmemo, $parentItemId) : false;
-                $qty = $parentItem ? $parentItem->getQty() * $qty : $qty;
+            $qty = $item->getQty();
+            if ($isAutoReturn || $this->canReturnItem($item, $qty, $parentItemId, $returnToStockItems)) {
                 if (isset($itemsToUpdate[$productId])) {
                     $itemsToUpdate[$productId] += $qty;
                 } else {
@@ -122,21 +104,6 @@ class ReturnProcessor
         }
     }
 
-    /**
-     * @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo
-     * @param int $parentItemId
-     * @return bool|CreditmemoItemInterface
-     */
-    private function getItemByOrderId(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo, $parentItemId)
-    {
-        foreach ($creditmemo->getItems() as $item) {
-            if ($item->getOrderItemId() == $parentItemId) {
-                return $item;
-            }
-        }
-        return false;
-    }
-
     /**
      * @param \Magento\Sales\Api\Data\CreditmemoItemInterface $item
      * @param int $qty
diff --git a/app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php b/app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php
similarity index 57%
rename from app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php
rename to app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php
index 9702bfc7cfe425b2c8987c1aec4e86430e1d62ac..acdebcf976a2eead77eb6074611968a9831cd524 100644
--- a/app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php
+++ b/app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php
@@ -4,54 +4,74 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\CatalogInventory\Observer;
+namespace Magento\SalesInventory\Observer;
 
 use Magento\CatalogInventory\Api\StockConfigurationInterface;
 use Magento\CatalogInventory\Api\StockManagementInterface;
 use Magento\Framework\Event\Observer as EventObserver;
 use Magento\Framework\Event\ObserverInterface;
+use Magento\Sales\Model\OrderRepository;
+use Magento\SalesInventory\Model\Order\ReturnProcessor;
 
 /**
  * Catalog inventory module observer
+ * @deprecated
  */
 class RefundOrderInventoryObserver implements ObserverInterface
 {
     /**
      * @var StockConfigurationInterface
      */
-    protected $stockConfiguration;
+    private $stockConfiguration;
 
     /**
      * @var StockManagementInterface
      */
-    protected $stockManagement;
+    private $stockManagement;
 
     /**
      * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
      */
-    protected $stockIndexerProcessor;
+    private $stockIndexerProcessor;
 
     /**
      * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
      */
-    protected $priceIndexer;
+    private $priceIndexer;
 
     /**
+     * @var \Magento\SalesInventory\Model\Order\ReturnProcessor
+     */
+    private $returnProcessor;
+
+    /**
+     * @var \Magento\Sales\Api\OrderRepositoryInterface
+     */
+    private $orderRepository;
+
+    /**
+     * RefundOrderInventoryObserver constructor.
      * @param StockConfigurationInterface $stockConfiguration
      * @param StockManagementInterface $stockManagement
      * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor
      * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer
+     * @param ReturnProcessor $returnProcessor
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
      */
     public function __construct(
         StockConfigurationInterface $stockConfiguration,
         StockManagementInterface $stockManagement,
         \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor,
-        \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer
+        \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer,
+        \Magento\SalesInventory\Model\Order\ReturnProcessor $returnProcessor,
+        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
     ) {
         $this->stockConfiguration = $stockConfiguration;
         $this->stockManagement = $stockManagement;
         $this->stockIndexerProcessor = $stockIndexerProcessor;
         $this->priceIndexer = $priceIndexer;
+        $this->returnProcessor = $returnProcessor;
+        $this->orderRepository = $orderRepository;
     }
 
     /**
@@ -64,31 +84,18 @@ class RefundOrderInventoryObserver implements ObserverInterface
     {
         /* @var $creditmemo \Magento\Sales\Model\Order\Creditmemo */
         $creditmemo = $observer->getEvent()->getCreditmemo();
-        $itemsToUpdate = [];
-        foreach ($creditmemo->getAllItems() as $item) {
-            $qty = $item->getQty();
-            if (($item->getBackToStock() && $qty) || $this->stockConfiguration->isAutoReturnEnabled()) {
-                $productId = $item->getProductId();
-                $parentItemId = $item->getOrderItem()->getParentItemId();
-                /* @var $parentItem \Magento\Sales\Model\Order\Creditmemo\Item */
-                $parentItem = $parentItemId ? $creditmemo->getItemByOrderId($parentItemId) : false;
-                $qty = $parentItem ? $parentItem->getQty() * $qty : $qty;
-                if (isset($itemsToUpdate[$productId])) {
-                    $itemsToUpdate[$productId] += $qty;
-                } else {
-                    $itemsToUpdate[$productId] = $qty;
-                }
+        $order = $this->orderRepository->get($creditmemo->getOrderId());
+        $returnToStockItems = [];
+        foreach ($creditmemo->getItems() as $item) {
+            if ($item->getBackToStock()) {
+                $returnToStockItems[] = $item->getOrderItemId();
             }
         }
-        if (!empty($itemsToUpdate)) {
-            $this->stockManagement->revertProductsSale(
-                $itemsToUpdate,
-                $creditmemo->getStore()->getWebsiteId()
-            );
-
-            $updatedItemIds = array_keys($itemsToUpdate);
-            $this->stockIndexerProcessor->reindexList($updatedItemIds);
-            $this->priceIndexer->reindexList($updatedItemIds);
-        }
+        $this->returnProcessor->execute(
+            $creditmemo,
+            $order,
+            $returnToStockItems,
+            $this->stockConfiguration->isAutoReturnEnabled()
+        );
     }
 }
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php
index 523759d54645a1e2db471db948fa116cf59cd32e..efa3bff32c0fa2b40c3a9a57ec04cb1ec5c9f257 100644
--- a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php
@@ -5,9 +5,7 @@
  */
 namespace Magento\SalesInventory\Test\Unit\Model\Order;
 
-use Magento\CatalogInventory\Api\StockConfigurationInterface;
 use Magento\CatalogInventory\Api\StockManagementInterface;
-use Magento\Sales\Api\CreditmemoRepositoryInterface;
 use Magento\Sales\Api\Data\CreditmemoInterface;
 use Magento\Sales\Api\Data\CreditmemoItemInterface;
 use Magento\Sales\Api\Data\OrderInterface;
@@ -49,21 +47,11 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
      */
     private $priceIndexerMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoRepositoryInterface
-     */
-    private $creditmemoRepositoryMock;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|StoreManagerInterface
      */
     private $storeManagerMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|OrderRepositoryInterface
-     */
-    private $orderRepositoryMock;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|OrderItemRepositoryInterface
      */
@@ -95,13 +83,10 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
         $this->priceIndexerMock = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Price\Processor::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->creditmemoRepositoryMock = $this->getMockBuilder(CreditmemoRepositoryInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
         $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
+        $this->orderItemRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->orderItemRepositoryMock = $this->getMockBuilder(OrderItemRepositoryInterface::class)
@@ -127,9 +112,7 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
             $this->stockManagementMock,
             $this->stockIndexerProcessorMock,
             $this->priceIndexerMock,
-            $this->creditmemoRepositoryMock,
             $this->storeManagerMock,
-            $this->orderRepositoryMock,
             $this->orderItemRepositoryMock
         );
     }
@@ -139,6 +122,7 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
         $orderItemId = 99;
         $productId = 50;
         $returnToStockItems = [$orderItemId];
+        $parentItemId = 52;
         $qty = 1;
         $storeId = 0;
         $webSiteId = 10;
@@ -147,10 +131,6 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
             ->method('getItems')
             ->willReturn([$this->creditmemoItemMock]);
 
-        $this->creditmemoItemMock->expects($this->once())
-            ->method('getQty')
-            ->willReturn($qty);
-
         $this->creditmemoItemMock->expects($this->exactly(2))
             ->method('getOrderItemId')
             ->willReturn($orderItemId);
@@ -190,6 +170,14 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
             ->method('reindexList')
             ->with([$productId]);
 
+        $this->orderItemMock->expects($this->once())
+            ->method('getParentItemId')
+            ->willReturn($parentItemId);
+
+        $this->creditmemoItemMock->expects($this->once())
+            ->method('getQty')
+            ->willReturn($qty);
+
         $this->returnProcessor->execute($this->creditmemoMock, $this->orderMock, $returnToStockItems);
     }
 }
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php b/app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php
similarity index 65%
rename from app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php
rename to app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php
index e440ed3380498a0c8d0deb9fb4edbd68a5d2c295..4e553493d07f63ed9f7d0a2d0d0ec7129d7580e7 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php
+++ b/app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php
@@ -3,9 +3,12 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\CatalogInventory\Test\Unit\Observer;
+namespace Magento\SalesInventory\Test\Unit\Observer;
 
-use Magento\CatalogInventory\Observer\RefundOrderInventoryObserver;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\OrderRepository;
+use Magento\SalesInventory\Model\Order\ReturnProcessor;
+use Magento\SalesInventory\Observer\RefundOrderInventoryObserver;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -47,6 +50,26 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase
      */
     protected $eventObserver;
 
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var OrderRepository|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderRepositoryMock;
+
+    /**
+     * @var ReturnProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $returnProcessorMock;
+
+    /**
+     * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $orderMock;
+
     protected function setUp()
     {
         $this->stockIndexerProcessor = $this->getMock(
@@ -93,8 +116,22 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase
             ->method('getEvent')
             ->will($this->returnValue($this->event));
 
-        $this->observer = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
-            \Magento\CatalogInventory\Observer\RefundOrderInventoryObserver::class,
+        $this->orderRepositoryMock = $this->getMockBuilder(OrderRepository::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->returnProcessorMock = $this->getMockBuilder(ReturnProcessor::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->orderMock = $this->getMockBuilder(OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->observer = $this->objectManagerHelper->getObject(
+            \Magento\SalesInventory\Observer\RefundOrderInventoryObserver::class,
             [
                 'stockConfiguration' => $this->stockConfiguration,
                 'stockManagement' => $this->stockManagement,
@@ -102,83 +139,67 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase
                 'priceIndexer' => $this->priceIndexer,
             ]
         );
+
+        $this->objectManagerHelper->setBackwardCompatibleProperty(
+            $this->observer,
+            'orderRepository',
+            $this->orderRepositoryMock
+        );
+        $this->objectManagerHelper->setBackwardCompatibleProperty(
+            $this->observer,
+            'returnProcessor',
+            $this->returnProcessorMock
+        );
     }
 
     public function testRefundOrderInventory()
     {
-        $websiteId = 0;
         $ids = ['1', '14'];
         $items = [];
         $isAutoReturnEnabled = true;
 
-        $store = $this->getMock(
-            \Magento\Store\Model\Store::class,
-            ['getWebsiteId'],
-            [],
-            '',
-            false
-        );
-        $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId));
+        $creditMemo = $this->getMock(\Magento\Sales\Model\Order\Creditmemo::class, [], [], '', false);
 
-        $itemsToUpdate = [];
         foreach ($ids as $id) {
             $item = $this->getCreditMemoItem($id);
             $items[] = $item;
-            $itemsToUpdate[$item->getProductId()] = $item->getQty();
         }
-        $creditMemo = $this->getMock(\Magento\Sales\Model\Order\Creditmemo::class, [], [], '', false);
+
         $creditMemo->expects($this->once())
-            ->method('getAllItems')
+            ->method('getItems')
             ->will($this->returnValue($items));
-        $creditMemo->expects($this->once())->method('getStore')->will($this->returnValue($store));
 
         $this->stockConfiguration->expects($this->any())
             ->method('isAutoReturnEnabled')
             ->will($this->returnValue($isAutoReturnEnabled));
 
-        $this->stockManagement->expects($this->once())
-            ->method('revertProductsSale')
-            ->with($itemsToUpdate, $websiteId);
-
-        $this->stockIndexerProcessor->expects($this->once())
-            ->method('reindexList')
-            ->with($ids);
-
-        $this->priceIndexer->expects($this->once())
-            ->method('reindexList')
-            ->with($ids);
-
         $this->event->expects($this->once())
             ->method('getCreditmemo')
             ->will($this->returnValue($creditMemo));
 
+        $this->orderRepositoryMock->expects($this->once())
+            ->method('get')
+            ->willReturn($this->orderMock);
+
+        $this->returnProcessorMock->expects($this->once())
+            ->method('execute')
+            ->with($creditMemo, $this->orderMock, $ids, $isAutoReturnEnabled);
+
         $this->observer->execute($this->eventObserver);
     }
 
     private function getCreditMemoItem($productId)
     {
-        $parentItemId = false;
         $backToStock = true;
-        $qty = 1;
         $item = $this->getMock(
             \Magento\Sales\Model\Order\Creditmemo\Item::class,
-            ['getProductId', 'getOrderItem', 'getBackToStock', 'getQty', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $orderItem = $this->getMock(
-            \Magento\Sales\Model\Order\Item::class,
-            ['getParentItemId', '__wakeup'],
+            ['getOrderItemId', 'getBackToStock', 'getQty', '__wakeup'],
             [],
             '',
             false
         );
-        $orderItem->expects($this->any())->method('getParentItemId')->willReturn($parentItemId);
-        $item->expects($this->any())->method('getOrderItem')->willReturn($orderItem);
-        $item->expects($this->any())->method('getProductId')->will($this->returnValue($productId));
         $item->expects($this->any())->method('getBackToStock')->willReturn($backToStock);
-        $item->expects($this->any())->method('getQty')->willReturn($qty);
+        $item->expects($this->any())->method('getOrderItemId')->willReturn($productId);
         return $item;
     }
 }
diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json
index ff72ce7f0022690682b356235c506512e65497b9..d7f9075cdd310141bab6b25869f33d6229f513dc 100644
--- a/app/code/Magento/SalesInventory/composer.json
+++ b/app/code/Magento/SalesInventory/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sales-inventory",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog-inventory": "100.2.*",
         "magento/module-sales": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/SalesInventory/etc/events.xml b/app/code/Magento/SalesInventory/etc/events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a71ed7f8a28a16a4ded03e507876757ec94f436c
--- /dev/null
+++ b/app/code/Magento/SalesInventory/etc/events.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
+    <event name="sales_order_creditmemo_save_after">
+        <observer name="inventory" instance="Magento\SalesInventory\Observer\RefundOrderInventoryObserver"/>
+    </event>
+</config>
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
index 57477b5ce0623f57bfc048839cc8bdaee8d40593..efa45512acc8320cd878c97b92c5912c7713f882 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
@@ -26,8 +26,13 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                     ['request' => $this->getRequest()]
                 );
                 $data = $this->getRequest()->getPostValue();
+
+                $filterValues = ['from_date' => $this->_dateFilter];
+                if ($this->getRequest()->getParam('to_date')) {
+                    $filterValues['to_date'] = $this->_dateFilter;
+                }
                 $inputFilter = new \Zend_Filter_Input(
-                    ['from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter],
+                    $filterValues,
                     [],
                     $data
                 );
diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json
index fabef581762a84cac8844bf7e7099b0bb8b6b6c0..8479acad47246a1f91bc6b098d88cfa6f6027f76 100644
--- a/app/code/Magento/SalesRule/composer.json
+++ b/app/code/Magento/SalesRule/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sales-rule",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-rule": "100.2.*",
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
index ed5744feb6ce84df31a5a59b42f520bb97316792..d1e294c9a8f0c1dc4edf82e52cbe509b09da8fbe 100644
--- a/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
@@ -17,16 +17,20 @@ define(
         'mage/storage',
         'Magento_Checkout/js/action/get-payment-information',
         'Magento_Checkout/js/model/totals',
-        'mage/translate'
+        'mage/translate',
+        'Magento_Checkout/js/model/full-screen-loader'
     ],
-    function ($, quote, urlManager, errorProcessor, messageContainer, storage, getPaymentInformationAction, totals, $t) {
+    function ($, quote, urlManager, errorProcessor, messageContainer, storage, getPaymentInformationAction, totals, $t,
+              fullScreenLoader) {
         'use strict';
 
-        return function (isApplied, isLoading) {
+        return function (isApplied) {
             var quoteId = quote.getQuoteId(),
                 url = urlManager.getCancelCouponUrl(quoteId),
                 message = $t('Your coupon was successfully removed.');
+
             messageContainer.clear();
+            fullScreenLoader.startLoader();
 
             return storage.delete(
                 url,
@@ -39,6 +43,7 @@ define(
                     $.when(deferred).done(function () {
                         isApplied(false);
                         totals.isLoading(false);
+                        fullScreenLoader.stopLoader();
                     });
                     messageContainer.addSuccessMessage({
                         'message': message
@@ -47,12 +52,9 @@ define(
             ).fail(
                 function (response) {
                     totals.isLoading(false);
+                    fullScreenLoader.stopLoader();
                     errorProcessor.process(response, messageContainer);
                 }
-            ).always(
-                function () {
-                    isLoading(false);
-                }
             );
         };
     }
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
index 606fe4013ea762c5460c49202907463d7c7952f2..a2b7ff19f2139ffa7e23b37eda039d5b9ccc32a8 100644
--- a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
@@ -18,25 +18,22 @@ define(
         'mage/storage',
         'mage/translate',
         'Magento_Checkout/js/action/get-payment-information',
-        'Magento_Checkout/js/model/totals'
+        'Magento_Checkout/js/model/totals',
+        'Magento_Checkout/js/model/full-screen-loader'
     ],
     function (
-        ko,
-        $,
-        quote,
-        urlManager,
-        errorProcessor,
-        messageContainer,
-        storage,
-        $t,
-        getPaymentInformationAction,
-        totals
+        ko, $, quote, urlManager, errorProcessor, messageContainer, storage, $t, getPaymentInformationAction, totals,
+        fullScreenLoader
     ) {
         'use strict';
-        return function (couponCode, isApplied, isLoading) {
-            var quoteId = quote.getQuoteId();
-            var url = urlManager.getApplyCouponUrl(couponCode, quoteId);
-            var message = $t('Your coupon was successfully applied.');
+
+        return function (couponCode, isApplied) {
+            var quoteId = quote.getQuoteId(),
+                url = urlManager.getApplyCouponUrl(couponCode, quoteId),
+                message = $t('Your coupon was successfully applied.');
+
+            fullScreenLoader.startLoader();
+
             return storage.put(
                 url,
                 {},
@@ -45,19 +42,22 @@ define(
                 function (response) {
                     if (response) {
                         var deferred = $.Deferred();
-                        isLoading(false);
+
                         isApplied(true);
                         totals.isLoading(true);
                         getPaymentInformationAction(deferred);
                         $.when(deferred).done(function () {
+                            fullScreenLoader.stopLoader();
                             totals.isLoading(false);
                         });
-                        messageContainer.addSuccessMessage({'message': message});
+                        messageContainer.addSuccessMessage({
+                            'message': message
+                        });
                     }
                 }
             ).fail(
                 function (response) {
-                    isLoading(false);
+                    fullScreenLoader.stopLoader();
                     totals.isLoading(false);
                     errorProcessor.process(response, messageContainer);
                 }
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
index 8e8c0798ff3b59ce0ffa0a803242abe1d02fcee7..6dc973a7a1e4298469251f71f6e26f09a95cc5d0 100644
--- a/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
@@ -13,49 +13,53 @@ define(
     ],
     function ($, ko, Component, quote, setCouponCodeAction, cancelCouponAction) {
         'use strict';
-        var totals = quote.getTotals();
-        var couponCode = ko.observable(null);
+
+        var totals = quote.getTotals(),
+            couponCode = ko.observable(null),
+            isApplied = ko.observable(couponCode() != null);
+
         if (totals()) {
             couponCode(totals()['coupon_code']);
         }
-        var isApplied = ko.observable(couponCode() != null);
-        var isLoading = ko.observable(false);
+
         return Component.extend({
             defaults: {
                 template: 'Magento_SalesRule/payment/discount'
             },
             couponCode: couponCode,
+
             /**
              * Applied flag
              */
             isApplied: isApplied,
-            isLoading: isLoading,
+
             /**
              * Coupon code application procedure
              */
             apply: function() {
                 if (this.validate()) {
-                    isLoading(true);
-                    setCouponCodeAction(couponCode(), isApplied, isLoading);
+                    setCouponCodeAction(couponCode(), isApplied);
                 }
             },
+
             /**
              * Cancel using coupon
              */
             cancel: function() {
                 if (this.validate()) {
-                    isLoading(true);
                     couponCode('');
-                    cancelCouponAction(isApplied, isLoading);
+                    cancelCouponAction(isApplied);
                 }
             },
+
             /**
              * Coupon form validation
              *
-             * @returns {boolean}
+             * @returns {Boolean}
              */
-            validate: function() {
+            validate: function () {
                 var form = '#discount-form';
+
                 return $(form).validation() && $(form).validation('isValid');
             }
         });
diff --git a/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html
index d6bc4c764d5714382d017adce856deaf84c8b3ff..4ba38906fe9c1e98c8d248574585cc01ef815914 100644
--- a/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html
+++ b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html
@@ -15,7 +15,7 @@
         <!-- ko foreach: getRegion('messages') -->
         <!-- ko template: getTemplate() --><!-- /ko -->
         <!--/ko-->
-        <form class="form form-discount" id="discount-form" data-bind="blockLoader: isLoading">
+        <form class="form form-discount" id="discount-form">
             <div class="payment-option-inner">
                 <div class="field">
                     <label class="label" for="discount-code">
diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json
index eeda2be05e68f86cb5552e6f48ca502dd96cb9be..5b9efe61f72724e28d23c1af0dc197fede8e117f 100644
--- a/app/code/Magento/SalesSequence/composer.json
+++ b/app/code/Magento/SalesSequence/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sales-sequence",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/SampleData/composer.json b/app/code/Magento/SampleData/composer.json
index 936bbf0d6be3a7399babc2e835282e7c71bea4c2..4c98a5abd3a16ab72b5ea04e0606955986924ebd 100644
--- a/app/code/Magento/SampleData/composer.json
+++ b/app/code/Magento/SampleData/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sample-data",
     "description": "Sample Data fixtures",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "suggest": {
diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json
index cc95e6784526f33bb65246b599a4147e8a1afa1d..8f809fb3b8af3533c4715aea1e13854650e0cbac 100644
--- a/app/code/Magento/Search/composer.json
+++ b/app/code/Magento/Search/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-search",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-catalog-search": "100.2.*",
diff --git a/app/code/Magento/Security/composer.json b/app/code/Magento/Security/composer.json
index f64c0f0b29d282b0feaefb24ebb3963086f0e083..4048b63bf607030d27ae7fa84dbec6a0da838957 100644
--- a/app/code/Magento/Security/composer.json
+++ b/app/code/Magento/Security/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-security",
     "description": "Security management module",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/framework": "100.2.*"
diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json
index de9dbf7a84576022d8f6b1a38324f902565870df..1095dedc0ba6606107660d65373096d8c82b204c 100644
--- a/app/code/Magento/SendFriend/composer.json
+++ b/app/code/Magento/SendFriend/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-send-friend",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-customer": "100.2.*",
diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json
index dc9ea808c0f7b19e396a7c73f2b416221729a34b..03f51bbd95e0ff5f65b88e565cfbe77102a44760 100644
--- a/app/code/Magento/Shipping/composer.json
+++ b/app/code/Magento/Shipping/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-shipping",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-sales": "100.2.*",
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index be553a4da194f4dbf64fb4237fd92bb27e4e17ff..9f556178fc2cccfd070c272a89164e438f1d33e8 100644
--- a/app/code/Magento/Sitemap/composer.json
+++ b/app/code/Magento/Sitemap/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-sitemap",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index b9f76f6c2c3137aa21d8f4a6cf97880fdc3e72f6..d5b8a2b4b980b58648c04cfed916b5bd390db048 100644
--- a/app/code/Magento/Store/composer.json
+++ b/app/code/Magento/Store/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-store",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-directory": "100.2.*",
         "magento/module-ui": "100.2.*",
diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json
index dc2d1cbee003de647cf72f7312ad7f7fcc222e3b..47e347426c83fdb1b969c5a03bd46d1776e89950 100644
--- a/app/code/Magento/Swagger/composer.json
+++ b/app/code/Magento/Swagger/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-swagger",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php
index 68a18ef8be6a1b2d51403acac0ebaca1ecc83996..a973a822c4101671faa0fe57925a0e9b0c5b2f2a 100644
--- a/app/code/Magento/Swatches/Helper/Data.php
+++ b/app/code/Magento/Swatches/Helper/Data.php
@@ -63,6 +63,13 @@ class Data
      */
     protected $imageHelper;
 
+    /**
+     * Product metadata pool
+     *
+     * @var \Magento\Framework\EntityManager\MetadataPool
+     */
+    private $metadataPool;
+
     /**
      * Data key which should populated to Attribute entity from "additional_data" field
      *
@@ -196,7 +203,13 @@ class Data
         }
 
         $productCollection = $this->productCollectionFactory->create();
-        $this->addFilterByParent($productCollection, $parentProduct->getId());
+
+        $productLinkedFiled = $this->getMetadataPool()
+            ->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
+            ->getLinkField();
+        $parentId = $parentProduct->getData($productLinkedFiled);
+
+        $this->addFilterByParent($productCollection, $parentId);
 
         $configurableAttributes = $this->getAttributesFromConfigurable($parentProduct);
         $allAttributesArray = [];
@@ -491,4 +504,19 @@ class Data
         }
         return $attribute->getData(Swatch::SWATCH_INPUT_TYPE_KEY) == Swatch::SWATCH_INPUT_TYPE_TEXT;
     }
+
+    /**
+     * Get product metadata pool.
+     *
+     * @return \Magento\Framework\EntityManager\MetadataPool
+     * @deprecared
+     */
+    protected function getMetadataPool()
+    {
+        if (!$this->metadataPool) {
+            $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\EntityManager\MetadataPool::class);
+        }
+        return $this->metadataPool;
+    }
 }
diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
index 6cf79dae309a583aca3ced31bd1411eb9d53b27b..e5f2f887836eff5ad73ca95602d4d7aec411150e 100644
--- a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php
@@ -46,6 +46,9 @@ class DataTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Api\ProductRepositoryInterface */
     protected $productRepoMock;
 
+    /** @var   \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\EntityManager\MetadataPool*/
+    private $metaDataPoolMock;
+
     protected function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -108,7 +111,13 @@ class DataTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-
+        $this->metaDataPoolMock = $this->getMock(
+            \Magento\Framework\EntityManager\MetadataPool::class,
+            [],
+            [],
+            '',
+            false
+        );
         $this->swatchHelperObject = $this->objectManager->getObject(
             \Magento\Swatches\Helper\Data::class,
             [
@@ -120,6 +129,11 @@ class DataTest extends \PHPUnit_Framework_TestCase
                 'imageHelper' => $this->imageHelperMock,
             ]
         );
+        $this->objectManager->setBackwardCompatibleProperty(
+            $this->swatchHelperObject,
+            'metadataPool',
+            $this->metaDataPoolMock
+        );
     }
 
     public function dataForAdditionalData()
@@ -246,12 +260,16 @@ class DataTest extends \PHPUnit_Framework_TestCase
      */
     public function testLoadVariationByFallback($product)
     {
+        $metadataMock = $this->getMock(\Magento\Framework\EntityManager\EntityMetadataInterface::class);
+        $this->metaDataPoolMock->expects($this->once())->method('getMetadata')->willReturn($metadataMock);
+        $metadataMock->expects($this->once())->method('getLinkField')->willReturn('id');
+
         $this->getSwatchAttributes($product);
 
         $this->prepareVariationCollection();
 
         $this->productCollectionMock->method('getFirstItem')->willReturn($this->productMock);
-        $this->productMock->method('getId')->willReturn(95);
+        $this->productMock->method('getData')->with('id')->willReturn(95);
         $this->productModelFactoryMock->method('create')->willReturn($this->productMock);
         $this->productMock->method('load')->with(95)->will($this->returnSelf());
 
diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json
index f87fdb635cb73386b40fec6ac932eaee3f9cd398..b61ff41d8c955890aae0c22baedcdb8abd22e004 100644
--- a/app/code/Magento/Swatches/composer.json
+++ b/app/code/Magento/Swatches/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-swatches",
     "description": "Add Swatches to Products",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-configurable-product": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml
index 86046fdce4b6ee3d264d86f94f3a7dcfbf4b13b3..9c3274627b984cc093ecf5f39c54190ead2412fa 100644
--- a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml
+++ b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml
@@ -7,15 +7,17 @@
 <?php /** @var $block \Magento\Swatches\Block\Product\Renderer\Configurable */ ?>
 <div class="swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>"></div>
 <script>
-    require(["jquery", "jquery/ui", "Magento_Swatches/js/swatch-renderer"], function ($) {
-        $('.swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>').SwatchRenderer({
-            selectorProduct: '.product-item-details',
-            onlySwatches: true,
-            enableControlLabel: false,
-            numberToShow: <?php /* @escapeNotVerified */ echo $block->getNumberSwatchesPerProduct(); ?>,
-            jsonConfig: <?php /* @escapeNotVerified */ echo $block->getJsonConfig(); ?>,
-            jsonSwatchConfig: <?php /* @escapeNotVerified */ echo $block->getJsonSwatchConfig(); ?>,
-            mediaCallback: '<?php /* @escapeNotVerified */ echo $block->getMediaCallback() ?>'
-        });
+    require(
+        ["jquery", "jquery/ui", "Magento_Swatches/js/swatch-renderer", "Magento_Swatches/js/catalog-add-to-cart"],
+        function ($) {
+            $('.swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>').SwatchRenderer({
+                selectorProduct: '.product-item-details',
+                onlySwatches: true,
+                enableControlLabel: false,
+                numberToShow: <?php /* @escapeNotVerified */ echo $block->getNumberSwatchesPerProduct(); ?>,
+                jsonConfig: <?php /* @escapeNotVerified */ echo $block->getJsonConfig(); ?>,
+                jsonSwatchConfig: <?php /* @escapeNotVerified */ echo $block->getJsonSwatchConfig(); ?>,
+                mediaCallback: '<?php /* @escapeNotVerified */ echo $block->getMediaCallback() ?>'
+            });
     });
 </script>
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js
new file mode 100644
index 0000000000000000000000000000000000000000..7900ff67b09be952f13bcfd1bd88842327dd0db4
--- /dev/null
+++ b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require([
+    'jquery'
+], function ($) {
+    'use strict';
+
+    $('body').on('catalogCategoryAddToCartRedirect', function (event, data) {
+        $(data.form).find('[name*="super"]').each(function (index, item) {
+            var $item = $(item);
+
+            data.redirectParameters.push($item.attr('data-attr-name') + '=' + $item.val());
+        });
+    });
+});
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
index 54e207c335ffb5b6a007a7774df4e2c4a0760628..452c9b6f94d3c60e83bd35a5a932c6b5f8a9092f 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
@@ -264,6 +264,8 @@ define([
          */
         _init: function () {
             if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {
+                // store unsorted attributes
+                this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);
                 this._sortAttributes();
                 this._RenderControls();
                 $(this.element).trigger('swatch.initialized');
@@ -617,6 +619,7 @@ define([
                 $parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected');
                 $label.text($this.attr('option-label'));
                 $input.val($this.attr('option-id'));
+                $input.attr('data-attr-name', this._getAttributeCodeById(attributeId));
                 $this.addClass('selected');
                 $widget._toggleCheckedAttributes($this, $wrapper);
             }
@@ -633,6 +636,19 @@ define([
             $input.trigger('change');
         },
 
+        /**
+         * Get human readable attribute code (eg. size, color) by it ID from configuration
+         *
+         * @param {Number} attributeId
+         * @returns {*}
+         * @private
+         */
+        _getAttributeCodeById: function (attributeId) {
+            var attribute = this.options.jsonConfig.mappedAttributes[attributeId];
+
+            return attribute ? attribute.code : attributeId;
+        },
+
         /**
          * Toggle accessibility attributes
          *
@@ -1104,7 +1120,7 @@ define([
                 params = $.parseQuery(window.location.href.substr(hashIndex + 1));
 
                 selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) {
-                    var attribute = this.options.jsonConfig.attributes[attributeId];
+                    var attribute = this.options.jsonConfig.mappedAttributes[attributeId];
 
                     return attribute ? attribute.code : attributeId;
                 }.bind(this)));
diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json
index 9b658d0a42e61e0b556f1aa5aed6e12ed8cfdbe7..67c6d90c51e7f81de645451da6553bcdb750fddd 100644
--- a/app/code/Magento/SwatchesLayeredNavigation/composer.json
+++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-swatches-layered-navigation",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/magento-composer-installer": "*"
     },
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index 4553fdbb383323732b667df9be3e140aca011744..3dfacaaecd9635dec8229175de2876da6c957a77 100644
--- a/app/code/Magento/Tax/composer.json
+++ b/app/code/Magento/Tax/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-tax",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-config": "100.2.*",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index c3d09e4926e02d67a98c0e15c050d67997ae1ecd..9d9cac5dec59c94e8013bc5ab3275fee84c73b6b 100644
--- a/app/code/Magento/TaxImportExport/composer.json
+++ b/app/code/Magento/TaxImportExport/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-tax-import-export",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-tax": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-directory": "100.2.*",
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index 49382f9642fa5d2b88d7d2f4cea79c07d5306cb1..7158ac314076d38aae4766bbea1a917dc869b5dd 100644
--- a/app/code/Magento/Theme/composer.json
+++ b/app/code/Magento/Theme/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-theme",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-customer": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index 9ea00544d805094927499672f98fb72ad12ae97a..b9ed830c9053ea492d76a2402ec8f523fb03a46a 100644
--- a/app/code/Magento/Translation/composer.json
+++ b/app/code/Magento/Translation/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-translation",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/module-developer": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/Ui/README.md b/app/code/Magento/Ui/README.md
index 1337383ea3fb83bf3e2927589859587aad5a48f7..b7dd1a858e4a8161f836b3ea73d1483ae56ba2dd 100644
--- a/app/code/Magento/Ui/README.md
+++ b/app/code/Magento/Ui/README.md
@@ -1,7 +1,7 @@
 # Overview
 ## Purpose of module
 
-The Magento\Ui module introduces a set of common UI components, which could be easily used and configured via layout XML files.
+The Magento\Ui module introduces a set of common UI components, which could be used and configured via layout XML files.
 
 # Deployment
 ## System requirements
diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json
index 43c7b7fa3011fd7c6386fcde17eb45b6c5e02695..a3de6c6dfbdde7860dbb07503e0e6fe25e8b3dcf 100644
--- a/app/code/Magento/Ui/composer.json
+++ b/app/code/Magento/Ui/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-ui",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/framework": "100.2.*",
         "magento/module-eav": "100.2.*",
diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
index de10c065d123bf773f9fba66135b2308a2abe3e9..518f09fa73ba6c6771654c7c9fc3f3ce07be79be 100644
--- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
+++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js
@@ -52,13 +52,15 @@ define([
                 obj;
 
             if (this.recordData().length && !this.update) {
-                this.recordData.each(function (recordData) {
+                _.each(this.recordData(), function (recordData) {
                     obj = {};
                     obj[this.map[this.identificationProperty]] = recordData[this.identificationProperty];
                     insertData.push(obj);
                 }, this);
 
-                this.source.set(this.dataProvider, insertData);
+                if (insertData.length) {
+                    this.source.set(this.dataProvider, insertData);
+                }
             }
         },
 
@@ -178,7 +180,7 @@ define([
                 tmpObj = {};
 
             if (data.length !== this.relatedData.length) {
-                data.forEach(function (obj) {
+                _.each(data, function (obj) {
                     tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty];
 
                     if (!_.findWhere(this.relatedData, tmpObj)) {
@@ -193,7 +195,7 @@ define([
         /**
          * Processing insert data
          *
-         * @param {Array} data
+         * @param {Object} data
          */
         processingInsertData: function (data) {
             var changes,
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
index 16c102b8367f4b8762030057c4d249adb132693b..77d3a069ccef76bbcacad28459820b3359b025e7 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
@@ -51,7 +51,12 @@ define([
 
             observable() && $(el).datepicker(
                 'setDate',
-                moment(observable(), utils.normalizeDate(config.options.dateFormat)).toDate()
+                moment(
+                    observable(),
+                    utils.normalizeDate(
+                        options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '')
+                    )
+                ).toDate()
             );
 
             $(el).blur();
diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html
index f3319a05525f2f55bc4ba43ec5ce9bc1e4e2c300..d1ec1d26df6c56dff099b09aa0eb83232687573e 100644
--- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html
+++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html
@@ -43,6 +43,7 @@
                             </div>
 
                             <button class="action-delete"
+                                    data-index="delete_button"
                                     type="button"
                                     title="'Delete'"
                                     click="function(){
diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json
index ade4e738a68efe0499041830892bb6b61f5a3156..c20dd28ba88876a70c04ea49038b94f82d3d9b06 100644
--- a/app/code/Magento/Ups/composer.json
+++ b/app/code/Magento/Ups/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-ups",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-backend": "100.2.*",
         "magento/module-sales": "100.2.*",
diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json
index ac75ecdf61b8fd0531f2b14f76d2aec7d72581be..290ffc6731d89ce142e94c58616ca1a74c82c54b 100644
--- a/app/code/Magento/UrlRewrite/composer.json
+++ b/app/code/Magento/UrlRewrite/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-url-rewrite",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-catalog": "101.1.*",
         "magento/module-store": "100.2.*",
         "magento/framework": "100.2.*",
diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
index 7aa02ab019c46b9ad7094764118a9f5d07519293..d0f9678602707ff2950b8b051b8dd50f0b4c7df0 100644
--- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
@@ -9,7 +9,7 @@
 /** @var \Magento\UrlRewrite\Block\Catalog\Category\Tree $block */
 ?>
 <fieldset class="admin__fieldset" data-ui-id="category-selector">
-    <legend class="admin__legend"><span><?php /* @escapeNotVerified */ echo __('Select Category') ?></span></legend>
+    <legend class="admin__legend"><span><?php echo $block->escapeHtml(__('Select Category')) ?></span></legend>
     <div class="content content-category-tree">
         <input type="hidden" name="categories" id="product_categories" value="" />
         <?php if ($block->getRoot()): ?>
diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json
index 755c47ac1147612e1e55b589e72afa705b39b0ce..4632e32bc17f90549f7271cadc5e1ef7ba08869e 100644
--- a/app/code/Magento/User/composer.json
+++ b/app/code/Magento/User/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-user",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-authorization": "100.2.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index d12341659cb6d8ad1fc4acabe0b8052e346ca102..b2345a86bff4d6349035950373d1e7975076f513 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -426,9 +426,14 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
             if (!$service) {
                 $service = $r->getService();
             }
-            if ($r->getContainer() == 'FLAT RATE BOX' || $r->getContainer() == 'FLAT RATE ENVELOPE') {
+
+            if (
+                strpos($r->getContainer(), 'FLAT RATE ENVELOPE') !== false ||
+                strpos($r->getContainer(), 'FLAT RATE BOX') !== false
+            ) {
                 $service = 'Priority';
             }
+
             $package->addChild('Service', $service);
 
             // no matter Letter, Flat or Parcel, use Parcel
@@ -794,8 +799,15 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
             'first_class_mail_type' => ['LETTER' => __('Letter'), 'FLAT' => __('Flat'), 'PARCEL' => __('Parcel')],
             'container' => [
                 'VARIABLE' => __('Variable'),
-                'FLAT RATE BOX' => __('Flat-Rate Box'),
+                'SM FLAT RATE BOX' => __('Small Flat-Rate Box'),
+                'MD FLAT RATE BOX' => __('Medium Flat-Rate Box'),
+                'LG FLAT RATE BOX' => __('Large Flat-Rate Box'),
                 'FLAT RATE ENVELOPE' => __('Flat-Rate Envelope'),
+                'SM FLAT RATE ENVELOPE' => __('Small Flat-Rate Envelope'),
+                'WINDOW FLAT RATE ENVELOPE' => __('Window Flat-Rate Envelope'),
+                'GIFT CARD FLAT RATE ENVELOPE' => __('Gift Card Flat-Rate Envelope'),
+                'LEGAL FLAT RATE ENVELOPE' => __('Legal Flat-Rate Envelope'),
+                'PADDED FLAT RATE ENVELOPE' => __('Padded Flat-Rate Envelope'),
                 'RECTANGULAR' => __('Rectangular'),
                 'NONRECTANGULAR' => __('Non-rectangular'),
             ],
@@ -805,73 +817,103 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                     'filters' => [
                         'within_us' => [
                             'method' => [
-                                'Priority Mail Express Flat Rate Envelope',
-                                'Priority Mail Express Flat Rate Envelope Hold For Pickup',
-                                'Priority Mail Flat Rate Envelope',
-                                'Priority Mail Large Flat Rate Box',
-                                'Priority Mail Medium Flat Rate Box',
-                                'Priority Mail Small Flat Rate Box',
-                                'Priority Mail Express Hold For Pickup',
-                                'Priority Mail Express',
-                                'Priority Mail',
-                                'Priority Mail Hold For Pickup',
-                                'Priority Mail Large Flat Rate Box Hold For Pickup',
-                                'Priority Mail Medium Flat Rate Box Hold For Pickup',
-                                'Priority Mail Small Flat Rate Box Hold For Pickup',
-                                'Priority Mail Flat Rate Envelope Hold For Pickup',
-                                'Priority Mail Small Flat Rate Envelope',
-                                'Priority Mail Small Flat Rate Envelope Hold For Pickup',
-                                'First-Class Package Service Hold For Pickup',
-                                'Retail Ground',
-                                'Media Mail',
-                                'First-Class Mail Large Envelope',
-                                'Priority Mail Express Sunday/Holiday Delivery',
-                                'Priority Mail Express Sunday/Holiday Delivery Flat Rate Envelope',
-                                'Priority Mail Express Sunday/Holiday Delivery Flat Rate Boxes',
+                                '13', '27', '16', '22', '17', '28', '2', '3', '1', '33', '34', '35',
+                                '36', '37', '42', '43', '53', '4', '6', '15', '23', '25', '57'
                             ],
                         ],
                         'from_us' => [
                             'method' => [
-                                'Priority Mail Express International Flat Rate Envelope',
-                                'Priority Mail International Flat Rate Envelope',
-                                'Priority Mail International Large Flat Rate Box',
-                                'Priority Mail International Medium Flat Rate Box',
-                                'Priority Mail International Small Flat Rate Box',
-                                'Priority Mail International Small Flat Rate Envelope',
-                                'Priority Mail Express International Flat Rate Boxes',
-                                'Global Express Guaranteed (GXG)',
-                                'USPS GXG Envelopes',
-                                'Priority Mail Express International',
-                                'Priority Mail International',
-                                'First-Class Mail International Letter',
-                                'First-Class Mail International Large Envelope',
-                                'First-Class Package International Service',
+                                'INT_10', 'INT_8', 'INT_11', 'INT_9', 'INT_16', 'INT_20', 'INT_4',
+                                'INT_12', 'INT_1', 'INT_2', 'INT_13', 'INT_14', 'INT_15'
                             ],
                         ],
                     ],
                 ],
                 [
-                    'containers' => ['FLAT RATE BOX'],
+                    'containers' => ['SM FLAT RATE BOX'],
                     'filters' => [
                         'within_us' => [
-                            'method' => [
-                                'Priority Mail Large Flat Rate Box',
-                                'Priority Mail Medium Flat Rate Box',
-                                'Priority Mail Small Flat Rate Box',
-                                'Priority Mail International Large Flat Rate Box',
-                                'Priority Mail International Medium Flat Rate Box',
-                                'Priority Mail International Small Flat Rate Box',
-                                'Priority Mail Express Sunday/Holiday Delivery Flat Rate Boxes',
-                            ],
+                            'method' => ['28', '57'],
                         ],
                         'from_us' => [
-                            'method' => [
-                                'Priority Mail International Large Flat Rate Box',
-                                'Priority Mail International Medium Flat Rate Box',
-                                'Priority Mail International Small Flat Rate Box',
-                                'Priority Mail International DVD Flat Rate priced box',
-                                'Priority Mail International Large Video Flat Rate priced box',
-                            ],
+                            'method' => ['INT_16', 'INT_24'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['MD FLAT RATE BOX'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['17', '57'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_9', 'INT_24'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['LG FLAT RATE BOX'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['22', '57'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_11', 'INT_24', 'INT_25'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['SM FLAT RATE ENVELOPE'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['42', '43'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_20'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['WINDOW FLAT RATE ENVELOPE'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['40', '41'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_19'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['GIFT CARD FLAT RATE ENVELOPE'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['38', '39'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_18'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['PADDED FLAT RATE ENVELOPE'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['62', '63', '64', '46', '29'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_27', 'INT_23'],
+                        ],
+                    ]
+                ],
+                [
+                    'containers' => ['LEGAL FLAT RATE ENVELOPE'],
+                    'filters' => [
+                        'within_us' => [
+                            'method' => ['44', '45', '30', '31', '32'],
+                        ],
+                        'from_us' => [
+                            'method' => ['INT_17', 'INT_22'],
                         ],
                     ]
                 ],
@@ -879,30 +921,11 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                     'containers' => ['FLAT RATE ENVELOPE'],
                     'filters' => [
                         'within_us' => [
-                            'method' => [
-                                'Priority Mail Flat Rate Envelope',
-                                'Priority Mail Express Flat Rate Envelope',
-                                'Priority Mail Express Flat Rate Envelope Hold For Pickup',
-                                'Priority Mail Flat Rate Envelope',
-                                'First-Class Mail Large Envelope',
-                                'Priority Mail Flat Rate Envelope Hold For Pickup',
-                                'Priority Mail Small Flat Rate Envelope',
-                                'Priority Mail Small Flat Rate Envelope Hold For Pickup',
-                                'Priority Mail Express Sunday/Holiday Delivery Flat Rate Envelope',
-                                'Priority Mail Express Padded Flat Rate Envelope',
-                            ],
+                            'method' => ['16', '13', '27', '16', '15', '37', '42', '43', '25', '62'],
                         ],
                         'from_us' => [
                             'method' => [
-                                'Priority Mail Express International Flat Rate Envelope',
-                                'Priority Mail International Flat Rate Envelope',
-                                'First-Class Mail International Large Envelope',
-                                'Priority Mail International Small Flat Rate Envelope',
-                                'Priority Mail Express International Legal Flat Rate Envelope',
-                                'Priority Mail International Gift Card Flat Rate Envelope',
-                                'Priority Mail International Window Flat Rate Envelope',
-                                'Priority Mail International Legal Flat Rate Envelope',
-                                'Priority Mail Express International Padded Flat Rate Envelope',
+                                'INT_10', 'INT_8', 'INT_14', 'INT_20', 'INT_17', 'INT_18', 'INT_19', 'INT_22', 'INT_27'
                             ],
                         ],
                     ]
@@ -911,22 +934,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                     'containers' => ['RECTANGULAR'],
                     'filters' => [
                         'within_us' => [
-                            'method' => [
-                                'Priority Mail Express',
-                                'Priority Mail',
-                                'Retail Ground',
-                                'Media Mail',
-                                'Library Mail',
-                                'First-Class Package Service',
-                            ],
+                            'method' => ['3', '1', '4', '6', '7', '61'],
                         ],
                         'from_us' => [
-                            'method' => [
-                                'USPS GXG Envelopes',
-                                'Priority Mail Express International',
-                                'Priority Mail International',
-                                'First-Class Package International Service',
-                            ],
+                            'method' => ['INT_12', 'INT_1', 'INT_2', 'INT_15'],
                         ],
                     ]
                 ],
@@ -934,21 +945,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                     'containers' => ['NONRECTANGULAR'],
                     'filters' => [
                         'within_us' => [
-                            'method' => [
-                                'Priority Mail Express',
-                                'Priority Mail',
-                                'Retail Ground',
-                                'Media Mail',
-                                'Library Mail',
-                            ],
+                            'method' => ['3', '1', '4', '6', '7'],
                         ],
                         'from_us' => [
-                            'method' => [
-                                'Global Express Guaranteed (GXG)',
-                                'Priority Mail Express International',
-                                'Priority Mail International',
-                                'First-Class Package International Service',
-                            ],
+                            'method' => ['INT_4', 'INT_1', 'INT_2', 'INT_15'],
                         ],
                     ]
                 ],
diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json
index 5baccddf4884307f4ebdeed9199fedb00debf4bc..15e93d0bea4fb6d0e89f21f180b2c91486c8f5aa 100644
--- a/app/code/Magento/Usps/composer.json
+++ b/app/code/Magento/Usps/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-usps",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-shipping": "100.2.*",
         "magento/module-directory": "100.2.*",
diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json
index 21f3ec1dd467f240c609d5931ffa5cbde8dc3e15..e4b06d0edb34ab25d4d1279fb463a4f630ee77e9 100644
--- a/app/code/Magento/Variable/composer.json
+++ b/app/code/Magento/Variable/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-variable",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-backend": "100.2.*",
         "magento/module-email": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/Vault/composer.json b/app/code/Magento/Vault/composer.json
index 74dd568e3b45ee4e3e7f9e235d3389191b7a93e4..b2edf040674d83f6335d407089201b46fe16ecce 100644
--- a/app/code/Magento/Vault/composer.json
+++ b/app/code/Magento/Vault/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-vault",
     "description": "",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*",
         "magento/module-sales": "100.2.*",
         "magento/module-store": "100.2.*",
diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json
index 3a972432101154fa2c4f167473fc6f4d6aa113a0..4396f1fb2b3bf4e114dd2ab4dfbd37eb7c2ffd7e 100644
--- a/app/code/Magento/Version/composer.json
+++ b/app/code/Magento/Version/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-version",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/Webapi/Model/Config.php b/app/code/Magento/Webapi/Model/Config.php
index 45d29bc59cf0d6a1c9c1be78ff84343f50b1029d..fb6dc894e3c0ae87915f12bdf38311a5be541874 100644
--- a/app/code/Magento/Webapi/Model/Config.php
+++ b/app/code/Magento/Webapi/Model/Config.php
@@ -8,6 +8,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache;
 use Magento\Webapi\Model\Config\Reader;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Web API Config Model.
@@ -40,16 +42,26 @@ class Config
      */
     protected $services;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
      * @param WebapiCache $cache
      * @param Reader $configReader
+     * @param SerializerInterface|null $serializer
      */
-    public function __construct(WebapiCache $cache, Reader $configReader)
-    {
+    public function __construct(
+        WebapiCache $cache,
+        Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->cache = $cache;
         $this->configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -62,10 +74,10 @@ class Config
         if (null === $this->services) {
             $services = $this->cache->load(self::CACHE_ID);
             if ($services && is_string($services)) {
-                $this->services = unserialize($services);
+                $this->services = $this->serializer->unserialize($services);
             } else {
                 $this->services = $this->configReader->read();
-                $this->cache->save(serialize($this->services), self::CACHE_ID);
+                $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID);
             }
         }
         return $this->services;
diff --git a/app/code/Magento/Webapi/Model/ServiceMetadata.php b/app/code/Magento/Webapi/Model/ServiceMetadata.php
index b75d10f9a271f7a3f39fff2ac9494f020b5cf660..14e45ccb409db24df2dd2f1c4f8d5693a55d3126 100644
--- a/app/code/Magento/Webapi/Model/ServiceMetadata.php
+++ b/app/code/Magento/Webapi/Model/ServiceMetadata.php
@@ -7,6 +7,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Config\Converter;
 use Magento\Webapi\Model\Cache\Type\Webapi as WebApiCache;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Service Metadata Model
@@ -74,6 +76,11 @@ class ServiceMetadata
      */
     protected $typeProcessor;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
@@ -81,17 +88,20 @@ class ServiceMetadata
      * @param WebApiCache $cache
      * @param \Magento\Webapi\Model\Config\ClassReflector $classReflector
      * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+     * @param SerializerInterface|null $serializer
      */
     public function __construct(
         \Magento\Webapi\Model\Config $config,
         WebApiCache $cache,
         \Magento\Webapi\Model\Config\ClassReflector $classReflector,
-        \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+        \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
+        SerializerInterface $serializer = null
     ) {
         $this->config = $config;
         $this->cache = $cache;
         $this->classReflector = $classReflector;
         $this->typeProcessor = $typeProcessor;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -142,12 +152,18 @@ class ServiceMetadata
             $servicesConfig = $this->cache->load(self::SERVICES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($servicesConfig && is_string($servicesConfig) && $typesData && is_string($typesData)) {
-                $this->services = unserialize($servicesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->services = $this->serializer->unserialize($servicesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->services = $this->initServicesMetadata();
-                $this->cache->save(serialize($this->services), self::SERVICES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->services),
+                    self::SERVICES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->services;
@@ -256,12 +272,18 @@ class ServiceMetadata
             $routesConfig = $this->cache->load(self::ROUTES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($routesConfig && is_string($routesConfig) && $typesData && is_string($typesData)) {
-                $this->routes = unserialize($routesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->routes = $this->serializer->unserialize($routesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->routes = $this->initRoutesMetadata();
-                $this->cache->save(serialize($this->routes), self::ROUTES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->routes),
+                    self::ROUTES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->routes;
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..74280f61916d7182e90bdf1e9b6125da55a6c31b
--- /dev/null
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Test\Unit\Model;
+
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Config\Reader;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    private $config;
+
+    /**
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $webapiCacheMock;
+
+    /**
+     * @var Reader|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configReaderMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializerMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->webapiCacheMock = $this->getMock(\Magento\Webapi\Model\Cache\Type\Webapi::class, [], [], '', false);
+        $this->configReaderMock = $this->getMock(\Magento\Webapi\Model\Config\Reader::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->config = $objectManager->getObject(
+            Config::class,
+            [
+                'cache' => $this->webapiCacheMock,
+                'configReader' => $this->configReaderMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServices()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn($serializedData);
+        $this->serializerMock->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedData)
+            ->willReturn($data);
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+
+    public function testGetServicesNoCache()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configReaderMock->expects($this->once())
+            ->method('read')
+            ->willReturn($data);
+        $this->serializerMock->expects($this->once())
+            ->method('serialize')
+            ->with($data)
+            ->willReturn($serializedData);
+        $this->webapiCacheMock->expects($this->once())
+            ->method('save')
+            ->with(
+                $serializedData,
+                Config::CACHE_ID
+            );
+
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+}
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
index 29c1bf90402ebe36d6ca91c5585cacb03f739cc3..4125f82b7923ffb30a3bfc0d86f3414255498231 100644
--- a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
@@ -1,187 +1,450 @@
 <?php
 /**
- * ServiceMetadata Unit tests.
- *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-/**
- * Class implements tests for \Magento\Webapi\Model\ServiceMetadata class.
- */
 namespace Magento\Webapi\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+use Magento\Webapi\Model\Config\ClassReflector;
+use Magento\Framework\Reflection\TypeProcessor;
+use Magento\Webapi\Model\ServiceMetadata;
+use Magento\Customer\Api\CustomerRepositoryInterface;
+
 class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\Webapi\Model\ServiceMetadata */
-    protected $serviceMetadata;
+    /**
+     * @var ServiceMetadata
+     */
+    private $serviceMetadata;
 
     /**
-     * Set up helper.
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheMock;
+
+    /**
+     * @var Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configMock;
+
+    /**
+     * @var ClassReflector|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $classReflectorMock;
+
+    /**
+     * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $typeProcessorMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
+    private $serializerMock;
+
     protected function setUp()
     {
-        $interfaceParameters = [
-            'activateById' => [
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->configMock = $this->getMock(Config::class, [], [], '', false);
+        $this->cacheMock = $this->getMock(Webapi::class, [], [], '', false);
+        $this->classReflectorMock = $this->getMock(ClassReflector::class, [], [], '', false);
+        $this->typeProcessorMock = $this->getMock(TypeProcessor::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->serviceMetadata = $objectManager->getObject(
+            ServiceMetadata::class,
+            [
+                'config' => $this->configMock,
+                'cache' => $this->cacheMock,
+                'classReflector' => $this->classReflectorMock,
+                'typeProcessor' => $this->typeProcessorMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServicesConfig()
+    {
+        $servicesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn($serializedServicesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedServicesConfig)
+            ->willReturn($servicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesConfig, $this->serviceMetadata->getServicesConfig());
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testGetServicesConfigNoCache()
+    {
+        $servicesConfig = [
+            'services' => [
+                CustomerRepositoryInterface::class => [
+                    'V1' => [
+                        'methods' => [
+                            'getById' => [
+                                'resources' => [
+                                    [
+                                        'Magento_Customer::customer',
+                                    ]
+                                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
                 'interface' => [
                     'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                            'requiredInputParameter' => [
+                                'type' => 'int',
                                 'required' => true,
-                            ],
-                        ],
+                                'documentation' => null
+                            ]
+                        ]
                     ],
                     'out' => [
                         'parameters' => [
-                            'outputParameter' => [
-                                'type' => 'string',
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $servicesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ],
                             ],
-                        ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
-                ],
-            ],
+                    $methodsReflectionData
+                ),
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
+            ]
         ];
-        $classReflection = $this->getMock(
-            \Magento\Webapi\Model\Config\ClassReflector::class,
-            ['reflectClassMethods', 'extractClassDescription'],
-            [],
-            '',
-            false
-        );
-        $classReflection->expects($this->any())
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->once())
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
             ->method('reflectClassMethods')
-            ->will($this->returnValue($interfaceParameters));
-        $classReflection->expects($this->any())
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
             ->method('extractClassDescription')
-            ->will($this->returnValue('classDescription'));
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->once())
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('serialize')
+            ->with($servicesMetadata)
+            ->willReturn($serializedServicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(2))
+            ->method('save')
+            ->with(
+                $serializedServicesConfig,
+                ServiceMetadata::SERVICES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(3))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesMetadata, $this->serviceMetadata->getServicesConfig());
+    }
+
+    public function testGetRoutesConfig()
+    {
+        $routesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn($serializedRoutesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedRoutesConfig)
+            ->willReturn($routesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesConfig, $this->serviceMetadata->getRoutesConfig());
+    }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testGetRoutesConfigNoCache()
+    {
         $servicesConfig = [
-            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'activateById' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::manage',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
+            'services' => [
+                CustomerRepositoryInterface::class => [
                     'V1' => [
                         'methods' => [
                             'getById' => [
                                 'resources' => [
                                     [
                                         'Magento_Customer::customer',
-                                    ],
+                                    ]
                                 ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
             ],
             'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
+                '/V1/customers/:customerId' => [
+                    'GET' => [
                         'secure' => false,
                         'service' => [
-                            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-                            'method' => 'activateById',
+                            'class' => CustomerRepositoryInterface::class,
+                            'method' => 'getById'
                         ],
                         'resources' => [
-                            'self' => true,
+                            'Magento_Customer::customer' => true
                         ],
+                        'parameters' => []
+                    ]
+                ]
+            ],
+            'class' => CustomerRepositoryInterface::class,
+            'description' => 'Customer CRUD interface.',
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
+                'interface' => [
+                    'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                        ],
+                                'type' => 'int',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
                     ],
-                ],
-                '/V1/customers/:customerId' => [
-                    'GET' => [
-                        'secure' => false,
-                        'service' => [
-                            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
-                            'method' => 'getById',
-                        ],
-                        'resources' => [
-                            'Magento_Customer::customer' => true,
-                        ],
+                    'out' => [
                         'parameters' => [
-                        ],
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $routesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ]
+                            ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
+                    $methodsReflectionData
+                ),
+                'routes' => [
+                    '/V1/customers/:customerId' => [
+                        'GET' => [
+                            'method' => 'getById',
+                            'parameters' => []
+                        ]
+                    ]
                 ],
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
             ]
         ];
-
-        /**
-         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
-         */
-        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
-        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
-
-        /** @var $config \Magento\Webapi\Model\Config */
-        $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock);
-
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $typeProcessor = $objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class);
-
-        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
-        $this->serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata(
-            $config,
-            $cacheMock,
-            $classReflection,
-            $typeProcessor
-        );
-
-        parent::setUp();
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->exactly(2))
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
+            ->method('reflectClassMethods')
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
+            ->method('extractClassDescription')
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->exactly(2))
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(2))
+            ->method('serialize')
+            ->with($routesMetadata)
+            ->willReturn($serializedRoutesConfig);
+        $this->serializerMock->expects($this->at(3))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(6))
+            ->method('save')
+            ->with(
+                $serializedRoutesConfig,
+                ServiceMetadata::ROUTES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(7))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesMetadata, $this->serviceMetadata->getRoutesConfig());
     }
 
     /**
-     * Test identifying service name including subservices using class name.
-     *
-     * @dataProvider serviceNameDataProvider
+     * @dataProvider getServiceNameDataProvider
      */
     public function testGetServiceName($className, $version, $preserveVersion, $expected)
     {
-        $actual = $this->serviceMetadata->getServiceName($className, $version, $preserveVersion);
-        $this->assertEquals($expected, $actual);
+        $this->assertEquals(
+            $expected,
+            $this->serviceMetadata->getServiceName($className, $version, $preserveVersion)
+        );
     }
 
     /**
-     * Dataprovider for testGetServiceName
-     *
      * @return string
      */
-    public function serviceNameDataProvider()
+    public function getServiceNameDataProvider()
     {
         return [
-            [\Magento\Customer\Api\AccountManagementInterface::class, 'V1', false, 'customerAccountManagement'],
-            [\Magento\Customer\Api\AddressRepositoryInterface::class, 'V1', true, 'customerAddressRepositoryV1'],
+            [
+                \Magento\Customer\Api\AccountManagementInterface::class,
+                'V1',
+                false,
+                'customerAccountManagement'
+            ],
+            [
+                \Magento\Customer\Api\AddressRepositoryInterface::class,
+                'V1',
+                true,
+                'customerAddressRepositoryV1'
+            ],
         ];
     }
 
     /**
      * @expectedException \InvalidArgumentException
-     * @dataProvider dataProviderForTestGetServiceNameInvalidName
+     * @dataProvider getServiceNameInvalidNameDataProvider
      */
     public function testGetServiceNameInvalidName($interfaceClassName, $version)
     {
@@ -189,111 +452,18 @@ class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Dataprovider for testGetServiceNameInvalidName
-     *
      * @return string
      */
-    public function dataProviderForTestGetServiceNameInvalidName()
+    public function getServiceNameInvalidNameDataProvider()
     {
         return [
-            ['BarV1Interface', 'V1'], // Missed vendor, module, 'Service'
+            ['BarV1Interface', 'V1'], // Missed vendor, module and Service
             ['Service\\V1Interface', 'V1'], // Missed vendor and module
             ['Magento\\Foo\\Service\\BarVxInterface', 'V1'], // Version number should be a number
-            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Version missed
-            ['Magento\\Foo\\Service\\BarV1', 'V1'], // 'Interface' missed
-            ['Foo\\Service\\BarV1Interface', 'V1'], // Module missed
-            ['Foo\\BarV1Interface', 'V1'] // Module and 'Service' missed
-        ];
-    }
-
-    public function testGetServiceMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
+            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Missed version
+            ['Magento\\Foo\\Service\\BarV1', 'V1'], // Missed Interface
+            ['Foo\\Service\\BarV1Interface', 'V1'], // Missed module
+            ['Foo\\BarV1Interface', 'V1'] // Missed module and Service
         ];
-        $result = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
-    }
-
-    public function testGetRouteMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
-            'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
-                        'method' => 'activateById',
-                        'parameters' => [
-                            'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%'
-                            ]
-                        ]
-                    ]
-                ]
-            ]
-        ];
-        $result = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
     }
 }
-
-require_once realpath(__DIR__ . '/../_files/test_interfaces.php');
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php
deleted file mode 100644
index aa5d1a7bfab7e5a1858ae9b321d41a1accba3955..0000000000000000000000000000000000000000
--- a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-/**
- * Config helper Unit tests.
- *
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/**
- * Class implements tests for \Magento\Webapi\Model\Soap\Config class.
- */
-namespace Magento\Webapi\Test\Unit\Model\Soap;
-
-class ConfigTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var \Magento\Webapi\Model\Soap\Config */
-    protected $_soapConfig;
-
-    /** @var  \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
-    protected $objectManager;
-
-    /**
-     * Set up helper.
-     */
-    protected function setUp()
-    {
-        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-
-        $typeProcessor = $this->objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class);
-
-        $objectManagerMock = $this->getMockBuilder(
-            \Magento\Framework\App\ObjectManager::class
-        )->disableOriginalConstructor()->getMock();
-
-        $classReflection = $this->getMock(
-            \Magento\Webapi\Model\Config\ClassReflector::class,
-            ['reflectClassMethods'],
-            ['_typeProcessor' => $typeProcessor],
-            ''
-        );
-        $classReflection->expects($this->any())->method('reflectClassMethods')->will($this->returnValue([]));
-
-        $servicesConfig = [
-            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'activate' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::manage',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'getById' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::customer',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-        ];
-
-        /**
-         * @var $registryMock \Magento\Framework\Registry
-         */
-        $registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /**
-         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
-         */
-        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
-        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
-
-        /** @var $config \Magento\Webapi\Model\Config */
-        $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock);
-
-        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
-        $serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata(
-            $config,
-            $cacheMock,
-            $classReflection,
-            $typeProcessor);
-
-        $this->_soapConfig = $this->objectManager->getObject(
-            \Magento\Webapi\Model\Soap\Config::class,
-            [
-                'objectManager' => $objectManagerMock,
-                'registry' => $registryMock,
-                'serviceMetadata' => $serviceMetadata,
-            ]
-        );
-        parent::setUp();
-    }
-
-    public function testGetRequestedSoapServices()
-    {
-        $expectedResult = [
-            'customerAccountManagementV1' =>
-                [
-                    'methods' => [
-                        'activate' => [
-                            'method' => 'activate',
-                            'inputRequired' => '',
-                            'isSecure' => '',
-                            'resources' => [['Magento_Customer::manage']],
-                        ],
-                    ],
-                    'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-                    'description' => 'Interface for managing customers accounts.',
-                ],
-        ];
-
-        $result = $this->_soapConfig->getRequestedSoapServices(
-            ['customerAccountManagementV1', 'moduleBarV2', 'moduleBazV1']
-        );
-
-        $this->assertEquals($expectedResult, $result);
-    }
-
-    public function testGetServiceMethodInfo()
-    {
-        $expectedResult = [
-            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
-            'method' => 'getById',
-            'isSecure' => false,
-            'resources' => [['Magento_Customer::customer']],
-        ];
-        $methodInfo = $this->_soapConfig->getServiceMethodInfo(
-            'customerCustomerRepositoryV1GetById',
-            ['customerCustomerRepositoryV1', 'moduleBazV1']
-        );
-        $this->assertEquals($expectedResult, $methodInfo);
-    }
-
-    public function testGetSoapOperation()
-    {
-        $expectedResult = 'customerAccountManagementV1Activate';
-        $soapOperation = $this->_soapConfig
-            ->getSoapOperation(\Magento\Customer\Api\AccountManagementInterface::class, 'activate', 'V1');
-        $this->assertEquals($expectedResult, $soapOperation);
-    }
-}
-
-require_once realpath(__DIR__ . '/../../_files/test_interfaces.php');
diff --git a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php b/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php
deleted file mode 100644
index 288a747cefd89cec4182de66890127eebd552806..0000000000000000000000000000000000000000
--- a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Framework\Module\Service;
-
-/**
- * The list of test interfaces.
- */
-interface FooV1Interface
-{
-    public function someMethod();
-}
-interface BarV1Interface
-{
-    public function someMethod();
-}
-interface FooBarV1Interface
-{
-    public function someMethod();
-}
-namespace Magento\Framework\Module\Service\Foo;
-
-interface BarV1Interface
-{
-    public function someMethod();
-}
diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json
index f2796df70a8fae522a34d0c94e079afd9f525f9c..6fc712722adddf10c16e4add70913a62c2ef2bc7 100644
--- a/app/code/Magento/Webapi/composer.json
+++ b/app/code/Magento/Webapi/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-webapi",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-authorization": "100.2.*",
         "magento/module-integration": "100.2.*",
diff --git a/app/code/Magento/WebapiSecurity/composer.json b/app/code/Magento/WebapiSecurity/composer.json
index 506975f1aa188d4f0d90f8d2f0484153998f2c39..0f4ef7b3dc8839518bcc2982e9975c53d99a6c1b 100644
--- a/app/code/Magento/WebapiSecurity/composer.json
+++ b/app/code/Magento/WebapiSecurity/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-webapi-security",
     "description": "WebapiSecurity module provides option to loosen security on some webapi resources.",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-webapi": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json
index 035d66e5a96b416f1f5e3140ef9e45e299c1b52a..70fd4a25d0310d94d4254a8079755eab01ad610f 100644
--- a/app/code/Magento/Weee/composer.json
+++ b/app/code/Magento/Weee/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-weee",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-catalog": "101.1.*",
         "magento/module-tax": "100.2.*",
diff --git a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php
index f5197dd7d0435d672023a0027d7bbb7674036abb..dc048d41612b800c9d291b5067b0106bb1fbf079 100644
--- a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php
+++ b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php
@@ -10,6 +10,10 @@
  */
 namespace Magento\Widget\Model\ResourceModel\Widget\Instance\Options;
 
+/**
+ * @deprecated created new class that correctly loads theme options and whose name follows naming convention
+ * @see \Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes
+ */
 class ThemeId implements \Magento\Framework\Option\ArrayInterface
 {
     /**
diff --git a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php
new file mode 100644
index 0000000000000000000000000000000000000000..403dfeb40ff2ea3330440c0a22db4247e9a5e377
--- /dev/null
+++ b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Widget\Model\ResourceModel\Widget\Instance\Options;
+
+use Magento\Framework\Data\OptionSourceInterface;
+use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory as ThemeCollectionFactory;
+
+/**
+ * Option source of the widget theme property.
+ *
+ * Can be used as a data provider for UI components that shows possible themes as a list.
+ */
+class Themes implements OptionSourceInterface
+{
+    /**
+     * @var ThemeCollectionFactory
+     */
+    private $themeCollectionFactory;
+
+    /**
+     * @param ThemeCollectionFactory $themeCollectionFactory
+     */
+    public function __construct(ThemeCollectionFactory $themeCollectionFactory)
+    {
+        $this->themeCollectionFactory = $themeCollectionFactory;
+    }
+
+    /**
+     * Return array of options as value-label pairs
+     *
+     * @return array Format: array('<theme ID>' => '<theme label>', ...)
+     */
+    public function toOptionArray()
+    {
+        // Load only visible themes that are used in frontend area
+        return $this->themeCollectionFactory->create()->loadRegisteredThemes()->toOptionHash();
+    }
+}
diff --git a/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php b/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3854a599013298e0b3bbd6439183611d14b95d3
--- /dev/null
+++ b/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Widget\Test\Unit\Model\ResourceModel\Widget\Instance\Options;
+
+use Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes;
+use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection;
+use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory as ThemeCollectionFactory;
+
+/**
+ * Test class for \Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes
+ */
+class ThemesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Themes
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $themeCollectionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $themeCollectionMock;
+
+    protected function setUp()
+    {
+        $this->themeCollectionMock = $this->getMock(ThemeCollection::class, [], [], '', false);
+        $this->themeCollectionFactoryMock = $this->getMock(ThemeCollectionFactory::class, ['create'], [], '', false);
+        $this->model = new Themes(
+            $this->themeCollectionFactoryMock
+        );
+    }
+
+    public function testToOptionArray()
+    {
+        $expectedResult = [
+            1 => 'Theme Label',
+        ];
+        $this->themeCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->themeCollectionMock);
+
+        $this->themeCollectionMock->expects($this->once())->method('loadRegisteredThemes')->willReturnSelf();
+        $this->themeCollectionMock->expects($this->once())->method('toOptionHash')->willReturn($expectedResult);
+
+        $this->assertEquals($expectedResult, $this->model->toOptionArray());
+    }
+}
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index f59c4180eb2bb56522ae20f3615da92dd0c60370..b5a5e9e5569e3c62641cfc2d3cbc34030229020b 100644
--- a/app/code/Magento/Widget/composer.json
+++ b/app/code/Magento/Widget/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-widget",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-cms": "101.1.*",
         "magento/module-backend": "100.2.*",
diff --git a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml
index 2d9cf935afa0d4281e46f997e22465285f69e53d..db73e302f4a7629e380292308cce534693560d99 100644
--- a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml
+++ b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml
@@ -52,7 +52,7 @@
                             <argument name="header" xsi:type="string" translate="true">Design Theme</argument>
                             <argument name="index" xsi:type="string">theme_id</argument>
                             <argument name="type" xsi:type="string">options</argument>
-                            <argument name="options" xsi:type="options" model="Magento\Widget\Model\ResourceModel\Widget\Instance\Options\ThemeId"/>
+                            <argument name="options" xsi:type="options" model="Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes"/>
                             <argument name="with_empty" xsi:type="string">1</argument>
                         </arguments>
                     </block>
diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml
index 4e240770b04622e4ec6c68bfa796a6a83da006e1..94ee88698111f72c81cbd86eb16adef0e9b94317 100644
--- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml
+++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml
@@ -79,7 +79,7 @@ jQuery(function()
                 // Add empty node to reset category filter
                 if(!emptyNodeAdded) {
                     var empty = Object.clone(_node);
-                    empty.text = '<?php /* @escapeNotVerified */ echo __('None') ?>';
+                    empty.text = '<?php echo $block->escapeJs($block->escapeHtml(__('None'))); ?>';
                     empty.children = [];
                     empty.id = 'none';
                     empty.path = '1/none';
diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml
index 62d92ac38aecdbc22f13de959eba3f419b47c431..5d55ba4035873d028f27e5662814cc838b7e18a8 100644
--- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml
+++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml
@@ -10,7 +10,7 @@
 
 ?>
 <fieldset class="fieldset">
-    <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Layout Updates') ?></span></legend>
+    <legend class="legend"><span><?php echo $block->escapeHtml(__('Layout Updates')); ?></span></legend>
     <br />
     <div class="widget-layout-updates">
         <div id="page_group_container"></div>
diff --git a/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php b/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php
index 6d8e4bcd2fd1c41844cd4398043b61dec4ff36ff..be995258794cc05f1fca4a2124cac04e8c0e1c87 100644
--- a/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php
+++ b/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php
@@ -21,15 +21,12 @@ class ConfigurableProduct extends FinalPrice implements ConfiguredPriceInterface
      */
     public function getValue()
     {
-        $result = 0.;
         /** @var \Magento\Wishlist\Model\Item\Option $customOption */
         $customOption = $this->getProduct()->getCustomOption('simple_product');
-        if ($customOption) {
-            /** @var \Magento\Framework\Pricing\PriceInfoInterface $priceInfo */
-            $priceInfo = $customOption->getProduct()->getPriceInfo();
-            $result = $priceInfo->getPrice(self::PRICE_CODE)->getValue();
-        }
-        return max(0, $result);
+        $product = $customOption ? $customOption->getProduct() : $this->getProduct();
+        $price = $product->getPriceInfo()->getPrice(self::PRICE_CODE)->getValue();
+
+        return max(0, $price);
     }
 
     /**
diff --git a/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php b/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php
index 9e05a578080efbd7ec91f49babfbbafc447e330d..ee4841ef79f2e6e31545f12e44fe49073166a8e3 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php
@@ -5,36 +5,30 @@
  */
 namespace Magento\Wishlist\Test\Unit\Pricing\ConfiguredPrice;
 
-use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
-use Magento\Framework\Pricing\PriceCurrencyInterface;
-use Magento\Framework\Pricing\PriceInfoInterface;
-use Magento\Framework\Pricing\SaleableInterface;
-use Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct;
-
 class ConfigurableProductTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var SaleableInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $saleableItem;
 
     /**
-     * @var CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\Adjustment\CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $calculator;
 
     /**
-     * @var PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $priceCurrency;
 
     /**
-     * @var ConfigurableProduct
+     * @var \Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct
      */
     private $model;
 
     /**
-     * @var PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $priceInfoMock;
 
@@ -49,9 +43,6 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase
                 'getCustomOption',
             ])
             ->getMockForAbstractClass();
-        $this->saleableItem->expects($this->once())
-            ->method('getPriceInfo')
-            ->willReturn($this->priceInfoMock);
 
         $this->calculator = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\CalculatorInterface::class)
             ->getMockForAbstractClass();
@@ -59,7 +50,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase
         $this->priceCurrency = $this->getMockBuilder(\Magento\Framework\Pricing\PriceCurrencyInterface::class)
             ->getMockForAbstractClass();
 
-        $this->model = new ConfigurableProduct(
+        $this->model = new \Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct(
             $this->saleableItem,
             null,
             $this->calculator,
@@ -82,7 +73,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $this->priceInfoMock->expects($this->once())
             ->method('getPrice')
-            ->with(ConfigurableProduct::PRICE_CODE)
+            ->with(\Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct::PRICE_CODE)
             ->willReturn($priceMock);
 
         $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
@@ -109,11 +100,28 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase
 
     public function testGetValueWithNoCustomOption()
     {
+        $priceValue = 100;
+
+        $priceMock = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
+            ->getMockForAbstractClass();
+        $priceMock->expects($this->once())
+            ->method('getValue')
+            ->willReturn($priceValue);
+
         $this->saleableItem->expects($this->once())
             ->method('getCustomOption')
             ->with('simple_product')
             ->willReturn(null);
 
-        $this->assertEquals(0, $this->model->getValue());
+        $this->saleableItem->expects($this->once())
+            ->method('getPriceInfo')
+            ->willReturn($this->priceInfoMock);
+
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrice')
+            ->with(\Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct::PRICE_CODE)
+            ->willReturn($priceMock);
+
+        $this->assertEquals(100, $this->model->getValue());
     }
 }
diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json
index 3faee8912493c96092f70d7fc3ca0e77164b39bc..b341edde760b0761872aecc488216faa37392c22 100644
--- a/app/code/Magento/Wishlist/composer.json
+++ b/app/code/Magento/Wishlist/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/module-wishlist",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/module-store": "100.2.*",
         "magento/module-customer": "100.2.*",
         "magento/module-catalog": "101.1.*",
diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json
index 29569db622d2ccc9fad9e9b87b3ad4f7ae4757d2..ff0eda055bba6a9e9899d66839216c14bbdbe02e 100644
--- a/app/design/adminhtml/Magento/backend/composer.json
+++ b/app/design/adminhtml/Magento/backend/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/theme-adminhtml-backend",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-theme",
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less
index 3804721026db50a77ebaf752c75f5dc35a23cf09..d861d4dcae256222cb30cc81ee21359a40e12582 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less
@@ -23,8 +23,7 @@
 
 & when (@media-common = true) {
 
-    .checkout-index-index,
-    .checkout-onepage-success {
+    .checkout-index-index {
         .page-title-wrapper {
             &:extend(.abs-visually-hidden all);
         }
@@ -61,6 +60,14 @@
             margin-left: 0;
         }
     }
+
+    .checkout-onepage-success {
+        &:extend(.abs-add-clearfix all);
+
+        .print {
+            display: none;
+        }
+    }
 }
 
 //
@@ -87,4 +94,12 @@
         .lib-layout-column(2, 1, @checkout-wrapper__columns);
         padding-right: @indent__l;
     }
+
+    .checkout-onepage-success {
+        .print {
+            display: block;
+            float: right;
+            margin: 22px 0 0;
+        }
+    }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less
index a8d0bf8b584822f7e0084d690f9feb5ad04246a2..6596fe2fd79762908b1a87d2fbeac90fd8be7824 100644
--- a/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less
+++ b/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less
@@ -158,11 +158,12 @@
     .block-returns-tracking {
         .block-title {
             .action {
-                margin: 12px 0 0 30px;
+                margin: 0 0 0 30px;
+            }
 
-                &.track {
-                    float: right;
-                }
+            .actions-track {
+                float: right;
+                margin-top: 12px;
             }
         }
     }
diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json
index 27ed40860dd5b065dc51e82f487722eb519ba215..7c03167ebc23278eaab5a72cddd381de7cd5afcc 100644
--- a/app/design/frontend/Magento/blank/composer.json
+++ b/app/design/frontend/Magento/blank/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/theme-frontend-blank",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "100.2.*"
     },
     "type": "magento2-theme",
diff --git a/app/design/frontend/Magento/blank/etc/view.xml b/app/design/frontend/Magento/blank/etc/view.xml
index 3a92ad0a6741040e0adb3fc25e00948520cfa565..6c53a8613f09ca1f91c9e024b8e2cec723f0b309 100644
--- a/app/design/frontend/Magento/blank/etc/view.xml
+++ b/app/design/frontend/Magento/blank/etc/view.xml
@@ -227,7 +227,7 @@
                 </var>
                 <var name="options">
                     <var name="options">
-                        <var name="navigation">dots</var>
+                        <var name="nav">dots</var>
                     </var>
                 </var>
             </var>
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less
index f037c1c5777cbf8f761fddf779f7c8e9942278f8..a1109523d26b5ea6b85e794a66ebad3100a551c0 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less
@@ -27,8 +27,7 @@
 
 & when (@media-common = true) {
 
-    .checkout-index-index,
-    .checkout-onepage-success {
+    .checkout-index-index {
         .page-title-wrapper {
             &:extend(.abs-visually-hidden all);
         }
@@ -66,6 +65,14 @@
             margin-left: 0;
         }
     }
+
+    .checkout-onepage-success {
+        &:extend(.abs-add-clearfix all);
+
+        .print {
+            display: none;
+        }
+    }
 }
 
 //
@@ -96,4 +103,12 @@
         .lib-layout-column(2, 1, @checkout-wrapper__columns);
         padding-right: @indent__l;
     }
+
+    .checkout-onepage-success {
+        .print {
+            display: block;
+            float: right;
+            margin: 23px 0 0;
+        }
+    }
 }
diff --git a/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less
index cfec28464244e59e48aeb16e674d8afcc33407b4..c7e955e69c3a66864e073365d2863968f014ed66 100644
--- a/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less
@@ -176,11 +176,12 @@
     .block-returns-tracking {
         .block-title {
             .action {
-                margin: 12px 0 0 30px;
+                margin: 0 0 0 30px;
+            }
 
-                &.track {
-                    float: right;
-                }
+            .actions-track {
+                float: right;
+                margin-top: 12px;
             }
         }
     }
diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json
index 98fe0ebf8061c23fa37d30a9551f05d5c41bce1b..97eb48f3c7e9efe028eae034757a6a17c4d98bd0 100644
--- a/app/design/frontend/Magento/luma/composer.json
+++ b/app/design/frontend/Magento/luma/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/theme-frontend-luma",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/theme-frontend-blank": "100.2.*",
         "magento/framework": "100.2.*"
     },
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 643390068a5e3e857ccb0e0d2d07fb5e26b8ea81..e430c15729d3d0cced20bf2b326d40f152b174e6 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -154,6 +154,7 @@
     <preference for="Magento\Framework\EntityManager\MapperInterface" type="Magento\Framework\EntityManager\CompositeMapper"/>
     <preference for="Magento\Framework\Console\CommandListInterface" type="Magento\Framework\Console\CommandList"/>
     <preference for="Magento\Framework\DataObject\IdentityGeneratorInterface" type="Magento\Framework\DataObject\IdentityService" />
+    <preference for="Magento\Framework\Serialize\SerializerInterface" type="Magento\Framework\Serialize\Serializer\Json" />
     <type name="Magento\Framework\Model\ResourceModel\Db\TransactionManager" shared="false" />
     <type name="Magento\Framework\Logger\Handler\Base">
         <arguments>
diff --git a/composer.json b/composer.json
index fed4465140724cef3c24cd7facdd2ec5ceeba5b6..f9e49415d6ad3aff6976144df442861909155d2d 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
         "AFL-3.0"
     ],
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "zendframework/zend-stdlib": "~2.4.6",
         "zendframework/zend-code": "~2.4.6",
         "zendframework/zend-server": "~2.4.6",
diff --git a/composer.lock b/composer.lock
index 7feb568d766d012e009c59a50226f3ea8bd7b74a..02f0e31a325638840641667cac1c6783cf381e87 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "c23e80be1cc71ab108ce5ac19b3fe509",
-    "content-hash": "5b9734c1bdbda68cf20507525cafa0f2",
+    "hash": "1f34dce6d48c9e4e694c27e001414000",
+    "content-hash": "600aca1692cf3fe5c2ea1cbf66de09ab",
     "packages": [
         {
             "name": "braintree/braintree_php",
@@ -56,7 +56,7 @@
         },
         {
             "name": "colinmollenhour/cache-backend-file",
-            "version": "1.4",
+            "version": "1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git",
@@ -818,16 +818,16 @@
         },
         {
             "name": "paragonie/random_compat",
-            "version": "v2.0.2",
+            "version": "v2.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/paragonie/random_compat.git",
-                "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
+                "reference": "c0125896dbb151380ab47e96c621741e79623beb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
-                "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
+                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c0125896dbb151380ab47e96c621741e79623beb",
+                "reference": "c0125896dbb151380ab47e96c621741e79623beb",
                 "shasum": ""
             },
             "require": {
@@ -862,7 +862,7 @@
                 "pseudorandom",
                 "random"
             ],
-            "time": "2016-04-03 06:00:07"
+            "time": "2016-10-17 15:23:22"
         },
         {
             "name": "pelago/emogrifier",
@@ -922,16 +922,16 @@
         },
         {
             "name": "phpseclib/phpseclib",
-            "version": "2.0.3",
+            "version": "2.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpseclib/phpseclib.git",
-                "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370"
+                "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/41f85e9c2582b3f6d1b7d20395fb40c687ad5370",
-                "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/ab8028c93c03cc8d9c824efa75dc94f1db2369bf",
+                "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf",
                 "shasum": ""
             },
             "require": {
@@ -1010,20 +1010,20 @@
                 "x.509",
                 "x509"
             ],
-            "time": "2016-08-18 18:49:14"
+            "time": "2016-10-04 00:57:04"
         },
         {
             "name": "psr/log",
-            "version": "1.0.1",
+            "version": "1.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "5277094ed527a1c4477177d102fe4c53551953e0"
+                "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0",
-                "reference": "5277094ed527a1c4477177d102fe4c53551953e0",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+                "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
                 "shasum": ""
             },
             "require": {
@@ -1057,7 +1057,7 @@
                 "psr",
                 "psr-3"
             ],
-            "time": "2016-09-19 16:02:08"
+            "time": "2016-10-10 12:19:37"
         },
         {
             "name": "ramsey/uuid",
@@ -1390,7 +1390,7 @@
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
@@ -1450,7 +1450,7 @@
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
@@ -1499,16 +1499,16 @@
         },
         {
             "name": "symfony/finder",
-            "version": "v3.1.4",
+            "version": "v3.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577"
+                "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577",
-                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f",
+                "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f",
                 "shasum": ""
             },
             "require": {
@@ -1544,20 +1544,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-26 12:04:02"
+            "time": "2016-09-28 00:11:12"
         },
         {
             "name": "symfony/process",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "05a03ed27073638658cab9405d99a67dd1014987"
+                "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/05a03ed27073638658cab9405d99a67dd1014987",
-                "reference": "05a03ed27073638658cab9405d99a67dd1014987",
+                "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
+                "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
                 "shasum": ""
             },
             "require": {
@@ -1593,7 +1593,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2016-09-06 10:55:00"
+            "time": "2016-09-29 14:03:54"
         },
         {
             "name": "tedivm/jshrink",
@@ -4329,16 +4329,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84"
+                "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/005bf10c156335ede2e89fb9a9ee10a0b742bc84",
-                "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84",
+                "url": "https://api.github.com/repos/symfony/config/zipball/f8b1922bbda9d2ac86aecd649399040bce849fde",
+                "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde",
                 "shasum": ""
             },
             "require": {
@@ -4378,20 +4378,20 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
-            "time": "2016-08-16 14:56:08"
+            "time": "2016-09-14 20:31:12"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9"
+                "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0a732a9cafc30e54077967da4d019e1d618a8cb9",
-                "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ee9ec9ac2b046462d341e9de7c4346142d335e75",
+                "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75",
                 "shasum": ""
             },
             "require": {
@@ -4441,11 +4441,11 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "time": "2016-09-06 23:19:39"
+            "time": "2016-09-24 09:47:20"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v3.1.4",
+            "version": "v3.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stopwatch.git",
@@ -4494,7 +4494,7 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.8.11",
+            "version": "v2.8.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
@@ -4590,7 +4590,7 @@
     "prefer-stable": true,
     "prefer-lowest": false,
     "platform": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "lib-libxml": "*",
         "ext-ctype": "*",
         "ext-gd": "*",
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json
index 629afd442a46e7549206c1520b1b6c75f024dcb1..00888c7baf74990c6ba4d98ba6569c210ba08c7e 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json
+++ b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json
@@ -2,7 +2,7 @@
   "name": "magento/module-test-module-integration-from-config",
   "description": "test integration create from config",
   "require": {
-    "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+    "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
     "magento/framework": "0.42.0-beta8",
     "magento/module-integration": "0.42.0-beta8"
   },
@@ -16,4 +16,4 @@
       ]
     ]
   }
-}
\ No newline at end of file
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json
index 1e2d9c0fa13dd80fcfe69374a7e02700f6b570ea..a9aa5a2ede89ce314a1f2257bc70c6b20b3bb2a0 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json
+++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json
@@ -2,7 +2,7 @@
   "name": "magento/module-test-join-directives",
   "description": "test integration for join directives",
   "require": {
-    "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+    "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
     "magento/framework": "0.42.0-beta8",
     "magento/module-sales": "0.42.0-beta8"
   },
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
index 4191ec1faa959aa1203ee45850c298f1d43bb988..cd02c6d4d7500ef9adf7d17ac9f866bfc8ef0711 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
@@ -713,6 +713,18 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
 
         $this->assertNotNull($response['items'][0]['sku']);
         $this->assertEquals('simple', $response['items'][0]['sku']);
+
+        $index = null;
+        foreach ($response['items'][0]['custom_attributes'] as $key => $customAttribute) {
+            if ($customAttribute['attribute_code'] == 'category_ids') {
+                $index = $key;
+                break;
+            }
+        }
+        $this->assertNotNull($index, 'Category information wasn\'t set');
+
+        $expectedResult = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ? ['string' => '2'] : ['2'];
+        $this->assertEquals($expectedResult, $response['items'][0]['custom_attributes'][$index]['value']);
     }
 
     /**
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
index e4129a0739912c05dbb8546beab7f028945ad5f6..1a06be978d34c897f10aadd32e7f3e1720b1983b 100644
--- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
@@ -6,12 +6,33 @@
  */
 namespace Magento\ConfigurableProduct\Api;
 
+use Magento\Eav\Model\AttributeRepository;
+
 class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
 {
     const SERVICE_NAME = 'configurableProductLinkManagementV1';
     const SERVICE_VERSION = 'V1';
     const RESOURCE_PATH = '/V1/configurable-products';
 
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @var AttributeRepository
+     */
+    protected $attributeRepository;
+
+    /**
+     * Execute per test initialization
+     */
+    public function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->attributeRepository = $this->objectManager->get(\Magento\Eav\Model\AttributeRepository::class);
+    }
+
     /**
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
      */
@@ -40,14 +61,76 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
     }
 
     /**
-     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/delete_association.php
      */
     public function testAddChild()
     {
         $productSku = 'configurable';
         $childSku = 'simple_77';
+        $res = $this->addChild($productSku, $childSku);
+        $this->assertTrue($res);
+    }
+
+    /**
+     * Test the full flow of creating a configurable product and adding a child via REST
+     *
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
+     */
+    public function testAddChildFullRestCreation()
+    {
+        $productSku = 'configurable-product-sku';
+        $childSku = 'simple-product-sku';
+
+        $this->createConfigurableProduct($productSku);
+        $attribute = $this->attributeRepository->get('catalog_product', 'test_configurable');
+        $attributeValue = $attribute->getOptions()[1]->getValue();
+        $this->addOptionToConfigurableProduct($productSku, $attribute->getAttributeId(), $attributeValue);
+        $this->createSimpleProduct($childSku, $attributeValue);
+        $res = $this->addChild($productSku, $childSku);
+        $this->assertTrue($res);
+
+        // confirm that the simple product was added
+        $children = $this->getChildren($productSku);
+        $added = false;
+        foreach ($children as $child) {
+            if ($child['sku'] == $childSku) {
+                $added = true;
+                break;
+            }
+        }
+        $this->assertTrue($added);
+
+        // clean up products
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1DeleteById',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['sku' => $productSku]);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $childSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1DeleteById',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['sku' => $childSku]);
+    }
+
+    private function addChild($productSku, $childSku)
+    {
         $serviceInfo = [
             'rest' => [
                 'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/child',
@@ -59,8 +142,90 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
                 'operation' => self::SERVICE_NAME . 'AddChild'
             ]
         ];
-        $res = $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]);
-        $this->assertTrue($res);
+        return $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]);
+    }
+
+    protected function createConfigurableProduct($productSku)
+    {
+        $requestData = [
+            'product' => [
+                'sku' => $productSku,
+                'name' => 'configurable-product-' . $productSku,
+                'type_id' => 'configurable',
+                'price' => 50,
+                'attribute_set_id' => 4
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    protected function addOptionToConfigurableProduct($productSku, $attributeId, $attributeValue)
+    {
+        $requestData = [
+            'sku' => $productSku,
+            'option' => [
+                'attribute_id' => $attributeId,
+                'label' => 'test_configurable',
+                'position' => 0,
+                'is_use_default' => true,
+                'values' => [
+                    ['value_index' => $attributeValue],
+                ]
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/configurable-products/'. $productSku .'/options',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'configurableProductOptionRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'configurableProductOptionRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    protected function createSimpleProduct($sku, $attributeValue)
+    {
+        $requestData = [
+            'product' => [
+                'sku' => $sku,
+                'name' => 'simple-product-' . $sku,
+                'type_id' => 'simple',
+                'attribute_set_id' => 4,
+                'price' => 3.62,
+                'status' => 1,
+                'visibility' => 4,
+                'custom_attributes' => [
+                    ['attribute_code' => 'test_configurable', 'value' => $attributeValue],
+                ]
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
     }
 
     /**
@@ -93,7 +258,7 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
 
     /**
      * @param string $productSku
-     * @return string
+     * @return string[]
      */
     protected function getChildren($productSku)
     {
diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json
index 512c5bc8d5df666ced655806af0da64952d0f4ef..cef145167860c8ebad9695d870b6cc73580e47f3 100644
--- a/dev/tests/functional/composer.json
+++ b/dev/tests/functional/composer.json
@@ -1,7 +1,7 @@
 {
     "require": {
         "magento/mtf": "1.0.0-rc48",
-        "php": "~5.6.0|7.0.2|~7.0.6",
+        "php": "~5.6.5|7.0.2|~7.0.6",
         "phpunit/phpunit": "~4.8.0|~5.5.0",
         "phpunit/phpunit-selenium": ">=1.2"
     },
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php
index 29361ced38bcc6b4ba344e2191f3c963eb92576d..fb22754faf483aa32b97d3e1672aeb17d58bec26 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php
@@ -19,7 +19,7 @@ class Template extends Block
      *
      * @var string
      */
-    protected $spinner = '[data-role="spinner"]';
+    protected $spinner = '#container [data-role="spinner"]';
 
     /**
      * Magento loader.
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml
index 269bff796c7bc618e4c257046426e35ab7a25eaa..accacc60fc5c07c386d02fdd4b038c15f6dcc166 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml
@@ -8,26 +8,31 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Backend\Test\TestCase\GlobalSearchEntityTest" summary="Global Search Backend " ticketId="MAGETWO-28457">
         <variation name="GlobalSearchEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">search shows admin preview</data>
             <data name="search/data/query" xsi:type="string">Some search term</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchPreview" />
         </variation>
         <variation name="GlobalSearchEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">search with 2 sign return no results</data>
             <data name="search/data/query" xsi:type="string">:)</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchNoRecordsFound" />
         </variation>
         <variation name="GlobalSearchEntityTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">search product by sku</data>
             <data name="search/data/query" xsi:type="string">orderInjectable::default::product::sku</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchProductName" />
         </variation>
         <variation name="GlobalSearchEntityTestVariation4">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">search existed customer</data>
             <data name="search/data/query" xsi:type="string">customer::johndoe_unique::lastname</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchCustomerName" />
         </variation>
         <variation name="GlobalSearchEntityTestVariation5">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">search order (by order id)</data>
             <data name="search/data/query" xsi:type="string">orderInjectable::default::id</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchOrderId" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml
index 03e0ba330fa3b74e2a33c2983655ced95cf3dbfe..86b5ff79d648c0807a2bc346e3431fc2a7c975a2 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Braintree\Test\TestCase\CreateOrderWithPayPalBraintreeVaultBackendTest" summary="Checkout with PayPal Braintree Vault token from Admin">
         <variation name="CreateOrderWithPayPalBraintreeVaultBackendTestVariation1" summary="Checkout with PayPal Braintree Vault token from Admin" ticketId="MAGETWO-59259">
-            <data name="tag" xsi:type="string">est_type:3rd_party_test, severity:S0</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
index 23fc729edb99f9645f7587d8e350464c81083fcd..f8ffa51982f1fae4d34a6290e1bebce28ba85712 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
@@ -30,5 +30,25 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
         </variation>
+        <variation name="OnePageCheckoutWithDiscountTestVariation2" summary="Checkout with 100% discount and free shipping if Braintree through PayPal is enabled" ticketId="MAGETWO-59940">
+            <data name="description" xsi:type="string">Use saved for Braintree credit card on checkout</data>
+            <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
+            <data name="customer/dataset" xsi:type="string">default</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data>
+            <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
+            <data name="checkoutMethod" xsi:type="string">login</data>
+            <data name="shipping/shipping_service" xsi:type="string">Free Shipping</data>
+            <data name="shipping/shipping_method" xsi:type="string">Free</data>
+            <data name="payment/method" xsi:type="string">free</data>
+            <data name="prices" xsi:type="array">
+                <item name="grandTotal" xsi:type="string">0.00</item>
+            </data>
+            <data name="configData" xsi:type="string">braintree, braintree_use_vault, freeshipping</data>
+            <data name="status" xsi:type="string">Pending</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
+            <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php
index e94ec38d010f3d519e8ab2e06c5fdd21dccd544c..5cf84cf6764270708bd30327f2596253f510370d 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php
@@ -8,7 +8,6 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Section;
 
 use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Section\Bundle\Option;
-use Magento\Mtf\Client\Element;
 use Magento\Mtf\Client\ElementInterface;
 use Magento\Mtf\Client\Locator;
 use Magento\Ui\Test\Block\Adminhtml\Section;
@@ -53,6 +52,13 @@ class Bundle extends Section
      */
     protected $bundleOptionRow = './tr[%d]';
 
+    /**
+     * Selector for trash can button in bundle option row.
+     *
+     * @var string
+     */
+    protected $deleteOption = './tr[%d]//*[@data-index="delete_button"]';
+
     /**
      * Get bundle options block.
      *
@@ -83,17 +89,49 @@ class Bundle extends Section
         if (!isset($fields['bundle_selections'])) {
             return $this;
         }
+
+        $context = $this->_rootElement->find($this->bundleOptions, Locator::SELECTOR_XPATH);
+
+        if (isset($fields['bundle_selections']['value']['bundle_options'])) {
+            foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => $bundleOption) {
+                $count = $key + 1;
+                $itemOption = $context->find(sprintf($this->openOption, $count), Locator::SELECTOR_XPATH);
+                $isContent = $context->find(sprintf($this->optionContent, $count), Locator::SELECTOR_XPATH)
+                    ->isVisible();
+                if ($itemOption->isVisible() && !$isContent) {
+                    $itemOption->click();
+                } elseif (!$itemOption->isVisible()) {
+                    $this->_rootElement->find($this->addNewOption)->click();
+                }
+                $this->getBundleOptionBlock($count, $context)->fillOption($bundleOption);
+            }
+        }
+
+        if (isset($fields['bundle_selections']['value']['bundle_options_delete'])) {
+            $this->deleteFieldsData($fields['bundle_selections']['value']['bundle_options_delete']);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Delete some bundle options.
+     *
+     * @param array $fields
+     * @return $this
+     */
+    public function deleteFieldsData(array $fields)
+    {
         $context = $this->_rootElement->find($this->bundleOptions, Locator::SELECTOR_XPATH);
-        foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => $bundleOption) {
-            $count = $key + 1;
-            $itemOption = $context->find(sprintf($this->openOption, $count), Locator::SELECTOR_XPATH);
-            $isContent = $context->find(sprintf($this->optionContent, $count), Locator::SELECTOR_XPATH)->isVisible();
-            if ($itemOption->isVisible() && !$isContent) {
-                $itemOption->click();
-            } elseif (!$itemOption->isVisible()) {
-                $this->_rootElement->find($this->addNewOption)->click();
+        foreach (array_keys($fields) as $key) {
+            $bundleOptionIndex = $key + 1;
+            $deleteOption = $context->find(
+                sprintf($this->deleteOption, $bundleOptionIndex),
+                Locator::SELECTOR_XPATH
+            );
+            if ($deleteOption->isVisible()) {
+                $deleteOption->click();
             }
-            $this->getBundleOptionBlock($count, $context)->fillOption($bundleOption);
         }
         return $this;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml
index 3a124f0cc38b5a76620fce7265890775a047d79f..e8485df0733de8385e31f55f2c95db9b0061848c 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml
@@ -21,6 +21,10 @@
         <selection_qty>
             <selector>[name$='[selection_qty]']</selector>
         </selection_qty>
+        <user_defined>
+            <selector>[name$='[selection_can_change_qty]']</selector>
+            <input>checkbox</input>
+        </user_defined>
         <getProductName>
             <selector>span[data-index="name"]</selector>
         </getProductName>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
index db349d16a86c673f7fcd89d57e94b42461f51012..ec96c5b27f50a39ffcfc6f88bfc5d1299a17af83 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
@@ -6,11 +6,10 @@
 
 namespace Magento\Bundle\Test\Block\Catalog\Product;
 
+use Magento\Bundle\Test\Block\Catalog\Product\View\Summary;
 use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Bundle;
-use Magento\Bundle\Test\Fixture\BundleProduct;
 use Magento\Mtf\Client\Locator;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Fixture\InjectableFixture;
 
 /**
  * Class View
@@ -46,6 +45,13 @@ class View extends \Magento\Catalog\Test\Block\Product\View
      */
     protected $newsletterFormSelector = '#newsletter-validate-detail[novalidate="novalidate"]';
 
+    /**
+     * Summary Block selector.
+     *
+     * @var string
+     */
+    private $summaryBlockSelector = '#bundleSummary';
+
     /**
      * Get bundle options block.
      *
@@ -59,6 +65,19 @@ class View extends \Magento\Catalog\Test\Block\Product\View
         );
     }
 
+    /**
+     * Get bundle Summary block.
+     *
+     * @return Summary
+     */
+    public function getBundleSummaryBlock()
+    {
+        return $this->blockFactory->create(
+            Summary::class,
+            ['element' => $this->_rootElement->find($this->summaryBlockSelector)]
+        );
+    }
+
     /**
      * Click "Customize and add to cart button".
      *
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php
new file mode 100644
index 0000000000000000000000000000000000000000..76a46bfe3088a47f79dafa7f8c71d649e324b130
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Block\Catalog\Product\View;
+
+use Magento\Bundle\Test\Block\Catalog\Product\View\Summary\ConfiguredPrice;
+
+/**
+ * Bundle Summary block.
+ */
+class Summary extends \Magento\Catalog\Test\Block\Product\View
+{
+    /**
+     * Configured Price block selector.
+     *
+     * @var string
+     */
+    private $configuredPriceBlockSelector = '.price-configured_price';
+
+    /**
+     * Get configured price block.
+     *
+     * @return ConfiguredPrice
+     */
+    public function getConfiguredPriceBlock()
+    {
+        return $this->blockFactory->create(
+            ConfiguredPrice::class,
+            ['element' => $this->_rootElement->find($this->configuredPriceBlockSelector)]
+        );
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php
new file mode 100644
index 0000000000000000000000000000000000000000..30effcdeef060af5a81f92ed1a463e3f69bc57a0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Block\Catalog\Product\View\Summary;
+
+/**
+ * This class is used to access the price related information from the storefront.
+ */
+class ConfiguredPrice extends \Magento\Catalog\Test\Block\AbstractPriceBlock
+{
+    /**
+     * Mapping for different type of price.
+     *
+     * @var array
+     */
+    protected $mapTypePrices = [
+        'configured_price' => [
+            'selector' => '.price',
+        ]
+    ];
+
+    /**
+     * This method returns the price represented by the block.
+     *
+     * @param string $currency
+     * @return string|null
+     */
+    public function getPrice($currency = '$')
+    {
+        return $this->getTypePrice('configured_price', $currency);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
index 23ac2d25ee017dab9e869e35b1dea7cac4abb94c..ccf47420b11521f9f5bf1a6c4b0f347d86c1baa0 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
@@ -107,11 +107,11 @@ class Bundle extends Block
 
             /** @var SimpleElement $optionElement */
             $optionElement = $listFormOptions[$title];
-            $getTypeData = 'get' . $this->optionNameConvert($option['type']) . 'Data';
+            $getTypeData = 'get' . $this->optionNameConvert($option['frontend_type']) . 'Data';
 
             $optionData = $this->$getTypeData($optionElement);
             $optionData['title'] = $title;
-            $optionData['type'] = $option['type'];
+            $optionData['type'] = $option['frontend_type'];
             $optionData['is_require'] = $optionElement->find($this->required, Locator::SELECTOR_XPATH)->isVisible()
                 ? 'Yes'
                 : 'No';
@@ -266,7 +266,7 @@ class Bundle extends Block
             /** @var Option $optionBlock */
             $optionBlock = $this->blockFactory->create(
                 'Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\\'
-                . $this->optionNameConvert($option['type']),
+                . $this->optionNameConvert($option['frontend_type']),
                 ['element' => $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)]
             );
             $optionBlock->fillOption($option['value']);
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php
new file mode 100644
index 0000000000000000000000000000000000000000..7506b81f8471c7ad8130aa45e31a1680cc26cd34
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Element;
+
+use Magento\Mtf\Client\Element\SimpleElement;
+
+/**
+ * Typified element class for qty element.
+ */
+class Qty extends SimpleElement
+{
+    /**
+     * "Backspace" key code.
+     */
+    const BACKSPACE = "\xEE\x80\x83";
+
+    /**
+     * "RIGHT" key code.
+     */
+    const RIGHT = "\xEE\x80\x94";
+
+    /**
+     * Set the value.
+     *
+     * @param string|array $value
+     * @return void
+     */
+    public function setValue($value)
+    {
+        $this->keys([self::RIGHT, self::BACKSPACE, $value]);
+        $this->context->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fa54759b8e579728cdf2ea053d94481eb520503
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option;
+
+use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option;
+
+/**
+ * Bundle option hidden type.
+ */
+class Hidden extends Option
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml
new file mode 100644
index 0000000000000000000000000000000000000000..356f6a52d6b0c296abc0eb857fe2d8b3dccc4b84
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<mapping strict="1">
+    <fields>
+        <qty>
+            <selector>//input[contains(@class,"qty")]</selector>
+            <strategy>xpath</strategy>
+            <class>Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Element\Qty</class>
+        </qty>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php
index ddd8e35a301d6907cf75c3790cefaf6d79b394da..411c53d982fcb8a2445e8a5d214383670ec7bf4a 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php
@@ -61,7 +61,7 @@ class AssertBundleItemsOnProductPage extends AbstractAssertForm
         foreach ($bundleOptions as $optionKey => $bundleOption) {
             $optionData = [
                 'title' => $bundleOption['title'],
-                'type' => $bundleOption['type'],
+                'type' => $bundleOption['frontend_type'],
                 'is_require' => $bundleOption['required'],
             ];
 
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php
new file mode 100644
index 0000000000000000000000000000000000000000..69e694abd261ab4ca4e4102f542b72f612552d5b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Constraint;
+
+use Magento\Bundle\Test\Fixture\BundleProduct;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Mtf\Fixture\FixtureInterface;
+
+/**
+ * Assert bundle product form.
+ */
+class AssertBundleOptionsDeleted extends AbstractConstraint
+{
+    /**
+     * Assert that displayed price view for bundle product on product page equals passed from fixture.
+     * @param BundleProduct $product
+     * @param BundleProduct $originalProduct
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductEdit $productPage
+     * @return void
+     */
+    public function processAssert(
+        BundleProduct $product,
+        BundleProduct $originalProduct,
+        CatalogProductIndex $productGrid,
+        CatalogProductEdit $productPage
+    ) {
+        $filter = ['sku' => $product->getSku()];
+        $productGrid->open();
+        $productGrid->getProductGrid()->searchAndOpen($filter);
+
+        $productData = $product->getData()['bundle_selections']['bundle_options'];
+        $originalProductData = $originalProduct->getData()['bundle_selections']['bundle_options'];
+        $formData = $productPage->getProductForm()->getData($product)['bundle_selections'];
+
+        $productDataLength = count($productData);
+        $formDataLength = count($productData);
+        \PHPUnit_Framework_Assert::assertEquals($productDataLength, $formDataLength);
+
+        foreach ($productData as $index => $option) {
+            $productAssociatedDataLength = count($option['assigned_products']);
+            $formAssociatedDataLength = count($formData[$index]['assigned_products']);
+            \PHPUnit_Framework_Assert::assertEquals($productAssociatedDataLength, $formAssociatedDataLength);
+
+            foreach ($option['assigned_products'] as $productIndex => $associatedProduct) {
+                $associatedProduct['data']['getProductName'] =
+                    $originalProductData[$index+1]['assigned_products'][$productIndex]['search_data']['name'];
+                $associatedProduct = $associatedProduct['data'];
+                $errorAssociatedProducts = array_diff(
+                    $associatedProduct,
+                    $formData[$index]['assigned_products'][$productIndex]
+                );
+                \PHPUnit_Framework_Assert::assertCount(0, $errorAssociatedProducts);
+            }
+
+            unset($option['assigned_products']);
+            unset($formData[$index]['assigned_products']);
+            $errorFields = array_diff($option, $formData[$index]);
+            \PHPUnit_Framework_Assert::assertCount(0, $errorFields);
+        }
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Bundle options were not deleted correctly. There is difference with expected options';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..756fe75eea7db1f943f3a8c490b8eb2427e63095
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\Constraint;
+
+use Magento\Bundle\Test\Fixture\BundleProduct;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Catalog\Test\TestStep\ConfigureProductOnProductPageStep;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Mtf\TestStep\TestStepFactory;
+
+/**
+ * Assert calculated price after configure bundle product on product page.
+ */
+class AssertBundlePriceCalculatedOnProductPage extends AbstractConstraint
+{
+    /**
+     * Assert calculated price after configure bundle product on product page.
+     *
+     * @param TestStepFactory $stepFactory
+     * @param BundleProduct $product
+     * @param CatalogProductView $catalogProductView
+     */
+    public function processAssert(
+        TestStepFactory $stepFactory,
+        BundleProduct $product,
+        CatalogProductView $catalogProductView
+    ) {
+        $stepFactory->create(ConfigureProductOnProductPageStep::class, ['product' => $product])->run();
+
+        //Process assertions
+        $this->assertPrice($product, $catalogProductView);
+    }
+
+    /**
+     * Assert prices on the product view Page.
+     *
+     * @param BundleProduct $product
+     * @param CatalogProductView $productView
+     * @return void
+     */
+    protected function assertPrice(BundleProduct $product, CatalogProductView $productView)
+    {
+        $checkoutData = $product->getCheckoutData();
+        \PHPUnit_Framework_Assert::assertEquals(
+            $checkoutData['cartItem']['configuredPrice'],
+            $productView->getBundleViewBlock()->getBundleSummaryBlock()->getConfiguredPriceBlock()->getPrice(),
+            'Bundle price calculated is not correct.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Bundle price calculates right on product view page.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
index 4a4aea603cf8619d0d12335f496b1e6a9e50fd33..6a3572ab15a7af1e9a84ee06841cedf772bc9283 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php
@@ -68,6 +68,10 @@ class Curl extends ProductCurl implements BundleProductInterface
             'gift_message_available' => [
                 'Yes' => 1,
                 'No' => 0
+            ],
+            'user_defined' => [
+                'Yes' => 1,
+                'No' => 0
             ]
         ];
     }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php
index 634f6c00a6cc87aac749b187fafd2452e3fd98fb..2fbdaffefc7a33192c73309d0dde80729311b5d8 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php
@@ -64,25 +64,8 @@ class Webapi extends SimpleProductWebapi implements BundleProductInterface
                     'title' => $bundleOption['title'],
                     'type' => $bundleOption['type'],
                     'required' => $bundleOption['required'],
-                    'product_links' => [],
+                    'product_links' => $this->prepareLinksInfo($bundleSelections, $key)
                 ];
-
-                $productLinksInfo = $bundleOption['assigned_products'];
-                $products = $bundleSelections['products'][$key];
-                foreach ($productLinksInfo as $linkKey => $productLink) {
-                    $product = $products[$linkKey];
-                    $bundleProductOptions[$key]['product_links'][] = [
-                        'sku' => $product->getSku(),
-                        'qty' => $productLink['data']['selection_qty'],
-                        'is_default' => false,
-                        'price' => isset($productLink['data']['selection_price_value'])
-                            ? $productLink['data']['selection_price_value']
-                            : null,
-                        'price_type' => isset($productLink['data']['selection_price_type'])
-                            ? $productLink['data']['selection_price_type']
-                            : null,
-                    ];
-                }
             }
         }
 
@@ -92,6 +75,39 @@ class Webapi extends SimpleProductWebapi implements BundleProductInterface
         unset($this->fields['product']['bundle_selections']);
     }
 
+    /**
+     * Prepare links info field.
+     *
+     * @param array $bundleSelections
+     * @param int $key
+     * @return array
+     */
+    private function prepareLinksInfo(array $bundleSelections, $key)
+    {
+        $result = [];
+        $productLinksInfo = $bundleSelections['bundle_options'][$key]['assigned_products'];
+        $products = $bundleSelections['products'][$key];
+        foreach ($productLinksInfo as $linkKey => $productLink) {
+            $product = $products[$linkKey];
+            $result[] = [
+                'sku' => $product->getSku(),
+                'qty' => $productLink['data']['selection_qty'],
+                'is_default' => false,
+                'price' => isset($productLink['data']['selection_price_value'])
+                    ? $productLink['data']['selection_price_value']
+                    : null,
+                'price_type' => isset($productLink['data']['selection_price_type'])
+                    ? $productLink['data']['selection_price_type']
+                    : null,
+                'can_change_quantity' => isset($productLink['data']['user_defined'])
+                    ? $productLink['data']['user_defined']
+                    : 0,
+            ];
+        }
+
+        return $result;
+    }
+
     /**
      * Parse response.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
index 2b5e9a437b32bdec615fd9e2a928b3784ba68fb4..6a507a7a99b437a793b4096f8f10d9e33ccb825a 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
@@ -225,5 +225,27 @@
                 <item name="dataset" xsi:type="string">bundle_fixed_100_dollar</item>
             </field>
         </dataset>
+
+        <dataset name="with_3_bundle_options">
+            <field name="name" xsi:type="string">Bundle with 3 options %isolation%</field>
+            <field name="url_key" xsi:type="string">with_3_bundle_options-%isolation%</field>
+            <field name="sku" xsi:type="string">sku_with_3_bundle_options_%isolation%</field>
+            <field name="sku_type" xsi:type="string">No</field>
+            <field name="price_type" xsi:type="string">No</field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">100</item>
+            </field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="bundle_selections" xsi:type="array">
+                <item name="dataset" xsi:type="string">with_3_options</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml
index 3e9b055c48ca5a1bfa5df3410ec48ef708a71fa7..c19a78f64894e17b256a1ec13828b0612bdada08 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml
@@ -12,6 +12,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -46,6 +47,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -84,6 +86,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -122,6 +125,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -160,6 +164,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -187,6 +192,7 @@
                 <item name="1" xsi:type="array">
                     <item name="title" xsi:type="string">Radio Button Option</item>
                     <item name="type" xsi:type="string">Radio Buttons</item>
+                    <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -214,6 +220,7 @@
                 <item name="2" xsi:type="array">
                     <item name="title" xsi:type="string">Checkbox Option</item>
                     <item name="type" xsi:type="string">Checkbox</item>
+                    <item name="frontend_type" xsi:type="string">Checkbox</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -241,6 +248,7 @@
                 <item name="3" xsi:type="array">
                     <item name="title" xsi:type="string">Multiple Select Option</item>
                     <item name="type" xsi:type="string">Multiple Select</item>
+                    <item name="frontend_type" xsi:type="string">Multiple Select</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -291,6 +299,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -314,6 +323,7 @@
                 <item name="1" xsi:type="array">
                     <item name="title" xsi:type="string">Radio Button Option</item>
                     <item name="type" xsi:type="string">Radio Buttons</item>
+                    <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -337,6 +347,7 @@
                 <item name="2" xsi:type="array">
                     <item name="title" xsi:type="string">Checkbox Option</item>
                     <item name="type" xsi:type="string">Checkbox</item>
+                    <item name="frontend_type" xsi:type="string">Checkbox</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -360,6 +371,7 @@
                 <item name="3" xsi:type="array">
                     <item name="title" xsi:type="string">Multiple Select Option</item>
                     <item name="type" xsi:type="string">Multiple Select</item>
+                    <item name="frontend_type" xsi:type="string">Multiple Select</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -406,6 +418,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">No</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -433,6 +446,7 @@
                 <item name="1" xsi:type="array">
                     <item name="title" xsi:type="string">Radio Button Option</item>
                     <item name="type" xsi:type="string">Radio Buttons</item>
+                    <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                     <item name="required" xsi:type="string">No</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -475,6 +489,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -513,6 +528,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -547,6 +563,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -572,6 +589,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -610,6 +628,7 @@
                 <item name="0" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -633,6 +652,7 @@
                 <item name="1" xsi:type="array">
                     <item name="title" xsi:type="string">Drop-down Option</item>
                     <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Drop-down</item>
                     <item name="required" xsi:type="string">Yes</item>
                     <item name="assigned_products" xsi:type="array">
                         <item name="0" xsi:type="array">
@@ -665,5 +685,197 @@
                 </item>
             </field>
         </dataset>
+
+        <dataset name="with_3_options">
+            <field name="bundle_options" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 1</item>
+                    <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="required" xsi:type="string">No</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">1</item>
+                                <item name="selection_price_value" xsi:type="string">1</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+                <item name="1" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 2</item>
+                    <item name="type" xsi:type="string">Radio Buttons</item>
+                    <item name="required" xsi:type="string">No</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">20</item>
+                                <item name="selection_price_value" xsi:type="string">20</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                        <item name="1" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">21</item>
+                                <item name="selection_price_value" xsi:type="string">21</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                        <item name="2" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">22</item>
+                                <item name="selection_price_value" xsi:type="string">22</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+                <item name="2" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 3</item>
+                    <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="required" xsi:type="string">No</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">3</item>
+                                <item name="selection_price_value" xsi:type="string">3</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="products" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                </item>
+                <item name="1" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                    <item name="1" xsi:type="string">catalogProductSimple::product_100_dollar</item>
+                    <item name="2" xsi:type="string">catalogProductSimple::product_without_category</item>
+                </item>
+                <item name="2" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                </item>
+            </field>
+        </dataset>
+
+        <dataset name="with_3_options_delete">
+            <field name="bundle_options_delete" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 1</item>
+                    <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="required" xsi:type="string">No</item>
+                </item>
+            </field>
+            <field name="bundle_options" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 2</item>
+                    <item name="type" xsi:type="string">Radio Buttons</item>
+                    <item name="required" xsi:type="string">No</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">20</item>
+                                <item name="selection_price_value" xsi:type="string">20</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                        <item name="1" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">21</item>
+                                <item name="selection_price_value" xsi:type="string">21</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                        <item name="2" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">22</item>
+                                <item name="selection_price_value" xsi:type="string">22</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+                <item name="1" xsi:type="array">
+                    <item name="title" xsi:type="string">Option 3</item>
+                    <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="required" xsi:type="string">No</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">3</item>
+                                <item name="selection_price_value" xsi:type="string">3</item>
+                                <item name="selection_price_type" xsi:type="string">Fixed</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="products" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                    <item name="1" xsi:type="string">catalogProductSimple::product_100_dollar</item>
+                    <item name="2" xsi:type="string">catalogProductSimple::product_without_category</item>
+                </item>
+                <item name="1" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                </item>
+            </field>
+        </dataset>
+
+        <dataset name="one_required_option_with_one_item">
+            <field name="bundle_options" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="title" xsi:type="string">Drop-down Option</item>
+                    <item name="type" xsi:type="string">Drop-down</item>
+                    <item name="frontend_type" xsi:type="string">Hidden</item>
+                    <item name="required" xsi:type="string">Yes</item>
+                    <item name="assigned_products" xsi:type="array">
+                        <item name="0" xsi:type="array">
+                            <item name="search_data" xsi:type="array">
+                                <item name="name" xsi:type="string">%product_name%</item>
+                            </item>
+                            <item name="data" xsi:type="array">
+                                <item name="selection_qty" xsi:type="string">1</item>
+                                <item name="user_defined" xsi:type="string">Yes</item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="products" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="0" xsi:type="string">catalogProductSimple::default</item>
+                </item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
index 3e7550b9d784e3858bd9800e66b88b8c60326b1b..d68fb0d0b83f8ff3520508a1c72bc51dcf8ff1c1 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
@@ -13,6 +13,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -27,6 +28,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -47,6 +49,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -67,6 +70,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_10_dollar</item>
                         </item>
@@ -87,6 +91,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">Simple Product</item>
                         </item>
@@ -107,6 +112,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -114,6 +120,7 @@
                     <item name="1" xsi:type="array">
                         <item name="title" xsi:type="string">Radio Button Option</item>
                         <item name="type" xsi:type="string">Radio Buttons</item>
+                        <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -128,6 +135,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -192,6 +200,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -212,6 +221,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_10_dollar</item>
                         </item>
@@ -242,6 +252,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -249,6 +260,7 @@
                     <item name="1" xsi:type="array">
                         <item name="title" xsi:type="string">Radio Button Option</item>
                         <item name="type" xsi:type="string">Radio Buttons</item>
+                        <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -256,6 +268,7 @@
                     <item name="2" xsi:type="array">
                         <item name="title" xsi:type="string">Checkbox Option</item>
                         <item name="type" xsi:type="string">Checkbox</item>
+                        <item name="frontend_type" xsi:type="string">Checkbox</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -263,6 +276,7 @@
                     <item name="3" xsi:type="array">
                         <item name="title" xsi:type="string">Multiple Select Option</item>
                         <item name="type" xsi:type="string">Multiple</item>
+                        <item name="frontend_type" xsi:type="string">Multiple</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -315,6 +329,7 @@
                     <item name="0" xsi:type="array">
                         <item name="title" xsi:type="string">Drop-down Option</item>
                         <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Drop-down</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -322,6 +337,7 @@
                     <item name="1" xsi:type="array">
                         <item name="title" xsi:type="string">Radio Button Option</item>
                         <item name="type" xsi:type="string">Radio Buttons</item>
+                        <item name="frontend_type" xsi:type="string">Radio Buttons</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -329,6 +345,7 @@
                     <item name="2" xsi:type="array">
                         <item name="title" xsi:type="string">Checkbox Option</item>
                         <item name="type" xsi:type="string">Checkbox</item>
+                        <item name="frontend_type" xsi:type="string">Checkbox</item>
                         <item name="value" xsi:type="array">
                             <item name="name" xsi:type="string">product_100_dollar</item>
                         </item>
@@ -357,5 +374,24 @@
                 </item>
             </field>
         </dataset>
+
+        <dataset name="one_required_option_with_one_item">
+            <field name="options" xsi:type="array">
+                <item name="bundle_options" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">Drop-down Option</item>
+                        <item name="type" xsi:type="string">Drop-down</item>
+                        <item name="frontend_type" xsi:type="string">Hidden</item>
+                        <item name="value" xsi:type="array">
+                            <item name="name" xsi:type="string">Simple Product</item>
+                            <item name="qty" xsi:type="string">3</item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="cartItem" xsi:type="array">
+                <item name="configuredPrice" xsi:type="string">1680</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
index 211e09861995f27e22a446b93e465a7197936965..56b2ceb917fe6d46296e408954bdfc88380af5a3 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Bundle\Test\TestCase\CreateBundleProductEntityTest" summary="Create Bundle Product" ticketId="MAGETWO-24118">
         <variation name="CreateBundleProductEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create default bundle with dynamic options</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
@@ -44,7 +45,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductNotSearchableBySku" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation3">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="description" xsi:type="string">Create dynamic bundle with price randle and all types options</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
@@ -74,6 +75,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceType" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation4">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create fixed bundle</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
@@ -97,6 +99,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundleItemsOnProductPage" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation5">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create fixed bundle with all types options</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
@@ -161,6 +164,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceView" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation7" summary="Check bundle dynamic product with tier price">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
             <data name="product/data/sku_type" xsi:type="string">Yes</data>
@@ -187,6 +191,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertTierPriceOnBundleProductPage" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation8">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create dynamic bundle with special price</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Bundle Dynamic %isolation%</data>
@@ -236,6 +241,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceType" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation11">
+            <data name="issue" xsi:type="string">MAGETWO-52788: Dynamic Rows: support status being changed</data>
             <data name="description" xsi:type="string">Create fixed product with checkout first option</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data>
@@ -334,6 +340,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductPage" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation17" summary="Create fixed bundle product with tier price and custom options with fixed and percent price">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data>
             <data name="product/data/sku_type" xsi:type="string">No</data>
@@ -359,6 +366,7 @@
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductInCart" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation18" summary="Create dynamic bundle product with tier price for sub-item">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data>
             <data name="product/data/sku_type" xsi:type="string">Yes</data>
@@ -394,6 +402,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" />
         </variation>
         <variation name="CreateBundleProductEntityTestVariation21" summary="Create default fixed bundle with custom Website">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data>
             <data name="product/data/sku_type" xsi:type="string">No</data>
@@ -446,5 +455,17 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductPage" />
         </variation>
+        <variation name="CreateBundleProductEntityTestVariation25" summary="Create Bundle (dynamic) Product with one require option with one item" ticketId="MAGETWO-59841">
+            <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Bundle Dynamic %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">sku_bundle_dynamic_%isolation%</data>
+            <data name="product/data/price_type" xsi:type="string">Yes</data>
+            <data name="product/data/category" xsi:type="string">category_%isolation%</data>
+            <data name="product/data/shipment_type" xsi:type="string">Together</data>
+            <data name="product/data/bundle_selections/dataset" xsi:type="string">one_required_option_with_one_item</data>
+            <data name="product/data/checkout_data/dataset" xsi:type="string">one_required_option_with_one_item</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceCalculatedOnProductPage" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c17360200f44f2fe8875590578c6960ea7757d0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Bundle\Test\TestCase;
+
+use Magento\Bundle\Test\Fixture\BundleProduct;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Mtf\TestCase\Injectable;
+
+/**
+ * Test Flow:
+ * 1. Login as admin
+ * 2. Navigate to the Products>Inventory>Catalog
+ * 3. Click on Bundle product in the grid to edit it
+ * 4. Fill in some Bundle Options data according to data set
+ * 5. Delete some Bundle Options data according to data set
+ * 6. Save product
+ * 7. Verify Bundle Options in the updated product
+ *
+ * @group Bundle_Product
+ * @ZephyrId MAGETWO-26195
+ */
+class UpdateBundleOptionsTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    /* end tags */
+
+    /**
+     * Page product on backend
+     *
+     * @var CatalogProductIndex
+     */
+    protected $catalogProductIndex;
+
+    /**
+     * Edit page on backend
+     *
+     * @var CatalogProductEdit
+     */
+    protected $catalogProductEdit;
+
+    /**
+     * Injection data
+     *
+     * @param CatalogProductIndex $catalogProductIndexNewPage
+     * @param CatalogProductEdit $catalogProductEditPage
+     * @return void
+     */
+    public function __inject(
+        CatalogProductIndex $catalogProductIndexNewPage,
+        CatalogProductEdit $catalogProductEditPage
+    ) {
+        $this->catalogProductIndex = $catalogProductIndexNewPage;
+        $this->catalogProductEdit = $catalogProductEditPage;
+    }
+
+    /**
+     * Test update bundle product
+     *
+     * @param BundleProduct $product
+     * @param BundleProduct $originalProduct
+     * @return void
+     */
+    public function test(BundleProduct $product, BundleProduct $originalProduct)
+    {
+        // Preconditions
+        $originalProduct->persist();
+
+        // Steps
+        $filter = ['sku' => $originalProduct->getSku()];
+
+        $this->catalogProductIndex->open();
+        $this->catalogProductIndex->getProductGrid()->searchAndOpen($filter);
+
+        $form = $this->catalogProductEdit->getProductForm();
+        $form->openSection('bundle');
+        $container = $form->getSection('bundle');
+        $containerFields = $product->getData()['bundle_selections']['bundle_options_delete'];
+        $container->deleteFieldsData($containerFields);
+
+        $form->openSection('product-details');
+        $container = $form->getSection('product-details');
+        $containerFields = $product->getData();
+        unset($containerFields['bundle_selections']);
+        $container->setFieldsData($containerFields);
+
+        $this->catalogProductEdit->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..795665d66d2bf7d34438381d3390e94c8458d3b7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Bundle\Test\TestCase\UpdateBundleOptionsTest" summary="Update Bundle Product Options" ticketId="MAGETWO-26195">
+        <variation name="UpdateBundleOptionsTestVariation1">
+            <data name="description" xsi:type="string">Update bundle product options</data>
+            <data name="originalProduct/dataset" xsi:type="string">with_3_bundle_options</data>
+            <data name="product/data/name" xsi:type="string">bundle_3_options_%isolation%</data>
+            <data name="product/data/sku" xsi:type="string">bundle_3_options_%isolation%</data>
+            <data name="product/data/bundle_selections/dataset" xsi:type="string">with_3_options_delete</data>
+            <constraint name="Magento\Bundle\Test\Constraint\AssertBundleOptionsDeleted" />
+        </variation>
+    </testCase>
+</config>
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php
index bf17d216bcf9b479e6279f449e782bc94438600e..8326b1ba4d9ae9b0589b1d55bd973f9db6efe970 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php
@@ -73,6 +73,7 @@ class UpdateBundleProductEntityTest extends Injectable
      */
     public function test(BundleProduct $product, BundleProduct $originalProduct)
     {
+        $this->markTestIncomplete('MAGETWO-56584: [FT] Custom options are not created for product in test');
         // Preconditions
         $originalProduct->persist();
         $originalCategory = $originalProduct->hasData('category_ids')
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc0d0b87f24bba19d2e249fa37be7e59e16cca92
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section;
+
+use Magento\Mtf\Client\Element\SimpleElement;
+use Magento\Mtf\Client\Locator;
+use Magento\Ui\Test\Block\Adminhtml\Section;
+
+/**
+ * Class for product gallery block.
+ */
+class BlockGallery extends Section
+{
+    /**
+     * Selector for image loader container.
+     *
+     * @var string
+     */
+    private $imageLoader = '.image.image-placeholder .file-row';
+
+    /**
+     * Selector for image upload input.
+     *
+     * @var string
+     */
+    private $imageUploadInput = '[name="image"]';
+
+    /**
+     * Upload product images.
+     *
+     * @param array $data
+     * @param SimpleElement|null $element
+     * @return $this
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function setFieldsData(array $data, SimpleElement $element = null)
+    {
+        foreach ($data['image']['value'] as $imageData) {
+            $uploadElement = $element->find($this->imageUploadInput, Locator::SELECTOR_CSS, 'upload');
+            $uploadElement->setValue($imageData['file']);
+            $this->waitForElementNotVisible($this->imageLoader);
+        }
+        return $this;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
index 407b5c9cb20a3b2097ea87e9d1f5a8240e5566b2..3b66164ebe658097e05fdba2e8b53c6cb3d643d2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
@@ -143,7 +143,7 @@
         </fields>
     </attributes>
     <gallery>
-        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\BlockGallery</class>
         <selector>[data-index='block_gallery']</selector>
         <strategy>css selector</strategy>
     </gallery>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
index 3134fda0d2b2b3f98b3e9d0ef5c835e8cb1aad53..de6adb0efd8b21df23cf0531624fa0b90983225d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
@@ -10,7 +10,7 @@ use Magento\Catalog\Test\Block\AbstractConfigureBlock;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Mtf\Client\Locator;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Fixture\InjectableFixture;
+use Magento\Checkout\Test\Block\Cart\Sidebar;
 
 /**
  * Product view block on the product page.
@@ -145,7 +145,14 @@ class View extends AbstractConfigureBlock
      *
      * @var string
      */
-    protected $miniCartBlock = '[data-block="minicart"]';
+    protected $miniCartBlockSelector = '[data-block="minicart"]';
+
+    /**
+     * Minicart block element.
+     *
+     * @var Sidebar
+     */
+    private $miniCartBlock;
 
     /**
      * Success message selector.
@@ -222,21 +229,44 @@ class View extends AbstractConfigureBlock
      */
     public function addToCart(FixtureInterface $product)
     {
-        /** @var \Magento\Checkout\Test\Block\Cart\Sidebar $miniCart */
-        $miniCart = $this->blockFactory->create(
-            \Magento\Checkout\Test\Block\Cart\Sidebar::class,
-            ['element' => $this->browser->find($this->miniCartBlock)]
-        );
+        $this->configure($product);
+        $this->clickAddToCart();
+        $this->getMiniCartBlock()->waitLoader();
+    }
+
+    /**
+     * Configure Product.
+     *
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function configure(FixtureInterface $product)
+    {
         /** @var CatalogProductSimple $product */
         $checkoutData = $product->getCheckoutData();
 
-        $miniCart->waitInit();
+        $this->getMiniCartBlock()->waitInit();
         $this->fillOptions($product);
         if (isset($checkoutData['qty'])) {
             $this->setQty($checkoutData['qty']);
         }
-        $this->clickAddToCart();
-        $miniCart->waitLoader();
+    }
+
+    /**
+     * Get MiniCart block.
+     *
+     * @return Sidebar
+     */
+    private function getMiniCartBlock()
+    {
+        if ($this->miniCartBlock === null) {
+            $this->miniCartBlock = $this->blockFactory->create(
+                Sidebar::class,
+                ['element' => $this->browser->find($this->miniCartBlockSelector)]
+            );
+        }
+
+        return $this->miniCartBlock;
     }
 
     /**
@@ -313,14 +343,8 @@ class View extends AbstractConfigureBlock
     public function braintreePaypalCheckout()
     {
         $currentWindow = $this->browser->getCurrentWindow();
-        /** @var \Magento\Checkout\Test\Block\Cart\Sidebar $miniCart */
-        $miniCart = $this->blockFactory->create(
-            \Magento\Checkout\Test\Block\Cart\Sidebar::class,
-            ['element' => $this->browser->find($this->miniCartBlock)]
-        );
-
-        $miniCart->openMiniCart();
-        $miniCart->clickBraintreePaypalButton();
+        $this->getMiniCartBlock()->openMiniCart();
+        $this->getMiniCartBlock()->clickBraintreePaypalButton();
         return $currentWindow;
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
index 54bf06f70b5f1c0f192b79bda3ade75a85cd37f7..da1ec8f71a1121bceba80b6a3138f77b07663310 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
@@ -13,9 +13,11 @@ use Magento\Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Mtf\Client\BrowserInterface;
 
 /**
  * Check attribute on product form.
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
 {
@@ -45,6 +47,13 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
      */
     protected $catalogProductEdit;
 
+    /**
+     * Locator for attributes section.
+     *
+     * @var string
+     */
+    protected $attributes = '[data-index="attributes"]';
+
     /**
      * Add this attribute to Default attribute Template. Create product and Assert that created attribute
      * is displayed on product form (Products > Inventory > Catalog).
@@ -66,6 +75,7 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
         CatalogProductEdit $catalogProductEdit,
         CatalogProductAttribute $attribute,
         CatalogAttributeSet $attributeSet,
+        BrowserInterface $browser,
         CatalogProductAttribute $productAttributeOriginal = null
     ) {
         $this->fixtureFactory = $fixtureFactory;
@@ -92,7 +102,9 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
         $catalogProductAttribute = ($productAttributeOriginal !== null)
             ? array_merge($productAttributeOriginal->getData(), $attribute->getData())
             : $attribute->getData();
-        $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES);
+        if ($browser->find($this->attributes)->isVisible()) {
+            $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES);
+        }
 
         \PHPUnit_Framework_Assert::assertTrue(
             $catalogProductEdit->getProductForm()->checkAttributeLabel($catalogProductAttribute),
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php
new file mode 100644
index 0000000000000000000000000000000000000000..04e1c034b3db77a49a583ee819f9b8d97cb440ba
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+/**
+ * Assert that can save already exist product.
+ */
+class AssertCanSaveProduct extends \Magento\Mtf\Constraint\AbstractConstraint
+{
+    /**
+     * Assert that can save already existing product.
+     *
+     * @param \Magento\Mtf\Fixture\FixtureInterface $product
+     * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit $catalogProductEdit
+     * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+     * @return void
+     */
+    public function processAssert(
+        \Magento\Mtf\Fixture\FixtureInterface $product,
+        \Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit $catalogProductEdit,
+        \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+    ) {
+        $filter = ['sku' => $product->getSku()];
+        $catalogProductIndex->open()->getProductGrid()->searchAndOpen($filter);
+        $catalogProductEdit->getFormPageActions()->save();
+
+        \PHPUnit_Framework_Assert::assertNotEmpty(
+            $catalogProductEdit->getMessagesBlock()->getSuccessMessage(),
+            'Can\'t save existing product.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product was saved without errors.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..fed3b36c08d661bbc0297b6f87d08aa692d3c04e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Magento\Mtf\Fixture\InjectableFixture;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+
+class AssertProductHasImageInGrid extends AbstractConstraint
+{
+    /**
+     * Assert that product image is present in grid.
+     *
+     * @param CatalogProductIndex $productGrid
+     * @param InjectableFixture $product
+     * @return void
+     */
+    public function processAssert(
+        CatalogProductIndex $productGrid,
+        InjectableFixture $product
+    ) {
+        $filter = ['sku' => $product->getSku()];
+        $productGrid->open();
+        $productGrid->getProductGrid()->search($filter);
+        $src = $productGrid->getProductGrid()->getBaseImageSource();
+        \PHPUnit_Framework_Assert::assertTrue(
+            strpos($src, '/placeholder/') === false,
+            'Product image is not present in product grid when it should be'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product image is displayed in product grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index b4514208a509358a6828a7b77d33ca0c2678072a..e8ceb1d0889247805746a401f6c60bb5a0556010 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -36,8 +36,8 @@
         <field name="gallery" is_required="0" />
         <field name="gift_message_available" is_required="0" />
         <field name="has_options" is_required="0" />
-        <field name="image" is_required="0" />
-        <field name="image_label" is_required="0" />
+        <field name="image" is_required="0" group="gallery" source="Magento\Catalog\Test\Fixture\Product\Image" />
+        <field name="image_label" group="gallery" is_required="0" />
         <field name="manufacturer" is_required="0" />
         <field name="media_gallery" is_required="0" />
         <field name="meta_description" is_required="0" group="search-engine-optimization" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad72a6db4f4cef615f4abb7edddc497886a73981
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Fixture\Product;
+
+use Magento\Mtf\Fixture\DataSource;
+use Magento\Mtf\Fixture\FixtureFactory;
+
+/**
+ * Image entity data source.
+ */
+class Image extends DataSource
+{
+    /**
+     * Fixture Factory instance.
+     *
+     * @var FixtureFactory
+     */
+    private $fixtureFactory;
+
+    /**
+     * Fixture data.
+     *
+     * @var array
+     */
+    private $fixtureData;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, $data = [])
+    {
+        $this->fixtureFactory = $fixtureFactory;
+        $this->params = $params;
+        $this->fixtureData = $data;
+    }
+
+    /**
+     * {@inheritdoc}
+     * @throws \Exception
+     */
+    public function getData($key = null)
+    {
+        foreach ($this->fixtureData as &$imageData) {
+            if (isset($imageData['file']) && file_exists(MTF_TESTS_PATH . $imageData['file'])) {
+                $imageData['file'] = MTF_TESTS_PATH . $imageData['file'];
+            } else {
+                throw new \Exception("Image '{$imageData['file']}'' not found on the server.");
+            }
+        }
+        $this->data = $this->fixtureData;
+
+        return parent::getData($key);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
index a4a773ae7c7ecd02e11b6e824d6ec3d50925523b..db43cc535ca01c4bbac96e425a435bd71ef3fcef 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
@@ -47,6 +47,14 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
             'No' => 0,
             'Yes' => 1,
         ],
+        'is_global' => [
+            'Store View' => '0',
+            'Global' => '1',
+        ],
+        'used_in_product_listing' => [
+            'No' => '0',
+            'Yes' => '1',
+        ],
     ];
 
     /**
@@ -76,6 +84,7 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
             unset($data['options']);
         }
 
+        $data = $this->changeStructureOfTheData($data);
         $url = $_ENV['app_backend_url'] . 'catalog/product_attribute/save/back/edit';
         $curl = new BackendDecorator(new CurlTransport(), $this->_configuration);
         $curl->write($url, $data);
@@ -104,4 +113,13 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
 
         return $resultData;
     }
+
+    /**
+     * @param array $data
+     * @return array
+     */
+    protected function changeStructureOfTheData(array $data)
+    {
+        return $data;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
index 9ae1e2ebfacca405f8505496f546cf2182e2dd3f..c32999a6ebce7e0a4c44c1a10bc8fe4010a795f7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
@@ -34,5 +34,16 @@
                 <item name="inherit" xsi:type="number">1</item>
             </field>
         </dataset>
+        <dataset name="attribute_product_mask_sku">
+            <field name="catalog/fields_masks/sku" xsi:type="array">
+                <item name="value" xsi:type="string">{{name}} {{country_of_manufacture}}</item>
+            </field>
+        </dataset>
+        <dataset name="attribute_product_mask_sku_rollback">
+            <field name="catalog/fields_masks/sku" xsi:type="array">
+                <item name="value" xsi:type="string">{{name}}</item>
+                <item name="inherit" xsi:type="number">1</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
index 22cdab45ac875c6a6987892898e3c8dda3382944..fa81264dd2d4b061ef769f882408b104ba92793f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
@@ -16,6 +16,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" />
         </variation>
         <variation name="CreateCategoryEntityTestVariation2_RootCategory_AllFields">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create root category with all fields</data>
             <data name="addCategory" xsi:type="string">addRootCategory</data>
             <data name="category/data/is_active" xsi:type="string">Yes</data>
@@ -56,6 +57,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryPage" />
         </variation>
         <variation name="CreateCategoryEntityTestVariation4_Subcategory_AllFields">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create not anchor subcategory specifying all fields</data>
             <data name="addCategory" xsi:type="string">addSubcategory</data>
             <data name="category/data/parent_id/dataset" xsi:type="string">default_category</data>
@@ -90,6 +92,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" />
         </variation>
         <variation name="CreateCategoryEntityTestVariation5_Anchor_MostOfFields">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create anchor subcategory with all fields</data>
             <data name="addCategory" xsi:type="string">addSubcategory</data>
             <data name="category/data/parent_id/dataset" xsi:type="string">default_category</data>
@@ -150,7 +153,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" />
         </variation>
         <variation name="CreateCategoryEntityTestVariation9_ThreeNesting">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="description" xsi:type="string">Create category with three nesting</data>
             <data name="addCategory" xsi:type="string">addSubcategory</data>
             <data name="category/data/parent_id/dataset" xsi:type="string">two_nested_categories</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml
index 2c8528595f44b99bc70133cdc473841a0cbb0e22..1b61b92beef1310aa78e49acf49d2501410961b3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml
@@ -14,7 +14,7 @@
         </variation>
         <variation name="NavigateMenuTest10">
             <data name="menuItem" xsi:type="string">Products > Categories</data>
-            <data name="pageTitle" xsi:type="string">Default Category</data>
+            <data name="pageTitle" xsi:type="string">Default Category (ID: 2)</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
         </variation>
         <variation name="NavigateMenuTest11">
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php
index 131163311bcd2af4d34031883d103b3c2341cdb8..eddb620feabb3a7b211d0a8d63e4b2bd6a9ec79d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php
@@ -29,6 +29,7 @@ class AddCompareProductsTest extends AbstractCompareProductsTest
 {
     /* tags */
     const MVP = 'yes';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml
index 64d2a1de8a28454df0498d0b8fed68f5064d38ba..c29c99193b75dc99ab725996b617ef1ff794353c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml
@@ -10,6 +10,7 @@
         <variation name="AddCompareProductsTestVariation1">
             <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products</data>
             <data name="isCustomerLoggedIn" xsi:type="string">No</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareItemsLink" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductComparePage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareBlockOnCmsPage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml
index 16ebdf323e5920fb90074845b53ab61b8b91c68a..19fc527e71ab7672a96a6b0226e43ede2d356b25 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\ClearAllCompareProductsTest" summary="Clear All Compare Products" ticketId="MAGETWO-25961">
         <variation name="ClearAllCompareProductsTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="config/dataset" xsi:type="string">compare_products</data>
             <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareSuccessRemoveAllProductsMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0884e93387b2ac60c0be00e56791ae2b03443d38
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\TestCase\Product;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
+use Magento\Mtf\TestCase\Injectable;
+
+/**
+ * Steps:
+ * 1. Login to the backend.
+ * 2. Navigate to Products > Catalog.
+ * 3. Start to create simple product.
+ * 4. Fill in data according to data set.
+ * 5. Save Product.
+ * 6. Perform appropriate assertions.
+ *
+ * @group Products
+ * @ZephyrId MAGETWO-59861
+ */
+class CreateSimpleProductEntityByAttributeMaskSkuTest extends Injectable
+{
+    /**
+     * Configuration setting.
+     *
+     * @var string
+     */
+    protected $configData;
+
+    /**
+     * Should cache be flushed
+     *
+     * @var bool
+     */
+    private $flushCache;
+
+    /**
+     * @var \Magento\Mtf\Fixture\FixtureFactory
+     */
+    private $fixtureFactory;
+
+    /**
+     * Run create product simple entity by attribute mask SKU test.
+     *
+     * @param CatalogProductSimple $product
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductNew $newProductPage
+     * @param string $configData
+     * @param bool $flushCache
+     * @return array
+     */
+    public function testCreate(
+        CatalogProductSimple $product,
+        CatalogProductIndex $productGrid,
+        CatalogProductNew $newProductPage,
+        \Magento\Mtf\Fixture\FixtureFactory $fixtureFactory,
+        $flushCache = false,
+        $configData = null
+    ) {
+        $this->configData = $configData;
+        $this->flushCache = $flushCache;
+        $this->fixtureFactory = $fixtureFactory;
+
+        // Preconditions
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'flushCache' => $this->flushCache]
+        )->run();
+
+        // Steps
+        $productGrid->open();
+        $productGrid->getGridPageActionBlock()->addProduct('simple');
+        $newProductPage->getProductForm()->fill($product);
+        $newProductPage->getFormPageActions()->save();
+
+        $skuMask = $this->prepareSkuByMask($product);
+
+        $productSimple = $fixtureFactory->createByCode(
+            'catalogProductSimple',
+            ['data' => array_merge($product->getData(), ['sku' => $skuMask])]
+        );
+
+        return ['product' => $productSimple];
+    }
+
+    /**
+     * Obtains product sku based on attributes define in Stores > Configuration->Catalog > Catalog > Mask for SKU
+     *
+     * @param CatalogProductSimple $product
+     * @return string
+     */
+    private function prepareSkuByMask(CatalogProductSimple $product)
+    {
+        $productData = $product->getData();
+        $skuMask = '';
+        $config = $this->fixtureFactory->createByCode('configData', ['dataset' => $this->configData]);
+        $section = $config->getData('section');
+        if (is_array($section) && array_key_exists('catalog/fields_masks/sku', $section)) {
+            $skuMask = $section['catalog/fields_masks/sku']['value'];
+        }
+
+        $attributesInPattern = [];
+        $count = preg_match_all('/{{(\w+)}}/', $skuMask, $matches);
+        if ($count > 0 && is_array($matches[0])) {
+            foreach ($matches[1] as $attributeName) {
+                if (array_key_exists($attributeName, $productData)) {
+                    $attributesInPattern[$attributeName] = $productData[$attributeName];
+                }
+            }
+        }
+        foreach ($attributesInPattern as $attributeName => $attributeValue) {
+            $skuMask = str_replace('{{' . $attributeName . '}}', $attributeValue, $skuMask);
+        }
+        return $skuMask;
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'rollback' => true, 'flushCache' => $this->flushCache]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..338f34a57ab5d8745a9cf53665d34e39a0369694
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Catalog\Test\TestCase\Product\CreateSimpleProductEntityByAttributeMaskSkuTest" summary="Create Simple Product with attribute sku mask" ticketId="MAGETWO-59861">
+        <variation name="CreateSimpleProductEntityByAttributeMaskSkuTest1">
+            <data name="configData" xsi:type="string">attribute_product_mask_sku</data>
+            <data name="description" xsi:type="string">Create product with country of manufacture attribute sku mask</data>
+            <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">10000</data>
+            <data name="product/data/weight" xsi:type="string">50</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">657</data>
+            <data name="product/data/country_of_manufacture" xsi:type="string">Ukraine</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
index 9e410c525deef720573e7c93e0de4d463b9b2ac7..9f4a5e4bb71fea9293612125157757f7e3d965da 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
@@ -137,6 +137,7 @@
             <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_percent_price</data>
             <data name="product/data/price/dataset" xsi:type="string">MAGETWO-23030</data>
             <data name="product/data/tier_price/dataset" xsi:type="string">MAGETWO-23002</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
@@ -157,6 +158,7 @@
             <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_fixed_price</data>
             <data name="product/data/price/dataset" xsi:type="string">MAGETWO-23029</data>
             <data name="product/data/tier_price/dataset" xsi:type="string">MAGETWO-23002</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
@@ -238,6 +240,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
         <variation name="CreateSimpleProductEntityTestVariation14">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create simple product and check visibility in category</data>
             <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
@@ -255,6 +258,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
         <variation name="CreateSimpleProductEntityTestVariation15">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create product with tax class and group price</data>
             <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
@@ -303,6 +307,7 @@
             <data name="product/data/weight" xsi:type="string">66</data>
             <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">143</data>
             <data name="product/data/tier_price/dataset" xsi:type="string">default</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
@@ -324,6 +329,7 @@
             <data name="product/data/custom_options/dataset" xsi:type="string">options_suite</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">simple_options_suite</data>
             <data name="product/data/custom_options/import_products" xsi:type="string">catalogProductSimple::with_two_custom_option,catalogProductSimple::with_all_custom_option</data>
+            <data name="issue" xsi:type="string">MAGETWO-58181: All kind of Custom Options have dynamic view on Bamboo</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
@@ -333,6 +339,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCustomOptionsOnProductPage" />
         </variation>
         <variation name="CreateSimpleProductEntityTestVariation19" summary="Create product with cross-sell products" ticketId="MAGETWO-29081">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
@@ -349,6 +356,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCrossSells" />
         </variation>
         <variation name="CreateSimpleProductEntityTestVariation20" summary="Create product with up-sell products" ticketId="MAGETWO-29105">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
@@ -401,6 +409,7 @@
             <data name="product/data/sku" xsi:type="string">simple%isolation%</data>
             <data name="product/data/price/value" xsi:type="string">10</data>
             <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">345</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
@@ -500,5 +509,19 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" />
         </variation>
+        <variation name="CreateSimpleProductEntityWithImageTestVariation1" summary="Create product with image and try to save it again">
+            <data name="product/data/image/0/file" xsi:type="string">Magento/Catalog/Test/_files/test1.png</data>
+            <data name="product/data/image/1/file" xsi:type="string">Magento/Catalog/Test/_files/test2.png</data>
+            <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">10</data>
+            <data name="product/data/weight" xsi:type="string">50</data>
+            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">100</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductHasImageInGrid" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertCanSaveProduct" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml
index bf158ce4d66b772daaa03f7795cf74d1826bbe59..ed124d152d29b280e2131d1a077a0ed41f5f79af 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\CreateVirtualProductEntityTest" summary="Create Virtual Product" ticketId="MAGETWO-23417">
         <variation name="CreateVirtualProductEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create product with required fields</data>
             <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data>
@@ -17,7 +18,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
         </variation>
         <variation name="CreateVirtualProductEntityTestVariation2" summary="Create product with tier price">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data>
             <data name="product/data/sku" xsi:type="string">virtual_sku_%isolation%</data>
@@ -65,12 +66,14 @@
             <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">In Stock</data>
             <data name="product/data/visibility" xsi:type="string">Catalog, Search</data>
             <data name="customer/dataset" xsi:type="string">default</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductVisibleInCategory" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPageWithCustomer" />
         </variation>
         <variation name="CreateVirtualProductEntityTestVariation5">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create product with custom options suite and import options</data>
             <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data>
@@ -110,6 +113,7 @@
             <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">999</data>
             <data name="product/data/tier_price/dataset" xsi:type="string">default</data>
             <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">Out of Stock</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php
index 7026b757bb7de03a00f18b525076a057749d2383..81cf672344d612224ff6cab99fec93bfa97b8253 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php
@@ -28,6 +28,7 @@ class DeleteCompareProductsTest extends AbstractCompareProductsTest
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml
index 883e7cdf6032c5813759db3d613378c34f04c277..9d983f52c08b6bde5c9edc5e59f30899e8da5f21 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\DeleteCompareProductsTest" summary="Delete Compare Products" ticketId="MAGETWO-26161">
         <variation name="DeleteCompareProductsTestVariation1_NotLoggedIn">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data>
             <data name="removeProductIndex" xsi:type="string">1</data>
             <data name="isCustomerLoggedIn" xsi:type="string">No</data>
@@ -15,6 +16,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductIsNotVisibleInComparePage" />
         </variation>
         <variation name="DeleteCompareProductsTestVariation2_LoggedIn">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data>
             <data name="removeProductIndex" xsi:type="string">6</data>
             <data name="isCustomerLoggedIn" xsi:type="string">Yes</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml
index 3bef2716d35728fff7c3a2cd730688862acae1e4..32d534941e2b91ad5ba1a96d9ba6b0e47d523e70 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml
@@ -10,6 +10,7 @@
         <variation name="DeleteProductEntityTestVariation1">
             <data name="products" xsi:type="string">catalogProductSimple::default</data>
             <data name="isRequired" xsi:type="string">Yes</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSuccessDeleteMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductNotInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductIsNotDisplayingOnFrontend" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml
index 5b81bebbc6d04e9551fa6399c308a365895b9bd7..0dad886f05ed55c7b951e32dfec8a74b433d6067 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest" summary="Duplicate Product" ticketId="MAGETWO-23294">
         <variation name="DuplicateProductEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productType" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
index 6cb89d424fee3a0e3ddc084dc304e3fe2f25751c..4ab490478958a81f7312dd1d7a9fc6fb9835a05a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\ProductTypeSwitchingOnCreationTest" summary="Product Type Switching on Creation" ticketId="MAGETWO-29398">
         <variation name="ProductTypeSwitchingOnCreationTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="createProduct" xsi:type="string">simple</data>
             <data name="product" xsi:type="string">configurableProduct::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
@@ -44,6 +45,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
         </variation>
         <variation name="ProductTypeSwitchingOnCreationTestVariation6">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="createProduct" xsi:type="string">virtual</data>
             <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
@@ -56,6 +58,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" />
         </variation>
         <variation name="ProductTypeSwitchingOnCreationTestVariation7">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="createProduct" xsi:type="string">virtual</data>
             <data name="product" xsi:type="string">downloadableProduct::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
@@ -73,6 +76,7 @@
         <variation name="ProductTypeSwitchingOnCreationTestVariation9">
             <data name="createProduct" xsi:type="string">downloadable</data>
             <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml
index a2580cee9b91a342c30d21fb4356c682e68a8383..874cac5d4bc5828769a88badc87a41643799d4fc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml
@@ -11,6 +11,7 @@
             <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data>
             <data name="product" xsi:type="string">configurableProduct::default</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" />
@@ -20,6 +21,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" />
         </variation>
         <variation name="ProductTypeSwitchingOnUpdateTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data>
             <data name="product" xsi:type="string">catalogProductVirtual::default</data>
             <data name="actionName" xsi:type="string">-</data>
@@ -27,6 +29,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
         </variation>
         <variation name="ProductTypeSwitchingOnUpdateTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="productOrigin" xsi:type="string">configurableProduct::default</data>
             <data name="product" xsi:type="string">catalogProductSimple::product_without_category</data>
             <data name="actionName" xsi:type="string">deleteVariations</data>
@@ -37,10 +40,12 @@
             <data name="productOrigin" xsi:type="string">configurableProduct::default</data>
             <data name="product" xsi:type="string">catalogProductVirtual::required_fields</data>
             <data name="actionName" xsi:type="string">deleteVariations</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
         </variation>
         <variation name="ProductTypeSwitchingOnUpdateTestVariation5">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data>
             <data name="product" xsi:type="string">catalogProductSimple::default</data>
             <data name="actionName" xsi:type="string">-</data>
@@ -51,6 +56,7 @@
             <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data>
             <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" />
@@ -63,6 +69,7 @@
             <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data>
             <data name="product" xsi:type="string">downloadableProduct::default</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
@@ -74,6 +81,7 @@
             <data name="productOrigin" xsi:type="string">downloadableProduct::default</data>
             <data name="product" xsi:type="string">catalogProductSimple::default</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
         </variation>
@@ -81,6 +89,7 @@
             <data name="productOrigin" xsi:type="string">downloadableProduct::default</data>
             <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" />
@@ -90,6 +99,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" />
         </variation>
         <variation name="ProductTypeSwitchingOnUpdateTestVariation10">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="productOrigin" xsi:type="string">downloadableProduct::default</data>
             <data name="product" xsi:type="string">catalogProductVirtual::default</data>
             <data name="actionName" xsi:type="string">clearDownloadableData</data>
@@ -100,6 +110,7 @@
             <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data>
             <data name="product" xsi:type="string">downloadableProduct::default</data>
             <data name="actionName" xsi:type="string">-</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
index 0395f9f5ed8cf83c0aa570252cc5ed7df32da3c8..31aaad654f92a914c14276ab770fa7fe9790f5de 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\UpdateSimpleProductEntityTest" summary="Update Simple Product" ticketId="MAGETWO-23544">
         <variation name="UpdateSimpleProductEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Update visibility to Catalog, Search</data>
             <data name="initialProduct/dataset" xsi:type="string">product_with_category</data>
             <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data>
@@ -24,6 +25,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
         <variation name="UpdateSimpleProductEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Update visibility to Not Visible Individually</data>
             <data name="initialProduct/dataset" xsi:type="string">product_with_category</data>
             <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data>
@@ -47,6 +49,7 @@
             <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
             <data name="product/data/weight" xsi:type="string">25.0000</data>
             <data name="product/data/visibility" xsi:type="string">Catalog</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInStock" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
@@ -64,6 +67,7 @@
             <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
             <data name="product/data/weight" xsi:type="string">89.0000</data>
             <data name="product/data/visibility" xsi:type="string">Search</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInStock" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
@@ -81,6 +85,7 @@
             <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">Out of Stock</data>
             <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
             <data name="product/data/weight" xsi:type="string">125.0000</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" />
@@ -89,6 +94,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSearchableBySku" />
         </variation>
         <variation name="UpdateSimpleProductEntityTestVariation6">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Update product status to offline</data>
             <data name="initialProduct/dataset" xsi:type="string">product_with_category</data>
             <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data>
@@ -112,6 +118,7 @@
             <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">87</data>
             <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
             <data name="product/data/weight" xsi:type="string">333.0000</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteUpdatedProductInGrid" />
@@ -124,6 +131,7 @@
             <data name="product/data/sku" xsi:type="string">test_simple_product_%isolation%</data>
             <data name="product/data/price/value" xsi:type="string">133.00</data>
             <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
@@ -142,10 +150,12 @@
             <data name="product/data/sku" xsi:type="string">sku_simple_product_%isolation%</data>
             <data name="product/data/price/value" xsi:type="string">1.99</data>
             <data name="product/data/attribute_set_id/dataset" xsi:type="string">default</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
         </variation>
         <variation name="EditSimpleProductTestVariation11" summary="Update simple product with custom option">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="initialProduct/dataset" xsi:type="string">product_with_category</data>
             <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">test_simple_product_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php
index ddd788d7ee1c91dde5164b06ea2d908056031c25..2a18f9e37f953b91e06332ffc1e4090c1a4acd73 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php
@@ -37,6 +37,7 @@ class UpdateVirtualProductEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml
index 3bc4b3c780d627c6ec6e049574381f1ff726867c..a263a70e8bfc007cbcc0a224e8bc1255e86dfe2a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\CreateAttributeSetEntityTest" summary="Create Attribute Set (Attribute Set)" ticketId="MAGETWO-25104">
         <variation name="CreateAttributeSetEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="attributeSet/data/attribute_set_name" xsi:type="string">AttributeSet%isolation%</data>
             <data name="attributeSet/data/skeleton_set/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeSetSuccessSaveMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml
index 2a94a12c0dbdf0d37082a16c19cff02c152ed7f3..543bece9331f4d0968e38b7d8f887f563b9b8ec3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\CreateProductAttributeEntityTest" summary="Create Product Attribute" ticketId="MAGETWO-24767">
         <variation name="CreateProductAttributeEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Text Field</data>
@@ -19,6 +20,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Text Area</data>
@@ -57,6 +59,7 @@
             <data name="productAttribute/data/used_in_product_listing" xsi:type="string">Yes</data>
             <data name="productAttribute/data/is_used_for_promo_rules" xsi:type="string">Yes</data>
             <data name="productAttribute/data/used_for_sort_by" xsi:type="string">Yes</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeForm" />
             <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductByAttribute" />
@@ -65,6 +68,7 @@
             <constraint name="Magento\CatalogRule\Test\Constraint\AssertProductAttributeIsUsedPromoRules" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation4">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Yes/No_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Yes/No</data>
@@ -97,6 +101,7 @@
             <data name="productAttribute/data/is_html_allowed_on_front" xsi:type="string">Yes</data>
             <data name="productAttribute/data/is_visible_on_front" xsi:type="string">Yes</data>
             <data name="productAttribute/data/used_in_product_listing" xsi:type="string">Yes</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeForm" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" />
@@ -110,7 +115,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeOptionsOnProductForm" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation6">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Dropdown_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Dropdown</data>
@@ -148,6 +153,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeOptionsOnProductForm" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation7">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Price_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Price</data>
@@ -169,6 +175,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeIsFilterableInSearch" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation8">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Fixed_Product_Tax_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Fixed Product Tax</data>
@@ -185,6 +192,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" />
         </variation>
         <variation name="CreateProductAttributeEntityTestVariation9">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data>
             <data name="productAttribute/data/frontend_input" xsi:type="string">Text Field</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml
index 3f547daa68eb58cfc8480f76ede8c1be5ea31ace..83b5be744f0251374798b2a151c9c1dabf737b53 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\DeleteAttributeSetTest" summary="Delete Attribute Set (Attribute Set)" ticketId="MAGETWO-25473">
         <variation name="DeleteAttributeSetTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="attributeSet/data/assigned_attributes/dataset" xsi:type="string">default</data>
             <data name="product/dataset" xsi:type="string">default</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml
index a11e2679b27e0860ba298008eaa48b9f2812fe01..83d819b7db1c4d6e0fc09d6209b0255c18f8f6c0 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml
@@ -15,6 +15,7 @@
             <constraint name="Magento\ImportExport\Test\Constraint\AssertProductAttributeAbsenceForExport" />
         </variation>
         <variation name="DeleteProductAttributeEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="attribute/dataset" xsi:type="string">attribute_type_dropdown</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeSuccessDeleteMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeAbsenceInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml
index a7b233a7aae4b9d97f83638c80572d7f8888a9f1..ff80366fea097217450ad1d95eb4d0b5f4191944 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\UpdateAttributeSetTest" summary="Update Attribute Set" ticketId="MAGETWO-26251">
         <variation name="UpdateAttributeSetTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="attributeSet/data/attribute_set_name" xsi:type="string">AttributeSetEdit1%isolation%</data>
             <data name="attributeSet/data/group" xsi:type="string">Custom-group%isolation%</data>
             <data name="attributeSetOriginal/dataset" xsi:type="string">custom_attribute_set</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml
index b7e27854a82441e35328c31d0c81f2088cf50408..7077b8e852b5e06f7fa240be8a8e106f36686068 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\UpdateProductAttributeEntityTest" summary="Update Product Attribute" ticketId="MAGETWO-23459">
         <variation name="UpdateProductAttributeEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttributeOriginal/dataset" xsi:type="string">attribute_type_text_field</data>
             <data name="attribute/data/frontend_label" xsi:type="string">Text_Field_%isolation%</data>
@@ -28,6 +29,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" />
         </variation>
         <variation name="UpdateProductAttributeEntityTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data>
             <data name="productAttributeOriginal/dataset" xsi:type="string">attribute_type_dropdown</data>
             <data name="attribute/data/frontend_label" xsi:type="string">Dropdown_%isolation%</data>
@@ -60,6 +62,7 @@
             <data name="cacheTags" xsi:type="array">
                 <item name="0" xsi:type="string">FPC</item>
             </data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\PageCache\Test\Constraint\AssertCacheIsRefreshableAndInvalidated" />
             <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductByAttribute" />
         </variation>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2f08513d7297ad1a3fe3345c8bdca1b848e4819
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\TestStep;
+
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Mtf\Client\BrowserInterface;
+use Magento\Mtf\Fixture\InjectableFixture;
+use Magento\Mtf\TestStep\TestStepInterface;
+
+/**
+ * Configure Product on Product Page step.
+ */
+class ConfigureProductOnProductPageStep implements TestStepInterface
+{
+    /**
+     * Product fixture.
+     *
+     * @var InjectableFixture
+     */
+    private $product;
+
+    /**
+     * Frontend product view page.
+     *
+     * @var CatalogProductView
+     */
+    private $catalogProductView;
+
+    /**
+     * Interface Browser.
+     *
+     * @var BrowserInterface
+     */
+    private $browser;
+
+    /**
+     * @constructor
+     * @param CatalogProductView $catalogProductView
+     * @param BrowserInterface $browser
+     * @param InjectableFixture $product
+     */
+    public function __construct(
+        CatalogProductView $catalogProductView,
+        BrowserInterface $browser,
+        InjectableFixture $product
+    ) {
+        $this->product = $product;
+        $this->catalogProductView = $catalogProductView;
+        $this->browser = $browser;
+    }
+
+    /**
+     * Configure product.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $this->browser->open($_ENV['app_frontend_url'] . $this->product->getUrlKey() . '.html');
+        $this->catalogProductView->getViewBlock()->configure($this->product);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png
new file mode 100644
index 0000000000000000000000000000000000000000..3077df38da2ffab3378a630914803dfad59e7961
Binary files /dev/null and b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png differ
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d219e6ee734b983a39e041a2386117a10d762be
Binary files /dev/null and b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png differ
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml
index 9359b0c402b953ba1b8fcd2343b5ca84af3a764f..3a2f2f8aa7816a53d674c6c665b058afb1a4b720 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml
@@ -8,11 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\CatalogSearch\Test\TestCase\SuggestSearchingResultEntityTest" summary="Suggest Searching Results" ticketId="MAGETWO-24671">
         <variation name="SuggestSearchingResultEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="catalogSearch/data/query_text/value" xsi:type="string">catalogProductSimple::name</data>
             <data name="catalogSearch/data/num_results" xsi:type="string">-</data>
             <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSuggestSearchingResult" />
         </variation>
         <variation name="SuggestSearchingResultEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="catalogSearch/data/query_text/value" xsi:type="string">catalogProductSimple::sku</data>
             <data name="catalogSearch/data/num_results" xsi:type="string">1</data>
             <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSuggestSearchingResult" />
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php
index f1776d2bf933e17d63006948795418309348ffe3..ce8f5a4cbfd99b41e990a11fc89527f28b0fec5f 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php
@@ -8,7 +8,6 @@ namespace Magento\Checkout\Test\Block\Onepage;
 
 use Magento\Mtf\Block\Block;
 use Magento\Mtf\Fixture\InjectableFixture;
-use Magento\Payment\Test\Fixture\CreditCard;
 
 /**
  * Checkout payment block.
@@ -85,11 +84,17 @@ class Payment extends Block
         $paymentLabelSelector = sprintf($this->paymentMethodLabel, $payment['method']);
 
         try {
+            $this->waitForElementNotVisible($this->waitElement);
             $this->waitForElementVisible($paymentLabelSelector);
         } catch (\Exception $exception) {
             throw new \Exception('Such payment method is absent.');
         }
-
+        $browser = $this->browser;
+        $browser->waitUntil(
+            function () use ($browser, $paymentSelector) {
+                return $browser->find($paymentSelector);
+            }
+        );
         $paymentRadioButton = $this->_rootElement->find($paymentSelector);
         if ($paymentRadioButton->isVisible()) {
             $paymentRadioButton->click();
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php
index 3bf6bda89ad939ad4ae100006996cf4077e1aeb9..dc1433506f2623d2122f293b063a0707017edc13 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php
@@ -14,6 +14,13 @@ use Magento\Mtf\Constraint\AbstractConstraint;
  */
 class AssertGrandTotalOrderReview extends AbstractConstraint
 {
+    /**
+     * Wait element.
+     *
+     * @var string
+     */
+    protected $waitElement = '.loading-mask';
+
     /**
      * Assert that Order Grand Total is correct on checkoutOnePage
      *
@@ -23,6 +30,7 @@ class AssertGrandTotalOrderReview extends AbstractConstraint
      */
     public function processAssert(CheckoutOnepage $checkoutOnepage, $grandTotal)
     {
+        $checkoutOnepage->getReviewBlock()->waitForElementNotVisible($this->waitElement);
         $checkoutReviewGrandTotal = $checkoutOnepage->getReviewBlock()->getGrandTotal();
 
         \PHPUnit_Framework_Assert::assertEquals(
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
index 30688723ae8edb8c83b761e89f2805f5dcdcd588..9a539d856e7082ae5131e903d7d86eec5f37d6c5 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Checkout\Test\TestCase\AddProductsToShoppingCartEntityTest" summary="Add Products to Shopping Cart" ticketId="MAGETWO-25382">
         <variation name="AddProductsToShoppingCartEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
             <data name="cart/data/grand_total" xsi:type="string">210</data>
             <data name="cart/data/subtotal" xsi:type="string">200</data>
@@ -20,6 +21,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <data name="cart/data/grand_total" xsi:type="string">761</data>
             <data name="cart/data/subtotal" xsi:type="string">756</data>
@@ -32,6 +34,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <data name="cart/data/grand_total" xsi:type="string">345</data>
             <data name="cart/data/subtotal" xsi:type="string">340</data>
@@ -44,6 +47,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation4">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="cart/data/grand_total" xsi:type="string">50</data>
             <data name="cart/data/subtotal" xsi:type="string">50</data>
@@ -56,6 +60,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation5">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">configurableProduct::default</data>
             <data name="cart/data/grand_total" xsi:type="string">135</data>
             <data name="cart/data/subtotal" xsi:type="string">120</data>
@@ -80,6 +85,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation7">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">groupedProduct::three_simple_products</data>
             <data name="cart/data/grand_total" xsi:type="string">1950</data>
             <data name="cart/data/subtotal" xsi:type="string">1920</data>
@@ -92,6 +98,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" />
         </variation>
         <variation name="AddProductsToShoppingCartEntityTestVariation8">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <data name="productsData/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="productsData/2" xsi:type="string">downloadableProduct::with_two_separately_links</data>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml
index 2f2177c6cc7efcdf9c7e1df8f71b8b4ca7752188..033ea76a2a5ff17c5233d7f1b543f6b72f013c61 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml
@@ -16,6 +16,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" />
         </variation>
         <variation name="DeleteProductsFromShoppingCartTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" />
         </variation>
@@ -36,6 +37,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" />
         </variation>
         <variation name="DeleteProductsFromShoppingCartTestVariation8">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <data name="productsData/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="productsData/2" xsi:type="string">downloadableProduct::with_two_separately_links</data>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
index 6a1f225bc9429e47b68ffb85bd06fc0443ebdbf9..797255d4e374acf001132647eee1121168ec0b50 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
@@ -27,6 +27,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
         </variation>
         <variation name="OnePageCheckoutTestVariation2" summary="US customer during checkout using coupon for all customer groups">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups</data>
             <data name="customer/dataset" xsi:type="string">default</data>
@@ -48,6 +49,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
         </variation>
         <variation name="OnePageCheckoutTestVariation3" summary="Checkout as UK guest with simple product" ticketId="MAGETWO-42603">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="checkoutMethod" xsi:type="string">guest</data>
@@ -167,6 +169,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
         </variation>
         <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with Tier Prices">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_order_qty_3</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="checkoutMethod" xsi:type="string">guest</data>
@@ -183,6 +186,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
         </variation>
         <variation name="OnePageCheckoutTestVariation10" summary="One Page Checkout with all product types">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductVirtual::default</data>
             <data name="products/1" xsi:type="string">downloadableProduct::with_two_separately_links</data>
             <data name="products/2" xsi:type="string">configurableProduct::with_one_option</data>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
index 1c60b0f156bae087433d03ac12e84c733bb9258f..5f9b069ab85ca92d37ac8773ac3d1694e5d6ee81 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
@@ -8,14 +8,14 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Checkout\Test\TestCase\UpdateProductFromMiniShoppingCartEntityTest" summary="Update Product from Mini Shopping Cart" ticketId="MAGETWO-29812">
         <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation1" summary="Update Simple">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="originalProduct/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <data name="checkoutData/dataset" xsi:type="string">simple_update_mini_shopping_cart</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductDataInMiniShoppingCart" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
         </variation>
         <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation2" summary="Update Configurable and verify previous product was updated to new one in shopping cart and mini shopping cart">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="originalProduct/0" xsi:type="string">configurableProduct::default</data>
             <data name="checkoutData/dataset" xsi:type="string">configurable_update_mini_shopping_cart</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" />
@@ -24,7 +24,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" />
         </variation>
         <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation3" summary="Update Bundle and verify previous product was updated to new one in shopping cart and mini shopping cart">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="originalProduct/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <data name="checkoutData/dataset" xsi:type="string">bundle_update_mini_shopping_cart</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" />
@@ -33,7 +33,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" />
         </variation>
         <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation4" summary="Update Downloadable and check previous link was updated to new one in shopping cart and mini shopping cart">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="originalProduct/0" xsi:type="string">downloadableProduct::with_two_separately_links</data>
             <data name="checkoutData/dataset" xsi:type="string">downloadable_update_mini_shopping_cart</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" />
@@ -42,7 +42,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" />
         </variation>
         <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation5" summary="Update Virtual product in mini shopping cart">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="originalProduct/0" xsi:type="string">catalogProductVirtual::default</data>
             <data name="checkoutData/dataset" xsi:type="string">virtual_update_mini_shopping_cart</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductDataInMiniShoppingCart" />
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php
index 809688cd8286a0afdc68ef3d236a6b1673b1c66b..3dba57e26e003726e856577f5e4b48a427428a24 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php
@@ -33,6 +33,7 @@ class UpdateShoppingCartTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
index fc043effe5a77682ef1a30307350ad72aab8401b..34c70c9e2a33bea3418e394a241a1d87d48ee27a 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\DeleteCmsBlockEntityTest" summary="Delete CMS Block" ticketId="MAGETWO-25698">
         <variation name="DeleteCmsBlockEntityTestVariation1">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, stable:no</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockDeleteMessage" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotOnCategoryPage" />
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
index 2a85425890e8e455a4ba6e32960f6d329bfcdf5b..745d60dad9f8ac8c67d891e84e33e502db1b6659 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\DeleteCmsPageEntityTest" summary="Delete CMS Page" ticketId="MAGETWO-23291">
         <variation name="DeleteCmsPageEntityTestVariation1">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, stable:no</data>
             <data name="cmsPage/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDeleteMessage" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageNotInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
index 893cfc2f0dacc75f92b31b3a14fcc54a41aaf6b5..fc279aad59d3d7e21590be2c256f83831e7295cf 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridFullTextSearchTest" summary="Grid UI Component Full Text Search" ticketId="MAGETWO-41023">
         <variation name="CmsPageGridFullTextSearch">
-            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="tag" xsi:type="string">severity:S2, stable:no</data>
             <data name="description" xsi:type="string">Verify cms page grid full text search</data>
             <data name="itemsCount" xsi:type="string">2</data>
             <data name="fixtureName" xsi:type="string">cmsPage</data>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
index d6467a53e15659a1e5859002c04be6ad3e91b3e3..1be7e61f6bd0ea27a99733a63828f438ab481215 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328">
         <variation name="CmsPagesGridSorting">
-            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="tag" xsi:type="string">severity:S2, stable:no</data>
             <data name="description" xsi:type="string">Verify cms page grid sorting</data>
             <data name="columnsForSorting" xsi:type="array">
                 <item name="id" xsi:type="string">ID</item>
@@ -19,7 +19,7 @@
             <constraint name="Magento\Ui\Test\Constraint\AssertGridSorting"/>
         </variation>
         <variation name="CmsBlocksGridSorting">
-            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="tag" xsi:type="string">severity:S2, stable:no</data>
             <data name="description" xsi:type="string">Verify cms blocks grid sorting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">-</item>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
index 75f8cf63f645e333e001ba26ef940f62ae95581c..93d38321ab7db4c2fa8fcda830022a8c52970e14 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\UpdateCmsPageEntityTest" summary="Update Cms Page" ticketId="MAGETWO-25186">
         <variation name="UpdateCmsPageEntityTestVariation1">
-            <data name="tag" xsi:type="string">severity:S3</data>
+            <data name="tag" xsi:type="string">severity:S3, to_maintain:yes</data>
             <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data>
             <data name="cms/data/is_active" xsi:type="string">No</data>
             <data name="cms/data/content/content" xsi:type="string">cms_page_text_content_after_edit</data>
@@ -16,7 +16,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDisabledOnFrontend" />
         </variation>
         <variation name="UpdateCmsPageEntityTestVariation2">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data>
             <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data>
             <data name="cms/data/identifier" xsi:type="string">cms_page_url_edited_%isolation%</data>
             <data name="cms/data/content_heading" xsi:type="string">Content Heading TextEdited</data>
diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php
index 30928810490d770c5ea8309748b07aeabf45314a..5df648a565dc7040c24e43d8b35bad5859a3b200 100644
--- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php
@@ -23,13 +23,14 @@ class VerifyAdminAccountSharingEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const DOMAIN = 'PS';
+    const TO_MAINTAIN = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
     /* end tags */
 
     /**
      * Admin account settings page.
      *
-     * @var adminAccountSharing
+     * @var AdminAccountSharing
      */
     private $adminAccountSharing;
 
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php
index 62d6c72efe8c6aa8d0a8ed4aff4594316318c9e3..ad9807b76d6e532fd00e9f22fac7bf4007a80502 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php
@@ -125,15 +125,23 @@ class AssertConfigurableProductPage extends AssertProductPage
     protected function getLowestConfigurablePrice()
     {
         $price = null;
-        $configurableOptions = $this->product->getConfigurableAttributesData();
-
-        foreach ($configurableOptions['matrix'] as $option) {
-            $price = $price === null ? $option['price'] : $price;
-            if ($price > $option['price']) {
-                $price = $option['price'];
+        $priceDataConfig = $this->product->getDataFieldConfig('price');
+        if (isset($priceDataConfig['source'])) {
+            $priceData = $priceDataConfig['source']->getPriceData();
+            if (isset($priceData['price_from'])) {
+                $price = $priceData['price_from'];
             }
         }
 
+        if (null === $price) {
+            $configurableOptions = $this->product->getConfigurableAttributesData();
+            foreach ($configurableOptions['matrix'] as $option) {
+                $price = $price === null ? $option['price'] : $price;
+                if ($price > $option['price']) {
+                    $price = $option['price'];
+                }
+            }
+        }
         return $price;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5c3ab4dad9ee121c1332649dabd8715c3544449
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Test\Constraint;
+
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\ObjectManager;
+use Magento\Mtf\System\Event\EventManagerInterface;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+
+/**
+ * Class AssertProductQtyDecreasedAfterCreditmemo
+ */
+class AssertProductQtyDecreasedAfterCreditmemo extends AbstractConstraint
+{
+    /**
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Skip fields for create product fixture.
+     *
+     * @var array
+     */
+    protected $skipFields = [
+        'attribute_set_id',
+        'website_ids',
+        'checkout_data',
+        'type_id',
+        'price',
+    ];
+
+    /**
+     * AssertFirstProductForm constructor.
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(
+        ObjectManager $objectManager,
+        EventManagerInterface $eventManager,
+        FixtureFactory $fixtureFactory
+    ) {
+        $this->fixtureFactory = $fixtureFactory;
+        parent::__construct($objectManager, $eventManager);
+    }
+
+    /**
+     * Assert form data equals fixture data
+     *
+     * @param OrderInjectable $order
+     * @param array $data
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductEdit $productPage
+     * @return void
+     */
+    public function processAssert(
+        OrderInjectable $order,
+        array $data,
+        CatalogProductIndex $productGrid,
+        CatalogProductEdit $productPage
+    ) {
+        $product = $this->getProduct($order, $data);
+        $this->objectManager->get(\Magento\Catalog\Test\Constraint\AssertProductForm::class)->processAssert(
+            $product,
+            $productGrid,
+            $productPage
+        );
+    }
+
+    /**
+     * Get product's fixture.
+     *
+     * @param OrderInjectable $order
+     * @param array $data
+     * @param int $index [optional]
+     * @return FixtureInterface
+     */
+    protected function getProduct(OrderInjectable $order, array $data, $index = 0)
+    {
+        if (!isset($data['items_data'][$index]['back_to_stock'])
+            || $data['items_data'][$index]['back_to_stock'] != 'Yes'
+        ) {
+            return $order->getEntityId()['products'][$index];
+        }
+        $product = $order->getEntityId()['products'][$index];
+        $productData = $product->getData();
+        $checkoutDataQty = $productData['checkout_data']['qty'];
+
+        $productKey = '';
+        foreach ($productData['checkout_data']['options']['configurable_options'] as $option) {
+            $productKey .= ' ' . $option['title'] . ':' . $option['value'];
+        }
+        $productKey = trim($productKey);
+        $optionProduct = $productData['configurable_attributes_data']['matrix'][$productKey];
+        $optionProduct['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']);
+        $productData = $optionProduct;
+
+        $productData = array_diff_key($productData, array_flip($this->skipFields));
+
+        return $this->fixtureFactory->create(get_class($product), ['data' => $productData]);
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product qty was decreased after creditmemo creation.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
index bf5d5944aa3da0a7093d5bbe33ea00897f3b5397..626be7dee3652ee88407d47f1bac313a96dde225 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
@@ -172,7 +172,7 @@ class Curl extends ProductCurl implements ConfigurableProductInterface
                 $keyIds[] = $attribute['options'][$optionKey]['id'];
                 $configurableAttribute[] = sprintf(
                     '"%s":"%s"',
-                    $attribute['attribute_code'],
+                    isset($attribute['attribute_code']) ? $attribute['attribute_code'] : $attribute['frontend_label'],
                     $attribute['options'][$optionKey]['id']
                 );
             }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
index 4a69a7604bca3d74119b07bdcea3b2115a1f6648..32f1957d4173f87b10069b60c8c428b921e260fb 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
@@ -71,7 +71,40 @@
         </dataset>
 
         <dataset name="configurable_with_qty_1">
-            <field name="name" xsi:type="string">Test configurable product %isolation%</field>
+            <field name="name" xsi:type="string">sku_test_configurable_product_%isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
+            <field name="price" xsi:type="array">
+                <item name="dataset" xsi:type="string">price_40</item>
+            </field>
+            <field name="product_has_weight" xsi:type="string">This item has weight</field>
+            <field name="weight" xsi:type="string">30</field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">configurable-product-%isolation%</field>
+            <field name="configurable_attributes_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="checkout_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">configurable_options_with_qty_1</item>
+            </field>
+        </dataset>
+
+        <dataset name="configurable_with_qty_2">
+            <field name="name" xsi:type="string">sku_test_configurable_product_%isolation%</field>
             <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
             <field name="price" xsi:type="array">
                 <item name="dataset" xsi:type="string">price_40</item>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
index 2e9d708dd42d82ca79d0507b6a698c0c5c897d3b..1b6282b9432c39fd444ca2089f1b8c8aa6bfb876 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
@@ -17,5 +17,8 @@
         <dataset name="MAGETWO-12620">
             <field name="category_price" xsi:type="string">11</field>
         </dataset>
+        <dataset name="from-9">
+            <field name="price_from" xsi:type="string">9</field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
index 58435b066261ed28cc7f33ff01fc250940b6eb17..14ff24f18908da187a0631662cf74bfdaad5db6f 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\ConfigurableProduct\Test\TestCase\CreateConfigurableProductEntityTest" summary="Create Configurable Product" ticketId="MAGETWO-26041">
         <variation name="CreateConfigurableProductEntityTestVariation1" summary="Create product with category and two new options">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_new_options</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options</data>
@@ -32,6 +33,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately"/>
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation2" summary="Create product with two options">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options</data>
@@ -53,11 +55,13 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInCart" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation3" summary="Create product with special price">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product_special_price</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_new_options_with_special_price</data>
             <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">configurable_sku_%isolation%</data>
+            <data name="product/data/price/dataset" xsi:type="string">from-9</data>
             <data name="product/data/price/value" xsi:type="string">100</data>
             <data name="product/data/special_price" xsi:type="string">9</data>
             <data name="product/data/short_description" xsi:type="string">Configurable short description</data>
@@ -74,6 +78,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSpecialPriceOnProductPage" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation4" summary="Create product with assigned products to options">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options_with_assigned_product</data>
@@ -94,6 +99,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInCart" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation5" summary="Create Configurable Product and Assign it to Category" ticketId="MAGETWO-12620">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_fixed_price</data>
             <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data>
@@ -142,6 +148,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductAutoincrementedSkuNoticeMessage" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation9" summary="Create configurable product and assign it to custom website">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product_special_price</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_new_options_with_special_price</data>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dd92edc82b3310ad9610c70138578a220e4358cd
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Sales\Test\TestCase\CreateCreditMemoEntityTest" summary="Create Credit Memo for Offline Payment Methods" ticketId="MAGETWO-59074">
+        <variation name="CreateCreditMemoEntityWithConfigurableTestVariation1" ticketId="MAGETWO-12447">
+            <data name="description" xsi:type="string">Assert items return to stock (partial refund)</data>
+            <data name="data/items_data/0/back_to_stock" xsi:type="string">Yes</data>
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/entity_id/products" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
+            <data name="order/data/price/dataset" xsi:type="string">full_refund</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
+            <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertProductQtyDecreasedAfterCreditmemo" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml
index 62279a9fa579c99b8fce18ca6c39279834ce22c6..b069371fe5bec2aa39ea7c5ce6c7a3e6eb1d8977 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest">
         <variation name="DuplicateProductEntityTestVariation2" firstConstraint="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" method="test">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="productType" xsi:type="string">configurableProduct::default</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" next="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" next="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductDuplicateForm" />
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml
index 3d58645d618ffe4f34beb84cd3a1d58212649148..d1066de26d66c608bc96198585bb8a92112b3fbf 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Catalog\Test\TestCase\Product\MassProductUpdateTest" summary="Edit Products Using Mass Actions" ticketId="MAGETWO-21128">
         <variation name="MassProductUpdateTestVariation2" summary="Update stock data for simple and configurable">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="configData" xsi:type="string">product_flat</data>
             <data name="initialProducts/1" xsi:type="string">configurableProduct::out_of_stock</data>
             <data name="initialProducts/0" xsi:type="string">catalogProductSimple::out_of_stock</data>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php
index 7ff2be303d677a944e5c2391a509882ecb7d3e96..d3ab2ffa6b026e0ec0fe8d0d93655a49193e6127 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php
@@ -32,6 +32,7 @@ class UpdateConfigurableProductEntityTest extends Scenario
 {
     /* tags */
     const MVP = 'yes';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php
index 4919d364dc6fa07592556bc66674588ec84589c0..ac6b26e85fbeb23e9a04c8a8b709e57da3b696ee 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php
@@ -97,7 +97,7 @@ abstract class AbstractCurrencySymbolEntityTest extends Injectable
         $this->currencyIndex->getCurrencyRateForm()->clickImportButton();
         $this->currencyIndex->getCurrencyRateForm()->fillCurrencyUSDUAHRate();
         if ($this->currencyIndex->getMessagesBlock()->isVisibleMessage('warning')) {
-            throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessages());
+            throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessage());
         }
         $this->currencyIndex->getFormPageActions()->save();
     }
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
index 14a9d6f283b278228f178f4f3a14ffbe7786aceb..302f23104d959119f125fb6ab3b82b78078efa3d 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php
@@ -27,6 +27,7 @@ class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest
 {
     /* tags */
     const MVP = 'no';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
index 8740b0000ff58324787941a92213528b6c24d11d..e49f25bc4fa181ffce4e442e1dbda485b8c5a76b 100644
--- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php
@@ -28,6 +28,7 @@ class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest
 {
     /* tags */
     const MVP = 'no';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml
index 9802ef998048a8f9cfb8914b7288c4f119a667d1..70191dc828af7aecada34068c5d0e93cce4736ee 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml
@@ -61,8 +61,8 @@
             <field name="postcode" xsi:type="string">90230</field>
             <field name="country_id" xsi:type="string">United States</field>
             <field name="telephone" xsi:type="string">555-55-555-55</field>
-            <field name="default_billing" xsi:type="string">Yes</field>
-            <field name="default_shipping" xsi:type="string">No</field>
+            <field name="default_billing" xsi:type="string">No</field>
+            <field name="default_shipping" xsi:type="string">Yes</field>
         </dataset>
 
         <dataset name="US_address_1">
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
index 14e3a9642d1a5d649536d0b84070c8ae3e9210a6..766cf96b3d6447029384715ea57e06bf21dda1e8 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
@@ -19,6 +19,7 @@
             <constraint name="Magento\Customer\Test\Constraint\AssertCustomerForm" />
         </variation>
         <variation name="CreateCustomerBackendEntityTestVariation2" summary="Customer with prefix">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="customerAction" xsi:type="string">save</data>
             <data name="customer/data/group_id/dataset" xsi:type="string">Wholesale</data>
             <data name="customer/data/prefix" xsi:type="string">M</data>
@@ -92,6 +93,7 @@
             <constraint name="Magento\Customer\Test\Constraint\AssertCustomerBackendFormTitle" />
         </variation>
         <variation name="CreateCustomerBackendEntityTestVariation7" summary="Create customer with custom customer group">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="customerAction" xsi:type="string">saveAndContinue</data>
             <data name="customer/data/website_id" xsi:type="string">Main Website</data>
             <data name="customer/data/group_id/dataset" xsi:type="string">customer_group_retail_customer</data>
@@ -131,6 +133,7 @@
             <constraint name="Magento\Customer\Test\Constraint\AssertCustomerBackendRequiredFields" />
         </variation>
         <variation name="CreateCustomerBackendEntityTestVariation10" summary="Create customer with 2 websites and with different allowed countries.">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="customerAction" xsi:type="string">save</data>
             <data name="customer/data/website_id" xsi:type="string">Main Website</data>
             <data name="customer/data/group_id/dataset" xsi:type="string">General</data>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php
index 64051195daa32a808536adb8afaa6a5100c51ce6..c354e733a6913263d3b2ea1cb72d63bb7434c9a2 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php
@@ -29,6 +29,7 @@ class CreateCustomerGroupEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php
index 61771665c059ed1783c3e3820a8005601d91e631..1f00df69dfb578e552429ccdeb43a02254951d95 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php
@@ -30,6 +30,7 @@ class DeleteCustomerAddressTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
index 18791441b1d20754360d80d7757bffe922d6c40e..b967fbd184526fd1d71fcf2055799842d0d018f1 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328">
         <variation name="CustomerGridSorting">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Verify customer page grid sorting</data>
             <data name="columnsForSorting" xsi:type="array">
                 <item name="id" xsi:type="string">ID</item>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml
index e86104e992deebf2b925e8a67b3346be7a6e2907..af57affcd7f07bf42182f444b16fc85ffe274ade 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Customer\Test\TestCase\MassAssignCustomerGroupTest" summary="Mass Assign Customer's Group to Customers" ticketId="MAGETWO-27892">
         <variation name="MassAssignCustomerGroupTestVariation1">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="customerGroup/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Customer\Test\Constraint\AssertMassActionSuccessUpdateMessage" />
             <constraint name="Magento\Customer\Test\Constraint\AssertCustomerGroupInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml
index 2985252d82ffae55c5a932927623ecf7cf470aa3..cdbfd91ddbd49dddc040569252bb1a988c262a5c 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Customer\Test\TestCase\MassDeleteCustomerBackendEntityTest" summary="Customer Mass Delete" ticketId="MAGETWO-26848">
         <variation name="MassDeleteCustomerBackendEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="customersQty" xsi:type="string">3</data>
             <data name="customersQtyToDelete" xsi:type="string">2</data>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml
index 31a947ad1ab02771464cdf9f8cd93f01f2451718..96e78f58d78c8402a133184b633614e4e4fd20c7 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Customer\Test\TestCase\RegisterCustomerFrontendEntityTest" summary="Register New Customer" ticketId="MAGETWO-23546">
         <variation name="RegisterCustomerFrontendEntityTestVariation1" summary="Register new customer">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="customer/data/firstname" xsi:type="string">john</data>
             <data name="customer/data/lastname" xsi:type="string">doe</data>
             <data name="customer/data/email" xsi:type="string">johndoe%isolation%@example.com</data>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
index c2132672d900a65fe81b3f011266d036cd390e91..7855fb0f17dd2d709a383722475ec1e95fbfa737 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Customer\Test\TestCase\UpdateCustomerBackendEntityTest" summary="Update Backend Customer" ticketId="MAGETWO-23881">
         <variation name="UpdateCustomerBackendEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="customer/data/group_id/dataset" xsi:type="string">Wholesale</data>
             <data name="customer/data/prefix" xsi:type="string">%isolation%Prefix_</data>
@@ -44,6 +45,7 @@
             <constraint name="Magento\Customer\Test\Constraint\AssertCustomerInGrid" />
         </variation>
         <variation name="UpdateCustomerBackendEntityTestVariation3" summary="Address with alphanumeric zip">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="customer/data/group_id/dataset" xsi:type="string">Retailer</data>
             <data name="customer/data/prefix" xsi:type="string">%isolation%Prefix_</data>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php
index 7fda95c0be7d2e48e58cb2a01317704cc54a0b57..bd21e9aca690525910b5500e69e6b5913449d2e5 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php
@@ -32,6 +32,7 @@ class UpdateCustomerGroupEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml
index e2f49d40cac7395734acc42783f5fce6b0c74083..9d12218ccf0dddf72b15a21db85e6c211848f0b8 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml
@@ -24,6 +24,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" />
         </variation>
         <variation name="CreateDownloadableProductEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create product with default set links</data>
             <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data>
             <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data>
@@ -53,6 +54,7 @@
             <data name="product/data/downloadable_sample/dataset" xsi:type="string">with_two_samples</data>
             <data name="product/data/downloadable_links/dataset" xsi:type="string">with_two_separately_links</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
@@ -91,6 +93,7 @@
             <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data>
             <data name="product/data/custom_options/dataset" xsi:type="string">two_options</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductCustomOptionsOnProductPage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
@@ -118,6 +121,7 @@
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
         </variation>
         <variation name="CreateDownloadableProductEntityTestVariation7">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create product with manage stock</data>
             <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data>
             <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data>
@@ -135,6 +139,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" />
         </variation>
         <variation name="CreateDownloadableProductEntityTestVariation8">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Create product without tax class id</data>
             <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data>
             <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data>
@@ -166,6 +171,7 @@
             <data name="product/data/custom_options/dataset" xsi:type="string">default</data>
             <data name="product/data/custom_options/import_products" xsi:type="string">catalogProductSimple::with_two_custom_option,catalogProductSimple::with_all_custom_option</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
@@ -189,6 +195,7 @@
             <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data>
             <data name="product/data/custom_options/dataset" xsi:type="string">default</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
@@ -210,6 +217,7 @@
             <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data>
             <data name="product/data/custom_options/dataset" xsi:type="string">default</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
@@ -278,6 +286,7 @@
             <data name="product/data/downloadable_links/dataset" xsi:type="string">with_two_separately_links</data>
             <data name="product/data/tier_price/dataset" xsi:type="string">default</data>
             <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" />
@@ -285,6 +294,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" />
         </variation>
         <variation name="CreateDownloadableProductEntityTestVariation16" summary="Create downloadable product and assign it to custom website">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data>
             <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data>
             <data name="product/data/price/value" xsi:type="string">350</data>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml
index be38a73902cd71a2a893b0f2aaf94ac70ebb4273..8e844fa90ddf94a48ed09bc1b7ed9285b51ef555 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml
@@ -9,6 +9,7 @@
     <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest">
         <variation name="DuplicateProductEntityTestVariation3" firstConstraint="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" method="test">
             <data name="productType" xsi:type="string">downloadableProduct::default</data>
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" next="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" next="Magento\Downloadable\Test\Constraint\AssertDownloadableDuplicateForm" />
             <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableDuplicateForm" next="Magento\Catalog\Test\Constraint\AssertProductDuplicatedInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml
index 87a124814fc222b7ae21df4b47b6b75284fdcdf0..e2afcbeb7cce01be9b5200b8a06c1af4392490f4 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest">
         <variation name="DownloadableTaxCalculationTestVariation1" summary="Downloadable product with sales rule, customer tax equals store tax and catalog price excluding tax" ticketId="MAGETWO-32076">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_special_price_and_category</data>
             <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
@@ -34,6 +35,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="DownloadableTaxCalculationTestVariation2" summary="Downloadable product with catalog rule, customer tax greater than store tax and catalog price excluding tax" ticketId="MAGETWO-32076">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_including_tax</data>
             <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_special_price_and_category</data>
             <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data>
@@ -53,6 +55,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendIncludingTax" />
         </variation>
         <variation name="DownloadableTaxCalculationTestVariation4" summary="Downloadable product with catalog rule, customer tax greater than store tax and catalog price including tax" ticketId="MAGETWO-32076">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_custom_options_and_category</data>
             <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data>
@@ -77,6 +80,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="DownloadableTaxCalculationTestVariation6" summary="Downloadable product with catalog rule, customer tax equals store tax and catalog price including tax" ticketId="MAGETWO-32076">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl</data>
             <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_custom_options_and_category</data>
             <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php
index 276cc08e8efb74f05c70868cdf67a77f452bb44a..91281de3cdbdaf1308d0aca1473aaf7aab808688 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php
@@ -37,6 +37,7 @@ class UpdateDownloadableProductEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php
index dc86b6479757e00564877fa3f52c7e5c6c3ef4f5..69bae8412db119983edf5f99e73da7399af5f9a7 100644
--- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php
@@ -30,6 +30,7 @@ class CreateEmailTemplateEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const DOMAIN = 'PS';
+    const TO_MAINTAIN = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
     /* end tags */
 
diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml
index 3913817d8f3205105356b39d39e48bc212e6ca66..6226713f316c5f0a90f06291a3a8160a65ac912f 100644
--- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml
@@ -27,6 +27,7 @@
             <constraint name="Magento\GiftMessage\Test\Constraint\AssertGiftMessageInFrontendOrder" />
         </variation>
         <variation name="CheckoutWithGiftMessagesTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="products/1" xsi:type="string">catalogProductVirtual::default</data>
             <data name="customer/dataset" xsi:type="string">default</data>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
index 47592328f39c10d7a257b014de640e82f969c639..a8a2aebbf2f259875cf55fecd3ac5d59f7b2b52c 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
@@ -57,6 +57,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" />
         </variation>
         <variation name="CreateGroupedProductEntityTestVariation5" summary="Create with no required products">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">test-grouped-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku%isolation%</data>
@@ -109,6 +110,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
         <variation name="CreateGroupedProductEntityTestVariation10" summary="Create Grouped Product and Assign it on Custom Website">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/data/url_key" xsi:type="string">test-grouped-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml
index 91c26ddb6acbc1adf214828b7cbde9b041b81eb0..92a842ee5a71e4ea2bc8a2eeba6fd3bdc6bbbeb8 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Checkout\Test\TestCase\DeleteProductFromMiniShoppingCartTest" summary="Delete Grouped Product from Mini Shopping Cart" ticketId="MAGETWO-29104">
         <variation name="DeleteGroupedProductFromMiniShoppingCartTestVariation">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">groupedProduct::default</data>
             <data name="deletedProductIndex" xsi:type="string">0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" />
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml
index d2ae0836e5e7654ddc37288c582ebe9dece27e65..11f854749d3fdcde8d149fcc6e1519e359dee3d1 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\GroupedProduct\Test\TestCase\UpdateGroupedProductEntityTest" summary="Update Grouped Product" ticketId="MAGETWO-26462">
         <variation name="UpdateGroupedProductEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="originalProduct/dataset" xsi:type="string">grouped_product_out_of_stock</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data>
@@ -21,6 +22,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
         </variation>
         <variation name="UpdateGroupedProductEntityTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="originalProduct/dataset" xsi:type="string">default</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data>
@@ -31,6 +33,7 @@
             <constraint name="Magento\GroupedProduct\Test\Constraint\AssertGroupedProductForm" />
         </variation>
         <variation name="UpdateGroupedProductEntityTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="originalProduct/dataset" xsi:type="string">default</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data>
@@ -42,6 +45,7 @@
             <constraint name="Magento\GroupedProduct\Test\Constraint\AssertGroupedProductForm" />
         </variation>
         <variation name="UpdateGroupedProductEntityTestVariation4">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="originalProduct/dataset" xsi:type="string">default</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data>
@@ -52,6 +56,7 @@
             <constraint name="Magento\GroupedProduct\Test\Constraint\AssertSpecialPriceOnGroupedProductPage" />
         </variation>
         <variation name="UpdateGroupedProductEntityTestVariation5">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="originalProduct/dataset" xsi:type="string">default</data>
             <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data>
             <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
index 03dbfee05ca6973d90da4a4205eb1b64f9f2edca..bf4886a9f208d4a9bf308ee8f5f8b26daf9c6d6e 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
@@ -21,7 +21,7 @@ class WebConfiguration extends Form
      *
      * @var string
      */
-    protected $next = "[ng-click*='next']";
+    protected $next = "[ng-click*='validateUrl']";
 
     /**
      * 'Advanced Options' locator.
diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml
index e09d2a23559b97a904e59899177177ae38f9b93f..5965aa7ce3c581264c73106afd52197be71af583 100644
--- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml
@@ -20,6 +20,7 @@
             <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationInGrid" />
         </variation>
         <variation name="UpdateIntegrationEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="integration/data/name" xsi:type="string">Integration_%isolation%</data>
             <data name="integration/data/email" xsi:type="string">-</data>
             <data name="integration/data/endpoint" xsi:type="string">-</data>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php
index a79ea3995eeff08464befe26a71e61171af3bc2e..0203cf89fe7d2d5b4745a65625df5cb14602be8d 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php
@@ -31,6 +31,7 @@ class ActionNewsletterTemplateEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml
index 13b499fca5e3c40754fd78f54b158361514bbb8a..206e2d01468e7e03300fd328e798bd6b70069b73 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Newsletter\Test\TestCase\PreviewNewsletterTemplateEntityTest" summary="Newsletter Template Preview" ticketId="MAGETWO-51979">
         <variation name="PreviewNewsletterTemplateEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="newsletter/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterPreview" />
         </variation>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php
index d83ae0c53ec0a575ba11280b9a8731bbe23a6f8a..6e4849669568851cbe4787766c6cf8b2f630e9e6 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php
@@ -20,8 +20,6 @@ class ExpressCheckout extends Block
      * @var array
      */
     private $fields = [
-        'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_alternative_payment_methods_express_' .
-            'checkout_us_express_checkout_required_express_checkout_required_express_checkout_business_account',
         'API Username' => '#payment_us_paypal_alternative_payment_methods_express_checkout_us_express_checkout_' .
             'required_express_checkout_required_express_checkout_api_username',
         'API Password' => '#payment_us_paypal_alternative_payment_methods_express_checkout_us_express_checkout_' .
@@ -72,8 +70,6 @@ class ExpressCheckout extends Block
      */
     public function specifyCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])
-            ->setValue('test@test.com');
         $this->_rootElement->find($this->fields['API Username'])->setValue('1');
         $this->_rootElement->find($this->fields['API Password'])->setValue('1');
         $this->_rootElement->find($this->fields['API Signature'])->setValue('1');
@@ -86,7 +82,6 @@ class ExpressCheckout extends Block
      */
     public function clearCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue('');
         $this->_rootElement->find($this->fields['API Username'])->setValue('');
         $this->_rootElement->find($this->fields['API Password'])->setValue('');
         $this->_rootElement->find($this->fields['API Signature'])->setValue('');
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php
index de6eb107c61ce5e6b63451abdea0473351ddde43..f1af6acb6174e1b462651b7887d80159d6910952 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php
@@ -20,8 +20,6 @@ class PayflowLink extends Block
      * @var array
      */
     private $fields = [
-        'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_payment_gateways_payflow_link_us_' .
-            'payflow_link_required_payflow_link_payflow_link_business_account',
         'Partner' => '#payment_us_paypal_payment_gateways_payflow_link_us_payflow_link_required_payflow_link_payflow_' .
             'link_partner',
         'Vendor' => '#payment_us_paypal_payment_gateways_payflow_link_us_payflow_link_required_payflow_link_payflow_' .
@@ -60,8 +58,6 @@ class PayflowLink extends Block
      */
     public function specifyCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])
-            ->setValue('test@test.com');
         $this->_rootElement->find($this->fields['Partner'])->setValue('1');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('1');
         $this->_rootElement->find($this->fields['User'])->setValue('1');
@@ -75,7 +71,6 @@ class PayflowLink extends Block
      */
     public function clearCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue('');
         $this->_rootElement->find($this->fields['Partner'])->setValue('');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('');
         $this->_rootElement->find($this->fields['User'])->setValue('');
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php
index e3b01aa3af9a0dfa4517ad3fe4b527eec9d30ad0..1db07ac435a37ed9c9d9d237f62b7debed956861 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php
@@ -20,8 +20,6 @@ class PayflowPro extends Block
      * @var array
      */
     private $fields = [
-        'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_' .
-            'with_express_checkout_paypal_payflow_required_paypal_payflow_api_settings_business_account',
         'Partner' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_with_express_checkout_paypal_payflow_' .
             'required_paypal_payflow_api_settings_partner',
         'Vendor' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_with_express_checkout_paypal_payflow_' .
@@ -60,8 +58,6 @@ class PayflowPro extends Block
      */
     public function specifyCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])
-            ->setValue('test@test.com');
         $this->_rootElement->find($this->fields['Partner'])->setValue('1');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('1');
         $this->_rootElement->find($this->fields['User'])->setValue('1');
@@ -75,7 +71,6 @@ class PayflowPro extends Block
      */
     public function clearCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue('');
         $this->_rootElement->find($this->fields['Partner'])->setValue('');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('');
         $this->_rootElement->find($this->fields['User'])->setValue('');
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php
index cd6d1a5b1b38a016382ffa2e68ab73bd566c4116..87adb729a1646e6eb5b61e8e167d2eed20111e4e 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php
@@ -20,8 +20,6 @@ class PaymentsAdvanced extends Block
      * @var array
      */
     private $fields = [
-        'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_group_all_in_one_payflow_advanced_' .
-            'required_settings_payments_advanced_business_account',
         'Partner' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_partner',
         'Vendor' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_vendor',
         'User' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_user',
@@ -54,8 +52,6 @@ class PaymentsAdvanced extends Block
      */
     public function specifyCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])
-            ->setValue('test@test.com');
         $this->_rootElement->find($this->fields['Partner'])->setValue('1');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('1');
         $this->_rootElement->find($this->fields['User'])->setValue('1');
@@ -69,7 +65,6 @@ class PaymentsAdvanced extends Block
      */
     public function clearCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue('');
         $this->_rootElement->find($this->fields['Partner'])->setValue('');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('');
         $this->_rootElement->find($this->fields['User'])->setValue('');
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php
index cd146aa8f809cf5de0cbddcb02be83a19e59928f..55fd7444ba50ad8dbf9662b758b10d7a70ee6c6d 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php
@@ -20,8 +20,6 @@ class PaymentsPro extends Block
      * @var array
      */
     private $fields = [
-        'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_' .
-            'payflow_required_paypal_payflow_api_settings_business_account',
         'Partner' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_payflow_required_paypal_payflow_api_' .
             'settings_partner',
         'Vendor' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_payflow_required_paypal_payflow_api_' .
@@ -60,8 +58,6 @@ class PaymentsPro extends Block
      */
     public function specifyCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])
-            ->setValue('test@test.com');
         $this->_rootElement->find($this->fields['Partner'])->setValue('1');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('1');
         $this->_rootElement->find($this->fields['User'])->setValue('1');
@@ -75,7 +71,6 @@ class PaymentsPro extends Block
      */
     public function clearCredentials()
     {
-        $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue('');
         $this->_rootElement->find($this->fields['Partner'])->setValue('');
         $this->_rootElement->find($this->fields['Vendor'])->setValue('');
         $this->_rootElement->find($this->fields['User'])->setValue('');
diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml
index 9dfcc4d8bac35141a99400cb88df7e4206dfce44..0bcf0db70b2fba7a98b02e326f7d986d5f3c95f9 100644
--- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\ProductVideo\Test\TestCase\AddProductVideoTest" summary="Add Video to PCF" ticketId="MAGETWO-43672">
         <variation name="AddProductVideoEntityTestVariation1" summary="Add youtube video with all available fields filled in">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/dataset" xsi:type="string">product_with_video_youtube</data>
             <data name="configData" xsi:type="string">youtube_api_key,play_if_base</data>
             <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" />
@@ -15,6 +16,7 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
         </variation>
         <variation name="AddProductVideoEntityTestVariation2" summary="Add vimeo video with all available fields filled in">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/dataset" xsi:type="string">product_with_video_vimeo</data>
             <data name="configData" xsi:type="string">play_if_base</data>
             <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" />
diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml
index 78a7fe00ab9f43227ffe4828769dd3b627e8cfce..26df238f11b286f47d4a923084cc56dd7d6985dd 100644
--- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\ProductVideo\Test\TestCase\DeleteProductVideoTest" summary="Delete Video from PCF - Delete video" ticketId="MAGETWO-43660">
         <variation name="DeleteVideoEntityTestVariation1" summary="Delete video youtube" ticketId="MAGETWO-43660">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/dataset" xsi:type="string">product_with_video_youtube</data>
             <data name="configData" xsi:type="string">youtube_api_key,play_if_base</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductNoImageInGrid" />
@@ -15,6 +16,7 @@
             <constraint name="Magento\ProductVideo\Test\Constraint\AssertNoVideoProductView" />
         </variation>
         <variation name="DeleteVideoEntityTestVariation2" summary="Delete video vimeo" ticketId="MAGETWO-43660">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/dataset" xsi:type="string">product_with_video_vimeo</data>
             <data name="configData" xsi:type="string">play_if_base</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductNoImageInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php
index 30df076817dff80416933e9bccf11d598fb28a87..a02ba30f716ecea19e2ec06a30e0627afcd997a6 100644
--- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php
+++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php
@@ -33,8 +33,9 @@ use Magento\Mtf\TestCase\Injectable;
 class UpdateProductVideoTest extends Injectable
 {
     /* tags */
-    const TEST_TYPE = 'acceptance_test, extended_acceptance_test';
+    const TEST_TYPE = 'extended_acceptance_test';
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
index 5930e63b9d3bd367a4c93fb241cc64613fa9aea6..95c9d518a391ddb679c3d5a4118ef79391d2cdca 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
@@ -34,6 +34,7 @@ class AbandonedCartsReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
index cacb6e5a329bff99eb28fd62118f440c569ade46..7dc9b6106b7bb20d8507af83840abb030e9b24e7 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
@@ -31,6 +31,7 @@ class CustomersOrderCountReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml
index 6e37965603c787083bfa0a9b337d1b770df3bfec..3a25f81d37fb6316e27a891a573503778443d57b 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml
@@ -8,16 +8,19 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Reports\Test\TestCase\DownloadProductsReportEntityTest" summary="Download Products Report" ticketId="MAGETWO-28823">
         <variation name="DownloadProductsReportEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="order/dataset" xsi:type="string">downloadable_product</data>
             <data name="downloads" xsi:type="string">1</data>
             <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" />
         </variation>
         <variation name="DownloadProductsReportEntityTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="order/dataset" xsi:type="string">two_downloadable_product</data>
             <data name="downloads" xsi:type="string">2</data>
             <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" />
         </variation>
         <variation name="DownloadProductsReportEntityTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="order/dataset" xsi:type="string">downloadable_product</data>
             <data name="downloads" xsi:type="string">0</data>
             <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" />
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml
index c484c94a976f6340706e0b6f5ab045b16c83caf7..582d41a9d3bb2957abdb136a0032c051f3b5d949 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Reports\Test\TestCase\NewAccountsReportEntityTest" summary="New Accounts Report" ticketId="MAGETWO-27742">
         <variation name="NewAccountsReportEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="total" xsi:type="string">1</data>
             <data name="customersReport/report_from" xsi:type="string">m/d/Y</data>
@@ -16,6 +17,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertNewAccountsReportTotalResult" />
         </variation>
         <variation name="NewAccountsReportEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="total" xsi:type="string">1</data>
             <data name="customersReport/report_from" xsi:type="string">m/d/Y</data>
@@ -24,6 +26,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertNewAccountsReportTotalResult" />
         </variation>
         <variation name="NewAccountsReportEntityTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="total" xsi:type="string">1</data>
             <data name="customersReport/report_from" xsi:type="string">m/d/Y</data>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
index 7d0d13862e7720b0b63516639d8b4968909c66cc..dc09819ab98790fd7b6b8acf6b69aad614ef7ccd 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
@@ -28,6 +28,7 @@ class OrderedProductsReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php
index 0d59b989fc25fc162e450ce719c96413229c45fe..8d686421a524bfc610ab22e16cc6780e559d32c9 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php
@@ -34,6 +34,7 @@ class SalesCouponReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php
index 3ebfd4746a858f92381e9c58e8b20cc84356c0be..b8e5a5276d616061eb1e2e0c30fe74801fb96479 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php
@@ -37,6 +37,7 @@ class SalesInvoiceReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml
index b1957b6315765538644619f27390d06ae0dd7aa0..1d8adebd6befdc04d23a4b6653eafeb3ce26d410 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml
@@ -21,6 +21,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertSalesReportTotalResult" />
         </variation>
         <variation name="SalesOrderReportEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/price/dataset" xsi:type="string">full_invoice</data>
             <data name="salesReport/report_type" xsi:type="string">Order Created</data>
@@ -34,6 +35,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertSalesReportTotalResult" />
         </variation>
         <variation name="SalesOrderReportEntityTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/price/dataset" xsi:type="string">full_invoice</data>
             <data name="salesReport/report_type" xsi:type="string">Order Updated</data>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml
index a3b971ec5a8caf5332c9be61a1397a28c4e4ead0..927e461fc2181d818ecaca45a57d9876f44f2965 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml
@@ -20,6 +20,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertRefundReportIntervalResult" />
         </variation>
         <variation name="SalesRefundsReportEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">assert refunds month report</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/price/dataset" xsi:type="string">full_invoice</data>
@@ -32,6 +33,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertRefundReportIntervalResult" />
         </variation>
         <variation name="SalesRefundsReportEntityTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">assert refund Daily report</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/price/dataset" xsi:type="string">full_invoice</data>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml
index df6eb7759fd5558110925b224de31d72090702c6..69440d5f15e3fe9508ae7d8a1efd3d31c8940417 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml
@@ -22,6 +22,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertTaxReportNotInGrid" />
         </variation>
         <variation name="SalesTaxReportEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="orderSteps" xsi:type="string">invoice</data>
             <data name="taxRule/dataset" xsi:type="string">custom_rule</data>
             <data name="order/dataset" xsi:type="string">default</data>
@@ -37,6 +38,7 @@
             <constraint name="Magento\Reports\Test\Constraint\AssertTaxReportInGrid" />
         </variation>
         <variation name="SalesTaxReportEntityTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="orderSteps" xsi:type="string">invoice,shipment</data>
             <data name="taxRule/dataset" xsi:type="string">custom_rule</data>
             <data name="order/dataset" xsi:type="string">default</data>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php
index 905fa8fb70f0cebff985cf4a99d193359969e5e1..6c22348179897ffa0d533dba563a5fce06657632 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php
@@ -33,6 +33,7 @@ class ViewedProductsReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
index 9130c5285848e2d04f5978403c23ae0b2278ff16..251cbd75a793f8a0382180041b20529784526e57 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
@@ -34,6 +34,7 @@ class CreateProductReviewBackendEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml
index 786203e93f24d8e29ba779c8ed0ad3b4b66f0626..8cd4e44b7622a2de828b9f2d9a96738a41ae2911 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Review\Test\TestCase\CreateProductReviewFrontendEntityTest" summary="Create Frontend Product Review" ticketId="MAGETWO-25519">
         <variation name="CreateProductReviewFrontendEntityTestVariation1" summary="Create product review with rating">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="review/data/type" xsi:type="string">Guest</data>
             <data name="review/data/nickname" xsi:type="string">name_%isolation%</data>
             <data name="review/data/title" xsi:type="string">title_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php
index fc58266356223d48457d54a14d508a01712acc4c..3f1adc16694ccee1b7ba8aec945e71d8d2b30d52 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php
@@ -43,6 +43,7 @@ class ManageProductReviewFromCustomerPageTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml
index 5d731c736fd69245c110161823374f3ca2843ccc..86dca577d0094e3d3fd20e15b1a9b22eabd75a1e 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Review\Test\TestCase\UpdateProductReviewEntityOnProductPageTest" summary="Update Product Review from Product Page" ticketId="MAGETWO-27743">
         <variation name="UpdateProductReviewEntityOnProductPageTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="rating" xsi:type="string">3</data>
             <data name="review/data/status_id" xsi:type="string">Approved</data>
             <data name="productRating/data/select_stores" xsi:type="string">Main Website/Main Website Store/Default Store View</data>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml
index 549c3c3ddc3a8d91292e1169c8fe3084f628b2e9..71c40ca27fac05b1b1c3b4e4c6609d98e788ea0b 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Review\Test\TestCase\UpdateProductReviewEntityTest" summary="Update Product Review" ticketId="MAGETWO-25604">
         <variation name="UpdateProductReviewEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="reviewInitial/dataset" xsi:type="string">review_for_simple_product_with_rating</data>
             <data name="review/data/nickname" xsi:type="string">name_upd_%isolation%</data>
             <data name="review/data/title" xsi:type="string">title_upd_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
index c25b96a624bfda79865d81f73f3208f0bc38d74a..9e0c1517d3d7eae9c8945b6c822928eaef0ac64f 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
@@ -339,6 +339,7 @@ class Create extends Block
         $this->getTemplateBlock()->waitLoader();
         $this->_rootElement->find($this->orderMethodsSelector)->click();
         $this->getBillingMethodBlock()->selectPaymentMethod($paymentCode, $creditCard);
+        $this->_rootElement->click();
         $this->getTemplateBlock()->waitLoader();
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..f48e9e198210c02a66870674cbc35178b7d91df4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Test\Constraint;
+
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\ObjectManager;
+use Magento\Mtf\System\Event\EventManagerInterface;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+
+/**
+ * Class AssertProductQtyDecreasedAfterCreditmemo
+ */
+class AssertProductQtyDecreasedAfterCreditmemo extends AbstractConstraint
+{
+    /**
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Skip fields for create product fixture.
+     *
+     * @var array
+     */
+    protected $skipFields = [
+        'attribute_set_id',
+        'website_ids',
+        'checkout_data',
+        'type_id',
+        'price',
+    ];
+
+    /**
+     * AssertFirstProductForm constructor.
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(
+        ObjectManager $objectManager,
+        EventManagerInterface $eventManager,
+        FixtureFactory $fixtureFactory
+    ) {
+        $this->fixtureFactory = $fixtureFactory;
+        parent::__construct($objectManager, $eventManager);
+    }
+
+    /**
+     * Assert form data equals fixture data
+     *
+     * @param OrderInjectable $order
+     * @param array $data
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductEdit $productPage
+     * @return void
+     */
+    public function processAssert(
+        OrderInjectable $order,
+        array $data,
+        CatalogProductIndex $productGrid,
+        CatalogProductEdit $productPage
+    ) {
+        $product = $this->getProduct($order, $data);
+        $this->objectManager->get(\Magento\Catalog\Test\Constraint\AssertProductForm::class)->processAssert(
+            $product,
+            $productGrid,
+            $productPage
+        );
+    }
+
+    /**
+     * Get product's fixture.
+     *
+     * @param OrderInjectable $order
+     * @param array $data
+     * @param int $index [optional]
+     * @return FixtureInterface
+     */
+    protected function getProduct(OrderInjectable $order, array $data, $index = 0)
+    {
+        if (!isset($data['items_data'][$index]['back_to_stock'])
+            || $data['items_data'][$index]['back_to_stock'] != 'Yes'
+        ) {
+            return $order->getEntityId()['products'][$index];
+        }
+        $product = $order->getEntityId()['products'][$index];
+        $productData = $product->getData();
+        $checkoutDataQty = $productData['checkout_data']['qty'];
+        $productData['quantity_and_stock_status']['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']);
+
+        $productData = array_diff_key($productData, array_flip($this->skipFields));
+
+        return $this->fixtureFactory->create(get_class($product), ['data' => $productData]);
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product qty was decreased after creditmemo creation.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml
index 3e2dfdd7125074ac64fdc6c7a39cdc762348585a..3da1f91925e0a1274cbe317d36f2bc40271cbeb6 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml
@@ -43,5 +43,12 @@
                 <item name="grand_creditmemo_total" xsi:type="string">110</item>
             </field>
         </dataset>
+
+        <dataset name="free_invoice">
+            <field name="0" xsi:type="array">
+                <item name="grand_order_total" xsi:type="string">0</item>
+                <item name="grand_invoice_total" xsi:type="string">0</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
index b65b9a31f72f3d7ff7290afb4393edeaf73679bc..e839681907c6d291b0855f138fa7d52c9b1dd4fa 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\CancelCreatedOrderTest" summary="Cancel Created Order for Offline Payment Methods" ticketId="MAGETWO-28191">
         <variation name="CancelCreatedOrderTestVariationWithCheckMoneyOrderPaymentMethod" summary="Cancel order with check/money order payment method and check status on storefront">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data>
             <data name="status" xsi:type="string">Canceled</data>
@@ -17,6 +18,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
         </variation>
         <variation name="CancelCreatedOrderTestVariationWithZeroSubtotalCheckout" summary="Cancel order with zero subtotal checkout payment method and check status on storefront">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data>
             <data name="order/data/shipping_method" xsi:type="string">freeshipping_freeshipping</data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
index 9d19d10f4d40c6c3e317a97e7e83cd3c79e6f8ae..92b341bef2675fe635f804da2d9a17c5eea54c49 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
@@ -90,32 +90,7 @@ class CreateCreditMemoEntityTest extends Injectable
 
         return [
             'ids' => ['creditMemoIds' => $result['creditMemoIds']],
-            'product' => $this->getProduct($order, $data),
             'customer' => $order->getDataFieldConfig('customer_id')['source']->getCustomer()
         ];
     }
-
-    /**
-     * Get product's fixture.
-     *
-     * @param OrderInjectable $order
-     * @param array $data
-     * @param int $index [optional]
-     * @return FixtureInterface
-     */
-    protected function getProduct(OrderInjectable $order, array $data, $index = 0)
-    {
-        if (!isset($data['items_data'][$index]['back_to_stock'])
-            || $data['items_data'][$index]['back_to_stock'] != 'Yes'
-        ) {
-            return $order->getEntityId()['products'][$index];
-        }
-        $product = $order->getEntityId()['products'][$index];
-        $productData = $product->getData();
-        $checkoutDataQty = $productData['checkout_data']['qty'];
-        $productData['quantity_and_stock_status']['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']);
-        $productData = array_diff_key($productData, array_flip($this->skipFields));
-
-        return $this->fixtureFactory->create(get_class($product), ['data' => $productData]);
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
index 02b9640acbea4159c0560e8a4727a13cc36e1199..b2cf9843598f48af778edda5a4240409fd9d0365 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
@@ -22,7 +22,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundOrderStatusInCommentsHistory" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderCommentsHistoryNotifyStatus" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" />
-            <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertProductQtyDecreasedAfterCreditmemo" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoItems" />
         </variation>
         <variation name="CreateCreditMemoEntityTestVariation2" summary="Assert 0 shipping refund">
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
index f7cdaf74ab0f57e0544a392f6a936498bcb8efee..fc866fab6dc17fbf35d1176594ae2e8836ecf87e 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
@@ -31,6 +31,7 @@ class CreateInvoiceEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
index 8753de91d1f4301710f15a968b7a7ea24e04d663..116d3cb5d4a5e36dcf30b04a953c0f94cdc3e7f0 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
@@ -68,7 +68,7 @@
         </variation>
         <variation name="CreateInvoiceEntityTestVariationWithZeroSubtotalCheckout">
             <data name="order/dataset" xsi:type="string">default</data>
-            <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data>
+            <data name="order/data/price/dataset" xsi:type="string">free_invoice</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data>
             <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml
index ad4cc670e43cdd6087ede4ffdb2ebffff5343f0a..bd592e9d71aaa1e9d74279af53c80ac3b319e376 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml
@@ -69,6 +69,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
         </variation>
         <variation name="CreateOrderBackendTestVariation4">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Create order with virtual product for registered UK customer using Bank Transfer payment method</data>
             <data name="products/0" xsi:type="string">catalogProductVirtual::default</data>
             <data name="customer/dataset" xsi:type="string">default</data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml
index 4e61abb7c5d50b783f407a926d56b6e60473a5ae..b4c3a7568a2a1dd4fb62fe0d013b6425d372d27d 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridFilteringTest" summary="Grid UI Component Filtering" ticketId="MAGETWO-41328">
         <variation name="SalesOrderGridFiltering">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Verify sales order grid filtering</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">-</item>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml
index abd9432fe098e836ce34f0107f89e099620a33de..0979d0dcbff250a7f0bdb2d5151f60004f72efd0 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridFullTextSearchTest" summary="Grid UI Component Full Text Search" ticketId="MAGETWO-41023">
         <variation name="SalesOrderGridFullTextSearch">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Verify sales order grid full text search</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">-</item>
@@ -23,6 +24,7 @@
             <constraint name="Magento\Ui\Test\Constraint\AssertGridFullTextSearch"/>
         </variation>
         <variation name="SalesInvoiceGridFullTextSearch">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Verify sales invoice grid full text search</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateInvoiceStep</item>
@@ -55,6 +57,7 @@
             <constraint name="Magento\Ui\Test\Constraint\AssertGridFullTextSearch"/>
         </variation>
         <variation name="SalesCreditMemoGridFullTextSearch">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Verify sales credit memo grid full text search</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml
index 056fa5136d433ba1700b462ad12a1c0747b9dcc1..f82f232625841ddfdd77e66812970a4de31efea6 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328">
         <variation name="SalesOrderGridSorting">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Verify sales order grid storting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">-</item>
@@ -26,6 +27,7 @@
             <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/>
         </variation>
         <variation name="SalesInvoiceGridSorting">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Verify sales invoince grid storting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateInvoiceStep</item>
@@ -43,6 +45,7 @@
             <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/>
         </variation>
         <variation name="SalesShipmentGridSorting">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Verify sales shipment grid storting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateShipmentStep</item>
@@ -60,6 +63,7 @@
             <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/>
         </variation>
         <variation name="SalesCreditMemoGridSorting">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Verify sales credit memo grid storting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
index 02dbf74225ba9d69ffe88e7c933e5ac0cc82da9e..4d54654a04bbbf7f1d3ea0cc2f53199538d7910c 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MassOrdersUpdateTest" summary="Mass Update Orders" ticketId="MAGETWO-27897">
         <variation name="MassOrdersUpdateTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">cancel orders in status Pending and Processing</data>
             <data name="steps" xsi:type="string">-</data>
             <data name="action" xsi:type="string">Cancel</data>
@@ -44,6 +45,7 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" />
         </variation>
         <variation name="MassOrdersUpdateTestVariation5">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Try to put order in status Complete on Hold</data>
             <data name="steps" xsi:type="string">invoice, shipment</data>
             <data name="action" xsi:type="string">Hold</data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml
index 8f6466b4edc4f538918c274564888758da706b62..5f4066c1d8027a7e95b2aeab2eb8f4a8aca12330 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml
@@ -8,11 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MoveLastOrderedProductsOnOrderPageTest" summary="Add Products to Order from Last Ordered Products Section" ticketId="MAGETWO-27640">
         <variation name="MoveLastOrderedProductsOnOrderPageTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
         <variation name="MoveLastOrderedProductsOnOrderPageTestVariation2">
+            <data name="issue" xsi:type="string">MAGETWO-58762: Customer grid does not open in MoveLastOrderedProductsOnOrderPageTestVariation2 on Jenkins</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/entity_id/products" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml
index 4fbfbe531e8fee71987f1881c70a889d7c3deba8..695948b8b10c9caa421ebe674cbe9fe078ec6c04 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml
@@ -8,11 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MoveProductsInComparedOnOrderPageTest" summary="Add Products to Order from Products in Comparison List Section" ticketId="MAGETWO-28050">
         <variation name="MoveProductsInComparedOnOrderPageTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="products/1" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
         <variation name="MoveProductsInComparedOnOrderPageTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <data name="products/1" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml
index e6f96da0367cae153191a4bf3c535bc33ed97b5a..601f550e4588bfd3c613ef8a50e8615174b298ae 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml
@@ -8,11 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MoveRecentlyComparedProductsOnOrderPageTest" summary="Add Products to Order from Recently Compared Products Section" ticketId="MAGETWO-28109">
         <variation name="MoveRecentlyComparedProductsOnOrderPageTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="products/1" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
         <variation name="MoveRecentlyComparedProductsOnOrderPageTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <data name="products/1" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml
index 2e1c3eeea7b8942febf1b8f3505f6c1c9e407106..ae955b301d95687cb1aad697fb79a591c4e5c2d2 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml
@@ -8,10 +8,12 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MoveRecentlyViewedProductsOnOrderPageTest" summary="Add Products to Order from Recently Viewed Products Section" ticketId="MAGETWO-29723">
         <variation name="MoveRecentlyViewedProductsOnOrderPageTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">configurableProduct::default</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
         <variation name="MoveRecentlyViewedProductsOnOrderPageTestVariation2">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml
index e29a63165ad03aa8eddb4186546632e0c97c7687..53f321366de5ecc53d2d87ade453478371572274 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml
@@ -8,10 +8,12 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\MoveShoppingCartProductsOnOrderPageTest" summary="Add Products to Order from Shopping Cart " ticketId="MAGETWO-28540">
         <variation name="MoveShoppingCartProductsOnOrderPageTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
         <variation name="MoveShoppingCartProductsOnOrderPageTestVariation2" firstConstraint="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInItemsOrderedGrid" method="test">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product" xsi:type="string">configurableProduct::configurable_with_qty_1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" />
         </variation>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml
index 4dc6ae8d2fcd1d55062da03c74b7dce41c70c08c..46349665259d03f2626dbbb2723e3a8d18e864f6 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\PrintOrderFrontendGuestTest" summary="Print Order from Guest on Frontend" ticketId="MAGETWO-30253">
         <variation name="PrintOrderFrontendGuestTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="customer" xsi:type="array">
                 <item name="dataset" xsi:type="string">johndoe_with_addresses</item>
             </data>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml
index 7608ec4f68ca0d01fd8c7f736d0429ad45972503..8124a32c66eb1149c2c3e30fd79ee41381b0ee15 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\ReorderOrderEntityTest" summary="Reorder Order from Admin for Offline Payment Methods" ticketId="MAGETWO-29007">
         <variation name="ReorderOrderEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Reorder placed order (update products, billing address).</data>
             <data name="order/dataset" xsi:type="string">two_simple_product</data>
             <data name="salesRule" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
index bfe0bc9eabddfb0cc0f746f79efdad5b6ad0a43b..1f3f0e5a300b46ac9a193666796e52c584b8c944 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php
@@ -25,8 +25,6 @@ class AssertCartPriceRuleForm extends AbstractConstraint
     protected $skippedFields = [
         'conditions_serialized',
         'actions_serialized',
-        'from_date',
-        'to_date',
         'rule_id'
     ];
 
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
index 13b68aca6c6eb7867286019b3a9609b3b93db2a8..3a35215d841d50780d212084d76d014af8708aa4 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
@@ -114,10 +114,10 @@
             <field name="uses_per_coupon" xsi:type="string">13</field>
             <field name="uses_per_customer" xsi:type="string">63</field>
             <field name="from_date" xsi:type="array">
-                <item name="pattern" xsi:type="string">3/25/2014</item>
+                <item name="pattern" xsi:type="string">03/25/2014</item>
             </field>
             <field name="to_date" xsi:type="array">
-                <item name="pattern" xsi:type="string">6/29/2024</item>
+                <item name="pattern" xsi:type="string">-</item>
             </field>
             <field name="sort_order" xsi:type="string">1</field>
             <field name="is_rss" xsi:type="string">Yes</field>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml
index 4b837e442a4abc83219daf45301fe5a20570f1e0..b1893651726f8a562fe4ba3b9299c17e2ca082d3 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\SalesRule\Test\TestCase\ApplySeveralSalesRuleEntityTest" summary="Apply Several Sales Rules" ticketId="MAGETWO-45883">
         <variation name="ApplySeveralSalesRuleEntityTestVariation1" summary="Rules with same priority, both are applied">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="salesRules/rule1" xsi:type="string">active_sales_rule_product_subselection</data>
             <data name="salesRules/rule2" xsi:type="string">active_sales_rule_product_attribute</data>
             <data name="cartPrice/sub_total" xsi:type="string">200.00</data>
@@ -31,6 +32,7 @@
             <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" />
         </variation>
         <variation name="ApplySeveralSalesRuleEntityTestVariation3" summary="Rules with different priority, both are applied">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="salesRules/rule1" xsi:type="string">active_sales_rule_product_attribute</data>
             <data name="salesRules/rule2" xsi:type="string">active_sales_total_items</data>
             <data name="cartPrice/sub_total" xsi:type="string">250.00</data>
@@ -43,6 +45,7 @@
             <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" />
         </variation>
         <variation name="ApplySeveralSalesRuleEntityTestVariation4" summary="Rules with different priority, none are applied">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="salesRules/rule1" xsi:type="string">active_sales_rule_row_total</data>
             <data name="salesRules/rule2" xsi:type="string">active_sales_total_items</data>
             <data name="productForSalesRule1/dataset" xsi:type="string">simple_for_salesrule_1</data>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml
index bfa18c65bdcf8362a49c2c2f25ddb6d439c4d99d..d0ad41011004a3fef531865ca1c6265f9406684e 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml
@@ -145,6 +145,7 @@
             <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" />
         </variation>
         <variation name="CreateSalesRuleEntityTestVariation6">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="address/data/country_id" xsi:type="string">United States</data>
             <data name="address/data/region_id" xsi:type="string">California</data>
             <data name="address/data/postcode" xsi:type="string">95814</data>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml
index 37f8366674e0573e6d7837a004b3d98fef1dadc0..b894aada2e2ba54ec7c0658b85492b66071dd1c1 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml
@@ -32,8 +32,8 @@
         <step name="applySalesRuleOnBackend" module="Magento_SalesRule" next="fillBillingAddress" />
     </scenario>
     <scenario name="CreateOrderBackendTest">
-        <step name="createSalesRule" module="Magento_SalesRule" next="applySalesRuleOnBackend" />
-        <step name="applySalesRuleOnBackend" module="Magento_SalesRule" next="fillBillingAddress" />
+        <step name="createSalesRule" module="Magento_SalesRule" prev="fillShippingAddress" next="applySalesRuleOnBackend" />
+        <step name="applySalesRuleOnBackend" module="Magento_SalesRule" />
     </scenario>
     <scenario name="CreateOrderFromCustomerPageTest">
         <step name="createSalesRule" module="Magento_SalesRule" next="applySalesRuleOnBackend" />
diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml
index 21279437ea834b921f2a910714f25daf5735ca84..79a170819c50600ba0f2f15811a8b3cdfe94cb7a 100644
--- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml
@@ -25,7 +25,7 @@
     </testCase>
     <testCase name="Magento\Search\Test\TestCase\CreateSynonymGroupEntityTest" summary="Create Synonym Group with custom Website and Store View" ticketId="MAGETWO-47681">
         <variation name="CreateSynonymGroupEntityTestVariation3">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, stable:no</data>
             <data name="synonymGroup/data/synonyms" xsi:type="string">synonym_%isolation%</data>
             <data name="synonymGroup/data/scope_id/dataset" xsi:type="string">custom_store</data>
             <constraint name="Magento\Search\Test\Constraint\AssertSynonymGroupSuccessSaveMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml
index 2e6e6cb2e4812b13e0354bf9ec9794f1c845a4db..636cf66fd2c86da20cd331b9a0b1c9b3f549f45d 100644
--- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml
@@ -8,9 +8,9 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Search\Test\TestCase\UpdateSynonymGroupEntityTest" summary="Update Synonym Groups" ticketId="MAGETWO-49412">
         <variation name="UpdateSynonymGroupEntityTestVariation1">
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data>
             <data name="initialSynonymGroup/dataset" xsi:type="string">prepareMerge</data>
             <data name="description" xsi:type="string">Update Synonym Groups Successfully</data>
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
             <data name="synonymGroup/data/synonyms" xsi:type="string">new_synonym_%isolation%</data>
             <data name="synonymGroup/data/scope_id/dataset" xsi:type="string">all_store_views</data>
             <constraint name="Magento\Search\Test\Constraint\AssertSynonymGroupSuccessSaveMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b42430c0b8a81987b78d907f8b4a4c56d6db834
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Security\Test\TestCase;
+
+
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\User\Test\Fixture\User;
+use Magento\Backend\Test\Page\AdminAuthLogin;
+
+/**
+ * Preconditions:
+ * 1. Create admin user.
+ * 2. Configure 'Maximum Login Failures to Lockout Account'.
+ *
+ * Steps:
+ * 1. Log in to backend as admin user.
+ * 2. Navigate to System > All Users.
+ * 3. Click on Add New User.
+ * 4. Fill in all data according to data set (password is incorrect).
+ * 5. Perform action 4 specified number of times.
+ * 6. "You have entered an invalid password for current user." appears after each attempt.
+ * 7. Perform all assertions.
+ *
+ * @ZephyrId MAGETWO-49034
+ */
+class LockAdminUserWhenCreatingNewUserTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    const SEVERITY = 'S2';
+    /* end tags */
+
+    /**
+     * User grid page
+     *
+     * @var UserIndex
+     */
+    protected $userIndexPage;
+
+    /**
+     * User new/edit page
+     *
+     * @var UserEdit
+     */
+    protected $userEditPage;
+
+    /**
+     * Configuration setting.
+     *
+     * @var string
+     */
+    protected $configData;
+
+    /**
+     * @var AdminAuthLogin page
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * Setup data for test.
+     * @param UserIndex $userIndex
+     * @param UserEdit $userEdit
+     * @param AdminAuthLogin $adminAuthLogin
+     */
+    public function __inject(
+        UserIndex $userIndex,
+        UserEdit $userEdit,
+        AdminAuthLogin $adminAuthLogin
+    ) {
+        $this->userIndexPage = $userIndex;
+        $this->userEditPage = $userEdit;
+        $this->adminAuthLogin = $adminAuthLogin;
+    }
+
+    /**
+     * Runs Lock admin user when creating new user test.
+     *
+     * @param int $attempts
+     * @param User $customAdmin,
+     * @param User $user,
+     * @param string $configData
+     * @return void
+     */
+    public function test(
+        $attempts,
+        User $customAdmin,
+        User $user,
+        $configData
+    ) {
+        $this->configData = $configData;
+
+        // Preconditions
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData]
+        )->run();
+        $customAdmin->persist();
+
+        // Steps
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+        $this->userIndexPage->open();
+        $this->userIndexPage->getPageActions()->addNew();
+        for ($i = 0; $i < $attempts; $i++) {
+            $this->userEditPage->getUserForm()->fill($user);
+            $this->userEditPage->getPageActions()->save();
+        }
+
+        // Reload
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'rollback' => true]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e36f8b4625dd66eeb5a41f15c74c4bdf6e7eeeea
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenCreatingNewUserTest" summary="Lock admin user after entering incorrect password while creating new User">
+        <variation name="LockAdminUserWhenCreatingNewUserTestVariation1">
+            <data name="configData" xsi:type="string">user_lockout_failures</data>
+            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
+            <data name="user/data/username" xsi:type="string">AdminUser%isolation%</data>
+            <data name="user/data/firstname" xsi:type="string">FirstName%isolation%</data>
+            <data name="user/data/lastname" xsi:type="string">LastName%isolation%</data>
+            <data name="user/data/email" xsi:type="string">email%isolation%@example.com</data>
+            <data name="user/data/password" xsi:type="string">123123q</data>
+            <data name="user/data/password_confirmation" xsi:type="string">123123q</data>
+            <data name="user/data/current_password" xsi:type="string">incorrect password</data>
+            <data name="attempts" xsi:type="string">4</data>
+            <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a1c1d0507c91ea3b9a86d254f6f2c01d58a7d2d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Security\Test\TestCase;
+
+use Magento\Integration\Test\Fixture\Integration;
+use Magento\User\Test\Fixture\User;
+use Magento\Integration\Test\Page\Adminhtml\IntegrationIndex;
+use Magento\Integration\Test\Page\Adminhtml\IntegrationNew;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\Backend\Test\Page\AdminAuthLogin;
+
+/**
+ * Preconditions:
+ * 1. Create admin user.
+ * 2. Create integration.
+ * 3. Configure 'Maximum Login Failures to Lockout Account'.
+ *
+ * Steps:
+ * 1. Log in to backend as admin user.
+ * 2. Navigate to System > Extensions > Integrations.
+ * 3. Start to edit existing Integration.
+ * 4. Fill in all data according to data set (password is incorrect).
+ * 5. Perform action 4 specified number of times.
+ * 6. "You have entered an invalid password for current user." appears after each attempt.
+ * 7. Perform all assertions.
+ *
+ * @ZephyrId MAGETWO-49039
+ */
+class LockAdminUserWhenEditingIntegrationTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    const SEVERITY = 'S2';
+    /* end tags */
+
+    /**
+     * Integration grid page.
+     *
+     * @var IntegrationIndex
+     */
+    protected $integrationIndexPage;
+
+    /**
+     * Integration new page.
+     *
+     * @var IntegrationNew
+     */
+    protected $integrationNewPage;
+
+    /**
+     * Configuration setting.
+     *
+     * @var string
+     */
+    protected $configData;
+
+    /**
+     * @var AdminAuthLogin
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * Preparing pages for test.
+     *
+     * @param IntegrationIndex $integrationIndex
+     * @param IntegrationNew $integrationNew
+     * @param AdminAuthLogin $adminAuthLogin
+     * @return void
+     */
+    public function __inject(
+        IntegrationIndex $integrationIndex,
+        IntegrationNew $integrationNew,
+        AdminAuthLogin $adminAuthLogin
+    ) {
+        $this->integrationIndexPage = $integrationIndex;
+        $this->integrationNewPage = $integrationNew;
+        $this->adminAuthLogin = $adminAuthLogin;
+    }
+
+    /**
+     * Run Lock user when creating new integration test.
+     *
+     * @param Integration $initintegration
+     * @param Integration $integration
+     * @param int $attempts
+     * @param User $customAdmin
+     * @param string $configData
+     * @return void
+     */
+    public function test(
+        Integration $initintegration,
+        Integration $integration,
+        $attempts,
+        User $customAdmin,
+        $configData
+    ) {
+        $this->configData = $configData;
+
+        // Preconditions
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData]
+        )->run();
+        $customAdmin->persist();
+        $initintegration->persist();
+
+        // login to backend with new user
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+
+        // Steps
+        $filter = ['name' => $initintegration->getName()];
+        $this->integrationIndexPage->open();
+        $this->integrationIndexPage->getIntegrationGrid()->searchAndOpen($filter);
+        for ($i = 0; $i < $attempts; $i++) {
+            $this->integrationNewPage->getIntegrationForm()->fill($integration);
+            $this->integrationNewPage->getFormPageActions()->save();
+        }
+
+        // Reload page
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'rollback' => true]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6efc88d78cd3836f00db79d2c567d3e6e38d1bb1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenEditingIntegrationTest" summary="Lock admin user after entering incorrect password while editing integration">
+        <variation name="LockAdminUserWhenCreatingNewIntegrationTestVariation1">
+            <data name="configData" xsi:type="string">user_lockout_failures</data>
+            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
+            <data name="initintegration/dataset" xsi:type="string">default_active</data>
+            <data name="integration/data/name" xsi:type="string">Integration%isolation%</data>
+            <data name="integration/data/current_password" xsi:type="string">incorrect password</data>
+            <data name="attempts" xsi:type="string">4</data>
+            <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" />
+        </variation>
+    </testCase>
+</config>
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd7c8cef92d8a320b43615983a95ea724cce0d78
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Security\Test\TestCase;
+
+use Magento\User\Test\Page\Adminhtml\UserRoleEditRole;
+use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\User\Test\Fixture\User;
+use Magento\User\Test\Fixture\Role;
+use Magento\Backend\Test\Page\AdminAuthLogin;
+
+/**
+ * Preconditions:
+ * 1. Create new admin user and assign it to new role.
+ * 2. Configure 'Maximum Login Failures to Lockout Account'.
+ *
+ * Steps:
+ * 1. Log in to backend as new created admin user.
+ * 2. Navigate to System > User Roles.
+ * 3. Start editing existing User Role.
+ * 4. Fill in all data according to data set (password is incorrect).
+ * 5. Perform action 4 specified number of times.
+ * 6. Admin account is locked.
+ * 7. Perform all assertions.
+ *
+ * @ZephyrId MAGETWO-49037
+ * @Group Security
+ *
+ */
+class LockAdminUserWhenEditingRoleTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    const SEVERITY = 'S2';
+    /* end tags */
+
+    /**
+     * UserRoleIndex page.
+     *
+     * @var UserRoleIndex
+     */
+    protected $userRoleIndex;
+
+    /**
+     * UserRoleEditRole page.
+     *
+     * @var UserRoleEditRole
+     */
+    protected $userRoleEditRole;
+
+    /**
+     * Configuration setting.
+     *
+     * @var string
+     */
+    protected $configData;
+
+    /**
+     * Admin login Page.
+     *
+     * @var AdminAuthLogin
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * Setup data for test.
+     *
+     * @param UserRoleIndex $userRoleIndex
+     * @param UserRoleEditRole $userRoleEditRole
+     * @param AdminAuthLogin $adminAuthLogin
+     * @return void
+     */
+    public function __inject(
+        UserRoleIndex $userRoleIndex,
+        UserRoleEditRole $userRoleEditRole,
+        AdminAuthLogin $adminAuthLogin
+    ) {
+        $this->userRoleIndex = $userRoleIndex;
+        $this->userRoleEditRole = $userRoleEditRole;
+        $this->adminAuthLogin = $adminAuthLogin;
+    }
+
+    /**
+     * Runs Lock admin user when editing existing role test.
+     *
+     * @param Role $role
+     * @param Role $initrole
+     * @param int $attempts
+     * @param User $customAdmin
+     * @param string $configData
+     * @return void
+     */
+    public function test(
+        Role $role,
+        Role $initrole,
+        $attempts,
+        User $customAdmin,
+        $configData
+    ) {
+        $this->configData = $configData;
+        // Preconditions
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData]
+        )->run();
+        $customAdmin->persist();
+        $initrole->persist();
+        // Steps login to backend with new user
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+        $filter = ['rolename' => $initrole->getRolename()];
+        $this->userRoleIndex->open();
+        $this->userRoleIndex->getRoleGrid()->searchAndOpen($filter);
+        for ($i = 0; $i < $attempts; $i++) {
+            $this->userRoleEditRole->getRoleFormTabs()->fill($role);
+            $this->userRoleEditRole->getPageActions()->save();
+        }
+        // Reload
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'rollback' => true]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1d081e5d2dd9af69f90aeed8b787c966238e62de
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenEditingRoleTest" summary="Lock admin user after entering incorrect password while editing existing role">
+        <variation name="LockAdminUserWhenEditingUserRoleTestVariation1">
+            <data name="configData" xsi:type="string">user_lockout_failures</data>
+            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="initrole/dataset" xsi:type="string">default</data>
+            <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
+            <data name="role/data/rolename" xsi:type="string">NewAdminRole%isolation%</data>
+            <data name="role/data/current_password" xsi:type="string">incorrect password</data>
+            <data name="role/data/resource_access" xsi:type="string">All</data>
+            <data name="attempts" xsi:type="string">4</data>
+            <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..912ebef9e91054236cc6b85b91c3cd8d973b54e9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Security\Test\TestCase;
+
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+use Magento\Backend\Test\Page\AdminAuthLogin;
+use Magento\User\Test\Fixture\User;
+use Magento\Mtf\TestCase\Injectable;
+
+/**
+ * Preconditions:
+ * 1. Create new admin user.
+ * 2. Configure 'Maximum Login Failures to Lockout Account'.
+ *
+ * Steps:
+ * 1. Log in to backend as new created admin user.
+ * 2. Navigate to System > All Users.
+ * 3. Start editing existing User.
+ * 4. Fill in all data according to data set (password is incorrect).
+ * 5. Perform action 4 specified number of times.
+ * 6. Admin account is locked.
+ * 7. Perform all assertions.
+ *
+ * @ZephyrId MAGETWO-49035
+ */
+class LockAdminUserWhenEditingUserTest extends Injectable
+{
+    /* tags */
+    const MVP = 'yes';
+    const SEVERITY = 'S2';
+    /* end tags */
+
+    /**
+     * User grid page
+     *
+     * @var UserIndex
+     */
+    protected $userIndexPage;
+
+    /**
+     * User edit page
+     *
+     * @var UserEdit
+     */
+    protected $userEditPage;
+
+    /**
+     * @var $configData
+     */
+    protected $configData;
+
+    /**
+     * @var AdminAuthLogin page
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * Setup data for test.
+     * @param UserIndex $userIndex
+     * @param UserEdit $userEdit
+     * @param AdminAuthLogin $adminAuthLogin
+     */
+    public function __inject(
+        UserIndex $userIndex,
+        UserEdit $userEdit,
+        AdminAuthLogin $adminAuthLogin
+    ) {
+        $this->userIndexPage = $userIndex;
+        $this->userEditPage = $userEdit;
+        $this->adminAuthLogin = $adminAuthLogin;
+    }
+
+    /**
+     * Runs Lock admin user when editing existing role test.
+     *
+     * @param User $user
+     * @param int $attempts
+     * @param User $customAdmin
+     * @param string $configData
+     * @return void
+     */
+    public function test(
+        $attempts,
+        User $customAdmin,
+        User $user,
+        $configData
+    ) {
+        $this->configData = $configData;
+
+        // Preconditions
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData]
+        )->run();
+        $customAdmin->persist();
+
+        // Steps login to backend with new user
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+        // Select user to edit.
+        $filter = ['username' => $customAdmin->getUsername()];
+        $this->userIndexPage->open();
+        $this->userIndexPage->getUserGrid()->searchAndOpen($filter);
+        // Edit user with wrong password
+        for ($i = 0; $i < $attempts; $i++) {
+            $this->userEditPage->getUserForm()->fill($user);
+            $this->userEditPage->getPageActions()->save();
+        }
+        // Reload
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($customAdmin);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+    }
+
+    /**
+     * Clean data after running test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $this->configData, 'rollback' => true]
+        )->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e1ec2f79ce6b5d306e694c9d2ae8e8adea0d3387
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenEditingUserTest" summary="Lock admin user after entering incorrect password while editing existing user">
+        <variation name="LockAdminUserWhenEditingUseruserTestVariation1">
+            <data name="configData" xsi:type="string">user_lockout_failures</data>
+            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
+            <data name="user/data/username" xsi:type="string">AdminUser%isolation%</data>
+            <data name="user/data/firstname" xsi:type="string">FirstName%isolation%</data>
+            <data name="user/data/lastname" xsi:type="string">LastName%isolation%</data>
+            <data name="user/data/email" xsi:type="string">email%isolation%@example.com</data>
+            <data name="user/data/password" xsi:type="string">123123qq</data>
+            <data name="user/data/password_confirmation" xsi:type="string">123123qq</data>
+            <data name="user/data/current_password" xsi:type="string">incorrect password</data>
+            <data name="attempts" xsi:type="string">4</data>
+            <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" />
+        </variation>
+    </testCase>
+</config>
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
index eeb0dd7ab12e9e33eec107f17d3678d4ec1827ad..1a5443ec9e61558b5b7cad2a9ada57825c451581 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockCustomerOnEditPageTest" summary="Lock customer from edit page">
         <variation name="LockCustomerOnEditPageTest1">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data>
             <data name="configData" xsi:type="string">customer_max_login_failures_number</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="customer/data/current_password" xsi:type="string">incorrect password</data>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
index a5376d73685bad9e54d4ff094348b7100c2a2a8d..df5c5bce59fe0400b308530085e99c541da60323 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockCustomerOnLoginPageTest" summary="Lock customer on login page">
         <variation name="LockCustomerOnLoginPageTestVariation1">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data>
             <data name="configData" xsi:type="string">customer_max_login_failures_number</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="incorrectPassword" xsi:type="string">incorrect password</data>
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
index b888ba1f778370d11e19ded0f8c40cfd543541ea..2c3809e27f2eff076ffd538d7aebcfa4fed04e7f 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
@@ -17,7 +17,7 @@
             <constraint name="Magento\Store\Test\Constraint\AssertStoreNotOnFrontend" />
         </variation>
         <variation name="DeleteStoreEntityTestVariation2">
-            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="tag" xsi:type="string">severity:S2, stable:no</data>
             <data name="store/dataset" xsi:type="string">custom</data>
             <data name="createBackup" xsi:type="string">No</data>
             <constraint name="Magento\Store\Test\Constraint\AssertStoreSuccessDeleteMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml
index 16c0aeb358bb0fe5e7f0e18216300161c6dfbbf1..cfda1263ac19f8355370ad5cb507b44a8aa43f29 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Store\Test\TestCase\DeleteStoreGroupEntityTest" summary="Delete Store Group" ticketId="MAGETWO-27596">
         <variation name="DeleteStoreGroupEntityTestVariation1">
-            <data name="tag" xsi:type="string">severity:S3</data>
+            <data name="tag" xsi:type="string">severity:S3, stable:no</data>
             <data name="storeGroup/dataset" xsi:type="string">custom</data>
             <data name="createBackup" xsi:type="string">Yes</data>
             <constraint name="Magento\Store\Test\Constraint\AssertStoreGroupSuccessDeleteAndBackupMessages" />
@@ -16,7 +16,7 @@
             <constraint name="Magento\Backup\Test\Constraint\AssertBackupInGrid" />
         </variation>
         <variation name="DeleteStoreGroupEntityTestVariation2">
-            <data name="tag" xsi:type="string">severity:S3</data>
+            <data name="tag" xsi:type="string">severity:S3, stable:no</data>
             <data name="storeGroup/dataset" xsi:type="string">custom</data>
             <data name="createBackup" xsi:type="string">No</data>
             <constraint name="Magento\Store\Test\Constraint\AssertStoreGroupSuccessDeleteMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php
index 94e14b4a42317edaa2b1f151a3858c770a74fc68..f349131fe5848a5a6b1f44c696bf96969053b19e 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php
@@ -39,6 +39,7 @@ class DeleteWebsiteEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const SEVERITY = 'S3';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php
new file mode 100644
index 0000000000000000000000000000000000000000..39c630a0aa2060f23e6ef87c2682e73169ffa777
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Block\Product;
+
+use Magento\Mtf\Client\Locator;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Catalog\Test\Block\Product\ListProduct as CatalogListProduct;
+
+/**
+ * Product list block.
+ */
+class ListProduct extends CatalogListProduct
+{
+    /**
+     * @inheritdoc
+     */
+    public function getProductItem(FixtureInterface $product)
+    {
+        $locator = sprintf($this->productItem, $product->getName());
+
+        return $this->blockFactory->create(
+            \Magento\Swatches\Test\Block\Product\ProductList\ProductItem::class,
+            ['element' => $this->_rootElement->find($locator, Locator::SELECTOR_XPATH)]
+        );
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php
new file mode 100755
index 0000000000000000000000000000000000000000..414d03bc687871490b551fcfb807f2958fd4e25e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Block\Product\ProductList;
+
+use Magento\Mtf\Client\Locator;
+use Magento\Catalog\Test\Block\Product\ProductList\ProductItem as CatalogProductItem;
+
+/**
+ * Product item block on frontend category view.
+ */
+class ProductItem extends CatalogProductItem
+{
+    /**
+     * Selector for the swatches of the product.
+     *
+     * @var string
+     */
+    protected $swatchSelector = 'div[option-id="%s"]';
+
+    /**
+     * Fill product options on category page.
+     *
+     * @param \Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct $product
+     * @return void
+     */
+    public function fillData(\Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct $product)
+    {
+        $checkoutData = $product->getCheckoutData();
+        $options = $checkoutData['options']['configurable_options'];
+        $confAttrData = $product->getDataFieldConfig('configurable_attributes_data');
+        $confAttrSource = $confAttrData['source'];
+        $attributes = $confAttrSource->getAttributes();
+
+        foreach ($options as $option) {
+            if (!isset($attributes[$option['title']])) {
+                continue;
+            }
+            $availableOptions = $attributes[$option['title']]->getOptions();
+            $optionKey = str_replace('option_key_', '', $option['value']);
+            if (!isset($availableOptions[$optionKey])) {
+                continue;
+            }
+            $optionForSelect = $availableOptions[$optionKey];
+            $this->clickOnSwatch($optionForSelect['id']);
+        }
+    }
+
+    /**
+     * Click on swatch.
+     *
+     * @param $optionId
+     */
+    private function clickOnSwatch($optionId)
+    {
+        $selector = sprintf($this->swatchSelector, $optionId);
+        $this->_rootElement->find($selector, Locator::SELECTOR_CSS)->click();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function clickAddToCart()
+    {
+        $this->_rootElement->hover();
+        parent::clickAddToCart();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1405b4a807718edbb511569ac23d03fc2b52d43
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Block\Product;
+
+use Magento\Catalog\Test\Block\Product\View;
+use Magento\Mtf\Fixture\InjectableFixture;
+
+/**
+ * Configurable product view block with swatch attributes on frontend product page
+ */
+class ViewWithSwatches extends View
+{
+    /**
+     * Selector for swatch attribute value
+     *
+     * @var string
+     */
+    private $swatchAttributeSelector = '.swatch-attribute.%s .swatch-attribute-selected-option';
+
+    /**
+     * Get chosen options from the product view page.
+     *
+     * @param InjectableFixture $product
+     * @return array
+     */
+    public function getSelectedSwatchOptions(InjectableFixture $product)
+    {
+        $checkoutData = $product->getCheckoutData();
+        $availableAttributes = $product->getConfigurableAttributesData();
+        $attributesData = $availableAttributes['attributes_data'];
+        $formData = [];
+        foreach ($checkoutData['options']['configurable_options'] as $item) {
+            $selector = sprintf($this->swatchAttributeSelector, $attributesData[$item['title']]['attribute_code']);
+            $this->waitForElementVisible($selector);
+            $selected = $this->_rootElement->find($selector)->getText();
+            $formData[$item['title']] = $selected;
+        }
+
+        return $formData;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..460a13ce49d704f30f513af5c8f3189c45f3ffc4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Constraint;
+
+use Magento\Catalog\Test\Constraint\AssertProductPage;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Mtf\Client\BrowserInterface;
+
+/**
+ * Assert that product with swatches and regular dropdown redirect can't be add to cart from catalog catergory page.
+ */
+class AssertSwatchConfigurableProductPage extends AssertProductPage
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function processAssert(
+        BrowserInterface $browser,
+        CatalogProductView $catalogProductView,
+        FixtureInterface $product
+    ) {
+        $this->product = $product;
+        $this->productView = $catalogProductView->getProductViewWithSwatchesBlock();
+        $this->objectManager->create(
+            \Magento\Swatches\Test\TestStep\AddProductToCartFromCatalogCategoryPageStep::class,
+            [
+                'product' => $product
+            ]
+        )->run();
+        // we need this line for waiti until page will be fully loaded
+        $this->productView->getSelectedSwatchOptions($this->product);
+        $errors = $this->verify();
+        \PHPUnit_Framework_Assert::assertEmpty(
+            $errors,
+            "\nFound the following errors:\n" . implode(" \n", $errors)
+        );
+    }
+
+    /**
+     * Verify product on product view page.
+     *
+     * @return array
+     */
+    protected function verify()
+    {
+        $errors = parent::verify();
+        $errors[] = $this->verifySwatches();
+
+        return array_filter($errors);
+    }
+
+    /**
+     * Verify selected swatches on product view page.
+     *
+     * @return array
+     */
+    protected function verifySwatches()
+    {
+        $actualData = $this->productView->getSelectedSwatchOptions($this->product);
+        $expectedData = $this->convertCheckoutData($this->product);
+        $this->verifyData($expectedData, $actualData);
+    }
+
+    /**
+     * Get swatch attributes formatter to attributes comparison.
+     *
+     * @param FixtureInterface $product
+     * @return array
+     */
+    public function convertCheckoutData(FixtureInterface  $product)
+    {
+        $out = [];
+        $checkoutData = $product->getCheckoutData();
+        $availableAttributes = $product->getConfigurableAttributesData();
+        $attributesData = $availableAttributes['attributes_data'];
+        foreach ($checkoutData['options']['configurable_options'] as $item) {
+            $out[$item['title']] = $attributesData[$item['title']]['options'][$item['value']]['label'];
+        }
+
+        return $out;
+    }
+
+    /**
+     * Return string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Swatch attributes displayed as expected on product page';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php
new file mode 100644
index 0000000000000000000000000000000000000000..46c9b383ae8420c5210a3d4f71ac49b3513b1724
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Fixture\Cart;
+
+use Magento\ConfigurableProduct\Test\Fixture\Cart\Item as ConfigurableCart;
+
+/**
+ * @inheritdoc
+ */
+class Item extends ConfigurableCart
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dbc57a321a68238adff45355fd87a4e97028cde2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+    <fixture
+            name="configurableProductSwatch"
+            module="Magento_Swatches"
+            class="Magento\Swatches\Test\Fixture\ConfigurableProduct"
+            extends="\Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct"
+            >
+    </fixture>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d96331b8159d50a60f6aa215d523d492aa5de7a4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd">
+    <fixture name="swatchesProductAttribute"
+             module="Magento_Swatches"
+             handler_interface="Magento\Swatches\Test\Handler\SwatchProductAttribute\SwatchProductAttributeInterface"
+             repository_class="Magento\Swatches\Test\Repository\SwatchProductAttribute"
+             class="Magento\Swatches\Test\Fixture\SwatchesProductAttribute"
+             extends="\Magento\Catalog\Test\Fixture\CatalogProductAttribute">
+    </fixture>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..86de2d651da1ecf3d48fdb165de0b223a665f126
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Handler\SwatchProductAttribute;
+
+use Magento\Catalog\Test\Handler\CatalogProductAttribute\Curl as CatalogProductAttributeCurl;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
+
+/**
+ * Curl handler for creating Swatch Attribute.
+ */
+class Curl extends CatalogProductAttributeCurl implements SwatchProductAttributeInterface
+{
+    /**
+     * Add mapping data related to swatches.
+     *
+     * @param DataInterface $configuration
+     * @param EventManagerInterface $eventManager
+     */
+    public function __construct(DataInterface $configuration, EventManagerInterface $eventManager)
+    {
+        parent::__construct($configuration, $eventManager);
+        $this->mappingData['frontend_input'] = [
+            'Text Swatch' => 'swatch_text',
+        ];
+    }
+
+    /**
+     * Re-map options from default options structure to swatches structure,
+     * as swatches was initially created with name convention differ from other attributes.
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function changeStructureOfTheData(array $data)
+    {
+        $data = parent::changeStructureOfTheData($data);
+        $data['optiontext'] = $data['option'];
+        $data['swatchtext'] = [
+            'value' => $data['option']['value']
+        ];
+        unset($data['option']);
+        return $data;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..41fdebdd5ce8b084eca0a40c58aeba580a7b3518
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\Handler\SwatchProductAttribute;
+
+use Magento\Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface for swatch specific Curl calls
+ */
+interface SwatchProductAttributeInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9cb5e4fbdf69756a5289555e15d568f577bbf21d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog">
+        <block name="listSwatchesProductBlock" class="Magento\Swatches\Test\Block\Product\ListProduct" locator=".products.wrapper.grid" strategy="css selector"/>
+    </page>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..315c6a02ee968e6bc93ec52bd5555d65be3f87d7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="CatalogProductView" area="Product" mca="catalog/product/view">
+        <block name="productViewWithSwatchesBlock" class="Magento\Swatches\Test\Block\Product\ViewWithSwatches" locator="#maincontent" strategy="css selector" />
+    </page>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml
new file mode 100644
index 0000000000000000000000000000000000000000..22e73572ead0d9081b3bdf15c78f75df12409a3c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\ConfigurableProduct\Test\Repository\ConfigurableProduct">
+        <dataset name="product_with_text_swatch">
+            <field name="name" xsi:type="string">Test configurable product with color and size %isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
+            <field name="product_has_weight" xsi:type="string">This item has weight</field>
+            <field name="weight" xsi:type="string">30</field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">configurable-product-%isolation%</field>
+            <field name="configurable_attributes_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">text_swatch</item>
+            </field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="category_ids" xsi:type="array">
+                <item name="dataset" xsi:type="string">default_subcategory</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">custom_attribute_set</item>
+            </field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">40</item>
+                <item name="dataset" xsi:type="string">price_40</item>
+            </field>
+            <field name="checkout_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">two_text_swatches</item>
+            </field>
+        </dataset>
+        <dataset name="product_with_text_swatch_and_size">
+            <field name="name" xsi:type="string">Test configurable product with color and size %isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
+            <field name="product_has_weight" xsi:type="string">This item has weight</field>
+            <field name="weight" xsi:type="string">30</field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">configurable-product-%isolation%</field>
+            <field name="configurable_attributes_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">text_swatch_with_dropdown</item>
+            </field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="category_ids" xsi:type="array">
+                <item name="dataset" xsi:type="string">default_subcategory</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">custom_attribute_set</item>
+            </field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">40</item>
+                <item name="dataset" xsi:type="string">price_40</item>
+            </field>
+            <field name="checkout_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">swatches_with_dropdown</item>
+            </field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9b369d5a536f0de9e41bb302910526dd8f5023fb
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\ConfigurableProduct\Test\Repository\ConfigurableProduct\CheckoutData">
+        <dataset name="two_text_swatches">
+            <field name="options" xsi:type="array">
+                <item name="configurable_options" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_key_0</item>
+                        <item name="value" xsi:type="string">option_key_1</item>
+                    </item>
+                    <item name="1" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_key_1</item>
+                        <item name="value" xsi:type="string">option_key_2</item>
+                    </item>
+                </item>
+            </field>
+            <field name="qty" xsi:type="string">1</field>
+            <field name="cartItem" xsi:type="array">
+                <item name="price" xsi:type="string">42</item>
+                <item name="qty" xsi:type="string">1</item>
+                <item name="subtotal" xsi:type="string">47</item>
+            </field>
+        </dataset>
+        <dataset name="swatches_with_dropdown">
+            <field name="options" xsi:type="array">
+                <item name="configurable_options" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_key_0</item>
+                        <item name="value" xsi:type="string">option_key_1</item>
+                    </item>
+                </item>
+            </field>
+            <field name="qty" xsi:type="string">1</field>
+            <field name="cartItem" xsi:type="array">
+                <item name="price" xsi:type="string">42</item>
+                <item name="qty" xsi:type="string">1</item>
+                <item name="subtotal" xsi:type="string">47</item>
+            </field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml
new file mode 100644
index 0000000000000000000000000000000000000000..492fda6b751c664bdfde231d813a866e24073f7b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\ConfigurableProduct\Test\Repository\ConfigurableProduct\ConfigurableAttributesData">
+        <dataset name="text_swatch">
+            <field name="attributes_data" xsi:type="array">
+                <item name="attribute_key_0" xsi:type="array">
+                    <item name="options" xsi:type="array">
+                        <item name="option_key_0" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">12.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_1" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">20.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_2" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">18.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                    </item>
+                </item>
+                <item name="attribute_key_1" xsi:type="array">
+                    <item name="options" xsi:type="array">
+                        <item name="option_key_0" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">42.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_1" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">40.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_2" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">48.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="attributes" xsi:type="array">
+                <item name="attribute_key_0" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item>
+                <item name="attribute_key_1" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item>
+            </field>
+            <field name="matrix" xsi:type="array">
+                <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_2" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_2" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_2" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+            </field>
+        </dataset>
+        <dataset name="text_swatch_with_dropdown">
+            <field name="attributes_data" xsi:type="array">
+                <item name="attribute_key_0" xsi:type="array">
+                    <item name="options" xsi:type="array">
+                        <item name="option_key_0" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">12.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_1" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">20.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_2" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">18.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                    </item>
+                </item>
+                <item name="attribute_key_1" xsi:type="array">
+                    <item name="options" xsi:type="array">
+                        <item name="option_key_0" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">42.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                        <item name="option_key_1" xsi:type="array">
+                            <item name="pricing_value" xsi:type="string">40.00</item>
+                            <item name="include" xsi:type="string">Yes</item>
+                        </item>
+                    </item>
+                </item>
+            </field>
+            <field name="attributes" xsi:type="array">
+                <item name="attribute_key_0" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item>
+                <item name="attribute_key_1" xsi:type="string">catalogProductAttribute::size</item>
+            </field>
+            <field name="matrix" xsi:type="array">
+                <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_0" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+                <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_1" xsi:type="array">
+                    <item name="qty" xsi:type="string">10</item>
+                    <item name="weight" xsi:type="string">1</item>
+                </item>
+            </field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fc92146861d1e89e5ef32666c67b8c63882d9691
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\Swatches\Test\Repository\SwatchProductAttribute">
+        <dataset name="attribute_type_text_swatch">
+            <field name="attribute_code" xsi:type="string">sw_color%isolation%</field>
+            <field name="frontend_input" xsi:type="string" >Text Swatch</field>
+            <field name="frontend_label" xsi:type="string" >Text Swatch</field>
+            <field name="options" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="is_default" xsi:type="string">No</item>
+                    <item name="admin" xsi:type="string">R</item>
+                    <item name="view" xsi:type="string">R</item>
+                </item>
+                <item name="1" xsi:type="array">
+                    <item name="is_default" xsi:type="string">No</item>
+                    <item name="admin" xsi:type="string">G</item>
+                    <item name="view" xsi:type="string">G</item>
+                </item>
+                <item name="2" xsi:type="array">
+                    <item name="is_default" xsi:type="string">No</item>
+                    <item name="admin" xsi:type="string">B</item>
+                    <item name="view" xsi:type="string">B</item>
+                </item>
+            </field>
+            <field name="is_global" xsi:type="string">Global</field>
+            <field name="used_in_product_listing" xsi:type="string">Yes</field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..60cc61f7f0f79319336d57d0d81289de6fe31cab
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\TestCase;
+
+use Magento\Mtf\TestCase\Scenario;
+
+/**
+ * Preconditions:
+ * 1. Configure text swatch attribute.
+ * 2. Create configurable product with this attribute
+ * 3. Open it on catalog page
+ * 4. Click on 'Add to Cart' button
+ *
+ * Steps:
+ * 1. Go to Frontend.
+ * 2. Open category page with created product
+ * 3. Click on 'Add to Cart' button
+ * 4. Perform asserts
+ *
+ * @group Configurable_Product
+ * @ZephyrId MAGETWO-59958
+ */
+class AddConfigurableProductWithSwatchToShopingCartTest extends Scenario
+{
+    /**
+     * Runs add configurable product with swatches attributes test.
+     *
+     * @return void
+     */
+    public function test()
+    {
+        $this->executeScenario();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..adf8d71395ccb9c4b714ad58887ec741391871a2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Swatches\Test\TestCase\AddConfigurableProductWithSwatchToShopingCartTest" summary="Create text swatch attribute" ticketId="MAGETWO-47017">
+        <variation name="AddConfigurableProductWithSwatchToShopingCartTest1">
+            <data name="attributeTypeAction" xsi:type="string">addOptions</data>
+            <data name="product" xsi:type="string">configurableProductSwatch::product_with_text_swatch</data>
+            <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac3016ade3f016b82a856677715db6c93736c1ef
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\TestCase;
+
+use Magento\Mtf\TestCase\Scenario;
+
+/**
+ * Preconditions:
+ * 1. Configure text swatch attribute.
+ * 2. Create configurable product with this attribute
+ * 3. Open it on catalog page
+ * 4. Click on 'Add to Cart' button
+ *
+ * Steps:
+ * 1. Go to Frontend.
+ * 2. Open category page with created product
+ * 3. Click on 'Add to Cart' button
+ * 4. Perform asserts
+ *
+ * @group Configurable_Product
+ * @ZephyrId TODO: MAGETWO-59979
+ */
+class TryToAddConfigurableProductWithSwatchToShopingCartTest extends Scenario
+{
+    /**
+     * Runs add configurable product with swatches attributes test.
+     *
+     * @return void
+     */
+    public function test()
+    {
+        $this->executeScenario();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4cb7a3e01676f09c6c3e6b9ffcd3d85fb9abbe4a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Swatches\Test\TestCase\TryToAddConfigurableProductWithSwatchToShopingCartTest" summary="Create text swatch attribute" ticketId="MAGETWO-47017">
+        <variation name="TryToAddConfigurableProductWithSwatchToShopingCartTest1">
+            <data name="attributeTypeAction" xsi:type="string">addOptions</data>
+            <data name="product" xsi:type="string">configurableProductSwatch::product_with_text_swatch_and_size</data>
+            <constraint name="Magento\Swatches\Test\Constraint\AssertSwatchConfigurableProductPage" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php
new file mode 100644
index 0000000000000000000000000000000000000000..e19f9d7b3c362ca61d5869ea409c20359b4b4ffb
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Swatches\Test\TestStep;
+
+use Magento\Mtf\TestStep\TestStepInterface;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Swatches\Test\Block\Product\ProductList\ProductItem;
+use Magento\Mtf\Fixture\InjectableFixture;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\Cms\Test\Page\CmsIndex;
+
+/**
+ * Add configurable product to cart.
+ */
+class AddProductToCartFromCatalogCategoryPageStep implements TestStepInterface
+{
+    /**
+     * Fixture of configurable product with swatches configuration.
+     *
+     * @var \Magento\Swatches\Test\Fixture\ConfigurableProduct
+     */
+    private $product;
+
+    /**
+     * Fixture factory for create/get fixtures.
+     *
+     * @var FixtureFactory
+     */
+    private $fixtureFactory;
+
+    /**
+     * Page of catalog category view.
+     *
+     * @var CatalogCategoryView
+     */
+    private $categoryView;
+
+    /**
+     * CMS index page.
+     *
+     * @var CmsIndex
+     */
+    private $cmsIndex;
+
+    /**
+     * @constructor
+     * @param FixtureFactory $fixtureFactory
+     * @param CmsIndex $cmsIndex
+     * @param InjectableFixture $product
+     * @param CatalogCategoryView $categoryView
+     */
+    public function __construct(
+        FixtureFactory $fixtureFactory,
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $categoryView,
+        InjectableFixture $product
+    ) {
+        $this->fixtureFactory = $fixtureFactory;
+        $this->cmsIndex = $cmsIndex;
+        $this->categoryView = $categoryView;
+        $this->product = $product;
+    }
+
+    /**
+     * Update configurable product.
+     *
+     * @return array
+     */
+    public function run()
+    {
+        $categoryName = $this->product->getCategoryIds()[0];
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName($categoryName);
+        /** @var  \Magento\Swatches\Test\Block\Product\ListProduct $productsList */
+        $productsList = $this->categoryView->getListSwatchesProductBlock();
+        /** @var ProductItem $productItemBlock */
+        $productItemBlock = $productsList->getProductItem($this->product);
+        $productItemBlock->fillData($this->product);
+        $productItemBlock->clickAddToCart();
+        $cart = [
+            'data' => [
+                'items' => [
+                    'products' => [$this->product]
+                ]
+            ]
+        ];
+
+        return [
+            'cart' => $this->fixtureFactory->createByCode('cart', $cart)
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ac3ad40f804e1abac634c135228d89fca3a90876
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <preference for="Magento\Swatches\Test\Handler\SwatchProductAttribute\SwatchProductAttributeInterface" type="\Magento\Swatches\Test\Handler\SwatchProductAttribute\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f2e30c42a7a859e52ad129eda213aa8b1e597aad
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/TestCase/etc/testcase.xsd">
+    <scenario name="AddConfigurableProductWithSwatchToShopingCartTest" firstStep="createProduct">
+        <step name="createProduct" module="Magento_Catalog" next="addProductToCartFromCatalogCategoryPage" />
+        <step name="addProductToCartFromCatalogCategoryPage" module="Magento_Swatches" />
+    </scenario>
+    <scenario name="TryToAddConfigurableProductWithSwatchToShopingCartTest" firstStep="createProduct">
+        <step name="createProduct" module="Magento_Catalog" />
+    </scenario>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php
index 31ca2396f07827735fa3f686facb412807bdf59e..3e69145b42b3416efb88b6557c780d83eae59a1c 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php
@@ -39,9 +39,9 @@ class RemoveTaxRule extends Curl
     public function persist(FixtureInterface $fixture = null)
     {
         $this->taxRuleGridUrl = $_ENV['app_backend_url'] . 'tax/rule/index/';
-        $curl = $this->_getCurl($this->taxRuleGridUrl);
+        $curl = $this->getCurl($this->taxRuleGridUrl);
         $response = $curl->read();
-        $this->_removeTaxRules($response);
+        $this->removeTaxRules($response);
         $curl->close();
         return $response;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php
index 9cfa401510bc17bd1e0651f7cb3a71370c46a2fe..55a6694571ac14f4bdb805f57d847db5db87fc62 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php
@@ -28,6 +28,7 @@ class CreateTaxRuleEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'acceptance_test, extended_acceptance_test';
+    const TO_MAINTAIN = 'yes';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
index 5d338af60555fbb68836d8abb8a53cf9c2d7ceae..7bbf6d29e7b9fb13c7df662f885c2a089f73f843 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
@@ -19,6 +19,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleForm" />
         </variation>
         <variation name="CreateTaxRuleEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="taxRule/data/code" xsi:type="string">TaxIdentifier%isolation%</data>
             <data name="taxRule/data/tax_rate/dataset/rate_0" xsi:type="string">US-CA-Rate_1</data>
             <data name="taxRule/data/tax_rate/dataset/rate_1" xsi:type="string">US-NY-Rate_1</data>
@@ -47,6 +48,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleForm" />
         </variation>
         <variation name="CreateTaxRuleEntityTestVariation4">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="taxRule/data/code" xsi:type="string">TaxIdentifier%isolation%</data>
             <data name="taxRule/data/tax_rate/dataset/rate_0" xsi:type="string">withZipRange</data>
             <data name="taxRule/data/tax_rate/dataset/rate_1" xsi:type="string">US-CA-Rate_1</data>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml
index 9414b9a0172f173d18604ed5929c5617adce4341..cda7bf0665b01b8ace1ef863d84932ab44388c47 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest" summary="Apply Taxes for products" ticketId="MAGETWO-27809">
         <variation name="TaxCalculationTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax equals store tax and catalog price including tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, row_cat_incl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
@@ -37,6 +38,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="TaxCalculationTestVariation4">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax less than store tax and catalog price including tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, row_cat_incl_ship_excl_before_disc_on_incl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
@@ -66,6 +68,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="TaxCalculationTestVariation5">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax less than store tax and catalog price including tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, unit_cat_incl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
@@ -95,6 +98,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="TaxCalculationTestVariation6">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax equals store tax and catalog price excluding tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, total_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
@@ -124,6 +128,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="TaxCalculationTestVariation9">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax greater than store tax and catalog price excluding tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data>
@@ -153,6 +158,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" />
         </variation>
         <variation name="TaxCalculationTestVariation10">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price excluding tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, unit_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data>
             <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php
index 9517ee063ce67cbf33e50ed44412d8e7253526e2..09debcf5f75eb3441b6b18bcab438ecda3f757a3 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php
@@ -37,6 +37,7 @@ class TaxWithCrossBorderTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml
index a485579634ed95e4027f2147088257ad6b256a52..58e7b2b038cc20cfb4ab079254f18edd6413bf9f 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml
@@ -48,6 +48,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsApplied" />
         </variation>
         <variation name="UpdateTaxRuleEntityTestVariation4">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="initialTaxRule/dataset" xsi:type="string">tax_rule_with_custom_tax_classes</data>
             <data name="address/data/country_id" xsi:type="string">United States</data>
             <data name="address/data/region_id" xsi:type="string">Idaho</data>
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
index 80df7e6f8c631722fb314525b2d6733e2ac605ad..c5968c8e936f8a5bead20016d9c70d699b8c1a0c 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
@@ -71,7 +71,7 @@ class DataGrid extends Grid
      *
      * @var string
      */
-    protected $massActionToggleList = '//span[contains(@class, "action-menu-item") and .= "%s"]';
+    protected $massActionToggleList = './/span[contains(@class, "action-menu-item") and .= "%s"]';
 
     /**
      * Action button (located above the Grid).
@@ -85,7 +85,7 @@ class DataGrid extends Grid
      *
      * @var string
      */
-    protected $actionList = '//span[contains(@class, "action-menu-item") and .= "%s"]';
+    protected $actionList = './/span[contains(@class, "action-menu-item") and .= "%s"]';
 
     /**
      * Column header locator.
@@ -104,6 +104,13 @@ class DataGrid extends Grid
      * @var string
      */
     private $cellByHeader = "//td[count(//th[span[.='%s']][not(ancestor::*[@class='sticky-header'])]/preceding-sibling::th)+1]";
+
+    /**
+     * Admin data grid header selector.
+     *
+     * @var string
+     */
+    private $gridHeader = './/div[@class="admin__data-grid-header"][(not(ancestor::*[@class="sticky-header"]) and not(contains(@style,"visibility: hidden"))) or (ancestor::*[@class="sticky-header" and not(contains(@style,"display: none"))])]';
     // @codingStandardsIgnoreEnd
 
     /**
@@ -165,7 +172,7 @@ class DataGrid extends Grid
      */
     protected function waitFilterToLoad()
     {
-        $this->getTemplateBlock()->waitForElementNotVisible($this->loader);
+        $this->getTemplateBlock()->waitLoader();
         $browser = $this->_rootElement;
         $selector = $this->filterButton . ', ' . $this->resetButton;
         $browser->waitUntil(
@@ -322,12 +329,12 @@ class DataGrid extends Grid
     public function selectAction($action)
     {
         $actionType = is_array($action) ? key($action) : $action;
-        $this->_rootElement->find($this->actionButton)->click();
-        $this->_rootElement
+        $this->getGridHeaderElement()->find($this->actionButton)->click();
+        $this->getGridHeaderElement()
             ->find(sprintf($this->actionList, $actionType), Locator::SELECTOR_XPATH)
             ->click();
         if (is_array($action)) {
-            $this->_rootElement
+            $this->getGridHeaderElement()
                 ->find(sprintf($this->actionList, end($action)), Locator::SELECTOR_XPATH)
                 ->click();
         }
@@ -463,4 +470,14 @@ class DataGrid extends Grid
 
         return $data;
     }
+
+    /**
+     * Returns admin data grid header element.
+     *
+     * @return \Magento\Mtf\Client\ElementInterface
+     */
+    private function getGridHeaderElement()
+    {
+        return $this->_rootElement->find($this->gridHeader, Locator::SELECTOR_XPATH);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php
index 39a80b783a0a1cf2dcb36a91e8d140bf3e236b8c..4b923dd4344a93be0e2bf3491c30eecf823f76ba 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php
@@ -28,6 +28,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid;
 class GridFilteringTest extends Injectable
 {
     /* tags */
+    const STABLE = 'no';
     const MVP = 'no';
     /* end tags */
 
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php
index c0049f0cc2fb39d22758a1ce3cae3fcc22bf9552..510d2d61c0acd2100b295ee1422015b1833d9c36 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php
@@ -28,6 +28,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid;
 class GridFullTextSearchTest extends Injectable
 {
     /* tags */
+    const STABLE = 'no';
     const MVP = 'no';
     /* end tags */
 
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php
index 2003bb4b27770239a2b9c2b8d75dc1a9a178f02b..fdf10565117764fa85727d38a4d10c44e4047261 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php
@@ -31,6 +31,7 @@ class CreateAdminUserEntityTest extends Injectable
     /* tags */
     const MVP = 'no';
     const TEST_TYPE = 'extended_acceptance_test';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml
index 85c6a6fd80eecc69cc945d96a908f40dcfb1a356..83b50205387d5da98401799e7486aba04368c355 100644
--- a/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml
@@ -54,7 +54,6 @@
                 <item name="value" xsi:type="number">1</item>
             </field>
         </dataset>
-
         <dataset name="usps_rollback">
             <field name="carriers/usps/active" xsi:type="array">
                 <item name="scope" xsi:type="string">carriers</item>
@@ -63,5 +62,21 @@
                 <item name="value" xsi:type="number">0</item>
             </field>
         </dataset>
+        <dataset name="usps_container_sm_flat_rate_box">
+            <field name="carriers/usps/container" xsi:type="array">
+                <item name="scope" xsi:type="string">carriers</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Small Flat-Rate Box</item>
+                <item name="value" xsi:type="string">SM FLAT RATE BOX</item>
+            </field>
+        </dataset>
+        <dataset name="usps_container_sm_flat_rate_box_rollback">
+            <field name="carriers/usps/container" xsi:type="array">
+                <item name="scope" xsi:type="string">carriers</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Variable</item>
+                <item name="value" xsi:type="string">VARIABLE</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
index 0bd219bab3bfff2103ea9f7a1ff2934ca8e1ad59..8081b485c27d5c0e803a051f9126bdf6599e6781 100644
--- a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
@@ -16,10 +16,10 @@
             <data name="address/dataset" xsi:type="string">US_address_1</data>
             <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
             <data name="shipping/shipping_service" xsi:type="string">United States Postal Service</data>
-            <data name="shipping/shipping_method" xsi:type="string">Priority Mail 1-Day</data>
-            <data name="cart/data/shipping_method" xsi:type="string">Priority Mail 1-Day</data>
+            <data name="shipping/shipping_method" xsi:type="string">Priority Mail 1-Day Small Flat Rate Box</data>
+            <data name="cart/data/shipping_method" xsi:type="string">Priority Mail 1-Day Small Flat Rate Box</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
-            <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA</data>
+            <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA, usps_container_sm_flat_rate_box</data>
             <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml
index 381728cb375aef1595153431fa704812689be7cd..4860c6c93696c038b9de309a9ee068e09d65b284 100644
--- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml
@@ -19,6 +19,7 @@
             <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableInPage" />
         </variation>
         <variation name="CreateCustomVariableEntityTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="customVariable/data/code" xsi:type="string">variableCode%isolation%</data>
             <data name="customVariable/data/name" xsi:type="string">variableName%isolation%</data>
             <data name="customVariable/data/html_value" xsi:type="string">&lt;p&gt;variableName%isolation%&lt;/p&gt;</data>
diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml
index 7f2306c5154e78095979c1b64c7f171feacd722f..7234c455fcc223a6b373a04cd0f0672a2c40781e 100644
--- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Variable\Test\TestCase\DeleteCustomVariableEntityTest" summary="Delete Custom Variable" ticketId="MAGETWO-25535">
         <variation name="DeleteCustomVariableEntityTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableSuccessDeleteMessage" />
             <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableNotInGrid" />
             <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableNotInCmsPageForm" />
diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml
index 060d2fbc9a7e6f51113238ebf186930d864eec4c..247b22c86a1b207e686fd584b06b297aa4fa3668 100644
--- a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Weee\Test\TestCase\CreateTaxWithFptTest" summary="Apply FPT to Different Type Prices" ticketId="MAGETWO-29551">
         <variation name="CreateTaxWithFptTestVariation1" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Check not taxed FPT display set to Excluding, Description and Including FPT on product with custom option catalog price Excluding Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl</data>
             <data name="productData" xsi:type="string">with_custom_option_and_fpt</data>
@@ -28,6 +29,7 @@
             <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" />
         </variation>
         <variation name="CreateTaxWithFptTestVariation2" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Check not taxed FPT display set to Including FPT and Description on product with custom option catalog price Excluding Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax</data>
             <data name="productData" xsi:type="string">with_custom_option_and_fpt</data>
@@ -50,6 +52,7 @@
             <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" />
         </variation>
         <variation name="CreateTaxWithFptTestVariation3" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Check not taxed FPT display set to Excluding, Description and Including FPT on product with special price catalog price Excluding Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax</data>
             <data name="productData" xsi:type="string">with_special_price_and_fpt</data>
@@ -72,6 +75,7 @@
             <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" />
         </variation>
         <variation name="CreateTaxWithFptTestVariation4" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="description" xsi:type="string">Check not taxed FPT display set to Including FPT and Description on product with special price catalog price Excluding Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl</data>
             <data name="productData" xsi:type="string">with_special_price_and_fpt</data>
@@ -92,6 +96,7 @@
             <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" />
         </variation>
         <variation name="CreateTaxWithFptTestVariation5" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="description" xsi:type="string">Check taxed FPT display set to Excluding, Description and Including FPT on product with with custom option catalog price Excluding Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_excl_disc_on_excl</data>
             <data name="productData" xsi:type="string">with_custom_option_and_fpt</data>
@@ -204,6 +209,7 @@
             <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" />
         </variation>
         <variation name="CreateTaxWithFptTestVariation11" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test">
+            <data name="issue" xsi:type="string">MAGETWO-44968: FPT Final price includes tax on custom option, when display is set to excluding tax</data>
             <data name="description" xsi:type="string">Check taxed FPT display set to Excluding, Description and Including FPT on product with with custom option and catalog price Including Tax</data>
             <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_incl_disc_on_excl</data>
             <data name="productData" xsi:type="string">with_custom_option_and_fpt</data>
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php
index 50a5657a4783088eabef74ea56aed23cd8592835..2a03872f4be6bce82a7764ec0358f83c654a5b0a 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php
@@ -7,12 +7,20 @@
 namespace Magento\Widget\Test\Block\Adminhtml\Widget;
 
 use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid;
+use Magento\Mtf\Client\Locator;
 
 /**
  * Widget grid on the Widget Instance Index page.
  */
 class WidgetGrid extends AbstractGrid
 {
+    /**
+     * Selector for not empty options at select element.
+     *
+     * @var string
+     */
+    private $notEmptyOptionsSelector = 'option:not([value=""])';
+
     /**
      * Locator value for link in action column.
      *
@@ -36,5 +44,28 @@ class WidgetGrid extends AbstractGrid
         'title' => [
             'selector' => 'input[name="title"]',
         ],
+        'theme_id' => [
+            'selector' => 'select[name="theme_id"]',
+            'input' => 'select',
+        ],
     ];
+
+    /**
+     * Returns values of theme_id filter.
+     *
+     * @return array
+     */
+    public function getThemeIdValues()
+    {
+        $values = [];
+        $themeFilter = $this->filters['theme_id'];
+        $strategy = empty($themeFilter['strategy']) ? Locator::SELECTOR_CSS : $themeFilter['strategy'];
+        $element = $this->_rootElement->find($themeFilter['selector'], $strategy, $themeFilter['input']);
+        $options = $element->getElements($this->notEmptyOptionsSelector);
+        foreach ($options as $option) {
+            $values[] = $option->getText();
+        }
+
+        return $values;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..31ebfd87c252b6e4142263636eb00329ab8d72b7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Widget\Test\Constraint;
+
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Widget\Test\Fixture\Widget;
+use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex;
+
+/**
+ * Assert theme filter contains all possible values from created widgets.
+ */
+class AssertThemeFilterValuesOnWidgetGrid extends AbstractConstraint
+{
+    /**
+     * Assert theme filter contains all possible values from created widgets.
+     *
+     * @param Widget[] $widgets
+     * @param WidgetInstanceIndex $widgetInstanceIndex
+     * @return void
+     */
+    public function processAssert(array $widgets, WidgetInstanceIndex $widgetInstanceIndex)
+    {
+        $expectedValues = [];
+        foreach ($widgets as $widget) {
+            $expectedValues[] = $widget->getThemeId();
+        }
+        $widgetInstanceIndex->open();
+        $actualValues = $widgetInstanceIndex->getWidgetGrid()->getThemeIdValues();
+        \PHPUnit_Framework_Assert::assertEmpty(
+            array_diff($expectedValues, $actualValues),
+            'Widget grid theme filter doesn\'t contain all possible values from created widgets.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Widget grid theme filter contains all possible values from created widgets.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php
index 5382d544a94b9f590a3475c915025c205e1453cd..2cc675f79fbd38a0f7654b40acc5d215be2a5191 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php
@@ -11,7 +11,7 @@ use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex;
 use Magento\Mtf\Constraint\AbstractConstraint;
 
 /**
- * Class AssertWidgetInGrid
+ * Assert widget is present in widget grid.
  */
 class AssertWidgetInGrid extends AbstractConstraint
 {
@@ -20,7 +20,10 @@ class AssertWidgetInGrid extends AbstractConstraint
     /* end tags */
 
     /**
-     * Assert widget availability in widget grid
+     * Assert widget availability in widget grid.
+     * Verifying such fields as:
+     * - title
+     * - theme_id
      *
      * @param Widget $widget
      * @param WidgetInstanceIndex $widgetInstanceIndex
@@ -28,7 +31,7 @@ class AssertWidgetInGrid extends AbstractConstraint
      */
     public function processAssert(Widget $widget, WidgetInstanceIndex $widgetInstanceIndex)
     {
-        $filter = ['title' => $widget->getTitle()];
+        $filter = ['title' => $widget->getTitle(), 'theme_id' => $widget->getThemeId()];
         $widgetInstanceIndex->open();
         \PHPUnit_Framework_Assert::assertTrue(
             $widgetInstanceIndex->getWidgetGrid()->isRowVisible($filter),
@@ -37,7 +40,7 @@ class AssertWidgetInGrid extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object
+     * Returns a string representation of the object.
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc61b3ef66f51585b0e21fc7dc1a64b7f04e57f7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Widget\Test\Constraint;
+
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Widget\Test\Fixture\Widget;
+use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex;
+
+/**
+ * Assert widgets are present in widget grid.
+ */
+class AssertWidgetsInGrid extends AbstractConstraint
+{
+    /**
+     * Assert widgets are present in widget grid.
+     * Verifying such fields as:
+     * - title
+     * - theme_id
+     *
+     * @param Widget[] $widgets
+     * @param WidgetInstanceIndex $widgetInstanceIndex
+     * @param AssertWidgetInGrid $assertWidgetInGrid
+     * @return void
+     */
+    public function processAssert(
+        array $widgets,
+        WidgetInstanceIndex $widgetInstanceIndex,
+        AssertWidgetInGrid $assertWidgetInGrid
+    ) {
+        foreach ($widgets as $widget) {
+            $assertWidgetInGrid->processAssert($widget, $widgetInstanceIndex);
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Widgets are present in widget grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php
index 4c9e61cdb873db0b32d3b77d9c16be3601537364..54520d0786a52732123a7fc0634d363f74d4b43d 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php
@@ -27,6 +27,7 @@ class Curl extends AbstractCurl
     protected $mappingData = [
         'code' => [
             'CMS Page Link' => 'cms_page_link',
+            'Recently Viewed Products' => 'recently_viewed',
         ],
         'block' => [
             'Main Content Area' => 'content',
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml
index dc39ed7fa1259a02da5eadbc84c38e22f64c71aa..4a8972bfd8dbb3f5a80b7f6fc8a7e20c2f80e0fc 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml
@@ -25,5 +25,20 @@
                 <item name="dataset" xsi:type="string">cmsPageLink</item>
             </field>
         </dataset>
+
+        <dataset name="recently_viewed_products_on_blank_theme">
+            <field name="code" xsi:type="string">Recently Viewed Products</field>
+            <field name="title" xsi:type="string">Title_%isolation%</field>
+            <field name="theme_id" xsi:type="string">Magento Blank</field>
+            <field name="store_ids" xsi:type="array">
+                <item name="dataset" xsi:type="string">all_store_views</item>
+            </field>
+            <field name="widget_instance" xsi:type="array">
+                <item name="dataset" xsi:type="string">for_viewed_products</item>
+            </field>
+            <field name="parameters" xsi:type="array">
+                <item name="dataset" xsi:type="string">recentlyViewedProducts</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
index 6358ac8821f26b621de3e83f7ef8380ffb7c3efc..cc02293ff8fdd98febf581beb87e8a00d7b128fb 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
@@ -48,7 +48,7 @@ class CreateWidgetEntityTest extends AbstractCreateWidgetEntityTest
         // Preconditions
         $this->caches = $caches;
         $this->adjustCacheSettings();
-        
+
         // Steps
         $this->widgetInstanceIndex->open();
         $this->widgetInstanceIndex->getPageActionsBlock()->addNew();
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
index f533e115253ed52100fa5c9a9d51f4aa2303ca6b..225759df91f179dbd911fca662c05476c4830a69 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
@@ -19,7 +19,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation2">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1, stable:no</data>
             <data name="widget/data/code" xsi:type="string">CMS Page Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -42,7 +42,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyViewedProducts" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation4">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, stable:no</data>
             <data name="widget/data/code" xsi:type="string">Recently Compared Products</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -53,7 +53,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyComparedProducts" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation5">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, stable:no</data>
             <data name="widget/data/code" xsi:type="string">Catalog Category Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -76,6 +76,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetProductLink" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation7" summary="Assert widget with disabled block_html cache type">
+            <data name="issue" xsi:type="string">MAGETWO-58146: There is no cache invalidate popup after creating widget with disabled block_html cache type</data>
             <data name="tag" xsi:type="string">severity:S2</data>
             <data name="caches/block_html" xsi:type="string">Disabled</data>
             <data name="widget/data/code" xsi:type="string">CMS Static Block</data>
@@ -91,6 +92,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation8" summary="Assert widget with invalidated block_html cache type">
+            <data name="issue" xsi:type="string">MAGETWO-58146: There is no cache invalidate popup after creating widget with disabled block_html cache type</data>
             <data name="tag" xsi:type="string">severity:S3</data>
             <data name="caches/block_html" xsi:type="string">Invalidated</data>
             <data name="widget/data/code" xsi:type="string">Catalog Category Link</data>
@@ -106,7 +108,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetAbsentOnFrontendHome" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation9" summary="Create Catalog New Products List type widget">
-            <data name="tag" xsi:type="string">severity:S1</data>
+            <data name="tag" xsi:type="string">severity:S1, stable:no</data>
             <data name="widget/data/code" xsi:type="string">Catalog New Products List</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5269c315f78fc23c55e6848ec2482f850cdf2c0e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Widget\Test\TestCase;
+
+use Magento\Mtf\Fixture\FixtureFactory;
+use \Magento\Mtf\TestCase\Injectable;
+use Magento\Widget\Test\Fixture\Widget;
+
+/**
+ * Steps:
+ * 1. Create widgets.
+ * 2. Perform all assertions.
+ *
+ * @group Widget
+ * @ZephyrId MAGETWO-60672
+ */
+class CreateWidgetsEntityTest extends Injectable
+{
+    /* tags */
+    const SEVERITY = 'S3';
+    /* end tags */
+
+    /**
+     * Create multiple widgets.
+     *
+     * @param array $widgets
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function test(array $widgets, FixtureFactory $fixtureFactory)
+    {
+        /** @var Widget[] $widgetInstances */
+        $widgetInstances = [];
+        // Preconditions
+        foreach ($widgets as $widget) {
+            $widget = $fixtureFactory->createByCode('widget', ['dataset' => $widget]);
+            $widget->persist();
+            $widgetInstances[] = $widget;
+        }
+
+        return ['widgets' => $widgetInstances];
+    }
+
+    /**
+     * Delete all widgets.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->objectManager->create(\Magento\Widget\Test\TestStep\DeleteAllWidgetsStep::class)->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..484ea26cf5253a6524b77e299ccdc2532924d3e9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Widget\Test\TestCase\CreateWidgetsEntityTest" summary="Create Widget" ticketId="MAGETWO-60672">
+        <variation name="CreateWidgetEntityTestWithDifferentThemes" summary="Widgets with different themes is presented in grid/filter">
+            <data name="tag" xsi:type="string">severity:S3</data>
+            <data name="widgets/0" xsi:type="string">default</data>
+            <data name="widgets/1" xsi:type="string">recently_viewed_products_on_blank_theme</data>
+            <constraint name="Magento\Widget\Test\Constraint\AssertThemeFilterValuesOnWidgetGrid" />
+            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetsInGrid" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml
index 122a9659cf2b6be0706218e1f761870784179ea7..c1595838b4f63d51d1732857c7ccdd6d6ff8bec3 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml
@@ -66,4 +66,14 @@
             <argument name="severity" xsi:type="string">S1</argument>
         </arguments>
     </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetsInGrid">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertThemeFilterValuesOnWidgetGrid">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
index 076739590e1f19b86fee7bc105221f51efda34cb..226faf7d9ce507dccfa830cc0f7053cf998eb53e 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
@@ -123,14 +123,12 @@ class Product extends Form
         $viewDetails = $this->_rootElement->find($this->viewDetails);
         if ($viewDetails->isVisible()) {
             $this->_rootElement->find($this->footer, Locator::SELECTOR_XPATH)->click();
-            $viewDetails->click();
+            $viewDetails->hover();
             $labels = $this->_rootElement->getElements($this->optionLabel);
             $values = $this->_rootElement->getElements($this->optionValue);
             $data = [];
             foreach ($labels as $key => $label) {
-                if (!$label->isVisible()) {
-                    $viewDetails->click();
-                }
+                $viewDetails->hover();
                 $data[] = [
                     'title' => $label->getText(),
                     'value' => str_replace('$', '', $values[$key]->getText()),
@@ -164,6 +162,18 @@ class Product extends Form
         $this->_rootElement->find($this->price)->hover();
     }
 
+    /**
+     * Returns product price
+     *
+     * @param string $currency
+     * @return string
+     */
+    public function getPrice($currency = '$')
+    {
+        $price = $this->_rootElement->find($this->price)->getText();
+        return str_replace($currency, '', $price);
+    }
+
     /**
      * Get Wish List data for the Product.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php
new file mode 100644
index 0000000000000000000000000000000000000000..24f6222dac09eb34cf3c3d6c5a063341b2acc2ef
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Wishlist\Test\Constraint;
+
+class AssertProductPriceIsNotZero extends \Magento\Mtf\Constraint\AbstractConstraint
+{
+    /**
+     * Assert that product price is not zero in default wishlist.
+     *
+     * @param \Magento\Cms\Test\Page\CmsIndex $cmsIndex
+     * @param \Magento\Customer\Test\Page\CustomerAccountIndex $customerAccountIndex
+     * @param \Magento\Wishlist\Test\Page\WishlistIndex $wishlistIndex
+     * @param \Magento\Mtf\Fixture\InjectableFixture $product
+     *
+     * @return void
+     */
+    public function processAssert(
+        \Magento\Cms\Test\Page\CmsIndex $cmsIndex,
+        \Magento\Customer\Test\Page\CustomerAccountIndex $customerAccountIndex,
+        \Magento\Wishlist\Test\Page\WishlistIndex $wishlistIndex,
+        \Magento\Mtf\Fixture\InjectableFixture $product
+    ) {
+        $cmsIndex->getLinksBlock()->openLink('My Account');
+        $customerAccountIndex->getAccountMenuBlock()->openMenuItem('My Wish List');
+        $wishlistItem = $wishlistIndex->getWishlistBlock()->getProductItemsBlock()->getItemProduct($product);
+
+        \PHPUnit_Framework_Assert::assertNotEquals(
+            '0.00',
+            $wishlistItem->getPrice(),
+            $product->getName() . ' has zero price on Wish List page.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product price is not zero in default Wish List.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php
index 9959796828df23943db8fc3f6dfdce4b6387e1ac..bd922feee99d0315b5f7f16ee13b60eb101b626e 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php
@@ -48,15 +48,16 @@ class AddProductToWishlistEntityTest extends AbstractWishlistTest
      *
      * @param Customer $customer
      * @param string $product
+     * @param bool $configure
      * @return array
      */
-    public function test(Customer $customer, $product)
+    public function test(Customer $customer, $product, $configure = true)
     {
         $product = $this->createProducts($product)[0];
 
         // Steps:
         $this->loginCustomer($customer);
-        $this->addToWishlist([$product], true);
+        $this->addToWishlist([$product], $configure);
 
         return ['product' => $product];
     }
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml
index 0557fa298ce985313593216b561b181175719a70..1a50facc1d67d756ea9ccfb051db7bb0a643c23b 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\AddProductToWishlistEntityTest" summary="Add Product to Wishlist" ticketId="MAGETWO-29045">
         <variation name="AddProductToWishlistEntityTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
@@ -38,16 +39,25 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" />
         </variation>
         <variation name="AddProductToWishlistEntityTestVariation6">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" />
         </variation>
         <variation name="AddProductToWishlistEntityTestVariation7">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" />
         </variation>
+        <variation name="AddProductToWishlistEntityTestVariation8">
+            <data name="product/0" xsi:type="string">configurableProduct::default</data>
+            <data name="configure" xsi:type="boolean">false</data>
+            <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" />
+            <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
+            <constraint name="Magento\Wishlist\Test\Constraint\AssertProductPriceIsNotZero" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
index cf16a045c3487ca9c8520a03ff4b47fc83ed84dd..6fec88a05de2885c57a61383497b06c353b0823a 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
@@ -28,6 +28,7 @@ class AddProductsToCartFromCustomerWishlistOnFrontendTest extends AbstractWishli
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
index 7f89b52dff6185330d0058d664fff9ea5c987d70..ab33641cd04420a2eaa7b92df44312278a0ec57e 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest" summary="Add Products from Wishlist to Cart" ticketId="MAGETWO-25268">
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_100_dollar</data>
             <data name="qty" xsi:type="string">2</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
@@ -20,6 +21,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
         </variation>
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="products/2" xsi:type="string">catalogProductSimple::default</data>
@@ -41,18 +43,21 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
         </variation>
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation6">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">configurableProduct::default</data>
             <data name="qty" xsi:type="string">3</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
         </variation>
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation7">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
             <data name="qty" xsi:type="string">2</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
         </variation>
         <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation8">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="products/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <data name="qty" xsi:type="string">2</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml
index ea6e122badf8bdcda1d57dcd4900b13a83d73d3a..62654bff2b7a91c4831a28b8f59068dc1667de14 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\ConfigureProductInCustomerWishlistOnBackendTest" summary="Configure Products in Customer Wishlist on Backend" ticketId="MAGETWO-29257">
         <variation name="ConfigureProductInCustomerWishlistOnBackendTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductInCustomerWishlistOnBackendGrid" />
         </variation>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php
index 3738dd0631e82510715c1ef10f2c12dd5cc7c5d1..037de4cba7bcaa00d884e2f5d926b8bc977f7c14 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php
@@ -29,6 +29,7 @@ class ConfigureProductInCustomerWishlistOnFrontendTest extends AbstractWishlistT
 {
     /* tags */
     const MVP = 'no';
+    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml
index c9da4e6ea9b2e4c12b7f8643939f30d8bc97b638..8708ea3c8073f559d2d72c6fbe1129de5fac5017 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml
@@ -8,26 +8,31 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\ConfigureProductInCustomerWishlistOnFrontendTest" summary="Configure Products in Customer Wishlist on Frontend" ticketId="MAGETWO-29507">
         <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">configurableProduct::default</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation4">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">downloadableProduct::with_two_separately_links</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation5">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">groupedProduct::three_simple_products</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml
index 4d410c03d6fe6df49f6a306108d20bc8a9005e06..f74039110ea4476db0b3b01a17a2968179bc7529 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\DeleteProductsFromWishlistOnFrontendTest" summary="Delete Products from Wishlist" ticketId="MAGETWO-28874">
         <variation name="DeleteProductsFromWishlistOnFrontendTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_100_dollar</data>
             <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="removedProductsIndex" xsi:type="array">
@@ -16,6 +17,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" />
         </variation>
         <variation name="DeleteProductsFromWishlistOnFrontendTestVariation2">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="removedProductsIndex" xsi:type="array">
                 <item name="0" xsi:type="string">1</item>
@@ -23,6 +25,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" />
         </variation>
         <variation name="DeleteProductsFromWishlistOnFrontendTestVariation3">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
             <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data>
             <data name="products/2" xsi:type="string">catalogProductSimple::default</data>
@@ -57,6 +60,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" />
         </variation>
         <variation name="DeleteProductsFromWishlistOnFrontendTestVariation7">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">downloadableProduct::with_two_separately_links</data>
             <data name="removedProductsIndex" xsi:type="array">
                 <item name="0" xsi:type="string">1</item>
@@ -64,6 +68,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" />
         </variation>
         <variation name="DeleteProductsFromWishlistOnFrontendTestVariation8">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="products/0" xsi:type="string">groupedProduct::three_simple_products</data>
             <data name="removedProductsIndex" xsi:type="array">
                 <item name="0" xsi:type="string">1</item>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml
index 3706c8f8b3085bbafc35d4974cbdefb8daacddf9..999591d3344f939db0865c53ce5cbd6013a5e069 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\MoveProductFromShoppingCartToWishlistTest" summary="Move Products from Shopping Cart to Wishlist" ticketId="MAGETWO-29545">
         <variation name="MoveProductFromShoppingCartToWishlistTestVariation1">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">catalogProductSimple::default</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
@@ -20,6 +21,7 @@
             <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" />
         </variation>
         <variation name="MoveProductFromShoppingCartToWishlistTestVariation3">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">downloadableProduct::with_two_separately_links</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
@@ -35,6 +37,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="MoveProductFromShoppingCartToWishlistTestVariation5">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
@@ -42,6 +45,7 @@
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" />
         </variation>
         <variation name="MoveProductFromShoppingCartToWishlistTestVariation6">
+            <data name="tag" xsi:type="string">stable:no</data>
             <data name="product/0" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" />
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" />
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml
index 82d6bf563ae627530781c47c6ad90b5824bfcdc3..5025cb97250d780a56d956e28a5641437494a425 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Wishlist\Test\TestCase\ViewProductInCustomerWishlistOnBackendTest" summary="View Product in Customer Wishlist on Backend" ticketId="MAGETWO-29616">
         <variation name="ViewProductInCustomerWishlistOnBackendTestVariation1">
+            <data name="tag" xsi:type="string">to_maintain:yes</data>
             <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data>
             <constraint name="Magento\Wishlist\Test\Constraint\AssertProductInCustomerWishlistOnBackendGrid" />
         </variation>
diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml
new file mode 100644
index 0000000000000000000000000000000000000000..df7b03a994df4d322b533162f04dd45c2108d650
--- /dev/null
+++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd">
+    <rule scope="testcase">
+        <deny>
+            <tag group="stable" value="no" />
+            <tag group="to_maintain" value="yes" />
+        </deny>
+    </rule>
+    <rule scope="testsuite">
+        <deny>
+            <module value="Magento_Setup" strict="1" />
+            <module value="Magento_SampleData" strict="1" />
+        </deny>
+    </rule>
+    <rule scope="variation">
+        <deny>
+            <tag group="test_type" value="3rd_party_test" />
+            <tag group="stable" value="no" />
+            <tag group="to_maintain" value="yes" />
+        </deny>
+    </rule>
+</config>
diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ce5ed9cb663a759edf057291f11ccc6a75fe6266
--- /dev/null
+++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
+    <module name="Magento_TestModuleDirectoryZipCodes" setup_version="0.0.1" active="true">
+        <sequence>
+            <module name="Magento_Directory"/>
+        </sequence>
+    </module>
+</config>
diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4f121c60daeb8c44f327f8149f0148051c252ff
--- /dev/null
+++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Directory:etc/zip_codes.xsd">
+    <zip countryCode="NL">
+        <codes>
+            <code id="pattern_1" active="true" example="test1">^[0-9]{4}\s[a-zA-Z]{2}$</code>
+            <code id="pattern_2" active="true" example="test2">^[0-5]{4}[a-z]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="NL_NEW">
+        <codes>
+            <code id="pattern_1" active="true" example="test1">^[0-2]{4}[A-Z]{2}$</code>
+        </codes>
+    </zip>
+</config>
diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ed368ecf3b23a4bd4db86357f6cbbca0bfc55de
--- /dev/null
+++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+use Magento\Framework\Component\ComponentRegistrar;
+
+$registrar = new ComponentRegistrar();
+if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleDirectoryZipCodes') === null) {
+    ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleDirectoryZipCodes', __DIR__);
+}
diff --git a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json
index 4d6383045d27f2123e84146eae970ec74ae77797..3e8e5650b85a77f75c079ae0ad9211a8d4d0764a 100644
--- a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json
+++ b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json
@@ -2,7 +2,7 @@
   "name": "magento/module-sample-test",
   "description": "test sample module",
   "require": {
-    "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+    "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
     "magento/framework": "100.1.*",
     "magento/module-integration": "100.1.*"
   },
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index 9ab7db147d811d370a4c2609d5baf5ea35225680..d8b2189e9f0d267d24d86ea77c67e84b2e2f73c9 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -1431,4 +1431,113 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
         $this->assertEquals(implode(',', [$multiselectOptions[1]->getValue(), $multiselectOptions[2]->getValue()]),
             $product2->getData('multiselect_attribute'));
     }
+
+    /**
+     * @param array $row
+     * @param string|null $behavior
+     * @param bool $expectedResult
+     * @magentoAppArea adminhtml
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     * @magentoDataFixture Magento/Catalog/Model/ResourceModel/_files/product_simple.php
+     * @dataProvider validateRowDataProvider
+     */
+    public function testValidateRow(array $row, $behavior, $expectedResult)
+    {
+        $this->_model->setParameters(['behavior' => $behavior, 'entity' => 'catalog_product']);
+        $this->assertSame($expectedResult, $this->_model->validateRow($row, 1));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateRowDataProvider()
+    {
+        return [
+            [
+                'row' => ['sku' => 'simple products'],
+                'behavior' => null,
+                'expectedResult' => true,
+            ],
+            [
+                'row' => ['sku' => 'simple products absent'],
+                'behavior' => null,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => [
+                    'sku' => 'simple products absent',
+                    'name' => 'Test',
+                    'product_type' => 'simple',
+                    '_attribute_set' => 'Default',
+                    'price' => 10.20,
+                ],
+                'behavior' => null,
+                'expectedResult' => true,
+            ],
+            [
+                'row' => ['sku' => 'simple products'],
+                'behavior' => Import::BEHAVIOR_ADD_UPDATE,
+                'expectedResult' => true,
+            ],
+            [
+                'row' => ['sku' => 'simple products absent'],
+                'behavior' => Import::BEHAVIOR_ADD_UPDATE,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => [
+                    'sku' => 'simple products absent',
+                    'name' => 'Test',
+                    'product_type' => 'simple',
+                    '_attribute_set' => 'Default',
+                    'price' => 10.20,
+                ],
+                'behavior' => Import::BEHAVIOR_ADD_UPDATE,
+                'expectedResult' => true,
+            ],
+            [
+                'row' => ['sku' => 'simple products'],
+                'behavior' => Import::BEHAVIOR_DELETE,
+                'expectedResult' => true,
+            ],
+            [
+                'row' => ['sku' => 'simple products absent'],
+                'behavior' => Import::BEHAVIOR_DELETE,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => ['sku' => 'simple products'],
+                'behavior' => Import::BEHAVIOR_REPLACE,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => ['sku' => 'simple products absent'],
+                'behavior' => Import::BEHAVIOR_REPLACE,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => [
+                    'sku' => 'simple products absent',
+                    'name' => 'Test',
+                    'product_type' => 'simple',
+                    '_attribute_set' => 'Default',
+                    'price' => 10.20,
+                ],
+                'behavior' => Import::BEHAVIOR_REPLACE,
+                'expectedResult' => false,
+            ],
+            [
+                'row' => [
+                    'sku' => 'simple products',
+                    'name' => 'Test',
+                    'product_type' => 'simple',
+                    '_attribute_set' => 'Default',
+                    'price' => 10.20,
+                ],
+                'behavior' => Import::BEHAVIOR_REPLACE,
+                'expectedResult' => true,
+            ],
+        ];
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6031429c66023491e2c411748046e76ecbddf41
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Controller\Cart\Index;
+
+/**
+ * @magentoDbIsolation enabled
+ */
+class CouponPostTest extends \Magento\TestFramework\TestCase\AbstractController
+{
+    /**
+     * Test for \Magento\Checkout\Controller\Cart\CouponPost::execute() with simple product
+     *
+     * @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     */
+    public function testExecute()
+    {
+        /** @var $session \Magento\Checkout\Model\Session */
+        $session = $this->_objectManager->create(\Magento\Checkout\Model\Session::class);
+        $quote = $session->getQuote();
+        $quote->setData('trigger_recollect', 1)->setTotalsCollectedFlag(true);
+        $inputData = [
+            'remove' => 0,
+            'coupon_code' => 'test'
+        ];
+        $this->getRequest()->setPostValue($inputData);
+        $this->dispatch(
+            'checkout/cart/couponPost/'
+        );
+
+        $this->assertSessionMessages(
+            $this->equalTo(['The coupon code "test" is not valid.']),
+            \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
index 34a484f749b7807a7096e22fc24c21b8b6e6c5dd..54a068dad5d0a26f1564d662eb962eca64527110 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
@@ -229,4 +229,51 @@ class CartTest extends \Magento\TestFramework\TestCase\AbstractController
         }
         return null;
     }
+
+    /**
+     * Test for \Magento\Checkout\Controller\Cart::execute() with simple product
+     *
+     * @param string $area
+     * @param string $expectedPrice
+     * @magentoDataFixture Magento/Catalog/_files/products.php
+     * @magentoAppIsolation enabled
+     * @dataProvider addAddProductDataProvider
+     */
+    public function testAddToCartSimpleProduct($area, $expectedPrice)
+    {
+        $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class);
+        $postData = [
+            'qty' => '1',
+            'product' => '1',
+            'custom_price' => 1,
+            'form_key' => $formKey->getFormKey(),
+            'isAjax' => 1
+        ];
+        \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($area);
+        $this->getRequest()->setPostValue($postData);
+
+        $quote =  $this->_objectManager->create(\Magento\Checkout\Model\Cart::class);
+        /** @var \Magento\Checkout\Controller\Cart\Add $controller */
+        $controller = $this->_objectManager->create(\Magento\Checkout\Controller\Cart\Add::class, [$quote]);
+        $controller->execute();
+
+        $this->assertContains(json_encode([]), $this->getResponse()->getBody());
+        $items = $quote->getItems()->getItems();
+        $this->assertTrue(is_array($items), 'Quote doesn\'t have any items');
+        $this->assertCount(1, $items, 'Expected quote items not equal to 1');
+        $item = reset($items);
+        $this->assertEquals(1, $item->getProductId(), 'Quote has more than one product');
+        $this->assertEquals($expectedPrice, $item->getPrice(), 'Expected product price failed');
+    }
+
+    /**
+     * Data provider for testAddToCartSimpleProduct
+     */
+    public function addAddProductDataProvider()
+    {
+        return [
+            'frontend' => ['frontend', 'expected_price' => 10],
+            'adminhtml' => ['adminhtml', 'expected_price' => 1]
+        ];
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php b/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php
index 0ce30e5b2984120c7e325a151d96c0ef044affa6..5a2db8ccb22fa0484ab71c04f8a6bbc4cbc7b0e6 100644
--- a/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php
+++ b/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php
@@ -95,33 +95,44 @@ class BaseurlTest extends \PHPUnit_Framework_TestCase
         $unsecurePlaceholder = '{{unsecure_base_url}}';
         $unsecureSuffix = '{{unsecure_base_url}}test/';
         $unsecureWrongSuffix = '{{unsecure_base_url}}test';
+        $unsecureWrongDomainName = 'http://example.com_test/';
         $securePlaceholder = '{{secure_base_url}}';
         $secureSuffix = '{{secure_base_url}}test/';
         $secureWrongSuffix = '{{secure_base_url}}test';
+        $secureWrongDomainName = 'https://example.com_test/';
 
         return [
             ['', 'not a valid URL'],
             ['', 'example.com'],
             ['', 'http://example.com'],
             ['', 'http://example.com/uri'],
+            ['', $unsecureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, ''],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $baseSuffix],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecureSuffix],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecurePlaceholder],
+            [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, ''],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $baseSuffix],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_STATIC_URL, $unsecureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_STATIC_URL, $unsecureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, ''],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $baseSuffix],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $secureSuffix],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $securePlaceholder],
+            [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $secureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, ''],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $baseSuffix],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $secureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $secureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureWrongDomainName],
             [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_STATIC_URL, $secureWrongSuffix],
+            [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_STATIC_URL, $secureWrongDomainName],
         ];
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5db97cc36614924ae915b7b924b2c7a1f575e344
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
+
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Model\ResourceModel\Product\Collection;
+use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * @magentoAppArea adminhtml
+ */
+class ConfigurableTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var ProductRepositoryInterface
+     */
+    private $productRepository;
+
+    protected function setUp()
+    {
+        $this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
+        $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+    }
+
+    /**
+     * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGetProductFinalPriceIfOneOfChildIsDisabled()
+    {
+        /** @var Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get(CollectionFactory::class)
+            ->create();
+        $configurableProduct = $collection
+            ->addIdFilter([1])
+            ->addMinimalPrice()
+            ->load()
+            ->getFirstItem();
+        $this->assertEquals(10, $configurableProduct->getMinimalPrice());
+
+        $childProduct = $this->productRepository->getById(10, false, null, true);
+        $childProduct->setStatus(Status::STATUS_DISABLED);
+        // update in global scope
+        $currentStoreId = $this->storeManager->getStore()->getId();
+        $this->storeManager->setCurrentStore(Store::ADMIN_CODE);
+        $this->productRepository->save($childProduct);
+        $this->storeManager->setCurrentStore($currentStoreId);
+
+        /** @var Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get(CollectionFactory::class)
+            ->create();
+        $configurableProduct = $collection
+            ->addIdFilter([1])
+            ->addMinimalPrice()
+            ->load()
+            ->getFirstItem();
+        $this->assertEquals(20, $configurableProduct->getMinimalPrice());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
index ff08056e4b18def3f520d2a5d9f2090b168d5ec8..0d8361b4751e38a96ae4dbb7aadb86510dad92dc 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Creates a simple product to be used for test cases.
+ *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -72,7 +74,8 @@ $product->setTypeId(Type::TYPE_SIMPLE)
             'is_in_stock'               => 1,
         ]
     )->setCanSaveCustomOptions(true)
-    ->setHasOptions(true);
+    ->setHasOptions(true)
+    ->setCustomAttribute('test_configurable', 42);
 
 $oldOptions = [
     [
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
index 1576ff90cb38ee4cd89b68766395fa0746d071d6..5f9b9e928b3178f3ae06a8d5a885022cc8e954cc 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
@@ -313,6 +313,8 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractBackendControlle
         $this->assertEquals(2, count($addresses));
         $updatedAddress = $this->addressRepository->getById(1);
         $this->assertEquals('update firstname', $updatedAddress->getFirstname());
+        $this->assertTrue($updatedAddress->isDefaultBilling());
+        $this->assertEquals($updatedAddress->getId(), $customer->getDefaultBilling());
         $newAddress = $this->accountManagement->getDefaultShippingAddress($customerId);
         $this->assertEquals('new firstname', $newAddress->getFirstname());
 
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c44e320e64f4d0cfe1646f97642a2080e604ed74
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Customer\Controller\Section;
+
+class LoadTest extends \Magento\TestFramework\TestCase\AbstractController
+{
+    public function testLoadInvalidSection()
+    {
+        $expected = [
+            'message' => '&quot;section&lt;invalid&quot; section source is not supported',
+        ];
+        $this->dispatch('/customer/section/load/?sections=section<invalid&update_section_id=false&_=147066166394');
+        self::assertEquals(json_encode($expected), $this->getResponse()->getBody());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b57fcb43a1a4326fc80dadcbc8211f6ed35b623
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Model\Country\Postcode\Config;
+
+class ReaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Directory\Model\Country\Postcode\Config\Reader
+     */
+    private $reader;
+
+    protected function setUp()
+    {
+        $this->reader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Directory\Model\Country\Postcode\Config\Reader::class
+        );
+    }
+
+    public function testRead()
+    {
+        $result = $this->reader->read();
+
+        $this->assertArrayHasKey('NL', $result);
+        $this->assertArrayHasKey('pattern_1', $result['NL']);
+        $this->assertArrayHasKey('pattern_2', $result['NL']);
+
+        $this->assertEquals('test1', $result['NL']['pattern_1']['example']);
+        $this->assertEquals('^[0-9]{4}\s[a-zA-Z]{2}$', $result['NL']['pattern_1']['pattern']);
+
+        $this->assertEquals('test2', $result['NL']['pattern_2']['example']);
+        $this->assertEquals('^[0-5]{4}[a-z]{2}$', $result['NL']['pattern_2']['pattern']);
+
+        $this->assertArrayHasKey('NL_NEW', $result);
+        $this->assertArrayHasKey('pattern_1', $result['NL_NEW']);
+
+        $this->assertEquals('test1', $result['NL_NEW']['pattern_1']['example']);
+        $this->assertEquals('^[0-2]{4}[A-Z]{2}$', $result['NL_NEW']['pattern_1']['pattern']);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..82d83938db148ace03cedf19a89cf098517a1d56
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Eav\Model;
+
+class AttributeManagementTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Api\AttributeManagementInterface
+     */
+    private $model;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    private $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->model = $this->objectManager->create(\Magento\Eav\Api\AttributeManagementInterface::class);
+    }
+
+    /**
+     * Verify that collection in service used correctly
+     */
+    public function testGetList()
+    {
+        $productAttributeSetId = $this->getAttributeSetId(
+            \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE
+        );
+        $productAttributes = $this->model->getAttributes(
+            \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+            $productAttributeSetId
+        );
+        // Verify that result contains only product attributes
+        $this->verifyAttributeSetIds($productAttributes, $productAttributeSetId);
+
+        $categoryAttributeSetId = $this->getAttributeSetId(
+            \Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE
+        );
+        $categoryAttributes = $this->model->getAttributes(
+            \Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE,
+            $categoryAttributeSetId
+        );
+        // Verify that result contains only category attributes
+        $this->verifyAttributeSetIds($categoryAttributes, $categoryAttributeSetId);
+    }
+
+    /**
+     * @param string $entityTypeCode
+     * @return int
+     */
+    private function getAttributeSetId($entityTypeCode)
+    {
+        /** @var \Magento\Eav\Model\Config $eavConfig */
+        $eavConfig = $this->objectManager->create(\Magento\Eav\Model\Config::class);
+        return $eavConfig->getEntityType($entityTypeCode)->getDefaultAttributeSetId();
+    }
+
+    /**
+     * @param array $items
+     * @param string $attributeSetId
+     * @return void
+     */
+    private function verifyAttributeSetIds(array $items, $attributeSetId)
+    {
+        /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $item */
+        foreach ($items as $item) {
+            $this->assertEquals($attributeSetId, $item->getAttributeSetId());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php b/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
index 8a566a0d4efe55e856716c095f5a3a7e14896af1..14118414859f0d9bced34e393bfb699f22251edf 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
@@ -12,6 +12,7 @@
 namespace Magento\Framework\DB\Adapter\Pdo;
 
 use Magento\Framework\App\ResourceConnection;
+use Zend_Db_Statement_Exception;
 
 class MysqlTest extends \PHPUnit_Framework_TestCase
 {
@@ -32,6 +33,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
         restore_error_handler();
     }
 
+
     /**
      * Test lost connection re-initializing
      *
@@ -125,9 +127,9 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
     protected function _getConnection()
     {
         if (is_null($this->_connection)) {
-            /** @var $coreResource \Magento\Framework\App\ResourceConnection */
+            /** @var $coreResource ResourceConnection */
             $coreResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-                ->get(\Magento\Framework\App\ResourceConnection::class);
+                ->get(ResourceConnection::class);
             $this->_connection = $coreResource->getConnection();
         }
         return $this->_connection;
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
index 9acfa6f1caab150b0a0db2d54e87358adf88cf5b..67a6e416973493887912e2e62674108b1694c315 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
@@ -414,6 +414,37 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($expectedRecordsCount, $queryResponse->count());
     }
 
+    /**
+     * @magentoDataFixture Magento/Framework/Search/_files/product_configurable.php
+     * @magentoConfigFixture current_store catalog/search/engine mysql
+     */
+    public function testAdvancedSearchCompositeProductWithOutOfStockOption()
+    {
+        /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
+        $attribute = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+            ->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'test_configurable');
+        /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection $selectOptions */
+        $selectOptions = $this->objectManager
+            ->create(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection::class)
+            ->setAttributeFilter($attribute->getId());
+
+        $firstOption = $selectOptions->getFirstItem();
+        $firstOptionId = $firstOption->getId();
+        $this->requestBuilder->bind('test_configurable', $firstOptionId);
+        $this->requestBuilder->setRequestName('filter_out_of_stock_child');
+
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(0, $queryResponse->count());
+
+        $secondOption = $selectOptions->getLastItem();
+        $secondOptionId = $secondOption->getId();
+        $this->requestBuilder->bind('test_configurable', $secondOptionId);
+        $this->requestBuilder->setRequestName('filter_out_of_stock_child');
+
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(1, $queryResponse->count());
+    }
+
     public function dateDataProvider()
     {
         return [
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..030e0250c3ec7fed4747aed4e168413207c7daf7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Eav\Api\AttributeRepositoryInterface;
+
+$eavConfig = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class);
+$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable');
+
+$eavConfig->clear();
+
+/** @var $installer \Magento\Catalog\Setup\CategorySetup */
+$installer = Bootstrap::getObjectManager()->create(\Magento\Catalog\Setup\CategorySetup::class);
+
+if (!$attribute->getId()) {
+
+    /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
+    $attribute = Bootstrap::getObjectManager()->create(
+        \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
+    );
+
+    /** @var AttributeRepositoryInterface $attributeRepository */
+    $attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class);
+
+    $attribute->setData(
+        [
+            'attribute_code' => 'test_configurable',
+            'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
+            'is_global' => 1,
+            'is_user_defined' => 1,
+            'frontend_input' => 'select',
+            'is_unique' => 0,
+            'is_required' => 0,
+            'is_searchable' => 1,
+            'is_visible_in_advanced_search' => 1,
+            'is_comparable' => 0,
+            'is_filterable' => 1,
+            'is_filterable_in_search' => 1,
+            'is_used_for_promo_rules' => 0,
+            'is_html_allowed_on_front' => 1,
+            'is_visible_on_front' => 0,
+            'used_in_product_listing' => 0,
+            'used_for_sort_by' => 0,
+            'frontend_label' => ['Test Configurable'],
+            'backend_type' => 'int',
+            'option' => [
+                'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']],
+                'order' => ['option_0' => 1, 'option_1' => 2],
+            ],
+        ]
+    );
+
+    $attributeRepository->save($attribute);
+}
+
+/* Assign attribute to attribute set */
+$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
+$eavConfig->clear();
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd18100f6d97b4b9b56c9743e8064e0723fdc6c8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+$productCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->get(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
+foreach ($productCollection as $product) {
+    $product->delete();
+}
+
+$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class);
+$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable');
+if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute
+    && $attribute->getId()
+) {
+    $attribute->delete();
+}
+$eavConfig->clear();
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php
new file mode 100644
index 0000000000000000000000000000000000000000..590f3c8041c6d819fafa14ef7ddc4d1f2ebccbeb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Model\Product\Type;
+use Magento\Catalog\Model\Product\Visibility;
+use Magento\Catalog\Setup\CategorySetup;
+use Magento\ConfigurableProduct\Helper\Product\Options\Factory;
+use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+use Magento\Eav\Api\Data\AttributeOptionInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
+
+require __DIR__ . '/configurable_attribute.php';
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = Bootstrap::getObjectManager()
+    ->create(ProductRepositoryInterface::class);
+
+/** @var $installer CategorySetup */
+$installer = Bootstrap::getObjectManager()->create(CategorySetup::class);
+
+/* Create simple products per each option value*/
+/** @var AttributeOptionInterface[] $options */
+$options = $attribute->getOptions();
+
+$attributeValues = [];
+$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
+$associatedProductIds = [];
+$productIds = [10, 20];
+array_shift($options); //remove the first option which is empty
+
+$isFirstOption = true;
+foreach ($options as $option) {
+    /** @var $product Product */
+    $product = Bootstrap::getObjectManager()->create(Product::class);
+    $productId = array_shift($productIds);
+    $product->setTypeId(Type::TYPE_SIMPLE)
+        ->setId($productId)
+        ->setAttributeSetId($attributeSetId)
+        ->setWebsiteIds([1])
+        ->setName('Configurable Option' . $option->getLabel())
+        ->setSku('simple_' . $productId)
+        ->setPrice($productId)
+        ->setTestConfigurable($option->getValue())
+        ->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE)
+        ->setStatus(Status::STATUS_ENABLED)
+        ->setStockData(
+            [
+                'use_config_manage_stock' => 1,
+                'qty' => 100,
+                'is_qty_decimal' => 0,
+                'is_in_stock' => (int)!$isFirstOption,
+            ]
+        );
+
+    $product = $productRepository->save($product);
+
+    /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */
+    $stockItem = Bootstrap::getObjectManager()->create(\Magento\CatalogInventory\Model\Stock\Item::class);
+    $stockItem->load($productId, 'product_id');
+
+    if (!$stockItem->getProductId()) {
+        $stockItem->setProductId($productId);
+    }
+    $stockItem->setUseConfigManageStock(1);
+    $stockItem->setQty(1000);
+    $stockItem->setIsQtyDecimal(0);
+    $stockItem->setIsInStock((int)!$isFirstOption);
+    $stockItem->save();
+
+    $attributeValues[] = [
+        'label' => 'test',
+        'attribute_id' => $attribute->getId(),
+        'value_index' => $option->getValue(),
+    ];
+    $associatedProductIds[] = $product->getId();
+    $isFirstOption = false;
+}
+
+/** @var $product Product */
+$product = Bootstrap::getObjectManager()->create(Product::class);
+
+/** @var Factory $optionsFactory */
+$optionsFactory = Bootstrap::getObjectManager()->create(Factory::class);
+
+$configurableAttributesData = [
+    [
+        'attribute_id' => $attribute->getId(),
+        'code' => $attribute->getAttributeCode(),
+        'label' => $attribute->getStoreLabel(),
+        'position' => '0',
+        'values' => $attributeValues,
+    ],
+];
+
+$configurableOptions = $optionsFactory->create($configurableAttributesData);
+
+$extensionConfigurableAttributes = $product->getExtensionAttributes();
+$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
+$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds);
+
+$product->setExtensionAttributes($extensionConfigurableAttributes);
+
+// Remove any previously created product with the same id.
+/** @var \Magento\Framework\Registry $registry */
+$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+try {
+    $productToDelete = $productRepository->getById(1);
+    $productRepository->delete($productToDelete);
+
+    /** @var \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource */
+    $itemResource = Bootstrap::getObjectManager()->get(\Magento\Quote\Model\ResourceModel\Quote\Item::class);
+    $itemResource->getConnection()->delete(
+        $itemResource->getMainTable(),
+        'product_id = ' . $productToDelete->getId()
+    );
+} catch (\Exception $e) {
+    // Nothing to remove
+}
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
+
+$product->setTypeId(Configurable::TYPE_CODE)
+    ->setId(1)
+    ->setAttributeSetId($attributeSetId)
+    ->setWebsiteIds([1])
+    ->setName('Configurable Product')
+    ->setSku('configurable')
+    ->setVisibility(Visibility::VISIBILITY_BOTH)
+    ->setStatus(Status::STATUS_ENABLED)
+    ->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]);
+
+$productRepository->save($product);
+//
+///** @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor $eavIndexer */
+//$eavIndexer = Bootstrap::getObjectManager()
+//    ->get(\Magento\Catalog\Model\Indexer\Product\Eav\Processor::class);
+//$eavIndexer->reindexAll();
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ba4e3abe21cc14a75a66270d22ea262dffeb788
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = $objectManager->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+
+foreach (['simple_10', 'simple_20', 'configurable'] as $sku) {
+    try {
+        $product = $productRepository->get($sku, false, null, true);
+
+        $stockStatus = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Status::class);
+        $stockStatus->load($product->getEntityId(), 'product_id');
+        $stockStatus->delete();
+
+        $productRepository->delete($product);
+    } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+        //Product already removed
+    }
+}
+
+require __DIR__ . '/configurable_attribute_rollback.php';
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
index 0cdfa11c3b6b5744abbd911e063553cd23039cc5..4cdc9a93e1f1f0ee093b8e0fd8e555a157fce851 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
@@ -387,4 +387,24 @@
         <from>0</from>
         <size>10</size>
     </request>
+    <request query="filter_out_of_stock_child" index="catalogsearch_fulltext">
+        <dimensions>
+            <dimension name="scope" value="default"/>
+        </dimensions>
+        <queries>
+            <query xsi:type="boolQuery" name="filter_out_of_stock_child" boost="1">
+                <queryReference clause="must" ref="test_configurable"/>
+            </query>
+            <query xsi:type="filteredQuery" name="test_configurable">
+                <filterReference clause="must" ref="test_configurable_filter"/>
+            </query>
+        </queries>
+        <filters>
+            <filter xsi:type="termFilter" name="test_configurable_filter" field="test_configurable" value="$test_configurable$"/>
+        </filters>
+        <aggregations/>
+        <from>0</from>
+        <size>10</size>
+    </request>
+
 </requests>
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml
index f9f8f1ffba91a55536c9d2221b68dc85b702e7f0..19feb33748c840b6c87f506ffd450897e2ace286 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml
@@ -593,7 +593,8 @@
                         <label>Express Checkout</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
                         <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5">
-                            <label>Email Associated with PayPal Merchant Account</label>
+                            <label>Email Associated with PayPal Merchant Account (Optional)</label>
+                            <frontend_class>not-required</frontend_class>
                             <comment>
                                 <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]>
                             </comment>
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json
index 222e5ff822b043185e44719804e0af75d8809c6e..a004d3a86b5b9d0c68ec096ab8beff48fa1e51c5 100644
--- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json
+++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json
@@ -1,7 +1,7 @@
 {
     "name": "magento/module-a",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "0.1",
         "magento/module-b": "0.1"
     },
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json
index 57944758267fd668f541b34586a8eb9f7acd9c98..0626cc6a84d055757c32d9192cc7f2682696912f 100644
--- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json
+++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json
@@ -1,7 +1,7 @@
 {
     "name": "magento/module-b",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "0.74.0-beta6",
         "magento/module-a": "0.1"
     },
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php b/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fe9ec2ee3ea13ef4b2b5881e4970f7aa99e9447
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Controller;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Zend\Stdlib\RequestInterface as Request;
+use Zend\View\Model\JsonModel;
+
+class UrlCheckTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var UrlCheck
+     */
+    private $controller;
+
+    protected function setUp()
+    {
+        $this->controller = Bootstrap::getObjectManager()->create(UrlCheck::class);
+    }
+
+    /**
+     * @param array $requestContent
+     * @param bool $successUrl
+     * @param bool $successSecureUrl
+     * @return void
+     * @dataProvider indexActionDataProvider
+     */
+    public function testIndexAction($requestContent, $successUrl, $successSecureUrl)
+    {
+        $requestMock = $this->getMockBuilder(Request::class)
+            ->getMockForAbstractClass();
+        $requestMock->expects($this->once())
+            ->method('getContent')
+            ->willReturn(json_encode($requestContent));
+
+        $requestProperty = new \ReflectionProperty(get_class($this->controller), 'request');
+        $requestProperty->setAccessible(true);
+        $requestProperty->setValue($this->controller, $requestMock);
+
+        $resultModel = new JsonModel(['successUrl' => $successUrl, 'successSecureUrl' => $successSecureUrl]);
+
+        $this->assertEquals($resultModel, $this->controller->indexAction());
+    }
+
+    /**
+     * @return array
+     */
+    public function indexActionDataProvider()
+    {
+        return [
+            [
+                'requestContent' => [
+                    'address' => [
+                        'actual_base_url' => 'http://example.com/'
+                    ],
+                    'https' => [
+                        'text' => 'https://example.com/',
+                        'admin' => true,
+                        'front' => false
+                    ],
+                ],
+                'successUrl' => true,
+                'successSecureUrl' => true
+            ],
+            [
+                'requestContent' => [
+                    'address' => [
+                        'actual_base_url' => 'http://example.com/folder/'
+                    ],
+                    'https' => [
+                        'text' => 'https://example.com/folder_name/',
+                        'admin' => false,
+                        'front' => true
+                    ],
+                ],
+                'successUrl' => true,
+                'successSecureUrl' => true
+            ],
+            [
+                'requestContent' => [
+                    'address' => [
+                        'actual_base_url' => 'ftp://example.com/'
+                    ],
+                    'https' => [
+                        'text' => 'https://example.com_test/',
+                        'admin' => true,
+                        'front' => true
+                    ],
+                ],
+                'successUrl' => false,
+                'successSecureUrl' => false
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fac1c9b0e7031277e59c67d31c8bbff555910c0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Model;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Framework\Exception\LocalizedException;
+
+class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ServiceMetadata
+     */
+    private $serviceMetadata;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->serviceMetadata = $objectManager->create(ServiceMetadata::class);
+    }
+
+    public function testGetServiceMetadata()
+    {
+        $expected = [
+            'methods' => [
+                'activate' => [
+                    'method' => 'activate',
+                    'inputRequired' => false,
+                    'isSecure' => false,
+                    'resources' => [
+                        'Magento_Customer::manage'
+                    ],
+                    'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.',
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'email' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ],
+                                'confirmationKey' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ]
+                            ]
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'result' => [
+                                    'type' => 'CustomerDataCustomerInterface',
+                                    'required' => true,
+                                    'documentation' => ''
+                                ]
+                            ],
+                            'throws' => [
+                                '\\' . LocalizedException::class
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            'class' => AccountManagementInterface::class,
+            'description' => 'Interface for managing customers accounts.',
+        ];
+        $actual = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+
+    public function testGetRouteMetadata()
+    {
+        $expected = [
+            'methods' => [
+                'activate' => [
+                    'method' => 'activate',
+                    'inputRequired' => false,
+                    'isSecure' => false,
+                    'resources' => [
+                        'Magento_Customer::manage'
+                    ],
+                    'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.',
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'email' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ],
+                                'confirmationKey' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ]
+                            ]
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'result' => [
+                                    'type' => 'CustomerDataCustomerInterface',
+                                    'required' => true,
+                                    'documentation' => ''
+                                ]
+                            ],
+                            'throws' => [
+                                '\\' . LocalizedException::class
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            'class' => AccountManagementInterface::class,
+            'description' => 'Interface for managing customers accounts.',
+            'routes' => [
+                '/V1/customers/me/activate' => [
+                    'PUT' => [
+                        'method' => 'activateById',
+                        'parameters' => [
+                            'customerId' => [
+                                'force' => true,
+                                'value' => '%customer_id%'
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $actual = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff1634c60782aee3de08203078f9592716de7803
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Model\Soap;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Customer\Api\CustomerRepositoryInterface;
+use Magento\Framework\Exception\LocalizedException;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    private $soapConfig;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->soapConfig = $objectManager->create(Config::class);
+    }
+
+    public function testGetRequestedSoapServices()
+    {
+        $expected = [
+            'customerAccountManagementV1' => [
+                'methods' => [
+                    'activate' => [
+                        'method' => 'activate',
+                        'inputRequired' => false,
+                        'isSecure' => false,
+                        'resources' => [
+                            'Magento_Customer::manage'
+                        ],
+                        'documentation'
+                            => 'Activate a customer account using a key that was sent in a confirmation email.',
+                        'interface' => [
+                            'in' => [
+                                'parameters' => [
+                                    'email' => [
+                                        'type' => 'string',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ],
+                                    'confirmationKey' => [
+                                        'type' => 'string',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ]
+                                ]
+                            ],
+                            'out' => [
+                                'parameters' => [
+                                    'result' => [
+                                        'type' => 'CustomerDataCustomerInterface',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ]
+                                ],
+                                'throws' => [
+                                    '\\' . LocalizedException::class
+                                ]
+                            ]
+                        ]
+                    ]
+                ],
+                'class' => AccountManagementInterface::class,
+                'description' => 'Interface for managing customers accounts.',
+            ]
+        ];
+        $actual = $this->soapConfig->getRequestedSoapServices(
+            [
+                'customerAccountManagementV1',
+                'NonExistentService'
+            ]
+        );
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+
+    public function testGetServiceMethodInfo()
+    {
+        $expected = [
+            'class' => CustomerRepositoryInterface::class,
+            'method' => 'getById',
+            'isSecure' => false,
+            'resources' => [
+                'Magento_Customer::customer',
+                'self'
+            ],
+        ];
+        $actual = $this->soapConfig->getServiceMethodInfo(
+            'customerCustomerRepositoryV1GetById',
+            [
+                'customerCustomerRepositoryV1',
+                'NonExistentService'
+            ]
+        );
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testGetSoapOperation()
+    {
+        $expected = 'customerAccountManagementV1Activate';
+        $actual = $this->soapConfig
+            ->getSoapOperation(
+                AccountManagementInterface::class,
+                'activate',
+                'V1'
+            );
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json
index 920dc1289b0cfa00cd696b35fb495434830850f6..47f9eb415d7badb00345e5436e2c10bd64532c2f 100644
--- a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json
+++ b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/admin-Magento_Catalog",
     "description": "N/A",
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "magento/framework": "0.1.0-alpha103"
     },
     "type": "magento2-theme",
diff --git a/dev/tests/js/JsTestDriver/run_js_tests.php b/dev/tests/js/JsTestDriver/run_js_tests.php
index e6578c52b0699ee334c2f0ce9213ec5f78373330..448fd85869cd28dea34d7a00384838674f086c5a 100644
--- a/dev/tests/js/JsTestDriver/run_js_tests.php
+++ b/dev/tests/js/JsTestDriver/run_js_tests.php
@@ -30,6 +30,8 @@ if (isset($config['Browser'])) {
 } else {
     if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
         $browser = 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe';
+    } elseif (PHP_OS === 'Darwin') {
+        $browser = '/Applications/Firefox.app/Contents/MacOS/firefox';
     } else {
         $browser = exec('which firefox');
     }
@@ -139,29 +141,35 @@ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
             kill -9 $LSOF
         fi
 
-        DISPLAY_NUM=99
-        ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM"
-        if [ $? -eq 0 ] ; then
-            pkill Xvfb
+        # Skip Xvfb setup for OS X since there browsers do not support headless display that way
+        if [ "$(uname)" != "Darwin" ]; then
+            DISPLAY_NUM=99
+            ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM"
+            if [ $? -eq 0 ] ; then
+                pkill Xvfb
+            fi
+    
+            XVFB=`which Xvfb`
+            if [ "$?" -eq 1 ];
+            then
+                echo "Xvfb not found."
+                exit 1
+            fi
+    
+            $XVFB :$DISPLAY_NUM -nolisten inet6 -ac &
+            PID_XVFB="$!"        # take the process ID
+            export DISPLAY=:$DISPLAY_NUM   # set display to use that of the Xvfb
         fi
-
-        XVFB=`which Xvfb`
-        if [ "$?" -eq 1 ];
-        then
-            echo "Xvfb not found."
-            exit 1
-        fi
-
-        $XVFB :$DISPLAY_NUM -nolisten inet6 -ac &
-        PID_XVFB="$!"        # take the process ID
-        export DISPLAY=:$DISPLAY_NUM   # set display to use that of the Xvfb
+        
         USER=`whoami`
         SUDO=`which sudo`
 
         # run the tests
         $SUDO -u $USER ' . $command . '
 
-        kill -9 $PID_XVFB    # shut down Xvfb (firefox will shut down cleanly by JsTestDriver)
+        if [ "$(uname)" != "Darwin" ]; then
+            kill -9 $PID_XVFB    # shut down Xvfb (firefox will shut down cleanly by JsTestDriver)
+        fi
         echo "Done."';
 
     fwrite($fh, $shellCommand . PHP_EOL);
diff --git a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
index b2d9c164fbd1bc57cf9f2497ff02d6fe6f6895e9..b2766ebd90d92e85072bd84c7c7939813d863bc8 100644
--- a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
+++ b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
@@ -56,8 +56,7 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface
      */
     public function canRun()
     {
-        $vendorDir = require BP . '/app/etc/vendor_path.php';
-        exec('php ' . BP . '/' . $vendorDir . '/bin/phpcpd --version', $output, $exitCode);
+        exec($this->getCommand() . ' --version', $output, $exitCode);
         return $exitCode === 0;
     }
 
@@ -71,22 +70,37 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface
      */
     public function run(array $whiteList)
     {
-        $blackListStr = ' ';
+        $blacklistedDirs = [];
+        $blacklistedFileNames = [];
         foreach ($this->blacklist as $file) {
             $file = escapeshellarg(trim($file));
             if (!$file) {
                 continue;
             }
-            $blackListStr .= '--exclude ' . $file . ' ';
+            $ext = pathinfo($file, PATHINFO_EXTENSION);
+            if ($ext != '') {
+                $blacklistedFileNames[] = $file;
+            } else {
+                $blacklistedDirs[] = '--exclude ' . $file . ' ';
+            }
         }
 
-        $vendorDir = require BP . '/app/etc/vendor_path.php';
-        $command = 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd' . ' --log-pmd ' . escapeshellarg(
-                $this->reportFile
-            ) . ' --names-exclude "*Test.php" --min-lines 13' . $blackListStr . ' ' . implode(' ', $whiteList);
-
+        $command = $this->getCommand() . ' --log-pmd ' . escapeshellarg($this->reportFile)
+            . ' --names-exclude ' . join(',', $blacklistedFileNames) . ' --min-lines 13 ' . join(' ', $blacklistedDirs)
+            . ' ' . implode(' ', $whiteList);
         exec($command, $output, $exitCode);
 
         return !(bool)$exitCode;
     }
+
+    /**
+     * Get PHPCPD command
+     *
+     * @return string
+     */
+    private function getCommand()
+    {
+        $vendorDir = require BP . '/app/etc/vendor_path.php';
+        return 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd';
+    }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php
index 52244463a535693746eddf8f4e0d07b05cf9de08..ff12618b399639fb8c4f56a422828cbb7c0c1e67 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php
@@ -100,7 +100,7 @@ Element 'filterReference': The attribute 'clause' is required but missing.
 Element 'filterReference': The attribute 'ref' is required but missing.
 Element 'filter': The attribute 'field' is required but missing.
 Element 'metric', attribute 'type': [facet 'enumeration'] " .
-                "The value 'sumasdasd' is not an element of the set {'sum', 'count', 'min', 'max'}.
+                "The value 'sumasdasd' is not an element of the set {'sum', 'count', 'min', 'max', 'avg'}.
 Element 'metric', attribute 'type': 'sumasdasd' is not a valid value of the local atomic type.
 Element 'bucket': Missing child element(s). Expected is one of ( metrics, ranges ).
 Element 'request': Missing child element(s). Expected is ( from )."
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
index 6b18eb2b71478463e39e815dec078478c4034a07..e5263713d71d7af374ea1f32c2d765d3639e56ce 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
@@ -64,7 +64,7 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
                 if ($regexp) {
                     $matches = preg_grep(
                         $regexp,
-                        file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
+                        file($fileName)
                     );
                     if (!empty($matches)) {
                         foreach (array_keys($matches) as $line) {
@@ -114,7 +114,8 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
                     if (strpos($path, $directory) === 0) {
                         if (preg_match($fileExtensions, $path)) {
                             foreach ($blackListFiles as $blackListFile) {
-                                if (preg_match($blackListFile, $path)) {
+                                $blackListFile = preg_quote($blackListFile, '#');
+                                if (preg_match('#' . $blackListFile . '#', $path)) {
                                     return false;
                                 }
                             }
@@ -158,10 +159,6 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
         if (empty($functions)) {
             return '';
         }
-        $regexArray = [];
-        foreach ($functions as $function) {
-            $regexArray[] = '\b' . $function . '\b\(';
-        }
-        return '/' . implode('|', $regexArray) . '/i';
+        return '/(?<!function |[^\s])\b(' . join('|', $functions) . ')\s*\(/i';
     }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
index d120a4543b9ddced597d330ab489de15c80cdb86..42b8e68e784111b96d43049ae27dc5ebc963ad40 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
@@ -4,6 +4,7 @@
  * See COPYING.txt for license details.
  */
 return [
-    '/Test\/Unit/',
-    '/lib\/internal\/Magento\/Framework\/DB\/Adapter\/Pdo\/Mysql\.php/',
+    'Test/Unit',
+    'lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php',
+    'lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php',
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
index 2567475de6a035b2a369ac342c076ce1e5cad07d..e464d9713657f6341ccbf1f6d77986ebac08d979 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
@@ -1,4 +1,5 @@
+# "Component Type" "Component Name" "Path Pattern"
 module * /
 library * /
 setup
-pub
\ No newline at end of file
+pub
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
index 56e0d51516c2632a28acd50ca2c3999e984720df..3afe3af79b14ff3177a0dc1c5ea9fe42e93b6331 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
@@ -196,4 +196,6 @@ Magento/Framework/Mview/Config/Data
 Magento/Framework/View/File/Collector/Override
 Magento/Framework/MessageQueue/Consumer/Config/ConsumerConfigItem
 Magento/Framework/MessageQueue/Publisher/Config/PublisherConfigItem
-Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem
\ No newline at end of file
+Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem
+IntegrationConfig.php
+*Test.php
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php
index c0316a435662ec4f85a42e5f65295e1f232b5c72..8075f9bddc318a81e8640f44c7e2081cd5aff161 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php
@@ -13,10 +13,8 @@ return [
     'Magento_CatalogInventory',
     'Magento_CatalogRule',
     'Magento_CatalogSearch',
-    'Magento_CatalogWidget',
     'Magento_Checkout',
     'Magento_CheckoutAgreements',
-    'Magento_Cms',
     'Magento_Config',
     'Magento_ConfigurableProduct',
     'Magento_CurrencySymbol',
@@ -47,8 +45,6 @@ return [
     'Magento_Theme',
     'Magento_Translation',
     'Magento_Ui',
-    'Magento_UrlRewrite',
     'Magento_User',
     'Magento_Weee',
-    'Magento_Widget',
 ];
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index cfbeb4f54c9e29d2f7b320b57c51ae7a7b31a676..9af29ab2c458d8a8b09a73e570695d133bd7a123 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -341,6 +341,9 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
     /**
      * Creates a PDO object and connects to the database.
      *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     *
      * @return void
      * @throws \Zend_Db_Adapter_Exception
      */
@@ -371,6 +374,10 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
             list($this->_config['host'], $this->_config['port']) = explode(':', $this->_config['host']);
         }
 
+        if (!isset($this->_config['driver_options'][\PDO::MYSQL_ATTR_MULTI_STATEMENTS])) {
+            $this->_config['driver_options'][\PDO::MYSQL_ATTR_MULTI_STATEMENTS] = false;
+        }
+
         $this->logger->startTimer();
         parent::_connect();
         $this->logger->logStats(LoggerInterface::TYPE_CONNECT, '');
@@ -562,6 +569,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * @throws \Zend_Db_Adapter_Exception To re-throw \PDOException.
      * @throws LocalizedException In case multiple queries are attempted at once, to protect from SQL injection
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @deprecated
      */
     public function multiQuery($sql, $bind = [])
     {
@@ -728,6 +736,8 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * @return array
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
+
+     * @deprecated
      */
     protected function _splitMultiQuery($sql)
     {
diff --git a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php
index 10f1289b90c1841c7e5c9c014b3943132ab8e5f3..ad4746a36513c4dd028b1c81d27dbbcec70148eb 100644
--- a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php
+++ b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php
@@ -31,7 +31,7 @@ class MaliciousCode implements \Zend_Filter_Interface
         //js attributes
         '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror)=[^<]*(?=\/*\>)/Uis',
         //tags
-        '/<\/?(script|meta|link|frame|iframe).*>/Uis',
+        '/<\/?(script|meta|link|frame|iframe|object).*>/Uis',
         //base64 usage
         '/src=[^<]*base64[^<]*(?=\/*\>)/Uis',
     ];
diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php
index 512d8e89750bc24c666e58237668ad63f7e440b8..93de72e3c57c5610882aece936c9346be40dea64 100644
--- a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php
+++ b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php
@@ -89,6 +89,7 @@ class MaliciousCodeTest extends \PHPUnit_Framework_TestCase
                     'Tag is removed <link>SomeLink</link>',
                     'Tag is removed <frame>SomeFrame</frame>',
                     'Tag is removed <iframe>SomeIFrame</iframe>',
+                    'Tag is removed <object>SomeObject</object>',
                 ],
                 [
                     'Tag is removed SomeScript',
@@ -96,6 +97,7 @@ class MaliciousCodeTest extends \PHPUnit_Framework_TestCase
                     'Tag is removed SomeLink',
                     'Tag is removed SomeFrame',
                     'Tag is removed SomeIFrame',
+                    'Tag is removed SomeObject',
                 ],
             ],
             'Base64' => [
diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php
index fb00e9f59c83097b13274e47e7b0a7a52634ecc2..181783c7b2115d8a216c681077e116e98344d15c 100644
--- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php
+++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php
@@ -20,7 +20,15 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
      *
      * @var array
      */
-    protected $_config = [];
+    protected $_config = [
+        'protocols' => (CURLPROTO_HTTP
+            | CURLPROTO_HTTPS
+            | CURLPROTO_FTP
+            | CURLPROTO_FTPS
+        ),
+        'verifypeer' => true,
+        'verifyhost' => 2,
+    ];
 
     /**
      * Curl handle
@@ -41,7 +49,10 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
         'ssl_cert'     => CURLOPT_SSLCERT,
         'userpwd'      => CURLOPT_USERPWD,
         'useragent'    => CURLOPT_USERAGENT,
-        'referer'      => CURLOPT_REFERER
+        'referer'      => CURLOPT_REFERER,
+        'protocols'    => CURLOPT_PROTOCOLS,
+        'verifypeer'   => CURLOPT_SSL_VERIFYPEER,
+        'verifyhost'   => CURLOPT_SSL_VERIFYHOST,
     ];
 
     /**
@@ -55,8 +66,6 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
      * Apply current configuration array to transport resource
      *
      * @return \Magento\Framework\HTTP\Adapter\Curl
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
      */
     protected function _applyConfig()
     {
@@ -65,22 +74,28 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
             curl_setopt($this->_getResource(), $option, $value);
         }
 
-        if (empty($this->_config)) {
-            return $this;
+        // apply config options
+        foreach ($this->getDefaultConfig() as $option => $value) {
+            curl_setopt($this->_getResource(), $option, $value);
         }
 
-        $verifyPeer = isset($this->_config['verifypeer']) ? $this->_config['verifypeer'] : true;
-        curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYPEER, $verifyPeer);
-
-        $verifyHost = isset($this->_config['verifyhost']) ? $this->_config['verifyhost'] : 2;
-        curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYHOST, $verifyHost);
+        return $this;
+    }
 
-        foreach ($this->_config as $param => $curlOption) {
+    /**
+     * Get default options
+     *
+     * @return array
+     */
+    private function getDefaultConfig()
+    {
+        $config = [];
+        foreach (array_keys($this->_config) as $param) {
             if (array_key_exists($param, $this->_allowedParams)) {
-                curl_setopt($this->_getResource(), $this->_allowedParams[$param], $this->_config[$param]);
+                $config[$this->_allowedParams[$param]] = $this->_config[$param];
             }
         }
-        return $this;
+        return $config;
     }
 
     /**
@@ -116,7 +131,9 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
      */
     public function setConfig($config = [])
     {
-        $this->_config = $config;
+        foreach ($config as $key => $value) {
+            $this->_config[$key] = $value;
+        }
         return $this;
     }
 
@@ -268,6 +285,13 @@ class Curl implements \Zend_Http_Client_Adapter_Interface
 
         $multihandle = curl_multi_init();
 
+        // add default parameters
+        foreach ($this->getDefaultConfig() as $defaultOption => $defaultValue) {
+            if (!isset($options[$defaultOption])) {
+                $options[$defaultOption] = $defaultValue;
+            }
+        }
+
         foreach ($urls as $key => $url) {
             $handles[$key] = curl_init();
             curl_setopt($handles[$key], CURLOPT_URL, $url);
diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php
index 255be0a5596a622151e9e1091841d4f5ff8bf58b..37cd33d18683062ab48d16ae8aae2733def7a75e 100644
--- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php
+++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php
@@ -10,10 +10,14 @@ use \Magento\Framework\HTTP\Adapter\Curl;
 
 class CurlTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var Curl */
+    /**
+     * @var Curl
+     */
     protected $model;
 
-    /** @var \Closure */
+    /**
+     * @var \Closure
+     */
     public static $curlExectClosure;
 
     protected function setUp()
@@ -42,4 +46,3 @@ class CurlTest extends \PHPUnit_Framework_TestCase
         ];
     }
 }
-
diff --git a/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php b/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php
index a3ed3b941844eec7497eb233d1c43e74045c45e1..779e8cf0a0e5ecf15b0fcb6da1e48b80a5bb3072 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php
@@ -1,15 +1,15 @@
 <?php
 /**
- *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Framework\ObjectManager\Config;
 
+use Magento\Framework\ObjectManager\ConfigInterface;
 use Magento\Framework\ObjectManager\ConfigCacheInterface;
 use Magento\Framework\ObjectManager\RelationsInterface;
 
-class Compiled implements \Magento\Framework\ObjectManager\ConfigInterface
+class Compiled implements ConfigInterface
 {
     /**
      * @var array
@@ -129,9 +129,15 @@ class Compiled implements \Magento\Framework\ObjectManager\ConfigInterface
      */
     public function extend(array $configuration)
     {
-        $this->arguments = $configuration['arguments'];
-        $this->virtualTypes = $configuration['instanceTypes'];
-        $this->preferences = $configuration['preferences'];
+        $this->arguments = isset($configuration['arguments'])
+            ? array_replace($this->arguments, $configuration['arguments'])
+            : $this->arguments;
+        $this->virtualTypes = isset($configuration['instanceTypes'])
+            ? array_replace($this->virtualTypes, $configuration['instanceTypes'])
+            : $this->virtualTypes;
+        $this->preferences = isset($configuration['preferences'])
+            ? array_replace($this->preferences, $configuration['preferences'])
+            : $this->preferences;
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
index 8ddb6255b9b862a37dea1aaefd742a4c03923d24..3d280f1224b8f3bb2e9082436fa7524308730387 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
@@ -71,6 +71,7 @@ class Adapter implements AdapterInterface
 
     /**
      * {@inheritdoc}
+     * @throws \LogicException
      */
     public function query(RequestInterface $request)
     {
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php
index 5860591eaf702494614ec89a90e816e159ffeb12..cf544eb126e1195096603979bd7378e08f44730d 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php
@@ -14,7 +14,7 @@ class Metrics
      *
      * @var string[]
      */
-    private $mapMetrics = ['count', 'sum', 'min', 'max', 'avg'];
+    private $allowedMetrics = ['count', 'sum', 'min', 'max', 'avg'];
 
     /**
      * Build metrics for Select->columns
@@ -30,7 +30,7 @@ class Metrics
 
         foreach ($metrics as $metric) {
             $metricType = $metric->getType();
-            if (in_array($metricType, $this->mapMetrics)) {
+            if (in_array($metricType, $this->allowedMetrics, true)) {
                 $selectAggregations[$metricType] = "$metricType(main_table.value)";
             }
         }
diff --git a/lib/internal/Magento/Framework/Search/etc/requests.xsd b/lib/internal/Magento/Framework/Search/etc/requests.xsd
index f185699c5a5e890757850fa8985b2e0400c56c35..294232513b7d2ec1938e243423a3113e151fd0c0 100644
--- a/lib/internal/Magento/Framework/Search/etc/requests.xsd
+++ b/lib/internal/Magento/Framework/Search/etc/requests.xsd
@@ -263,6 +263,7 @@
               <xs:enumeration value="count" />
               <xs:enumeration value="min" />
               <xs:enumeration value="max" />
+              <xs:enumeration value="avg" />
             </xs:restriction>
           </xs:simpleType>
         </xs:attribute>
diff --git a/lib/internal/Magento/Framework/Serialize/README.md b/lib/internal/Magento/Framework/Serialize/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5af8fb7f71b6b174855cb39d004ea29cb6d518a3
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/README.md
@@ -0,0 +1,8 @@
+# Serialize
+
+**Serialize** library provides interface *SerializerInterface* and multiple implementations:
+
+ * *Json* - default implementation. Uses PHP native json_encode/json_decode functions;
+ * *Serialize* - less secure than *Json*, but gives higher performance on big arrays. Uses PHP native serialize/unserialize functions, does not unserialize objects on PHP 7.
+ 
+Using *Serialize* implementation directly is discouraged, always use *SerializerInterface*, using *Serialize* implementation may lead to security vulnerabilities.
\ No newline at end of file
diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Json.php b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c5e55b194165849cddaeebc9d6f772375d7a66e
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Serializer;
+
+use Magento\Framework\Serialize\SerializerInterface;
+
+/**
+ * Class for serializing data to json string and unserializing json string to data
+ */
+class Json implements SerializerInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function serialize($data)
+    {
+        return json_encode($data);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function unserialize($string)
+    {
+        return json_decode($string, true);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d2dc66e502ef478a868d04eac3bdc2e01bf8519
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Serializer;
+
+use Magento\Framework\Serialize\SerializerInterface;
+
+/**
+ * Less secure than Json implementation, but gives higher performance on big arrays. Does not unserialize objects on
+ * PHP 7. Using this implementation directly is discouraged as it may lead to security vulnerabilities, especially on
+ * older versions of PHP
+ */
+class Serialize implements SerializerInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function serialize($data)
+    {
+        return serialize($data);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function unserialize($string)
+    {
+        if ($this->getPhpVersion() >= 7) {
+            return unserialize($string, ['allowed_classes' => false]);
+        }
+        return unserialize($string);
+    }
+
+    /**
+     * Return major PHP version
+     *
+     * @return int
+     */
+    private function getPhpVersion()
+    {
+        return PHP_MAJOR_VERSION;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/SerializerInterface.php b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7a15b31a826e004541434a6ec6b4b30863ba9c3
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize;
+
+/**
+ * Interface for serializing
+ */
+interface SerializerInterface
+{
+    /**
+     * Serialize data into string
+     *
+     * @param string|int|float|bool|array|null $data
+     * @return string|bool
+     */
+    public function serialize($data);
+
+    /**
+     * Unserialize the given string
+     *
+     * @param string $string
+     * @return string|int|float|bool|array|null
+     */
+    public function unserialize($string);
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..88e06d89e3763d36a1301b595942a513359ce076
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Test\Unit\Serializer;
+
+use Magento\Framework\DataObject;
+use Magento\Framework\Serialize\Serializer\Json;
+
+class JsonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Serialize\Serializer\Json
+     */
+    private $json;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->json = $objectManager->getObject(Json::class);
+    }
+
+    /**
+     * @param string|int|float|bool|array|null $value
+     * @param string $expected
+     * @dataProvider serializeDataProvider
+     */
+    public function testSerialize($value, $expected)
+    {
+        $this->assertEquals(
+            $expected,
+            $this->json->serialize($value)
+        );
+    }
+
+    public function serializeDataProvider()
+    {
+        $dataObject = new DataObject(['something']);
+        return [
+            ['', '""'],
+            ['string', '"string"'],
+            [null, 'null'],
+            [false, 'false'],
+            [['a' => 'b', 'd' => 123], '{"a":"b","d":123}'],
+            [123, '123'],
+            [10.56, '10.56'],
+            [$dataObject, '{}'],
+        ];
+    }
+
+    /**
+     * @param string $value
+     * @param string|int|float|bool|array|null $expected
+     * @dataProvider unserializeDataProvider
+     */
+    public function testUnserialize($value, $expected)
+    {
+        $this->assertEquals(
+            $expected,
+            $this->json->unserialize($value)
+        );
+    }
+
+    public function unserializeDataProvider()
+    {
+        return [
+            ['""', ''],
+            ['"string"', 'string'],
+            ['null', null],
+            ['false', false],
+            ['{"a":"b","d":123}', ['a' => 'b', 'd' => 123]],
+            ['123', 123],
+            ['10.56', 10.56],
+            ['{}', []],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..874647b5d705fc55e6b9328bab8450e1908a8921
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Test\Unit\Serializer;
+
+use Magento\Framework\Serialize\Serializer\Serialize;
+use Magento\Framework\Serialize\Signer;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\Serialize\InvalidSignatureException;
+
+class SerializeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Serialize
+     */
+    private $serialize;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->serialize = $objectManager->getObject(Serialize::class);
+    }
+
+    /**
+     * @param string|int|float|bool|array|null $value
+     * @param string $serializedValue
+     * @dataProvider serializeDataProvider
+     */
+    public function testSerialize($value, $serializedValue)
+    {
+        $this->assertEquals($serializedValue, $this->serialize->serialize($value));
+    }
+
+    public function serializeDataProvider()
+    {
+        return [
+            ['string', 's:6:"string";'],
+            ['', 's:0:"";'],
+            [10, 'i:10;'],
+            [10.5, 'd:10.5;'],
+            [null, 'N;'],
+            [false, 'b:0;'],
+            [['foo' => 'bar'], 'a:1:{s:3:"foo";s:3:"bar";}'],
+        ];
+    }
+
+    /**
+     * @param string $serializedValue
+     * @param string|int|float|bool|array|null $value
+     * @dataProvider unserializeDataProvider
+     */
+    public function testUnserialize($serializedValue, $value)
+    {
+        $this->assertEquals($value, $this->serialize->unserialize($serializedValue));
+    }
+
+    public function unserializeDataProvider()
+    {
+        return [
+            ['s:6:"string";', 'string'],
+            ['s:0:"";', ''],
+            ['i:10;', 10],
+            ['d:10.5;', 10.5],
+            ['N;', null],
+            ['b:0;', false],
+            ['a:1:{s:3:"foo";s:3:"bar";}', ['foo' => 'bar']],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index e8013b024f4384e2c9b2261daed97a2ccbfb7f03..a517f1fd0b0b744cd44bad6b78ddd9c687a1fab5 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -298,6 +298,7 @@ class SessionManager implements SessionManagerInterface
             return;
         }
 
+        session_regenerate_id(true);
         session_destroy();
         if ($options['send_expire_cookie']) {
             $this->expireSessionCookie();
diff --git a/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php b/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3dd9f5065a1421ec822d4a81377ea81a5c3f8f52
--- /dev/null
+++ b/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Test\Unit\ObjectManager\Config;
+
+use Magento\Framework\ObjectManager\Config\Compiled as CompiledConfig;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class CompiledTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ObjectManagerHelper
+     */
+    private $objectManagerHelper;
+
+    protected function setUp()
+    {
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+    }
+
+    /**
+     * @param array $initialData
+     * @param array $configuration
+     * @param array $expectedArguments
+     * @param array $expectedVirtualTypes
+     * @param array $expectedPreferences
+     *
+     * @dataProvider extendDataProvider
+     */
+    public function testExtend(
+        array $initialData,
+        array $configuration,
+        array $expectedArguments,
+        array $expectedVirtualTypes,
+        array $expectedPreferences
+    ) {
+        /** @var CompiledConfig $compiledConfig */
+        $compiledConfig = $this->objectManagerHelper->getObject(CompiledConfig::class, ['data' => $initialData]);
+        $compiledConfig->extend($configuration);
+
+        foreach ($expectedArguments as $type => $arguments) {
+            $this->assertEquals($arguments, $compiledConfig->getArguments($type));
+        }
+
+        $this->assertEquals($expectedVirtualTypes, $compiledConfig->getVirtualTypes());
+        $this->assertEquals($expectedPreferences, $compiledConfig->getPreferences());
+    }
+
+    /**
+     * @return array
+     */
+    public function extendDataProvider()
+    {
+        return [
+            [
+                'initialData' => [
+                    'arguments' => [
+                        'type1' => serialize(['argument1_1' => 'argumentValue1_1', 'argument1_2' => 'argumentValue1_2'])
+                    ],
+                    'instanceTypes' => [
+                        'instanceType1' => 'instanceTypeValue1', 'instanceType2' => 'instanceTypeValue2'
+                    ],
+                    'preferences' => ['preference1' => 'preferenceValue1', 'preference2' => 'preferenceValue2']
+                ],
+                'configuration' => [
+                    'arguments' => [
+                        'type1' => serialize(['argument1_1' => 'newArgumentValue1_1']),
+                        'type2' => serialize(['argument2_1' => 'newArgumentValue2_1'])
+                    ],
+                    'instanceTypes' => [
+                        'instanceType2' => 'newInstanceTypeValue2', 'instanceType3' => 'newInstanceTypeValue3'
+                    ],
+                    'preferences' => ['preference1' => 'newPreferenceValue1']
+                ],
+                'expectedArguments' => [
+                    'type1' => ['argument1_1' => 'newArgumentValue1_1'],
+                    'type2' => ['argument2_1' => 'newArgumentValue2_1']
+                ],
+                'expectedVirtualTypes' => [
+                    'instanceType1' => 'instanceTypeValue1', 'instanceType2' => 'newInstanceTypeValue2',
+                    'instanceType3' => 'newInstanceTypeValue3'
+                ],
+                'expectedPreferences' => [
+                    'preference1' => 'newPreferenceValue1', 'preference2' => 'preferenceValue2'
+                ]
+            ]
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Validator/AllowedProtocols.php b/lib/internal/Magento/Framework/Validator/AllowedProtocols.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c7bbb3d997236aae0e7cc91994505af78620957
--- /dev/null
+++ b/lib/internal/Magento/Framework/Validator/AllowedProtocols.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Protocol validator
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Validator;
+
+use \Zend\Uri\Uri;
+
+/**
+ * Check is URI starts from allowed protocol
+ *
+ * Class AllowedProtocols
+ * @package Magento\Framework\Validator
+ */
+class AllowedProtocols extends AbstractValidator
+{
+    /**
+     * List of supported protocols
+     *
+     * @var array
+     */
+    private $listOfProtocols = [
+        'http',
+        'https',
+    ];
+
+    /**
+     * Constructor.
+     * @param array $listOfProtocols
+     */
+    public function __construct($listOfProtocols = [])
+    {
+        if (count($listOfProtocols)) {
+            $this->listOfProtocols = $listOfProtocols;
+        }
+    }
+
+    /**
+     * Validate URI
+     *
+     * @param string $value
+     * @return bool
+     */
+    public function isValid($value)
+    {
+        $uri = new Uri($value);
+        $isValid = in_array(
+            strtolower($uri->getScheme()),
+            $this->listOfProtocols
+        );
+        if (!$isValid) {
+            $this->_addMessages(["Protocol isn't allowed"]);
+        }
+        return $isValid;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php b/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d66f84289424920d3d8aca1e5b39e76fa1ad1503
--- /dev/null
+++ b/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Validator\Test\Unit;
+
+use Magento\Framework\Validator\Url as UrlValidator;
+
+class UrlTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var UrlValidator
+     */
+    private $validator;
+
+    protected function setUp()
+    {
+        $this->validator = new UrlValidator();
+    }
+
+    /**
+     * @param array $allowedSchemes
+     * @param string $url
+     * @param bool $expectedResult
+     * @dataProvider isValidDataProvider
+     */
+    public function testIsValid(array $allowedSchemes, $url, $expectedResult)
+    {
+        $this->assertSame($expectedResult, $this->validator->isValid($url, $allowedSchemes));
+    }
+
+    /**
+     * @return array
+     */
+    public function isValidDataProvider()
+    {
+        return [
+            [
+                'allowedSchemes' => [],
+                'url' => 'http://example.com',
+                'expectedResult' => true,
+            ],
+            [
+                'allowedSchemes' => ['http'],
+                'url' => 'http://example.com',
+                'expectedResult' => true,
+            ],
+            [
+                'allowedSchemes' => [],
+                'url' => 'https://example.com',
+                'expectedResult' => true,
+            ],
+            [
+                'allowedSchemes' => ['https'],
+                'url' => 'https://example.com',
+                'expectedResult' => true,
+            ],
+            [
+                'allowedSchemes' => [],
+                'url' => 'http://example.com_test',
+                'expectedResult' => false,
+            ],
+            [
+                'allowedSchemes' => [],
+                'url' => 'ftp://example.com',
+                'expectedResult' => true,
+            ],
+            [
+                'allowedSchemes' => ['ftp'],
+                'url' => 'ftp://example.com',
+                'expectedResult' => true,
+            ],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Validator/Url.php b/lib/internal/Magento/Framework/Validator/Url.php
new file mode 100644
index 0000000000000000000000000000000000000000..27262009b2d200bc354947208bfd075898a3ac0e
--- /dev/null
+++ b/lib/internal/Magento/Framework/Validator/Url.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Validator;
+
+/**
+ * Class Url validates URL and checks that it has allowed scheme
+ */
+class Url
+{
+    /**
+     * Validate URL and check that it has allowed scheme
+     *
+     * @param string $value
+     * @param array $allowedSchemes
+     * @return bool
+     */
+    public function isValid($value, array $allowedSchemes = [])
+    {
+        $isValid = true;
+
+        if (!filter_var($value, FILTER_VALIDATE_URL)) {
+            $isValid = false;
+        }
+
+        if ($isValid && !empty($allowedSchemes)) {
+            $url = parse_url($value);
+            if (empty($url['scheme']) || !in_array($url['scheme'], $allowedSchemes)) {
+                $isValid = false;
+            }
+        }
+
+        return $isValid;
+    }
+}
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index 98338ed4b099d202ce7d8e482b2bda9e3a675068..926d4cc54c140efb315921432b8afc5ebd237cf7 100644
--- a/lib/internal/Magento/Framework/composer.json
+++ b/lib/internal/Magento/Framework/composer.json
@@ -8,7 +8,7 @@
         "AFL-3.0"
     ],
     "require": {
-        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "php": "~5.6.5|7.0.2|7.0.4|~7.0.6",
         "ext-spl": "*",
         "ext-dom": "*",
         "ext-simplexml": "*",
diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
index 7b5100215200473f0610afaf27c922e4662cce8f..2c4ab52b896cb8fd8bf01974d7f39cfc8f11e4f4 100755
--- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
+++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
@@ -82,6 +82,7 @@ define([
             }
 
             var settings = {
+                entity_encoding: 'raw',
                 mode: (mode != undefined ? mode : 'none'),
                 elements: this.id,
                 theme: 'advanced',
diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js
index 3041a177185cf1dfa5bda6e233a2c58a0282d0de..eed9c676b4c90ce1a944d9e7c5ce88a815af08cf 100644
--- a/lib/web/mage/validation.js
+++ b/lib/web/mage/validation.js
@@ -1441,17 +1441,19 @@
      * Validate single element.
      *
      * @param {Element} element
+     * @param {Object} config
      * @returns {*}
      */
-    $.validator.validateSingleElement = function (element) {
+    $.validator.validateSingleElement = function (element, config) {
         var errors = {},
             valid = true,
             validateConfig = {
                 errorElement: 'label',
                 ignore: '.ignore-validate'
             },
-            form, validator, classes;
+            form, validator, classes, elementValue;
 
+        $.extend(validateConfig, config);
         element = $(element).not(validateConfig.ignore);
 
         if (!element.length) {
@@ -1475,7 +1477,11 @@
         validator.toShow = validator.toHide = $([]);
 
         $.each(classes, $.proxy(function (i, className) {
-            if (this.methods[className] && !this.methods[className](element.val(), element.get(0))) {
+            elementValue = element.val();
+            if (element.is(':checkbox') || element.is(':radio')) {
+                elementValue = element.is(':checked') || null;
+            }
+            if (this.methods[className] && !this.methods[className](elementValue, element.get(0))) {
                 valid = false;
                 errors[element.get(0).name] = this.messages[className];
                 validator.invalid[element.get(0).name] = true;
diff --git a/setup/config/di.config.php b/setup/config/di.config.php
index 804f18462065aa3af62cbba93d1fa5339b548f7e..b0dcb452ccd4030cf9736e6ab4a521199d1a899f 100644
--- a/setup/config/di.config.php
+++ b/setup/config/di.config.php
@@ -21,6 +21,7 @@ return [
             \Magento\Setup\Controller\Environment::class,
             \Magento\Setup\Controller\DependencyCheck::class,
             \Magento\Setup\Controller\DatabaseCheck::class,
+            \Magento\Setup\Controller\UrlCheck::class,
             \Magento\Setup\Controller\ValidateAdminCredentials::class,
             \Magento\Setup\Controller\AddDatabase::class,
             \Magento\Setup\Controller\WebConfiguration::class,
diff --git a/setup/pub/magento/setup/web-configuration.js b/setup/pub/magento/setup/web-configuration.js
index 03a0fc7845dda90225d3be867f4bf9ddd1621f63..47458056b33b52f8913017a5f6f7c6317fd98347 100644
--- a/setup/pub/magento/setup/web-configuration.js
+++ b/setup/pub/magento/setup/web-configuration.js
@@ -5,7 +5,7 @@
 
 'use strict';
 angular.module('web-configuration', ['ngStorage'])
-    .controller('webConfigurationController', ['$scope', '$state', '$localStorage', function ($scope, $state, $localStorage) {
+    .controller('webConfigurationController', ['$scope', '$state', '$localStorage', '$http', function ($scope, $state, $localStorage, $http) {
         $scope.config = {
             address: {
                 base_url: '',
@@ -119,4 +119,28 @@ angular.module('web-configuration', ['ngStorage'])
                 $scope.webconfig.submitted = false;
             }
         });
+
+        // Validate URL
+        $scope.validateUrl = function () {
+            if (!$scope.webconfig.submitted) {
+                $http.post('index.php/url-check', $scope.config)
+                    .success(function (data) {
+                        $scope.validateUrl.result = data;
+                        if ($scope.validateUrl.result.successUrl && $scope.validateUrl.result.successSecureUrl) {
+                            $scope.nextState();
+                        }
+                        if (!$scope.validateUrl.result.successUrl) {
+                            $scope.webconfig.submitted = true;
+                            $scope.webconfig.base_url.$setValidity('url', false);
+                        }
+                        if (!$scope.validateUrl.result.successSecureUrl) {
+                            $scope.webconfig.submitted = true;
+                            $scope.webconfig.https.$setValidity('url', false);
+                        }
+                    })
+                    .error(function (data) {
+                        $scope.validateUrl.failed = data;
+                    });
+            }
+        };
     }]);
diff --git a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
index 928fe1e3d4b8d32f7bc4656bf6c00ac500972234..f1098af2db00916e328f515a2a88696553603f78 100644
--- a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
@@ -16,11 +16,10 @@ use Magento\Setup\Model\StoreConfigurationDataMapper;
 use Magento\Setup\Model\ObjectManagerProvider;
 use Magento\Framework\ObjectManagerInterface;
 use Magento\Framework\Exception\LocalizedException;
-use Magento\Store\Model\Store;
-use Magento\Framework\Validator\Locale;
-use Magento\Framework\Validator\Timezone;
-use Magento\Framework\Validator\Currency;
-use Magento\Framework\Url\Validator;
+use Magento\Framework\Validator\Locale as LocaleValidator;
+use Magento\Framework\Validator\Timezone as TimezoneValidator;
+use Magento\Framework\Validator\Currency as CurrencyValidator;
+use Magento\Framework\Validator\Url as UrlValidator;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -43,24 +42,57 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
      * Object Manager
      *
      * @var ObjectManagerInterface
+     * @deprecated
      */
     private $objectManager;
 
+    /**
+     * @var LocaleValidator
+     */
+    private $localeValidator;
+
+    /**
+     * @var TimezoneValidator
+     */
+    private $timezoneValidator;
+
+    /**
+     * @var CurrencyValidator
+     */
+    private $currencyValidator;
+
+    /**
+     * @var UrlValidator
+     */
+    private $urlValidator;
+
     /**
      * Inject dependencies
      *
      * @param InstallerFactory $installerFactory
      * @param DeploymentConfig $deploymentConfig
      * @param ObjectManagerProvider $objectManagerProvider
+     * @param LocaleValidator $localeValidator,
+     * @param TimezoneValidator $timezoneValidator,
+     * @param CurrencyValidator $currencyValidator,
+     * @param UrlValidator $urlValidator
      */
     public function __construct(
         InstallerFactory $installerFactory,
         DeploymentConfig $deploymentConfig,
-        ObjectManagerProvider $objectManagerProvider
+        ObjectManagerProvider $objectManagerProvider,
+        LocaleValidator $localeValidator,
+        TimezoneValidator $timezoneValidator,
+        CurrencyValidator $currencyValidator,
+        UrlValidator $urlValidator
     ) {
         $this->installerFactory = $installerFactory;
         $this->deploymentConfig = $deploymentConfig;
         $this->objectManager = $objectManagerProvider->get();
+        $this->localeValidator = $localeValidator;
+        $this->timezoneValidator = $timezoneValidator;
+        $this->currencyValidator = $currencyValidator;
+        $this->urlValidator = $urlValidator;
         parent::__construct();
     }
 
@@ -173,6 +205,7 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
     public function validate(InputInterface $input)
     {
         $errors = [];
+        $errorMsg = '';
         $options = $input->getOptions();
         foreach ($options as $key => $value) {
             if (!$value) {
@@ -180,99 +213,69 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
             }
             switch ($key) {
                 case StoreConfigurationDataMapper::KEY_BASE_URL:
-                    /** @var Validator $url */
                     if (strcmp($value, '{{base_url}}') == 0) {
                         break;
                     }
-                    $url = $this->objectManager->get(\Magento\Framework\Url\Validator::class);
-                    if (!$url->isValid($value)) {
-                        $errorMsgs = $url->getMessages();
-                        $errors[] = '<error>' . 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL
-                            . '\': ' . $errorMsgs[Validator::INVALID_URL] .'</error>';
-                    }
+                    $errorMsg = $this->validateUrl(
+                        $value,
+                        StoreConfigurationDataMapper::KEY_BASE_URL,
+                        ['http', 'https']
+                    );
+
                     break;
                 case StoreConfigurationDataMapper::KEY_LANGUAGE:
-                    /** @var Locale $lists */
-                    $lists = $this->objectManager->get(\Magento\Framework\Validator\Locale::class);
-                    $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_LANGUAGE);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
+                    $errorMsg = $this->validateCodes(
+                        $this->localeValidator,
+                        $value,
+                        StoreConfigurationDataMapper::KEY_LANGUAGE
+                    );
                     break;
                 case StoreConfigurationDataMapper::KEY_TIMEZONE:
-                    /** @var Timezone $lists */
-                    $lists = $this->objectManager->get(\Magento\Framework\Validator\Timezone::class);
-                    $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_TIMEZONE);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
+                    $errorMsg = $this->validateCodes(
+                        $this->timezoneValidator,
+                        $value,
+                        StoreConfigurationDataMapper::KEY_TIMEZONE
+                    );
                     break;
                 case StoreConfigurationDataMapper::KEY_CURRENCY:
-                    /** @var Currency $lists */
-                    $lists = $this->objectManager->get(\Magento\Framework\Validator\Currency::class);
-                    $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_CURRENCY);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
+                    $errorMsg = $this->validateCodes(
+                        $this->currencyValidator,
+                        $value,
+                        StoreConfigurationDataMapper::KEY_CURRENCY
+                    );
                     break;
                 case StoreConfigurationDataMapper::KEY_USE_SEF_URL:
                     $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_USE_SEF_URL);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
                     break;
                 case StoreConfigurationDataMapper::KEY_IS_SECURE:
                     $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_IS_SECURE);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
                     break;
                 case StoreConfigurationDataMapper::KEY_BASE_URL_SECURE:
-                    try {
-                        /** @var Validator $url */
-                        $url = $this->objectManager->get(\Magento\Framework\Url\Validator::class);
-                        $errorMsgs = '';
-                        if (!$url->isValid($value)) {
-                            $errorMsgs = $url->getMessages();
-                            if (!empty($errorMsgs)) {
-                                $errors[] = '<error>' . 'Command option \''
-                                    . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE
-                                    . '\': ' . $errorMsgs[Validator::INVALID_URL] .'</error>';
-                            }
-                        }
-                        if (empty($errorMsgs) && strpos($value, 'https:') === false) {
-                            throw new LocalizedException(new \Magento\Framework\Phrase("Invalid secure URL."));
-                        }
-                    } catch (LocalizedException $e) {
-                        $errors[] = '<error>' . 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE
-                            . '\': ' . $e->getLogMessage() .'</error>';
-                    }
+                    $errorMsg = $this->validateUrl(
+                        $value,
+                        StoreConfigurationDataMapper::KEY_BASE_URL_SECURE,
+                        ['https']
+                    );
                     break;
                 case StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN:
                     $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN);
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
                     break;
                 case StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY:
                     $errorMsg = $this->validateBinaryValue(
                         $value,
                         StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY
                     );
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
                     break;
                 case StoreConfigurationDataMapper::KEY_JS_LOGGING:
                     $errorMsg = $this->validateBinaryValue(
                         $value,
                         StoreConfigurationDataMapper::KEY_JS_LOGGING
                     );
-                    if ($errorMsg !== '') {
-                        $errors[] = $errorMsg;
-                    }
                     break;
             }
+            if ($errorMsg !== '') {
+                $errors[] = $errorMsg;
+            }
         }
         return $errors;
     }
@@ -296,7 +299,7 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
     /**
      * Validate codes for languages, currencies or timezones
      *
-     * @param Locale|Timezone|Currency  $lists
+     * @param LocaleValidator|TimezoneValidator|CurrencyValidator  $lists
      * @param string  $code
      * @param string  $type
      * @return string
@@ -310,4 +313,31 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
         }
         return $errorMsg;
     }
+
+    /**
+     * Validate URL
+     *
+     * @param string $url
+     * @param string $option
+     * @param array $allowedSchemes
+     * @return string
+     */
+    private function validateUrl($url, $option, array $allowedSchemes)
+    {
+        $errorMsg = '';
+
+        if (!$this->urlValidator->isValid($url, $allowedSchemes)) {
+            $errorTemplate = '<error>Command option \'%s\': Invalid URL \'%s\'.'
+                . ' Domain Name should contain only letters, digits and hyphen.'
+                . ' And you should use only following schemes: \'%s\'.</error>';
+            $errorMsg = sprintf(
+                $errorTemplate,
+                $option,
+                $url,
+                implode(', ', $allowedSchemes)
+            );
+        }
+
+        return $errorMsg;
+    }
 }
diff --git a/setup/src/Magento/Setup/Controller/UrlCheck.php b/setup/src/Magento/Setup/Controller/UrlCheck.php
new file mode 100644
index 0000000000000000000000000000000000000000..08a0d50404c0a2e457a2646a30860d1f958f14d3
--- /dev/null
+++ b/setup/src/Magento/Setup/Controller/UrlCheck.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Controller;
+
+use Zend\Mvc\Controller\AbstractActionController;
+use Zend\View\Model\JsonModel;
+use Zend\Json\Json;
+use Magento\Framework\Validator\Url as UrlValidator;
+
+class UrlCheck extends AbstractActionController
+{
+    /**
+     * @var UrlValidator
+     */
+    private $urlValidator;
+
+    /**
+     * @param UrlValidator $urlValidator
+     */
+    public function __construct(UrlValidator $urlValidator)
+    {
+        $this->urlValidator = $urlValidator;
+    }
+
+    /**
+     * Validate URL
+     *
+     * @return JsonModel
+     */
+    public function indexAction()
+    {
+        $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
+        $result = ['successUrl' => false, 'successSecureUrl' => true];
+
+        $hasBaseUrl = isset($params['address']['actual_base_url']);
+        $hasSecureBaseUrl = isset($params['https']['text']);
+        $hasSecureAdminUrl = !empty($params['https']['admin']);
+        $hasSecureFrontUrl = !empty($params['https']['front']);
+        $schemes = ['http', 'https'];
+
+        // Validating of Base URL
+        if ($hasBaseUrl && $this->urlValidator->isValid($params['address']['actual_base_url'], $schemes)) {
+            $result['successUrl'] = true;
+        }
+
+        // Validating of Secure Base URL
+        if ($hasSecureAdminUrl || $hasSecureFrontUrl) {
+            if (!($hasSecureBaseUrl && $this->urlValidator->isValid($params['https']['text'], $schemes))) {
+                $result['successSecureUrl'] = false;
+            }
+        }
+
+        return new JsonModel($result);
+    }
+}
diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
index 6a4b3a72b372c8ff611bcc7e535c99cbef4bb404..935f395a5e219f0546daf7967dbcc0726c695055 100644
--- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
+++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
@@ -99,10 +99,10 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
     }
 
     /**
-     * Check if user login
+     * Check if user logged-in and has permissions
      *
      * @param \Zend\Mvc\MvcEvent $event
-     * @return bool
+     * @return false|\Zend\Http\Response
      * @throws \Magento\Framework\Exception\LocalizedException
      */
     public function authPreDispatch($event)
@@ -115,6 +115,7 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
             /** @var Application $application */
             $application = $event->getApplication();
             $serviceManager = $application->getServiceManager();
+
             if ($serviceManager->get(\Magento\Framework\App\DeploymentConfig::class)->isAvailable()) {
                 /** @var \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider */
                 $objectManagerProvider = $serviceManager->get(\Magento\Setup\Model\ObjectManagerProvider::class);
@@ -135,17 +136,26 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
                         'appState' => $adminAppState
                     ]
                 );
-                if (!$objectManager->get(\Magento\Backend\Model\Auth::class)->isLoggedIn()) {
+                /** @var \Magento\Backend\Model\Auth $auth */
+                $authentication = $objectManager->get(\Magento\Backend\Model\Auth::class);
+
+                if (
+                    !$authentication->isLoggedIn() ||
+                    !$adminSession->isAllowed('Magento_Backend::setup_wizard')
+                ) {
                     $adminSession->destroy();
+                    /** @var \Zend\Http\Response $response */
                     $response = $event->getResponse();
                     $baseUrl = Http::getDistroBaseUrlPath($_SERVER);
                     $response->getHeaders()->addHeaderLine('Location', $baseUrl . 'index.php/session/unlogin');
                     $response->setStatusCode(302);
                     $event->stopPropagation();
+
                     return $response;
                 }
             }
         }
+
         return false;
     }
 
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php
index 6f5ab3a5a64c537751cc8964229e35869b06c8e5..c3494b389aa5ecb2a2ab2465b5d848627a5d8e7a 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php
@@ -11,8 +11,14 @@ use Symfony\Component\Console\Tester\CommandTester;
 use Magento\Setup\Model\Installer;
 use Magento\Framework\ObjectManagerInterface;
 use Magento\Setup\Model\StoreConfigurationDataMapper;
-use Magento\Framework\Url\Validator;
+use Magento\Framework\Validator\Url as UrlValidator;
+use Magento\Framework\Validator\Locale as LocaleValidator;
+use Magento\Framework\Validator\Timezone as TimezoneValidator;
+use Magento\Framework\Validator\Currency as CurrencyValidator;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -35,6 +41,26 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
      */
     private $objectManager;
 
+    /**
+     * @var LocaleValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $localeValidatorMock;
+
+    /**
+     * @var TimezoneValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $timezoneValidatorMock;
+
+    /**
+     * @var CurrencyValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $currencyValidatorMock;
+
+    /**
+     * @var UrlValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $urlValidatorMock;
+
     /**
      * @var InstallStoreConfigurationCommand
      */
@@ -42,6 +68,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
+        $this->urlValidatorMock = $this->getMock(UrlValidator::class, [], [], '', false);
+        $this->localeValidatorMock = $this->getMock(LocaleValidator::class, [], [], '', false);
+        $this->timezoneValidatorMock = $this->getMock(TimezoneValidator::class, [], [], '', false);
+        $this->currencyValidatorMock = $this->getMock(CurrencyValidator::class, [], [], '', false);
+
         $this->installerFactory = $this->getMock(\Magento\Setup\Model\InstallerFactory::class, [], [], '', false);
         $this->deploymentConfig = $this->getMock(\Magento\Framework\App\DeploymentConfig::class, [], [], '', false);
         $this->installer = $this->getMock(\Magento\Setup\Model\Installer::class, [], [], '', false);
@@ -62,7 +93,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
         $this->command = new InstallStoreConfigurationCommand(
             $this->installerFactory,
             $this->deploymentConfig,
-            $objectManagerProvider
+            $objectManagerProvider,
+            $this->localeValidatorMock,
+            $this->timezoneValidatorMock,
+            $this->currencyValidatorMock,
+            $this->urlValidatorMock
         );
     }
 
@@ -102,41 +137,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
      */
     public function testExecuteInvalidData(array $option, $error)
     {
-        $url= $this->getMock(\Magento\Framework\Url\Validator::class, [], [], '', false);
-        $url->expects($this->any())->method('isValid')->will($this->returnValue(false));
-        if (!isset($option['--' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE])) {
-            $url->expects($this->any())->method('getMessages')->will($this->returnValue([
-                Validator::INVALID_URL => 'Invalid URL.'
-            ]));
-        }
-        $localeLists= $this->getMock(\Magento\Framework\Validator\Locale::class, [], [], '', false);
-        $localeLists->expects($this->any())->method('isValid')->will($this->returnValue(false));
-        $timezoneLists= $this->getMock(\Magento\Framework\Validator\Timezone::class, [], [], '', false);
-        $timezoneLists->expects($this->any())->method('isValid')->will($this->returnValue(false));
-        $currencyLists= $this->getMock(\Magento\Framework\Validator\Currency::class, [], [], '', false);
-        $currencyLists->expects($this->any())->method('isValid')->will($this->returnValue(false));
-
-        $returnValueMapOM = [
-            [
-                \Magento\Framework\Url\Validator::class,
-                $url
-            ],
-            [
-                \Magento\Framework\Validator\Locale::class,
-                $localeLists
-            ],
-            [
-                \Magento\Framework\Validator\Timezone::class,
-                $timezoneLists
-            ],
-            [
-                \Magento\Framework\Validator\Currency::class,
-                $currencyLists
-            ],
-        ];
-        $this->objectManager->expects($this->any())
-            ->method('get')
-            ->will($this->returnValueMap($returnValueMapOM));
+        $this->localeValidatorMock->expects($this->any())->method('isValid')->willReturn(false);
+        $this->timezoneValidatorMock->expects($this->any())->method('isValid')->willReturn(false);
+        $this->currencyValidatorMock->expects($this->any())->method('isValid')->willReturn(false);
+        $this->urlValidatorMock->expects($this->any())->method('isValid')->willReturn(false);
+
         $this->deploymentConfig->expects($this->once())
             ->method('isAvailable')
             ->will($this->returnValue(true));
@@ -144,7 +149,7 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
             ->method('create');
         $commandTester = new CommandTester($this->command);
         $commandTester->execute($option);
-        $this->assertEquals($error . PHP_EOL, $commandTester->getDisplay());
+        $this->assertContains($error, $commandTester->getDisplay());
     }
 
     /**
@@ -155,48 +160,54 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
         return [
             [
                 ['--' . StoreConfigurationDataMapper::KEY_BASE_URL => 'sampleUrl'],
-                'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL . '\': Invalid URL.'
+                'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL . '\': Invalid URL \'sampleUrl\'.'
+            ],
+            [
+                ['--' . StoreConfigurationDataMapper::KEY_BASE_URL => 'http://example.com_test'],
+                'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL
+                    . '\': Invalid URL \'http://example.com_test\'.'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_LANGUAGE => 'sampleLanguage'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_LANGUAGE
-                . '\': Invalid value. To see possible values, run command \'bin/magento info:language:list\'.'
+                    . '\': Invalid value. To see possible values, run command \'bin/magento info:language:list\'.'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_TIMEZONE => 'sampleTimezone'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_TIMEZONE
-                . '\': Invalid value. To see possible values, run command \'bin/magento info:timezone:list\'.'
+                    . '\': Invalid value. To see possible values, run command \'bin/magento info:timezone:list\'.'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_CURRENCY => 'sampleLanguage'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_CURRENCY
-                . '\': Invalid value. To see possible values, run command \'bin/magento info:currency:list\'.'
+                    . '\': Invalid value. To see possible values, run command \'bin/magento info:currency:list\'.'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_USE_SEF_URL => 'invalidValue'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_USE_SEF_URL
-                . '\': Invalid value. Possible values (0|1).'
+                    . '\': Invalid value. Possible values (0|1).'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_IS_SECURE => 'invalidValue'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_IS_SECURE
-                . '\': Invalid value. Possible values (0|1).'
+                    . '\': Invalid value. Possible values (0|1).'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'http://www.sample.com'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE
-                . '\': Invalid secure URL.'
+                    . '\': Invalid URL \'http://www.sample.com\'.'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => 'invalidValue'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN
-                . '\': Invalid value. Possible values (0|1).'
+                    . '\': Invalid value. Possible values (0|1).'
             ],
             [
                 ['--' . StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => 'invalidValue'],
                 'Command option \'' . StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY
-                . '\': Invalid value. Possible values (0|1).'
+                    . '\': Invalid value. Possible values (0|1).'
             ],
+
         ];
     }
 }
diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b44887b586d5c69b6c56a1e19a4b9d68ae96bfe
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Controller;
+
+use Magento\Setup\Controller\UrlCheck;
+use Zend\Stdlib\RequestInterface;
+use Zend\View\Model\JsonModel;
+use Magento\Framework\Validator\Url as UrlValidator;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class UrlCheckTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @param array $requestJson
+     * @param array $expectedResult
+     * @dataProvider indexActionDataProvider
+     */
+    public function testIndexAction($requestJson, $expectedResult)
+    {
+        /** @var ObjectManagerHelper $objectManagerHelper */
+        $objectManagerHelper = new ObjectManagerHelper($this);
+
+        $allowedSchemes = ['http', 'https'];
+        $returnMap = [];
+        if (isset($requestJson['address']['actual_base_url'])) {
+            $returnMap[] = [
+                $requestJson['address']['actual_base_url'],
+                $allowedSchemes,
+                $expectedResult['successUrl'],
+            ];
+        }
+        if (isset($requestJson['https']['text'])) {
+            $returnMap[] = [
+                $requestJson['https']['text'],
+                $allowedSchemes,
+                $expectedResult['successSecureUrl'],
+            ];
+        }
+
+        /** @var UrlValidator|\PHPUnit_Framework_MockObject_MockObject $validator */
+        $validator = $this->getMockBuilder(UrlValidator::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validator->expects($this->any())
+            ->method('isValid')
+            ->willReturnMap($returnMap);
+
+        /** @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject $requestMock */
+        $requestMock = $this->getMockBuilder(RequestInterface::class)
+            ->getMockForAbstractClass();
+        $requestMock->expects($this->once())
+            ->method('getContent')
+            ->willReturn(json_encode($requestJson));
+
+        $controller = $objectManagerHelper->getObject(
+            UrlCheck::class,
+            ['urlValidator' => $validator]
+        );
+        $objectManagerHelper->setBackwardCompatibleProperty($controller, 'request', $requestMock);
+
+        $this->assertEquals(new JsonModel($expectedResult), $controller->indexAction());
+    }
+
+    /**
+     * @return array
+     */
+    public function indexActionDataProvider()
+    {
+        return [
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost'
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true]
+            ],
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost.com_test'
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => false, 'successSecureUrl' => true]
+            ],
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost.com_test'
+                    ],
+                    'https' => [
+                        'admin' => false,
+                        'front' => false,
+                        'text' => ''
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => false, 'successSecureUrl' => true]
+            ],
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost.com:8080'
+                    ],
+                    'https' => [
+                        'admin' => true,
+                        'front' => false,
+                        'text' => 'https://example.com.ua/'
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true]
+            ],
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost.com:8080/folder_name/'
+                    ],
+                    'https' => [
+                        'admin' => false,
+                        'front' => true,
+                        'text' => 'https://example.com.ua/'
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true]
+            ],
+            [
+                'requestJson' => [
+                    'address' => [
+                        'actual_base_url' => 'http://localhost.com:8080/folder_name/'
+                    ],
+                    'https' => [
+                        'admin' => true,
+                        'front' => true,
+                        'text' => 'https://example.com.ua:8090/folder_name/'
+                    ]
+                ],
+                'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true]
+            ],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
index 558533afe92429582cbfa79e5fcd691b200ecef8..1ace3f452c4f917181c43a86744f2b4db39b9439 100644
--- a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
@@ -3,7 +3,6 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Setup\Test\Unit\Mvc\Bootstrap;
 
 use \Magento\Setup\Mvc\Bootstrap\InitParamListener;
@@ -59,11 +58,11 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
             ->withConsecutive(
                 [
                     \Magento\Framework\App\Filesystem\DirectoryList::class,
-                    $this->isInstanceOf(\Magento\Framework\App\Filesystem\DirectoryList::class)
+                    $this->isInstanceOf(\Magento\Framework\App\Filesystem\DirectoryList::class),
                 ],
                 [
                     \Magento\Framework\Filesystem::class,
-                    $this->isInstanceOf(\Magento\Framework\Filesystem::class)
+                    $this->isInstanceOf(\Magento\Framework\Filesystem::class),
                 ]
             );
         $mvcApplication->expects($this->any())->method('getServiceManager')->willReturn($serviceManager);
@@ -130,10 +129,10 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
         $request->expects($this->any())
             ->method('getContent')
             ->willReturn(
-                $cliParam ? ['install', '--magento-init-params=' . $cliParam ] : ['install']
+                $cliParam ? ['install', '--magento-init-params=' . $cliParam] : ['install']
             );
         $mvcApplication->expects($this->any())->method('getConfig')->willReturn(
-            $zfAppConfig ? [InitParamListener::BOOTSTRAP_PARAM => $zfAppConfig]:[]
+            $zfAppConfig ? [InitParamListener::BOOTSTRAP_PARAM => $zfAppConfig] : []
         );
 
         $mvcApplication->expects($this->any())->method('getRequest')->willReturn($request);
@@ -150,41 +149,55 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
             'mage_mode App' => [['MAGE_MODE' => 'developer'], [], '', ['MAGE_MODE' => 'developer']],
             'mage_mode Env' => [[], ['MAGE_MODE' => 'developer'], '', ['MAGE_MODE' => 'developer']],
             'mage_mode CLI' => [[], [], 'MAGE_MODE=developer', ['MAGE_MODE' => 'developer']],
-            'one MAGE_DIRS CLI' => [[], [], 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2',
-                       ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer']],
+            'one MAGE_DIRS CLI' => [
+                [],
+                [],
+                'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2',
+                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'],
+            ],
             'two MAGE_DIRS CLI' => [
                 [],
                 [],
                 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2&MAGE_DIRS[cache][path]=/tmp/cache',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']],
-                 'MAGE_MODE' => 'developer']],
+                [
+                    'MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']],
+                    'MAGE_MODE' => 'developer',
+                ],
+            ],
             'mage_mode only' => [[], [], 'MAGE_MODE=developer', ['MAGE_MODE' => 'developer']],
             'MAGE_DIRS Env' => [
                 [],
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'],
                 '',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer']],
+                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'],
+            ],
             'two MAGE_DIRS' => [
                 [],
                 [],
                 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2&MAGE_DIRS[cache][path]=/tmp/cache',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']],
-                 'MAGE_MODE' => 'developer']],
+                [
+                    'MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']],
+                    'MAGE_MODE' => 'developer',
+                ],
+            ],
             'Env overwrites App' => [
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/App']], 'MAGE_MODE' => 'developer'],
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer'],
                 '',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer']],
+                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer'],
+            ],
             'CLI overwrites Env' => [
                 ['MAGE_MODE' => 'developerApp'],
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']]],
                 'MAGE_DIRS[base][path]=/var/www/magento2/CLI',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'developerApp']],
+                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'developerApp'],
+            ],
             'CLI overwrites All' => [
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/App']], 'MAGE_MODE' => 'production'],
                 ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']]],
                 'MAGE_DIRS[base][path]=/var/www/magento2/CLI',
-                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'production']],
+                ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'production'],
+            ],
         ];
     }
 
@@ -226,6 +239,168 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
             [$this->listener, 'onBootstrap']
         )->willReturn($this->callbackHandler);
         $eventManager->expects($this->once())->method('getSharedManager')->willReturn($sharedManager);
+
         return $eventManager;
     }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testAuthPreDispatch()
+    {
+        $eventMock = $this->getMockBuilder(\Zend\Mvc\MvcEvent::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $routeMatchMock = $this->getMockBuilder(\Zend\Mvc\Router\Http\RouteMatch::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $applicationMock = $this->getMockBuilder(\Zend\Mvc\Application::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $serviceManagerMock = $this->getMockBuilder(\Zend\ServiceManager\ServiceManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $deploymentConfigMock = $this->getMockBuilder(\Magento\Framework\App\DeploymentConfig::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $deploymentConfigMock->expects($this->once())
+            ->method('isAvailable')
+            ->willReturn(true);
+        $omProvider = $this->getMockBuilder(\Magento\Setup\Model\ObjectManagerProvider::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManagerMock = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class);
+        $adminAppStateMock = $this->getMockBuilder(\Magento\Framework\App\State::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $sessionConfigMock = $this->getMockBuilder(\Magento\Backend\Model\Session\AdminConfig::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $backendAppListMock = $this->getMockBuilder(\Magento\Backend\App\BackendAppList::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $backendAppMock = $this->getMockBuilder(\Magento\Backend\App\BackendApp::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $backendUrlFactoryMock = $this->getMockBuilder(\Magento\Backend\Model\UrlFactory::class)
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $backendUrlMock = $this->getMockBuilder(\Magento\Backend\Model\Url::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $authenticationMock = $this->getMockBuilder(\Magento\Backend\Model\Auth::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $adminSessionMock = $this->getMockBuilder(\Magento\Backend\Model\Auth\Session::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $responseMock = $this->getMockBuilder(\Zend\Http\Response::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $headersMock = $this->getMockBuilder(\Zend\Http\Headers::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $routeMatchMock->expects($this->once())
+            ->method('getParam')
+            ->with('controller')
+            ->willReturn('testController');
+        $eventMock->expects($this->once())
+            ->method('getRouteMatch')
+            ->willReturn($routeMatchMock);
+        $eventMock->expects($this->once())
+            ->method('getApplication')
+            ->willReturn($applicationMock);
+        $serviceManagerMock->expects($this->any())
+            ->method('get')
+            ->willReturnMap(
+                [
+                    [
+                        \Magento\Framework\App\DeploymentConfig::class,
+                        true,
+                        $deploymentConfigMock,
+                    ],
+                    [
+                        \Magento\Setup\Model\ObjectManagerProvider::class,
+                        true,
+                        $omProvider,
+                    ],
+                ]
+            );
+        $objectManagerMock->expects($this->any())
+            ->method('get')
+            ->willReturnMap(
+                [
+                    [
+                        \Magento\Framework\App\State::class,
+                        $adminAppStateMock,
+                    ],
+                    [
+                        \Magento\Backend\Model\Session\AdminConfig::class,
+                        $sessionConfigMock,
+                    ],
+                    [
+                        \Magento\Backend\App\BackendAppList::class,
+                        $backendAppListMock,
+                    ],
+                    [
+                        \Magento\Backend\Model\UrlFactory::class,
+                        $backendUrlFactoryMock,
+                    ],
+                    [
+                        \Magento\Backend\Model\Auth::class,
+                        $authenticationMock,
+                    ],
+                ]
+            );
+        $objectManagerMock->expects($this->any())
+            ->method('create')
+            ->willReturn($adminSessionMock);
+        $omProvider->expects($this->once())
+            ->method('get')
+            ->willReturn($objectManagerMock);
+        $adminAppStateMock->expects($this->once())
+            ->method('setAreaCode')
+            ->with(\Magento\Framework\App\Area::AREA_ADMINHTML);
+        $applicationMock->expects($this->once())
+            ->method('getServiceManager')
+            ->willReturn($serviceManagerMock);
+        $backendAppMock->expects($this->once())
+            ->method('getCookiePath')
+            ->willReturn('');
+        $backendUrlFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($backendUrlMock);
+        $backendAppListMock->expects($this->once())
+            ->method('getBackendApp')
+            ->willReturn($backendAppMock);
+        $authenticationMock->expects($this->once())
+            ->method('isLoggedIn')
+            ->willReturn(true);
+        $adminSessionMock->expects($this->once())
+            ->method('isAllowed')
+            ->with('Magento_Backend::setup_wizard', null)
+            ->willReturn(false);
+        $adminSessionMock->expects($this->once())
+            ->method('destroy');
+        $eventMock->expects($this->once())
+            ->method('getResponse')
+            ->willReturn($responseMock);
+        $responseMock->expects($this->once())
+            ->method('getHeaders')
+            ->willReturn($headersMock);
+        $headersMock->expects($this->once())
+            ->method('addHeaderLine');
+        $responseMock->expects($this->once())
+            ->method('setStatusCode')
+            ->with(302);
+        $eventMock->expects($this->once())
+            ->method('stopPropagation');
+
+        $this->assertSame(
+            $this->listener->authPreDispatch($eventMock),
+            $responseMock
+        );
+    }
 }
diff --git a/setup/view/magento/setup/web-configuration.phtml b/setup/view/magento/setup/web-configuration.phtml
index 35aa19484ed53f39bf37ae0e90e7b76c7f5efe87..ab2a00342b715b05f215d1d3e12010b0fc4993cc 100644
--- a/setup/view/magento/setup/web-configuration.phtml
+++ b/setup/view/magento/setup/web-configuration.phtml
@@ -30,7 +30,7 @@ $hints = [
 <div class="nav-bar-outer-actions">
     <div class="outer-actions-inner-wrap">
         <div class="btn-wrap btn-wrap-triangle-right btn-wrap-next">
-            <button type="button" class="btn btn-prime" ng-click="nextState()" dis>Next</button>
+            <button type="button" class="btn btn-prime" ng-click="validateUrl()" dis>Next</button>
         </div>
         <div class="btn-wrap btn-wrap-triangle-left btn-wrap-prev">
             <button type="button" class="btn" ng-click="previousState()">Back</button>
@@ -40,6 +40,13 @@ $hints = [
 
 <h2 class="page-sub-title">{{$state.current.header}}</h2>
 
+<div
+    class="message message-error"
+    ng-show="validateUrl.failed !== undefined"
+>
+    <span class="message-text">{{validateUrl.failed}}</span>
+</div>
+
 <form
     name="webconfig"
     role="form"