diff --git a/app/code/Magento/Backend/App/BackendAppList.php b/app/code/Magento/Backend/App/BackendAppList.php
index 224ce9893100c6b416da0362ca9a0e3af569bf1e..afb812b823488b29898a2027afa87b6980d9974c 100644
--- a/app/code/Magento/Backend/App/BackendAppList.php
+++ b/app/code/Magento/Backend/App/BackendAppList.php
@@ -44,6 +44,7 @@ class BackendAppList
         if ($appName && isset($this->backendApps[$appName])) {
             return $this->backendApps[$appName];
         }
+        return null;
     }
 
     /**
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
index 353605881db41afc7ea63e2dd2169c2bbf7ab2ab..0968047053bc5b2088f2a449ec243a08da5a99b7 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/admin/login.phtml
@@ -27,7 +27,7 @@
                        value=""
                        data-validate="{required:true}"
                        placeholder="<?php /* @escapeNotVerified */ echo __('user name') ?>"
-                       autocomplete="username"
+                       autocomplete="off"
                     />
             </div>
         </div>
@@ -43,7 +43,7 @@
                        data-validate="{required:true}"
                        value=""
                        placeholder="<?php /* @escapeNotVerified */ echo __('password') ?>"
-                       autocomplete="current-password"
+                       autocomplete="off"
                     />
             </div>
         </div>
diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php
index 0013ba1f17f1bb404640c5da4b3f8ddb2d77d632..86ed5c6a10766bb8a3f475e9b2bf70e0d4c9e279 100644
--- a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php
+++ b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php
@@ -59,33 +59,27 @@ class Stock extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\
             "bo.parent_id = product.$linkField",
             []
         );
-        $this->_addWebsiteJoinToSelect($select, false);
         $status = new \Zend_Db_Expr(
             'MAX(' . $connection->getCheckSql('e.required_options = 0', 'i.stock_status', '0') . ')'
         );
-        $select->columns(
-            'website_id',
-            'cw'
-        )->join(
+        $select->join(
             ['cis' => $this->getTable('cataloginventory_stock')],
             '',
-            ['stock_id']
+            ['website_id', 'stock_id']
         )->joinLeft(
             ['bs' => $this->getTable('catalog_product_bundle_selection')],
             'bs.option_id = bo.option_id',
             []
         )->joinLeft(
             ['i' => $idxTable],
-            'i.product_id = bs.product_id AND i.website_id = cw.website_id AND i.stock_id = cis.stock_id',
+            'i.product_id = bs.product_id AND i.website_id = cis.website_id AND i.stock_id = cis.stock_id',
             []
         )->joinLeft(
             ['e' => $this->getTable('catalog_product_entity')],
             'e.entity_id = bs.product_id',
             []
-        )->where(
-            'cw.website_id != 0'
         )->group(
-            ['product.entity_id', 'cw.website_id', 'cis.stock_id', 'bo.option_id']
+            ['product.entity_id', 'cis.website_id', 'cis.stock_id', 'bo.option_id']
         )->columns(
             ['option_id' => 'bo.option_id', 'status' => $status]
         );
@@ -118,45 +112,19 @@ class Stock extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\
     protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false)
     {
         $this->_prepareBundleOptionStockData($entityIds, $usePrimaryTable);
-        $linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField();
         $connection = $this->getConnection();
-        $select = $connection->select()->from(
-            ['e' => $this->getTable('catalog_product_entity')],
-            ['entity_id']
-        );
-        $this->_addWebsiteJoinToSelect($select, true);
-        $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id');
-        $select->columns(
-            'cw.website_id'
-        )->join(
-            ['cis' => $this->getTable('cataloginventory_stock')],
-            '',
-            ['stock_id']
-        )->joinLeft(
-            ['cisi' => $this->getTable('cataloginventory_stock_item')],
-            'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
-            []
+        $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable);
+        $select->reset(
+            \Magento\Framework\DB\Select::COLUMNS
+        )->columns(
+            ['e.entity_id', 'cis.website_id', 'cis.stock_id']
         )->joinLeft(
             ['o' => $this->_getBundleOptionTable()],
-            'o.entity_id = e.entity_id AND o.website_id = cw.website_id AND o.stock_id = cis.stock_id',
+            'o.entity_id = e.entity_id AND o.website_id = cis.website_id AND o.stock_id = cis.stock_id',
             []
         )->columns(
             ['qty' => new \Zend_Db_Expr('0')]
-        )->where(
-            'cw.website_id != 0'
-        )->where(
-            'e.type_id = ?',
-            $this->getTypeId()
-        )->group(
-            ['e.entity_id', 'cw.website_id', 'cis.stock_id']
-        );
-
-        // add limitation of status
-        $condition = $connection->quoteInto(
-            '=?',
-            \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
         );
-        $this->_addAttributeToSelect($select, 'status', "e.$linkField", 'cs.store_id', $condition);
 
         $statusExpr = $this->getStatusExpression($connection);
         $select->columns(
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 d8ac9fdf9131d8dbab66cde7181dfa23b28ec63c..0ec9ddf3298f9daec7ab9dfec22765ad95521919 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
@@ -458,7 +458,8 @@ class BundlePanel extends AbstractModifier
                                 'component' => 'Magento_Bundle/js/components/bundle-input-type',
                                 'parentContainer' => 'product_bundle_container',
                                 'selections' => 'bundle_selections',
-                                'targetIndex' => 'is_default',
+                                'isDefaultIndex' => 'is_default',
+                                'userDefinedIndex' => 'selection_can_change_qty',
                                 'dataScope' => 'type',
                                 'label' => __('Input Type'),
                                 'sortOrder' => 20,
diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js
index e52856e53891c64981c9e617afb01c77b453363a..14dd426ed02aa7f144c109a0ac17016be2d56329 100644
--- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js
+++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js
@@ -26,36 +26,42 @@ define([
 
             if (type !== this.previousType) {
                 this.previousType = type;
-
-                if (type === 'radio') {
-                    this.clearValues();
-                }
+                this.processSelections(type === 'radio');
             }
 
             this._super();
         },
 
         /**
-         * Clears values in components like this.
+         * Toggle 'User Defined' column and clears values
+         * @param {Boolean} isRadio
          */
-        clearValues: function () {
+        processSelections: function (isRadio) {
             var records = registry.get(this.retrieveParentName(this.parentContainer) + '.' + this.selections),
                 checkedFound = false;
 
             records.elems.each(function (record) {
                 record.elems.filter(function (comp) {
-                    return comp.index === this.targetIndex;
+                    return comp.index === this.userDefinedIndex;
                 }, this).each(function (comp) {
-                    if (comp.checked()) {
-                        if (checkedFound) {
-                            comp.clearing = true;
-                            comp.clear();
-                            comp.clearing = false;
-                        }
-
-                        checkedFound = true;
-                    }
+                    comp.visible(isRadio);
                 });
+
+                if (isRadio) {
+                    record.elems.filter(function (comp) {
+                        return comp.index === this.isDefaultIndex;
+                    }, this).each(function (comp) {
+                        if (comp.checked()) {
+                            if (checkedFound) {
+                                comp.clearing = true;
+                                comp.clear();
+                                comp.clearing = false;
+                            }
+
+                            checkedFound = true;
+                        }
+                    });
+                }
             }, this);
         },
 
diff --git a/app/code/Magento/CacheInvalidate/etc/events.xml b/app/code/Magento/CacheInvalidate/etc/events.xml
index 47d27f98f1e796419333e74dc467a4a7628468b6..58ddeb64c9257d70788d9c63dbfbbc77099dea4f 100644
--- a/app/code/Magento/CacheInvalidate/etc/events.xml
+++ b/app/code/Magento/CacheInvalidate/etc/events.xml
@@ -48,4 +48,7 @@
     <event name="controller_action_postdispatch_adminhtml_system_currencysymbol_save">
         <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Observer\InvalidateVarnishObserver"/>
     </event>
+    <event name="clean_cache_after_reindex">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Observer\InvalidateVarnishObserver"/>
+    </event>
 </config>
\ No newline at end of file
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
index d7cd6ba3984241576669bac898c412a9351d0858..89081edb46ca1c6f1f3849f6a7f8246dd0625fba 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
@@ -9,7 +9,12 @@ namespace Magento\Catalog\Controller\Adminhtml\Product;
 use Magento\Backend\App\Action;
 use Magento\Catalog\Controller\Adminhtml\Product;
 use Magento\Store\Model\StoreManagerInterface;
+use Magento\Framework\App\Request\DataPersistorInterface;
 
+/**
+ * Class Save
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class Save extends \Magento\Catalog\Controller\Adminhtml\Product
 {
     /**
@@ -37,6 +42,11 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
      */
     protected $productRepository;
 
+    /**
+     * @var DataPersistorInterface
+     */
+    protected $dataPersistor;
+
     /**
      * @var StoreManagerInterface
      */
@@ -110,6 +120,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
                 $this->copyToStores($data, $productId);
 
                 $this->messageManager->addSuccess(__('You saved the product.'));
+                $this->getDataPersistor()->clear('catalog_product');
                 if ($product->getSku() != $originalSku) {
                     $this->messageManager->addNotice(
                         __(
@@ -131,11 +142,13 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
             } catch (\Magento\Framework\Exception\LocalizedException $e) {
                 $this->messageManager->addError($e->getMessage());
                 $this->_session->setProductData($data);
+                $this->getDataPersistor()->set('catalog_product', $data);
                 $redirectBack = $productId ? true : 'new';
             } catch (\Exception $e) {
                 $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError($e->getMessage());
                 $this->_session->setProductData($data);
+                $this->getDataPersistor()->set('catalog_product', $data);
                 $redirectBack = $productId ? true : 'new';
             }
         } else {
@@ -246,4 +259,18 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
         }
         return $this->storeManager;
     }
+
+    /**
+     * Retrieve data persistor
+     *
+     * @return DataPersistorInterface|mixed
+     */
+    protected function getDataPersistor()
+    {
+        if (null === $this->dataPersistor) {
+            $this->dataPersistor = $this->_objectManager->get(DataPersistorInterface::class);
+        }
+
+        return $this->dataPersistor;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ImageExtractor.php b/app/code/Magento/Catalog/Model/ImageExtractor.php
index bf45816f45a1c063ef616f16b074326fdc885e3e..c83c7106ce20a5621951ee950c2812251341730f 100644
--- a/app/code/Magento/Catalog/Model/ImageExtractor.php
+++ b/app/code/Magento/Catalog/Model/ImageExtractor.php
@@ -30,7 +30,11 @@ class ImageExtractor implements \Magento\Framework\View\Xsd\Media\TypeDataExtrac
                 if ($attribute->nodeType != XML_ELEMENT_NODE) {
                     continue;
                 }
-                $nodeValue = $attribute->nodeValue;
+                if ($attribute->tagName == 'background') {
+                    $nodeValue = $this->processImageBackground($attribute->nodeValue);
+                } else {
+                    $nodeValue = $attribute->nodeValue;
+                }
                 $result[$mediaParentTag][$moduleNameImage][Image::MEDIA_TYPE_CONFIG_NODE][$imageId][$attribute->tagName]
                     = $nodeValue;
             }
@@ -38,4 +42,20 @@ class ImageExtractor implements \Magento\Framework\View\Xsd\Media\TypeDataExtrac
 
         return $result;
     }
+
+    /**
+     * Convert rgb background string into array
+     *
+     * @param string $backgroundString
+     * @return int[]
+     */
+    private function processImageBackground($backgroundString)
+    {
+        $pattern = '#\[(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\]#';
+        $backgroundArray = [];
+        if (preg_match($pattern, $backgroundString, $backgroundArray)) {
+            array_shift($backgroundArray);
+        }
+        return $backgroundArray;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php b/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php
deleted file mode 100644
index 098e636b8655cd07053490f3b454c1507ef73f17..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Catalog\Model\Indexer\Category;
-
-/**
- * Class AffectCache
- */
-class AffectCache
-{
-    /**
-     * @var \Magento\Framework\Indexer\CacheContext
-     */
-    protected $context;
-
-    /**
-     * @param \Magento\Framework\Indexer\CacheContext $context
-     */
-    public function __construct(
-        \Magento\Framework\Indexer\CacheContext $context
-    ) {
-        $this->context = $context;
-    }
-
-    /**
-     * @param \Magento\Framework\Indexer\ActionInterface $subject
-     * @param array $ids
-     * @return array
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function beforeExecute(\Magento\Framework\Indexer\ActionInterface $subject, $ids)
-    {
-        $this->context->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
-        return [$ids];
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php
index 2338a72c1aa7891d76daf25eaa507c8c7074dbb8..280f53fe70186970b6fb98e9cda4b18eb5f588d0 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Model\Indexer\Category;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -17,9 +19,16 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
      */
     protected $rowsActionFactory;
 
-    /** @var \Magento\Framework\Indexer\IndexerRegistry */
+    /**
+     * @var \Magento\Framework\Indexer\IndexerRegistry
+     */
     protected $indexerRegistry;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    private $cacheContext;
+
     /**
      * @param Flat\Action\FullFactory $fullActionFactory
      * @param Flat\Action\RowsFactory $rowsActionFactory
@@ -54,6 +63,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
             $action->reindex($ids, true);
         }
         $action->reindex($ids);
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
     }
 
     /**
@@ -64,6 +74,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
     public function executeFull()
     {
         $this->fullActionFactory->create()->reindexAll();
+        $this->getCacheContext()->registerTags([\Magento\Catalog\Model\Category::CACHE_TAG]);
     }
 
     /**
@@ -87,4 +98,19 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
     {
         $this->execute([$id]);
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product.php
index 44a24f4623d7fa008247246577548e182513da64..ffcca0d3dfb7a7b1fdb80cca772cacc8c3aba895 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Product.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Model\Indexer\Category;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -22,9 +24,16 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr
      */
     protected $rowsActionFactory;
 
-    /** @var \Magento\Framework\Indexer\IndexerRegistry */
+    /**
+     * @var \Magento\Framework\Indexer\IndexerRegistry
+     */
     protected $indexerRegistry;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    protected $cacheContext;
+
     /**
      * @param Product\Action\FullFactory $fullActionFactory
      * @param Product\Action\RowsFactory $rowsActionFactory
@@ -49,6 +58,18 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr
     public function execute($ids)
     {
         $this->executeAction($ids);
+        $this->registerEntities($ids);
+    }
+
+    /**
+     * Add entities to cache context
+     *
+     * @param int[] $ids
+     * @return void
+     */
+    protected function registerEntities($ids)
+    {
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
     }
 
     /**
@@ -59,6 +80,17 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr
     public function executeFull()
     {
         $this->fullActionFactory->create()->execute();
+        $this->registerTags();
+    }
+
+    /**
+     * Add tags to cache context
+     *
+     * @return void
+     */
+    protected function registerTags()
+    {
+        $this->getCacheContext()->registerTags([\Magento\Catalog\Model\Category::CACHE_TAG]);
     }
 
     /**
@@ -103,4 +135,19 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr
 
         return $this;
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php b/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php
deleted file mode 100644
index 44a00e41e75459ff91be930671164083cedc1048..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Catalog\Model\Indexer\Product;
-
-/**
- * Class AffectCache
- */
-class AffectCache
-{
-    /**
-     * @var \Magento\Framework\Indexer\CacheContext $context
-     */
-    protected $context;
-
-    /**
-     * @param \Magento\Framework\Indexer\CacheContext $context
-     */
-    public function __construct(
-        \Magento\Framework\Indexer\CacheContext $context
-    ) {
-        $this->context = $context;
-    }
-
-    /**
-     * @param \Magento\Framework\Indexer\ActionInterface $subject
-     * @param array $ids
-     * @return array
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function beforeExecute(\Magento\Framework\Indexer\ActionInterface $subject, $ids)
-    {
-        $this->context->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
-        return [$ids];
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Category.php b/app/code/Magento/Catalog/Model/Indexer/Product/Category.php
index 282591ba26b2ac17600cfa2a5dc5f222f66c3dd1..b272870b9f770e5de82cbb04d21d6c2320b7a8eb 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Category.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Category.php
@@ -24,4 +24,30 @@ class Category extends \Magento\Catalog\Model\Indexer\Category\Product
     ) {
         parent::__construct($fullActionFactory, $rowsActionFactory, $indexerRegistry);
     }
+
+    /**
+     * Add tags to cache context
+     *
+     * @return void
+     */
+    protected function registerTags()
+    {
+        $this->getCacheContext()->registerTags(
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Catalog\Model\Product::CACHE_TAG
+            ]
+        );
+    }
+
+    /**
+     * Add entities to cache context
+     *
+     * @param int[] $ids
+     * @return void
+     */
+    protected function registerEntities($ids)
+    {
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php
index a66637e8b3a88dd3ce05378cf7e689f9b932ee1d..0b3ccf1cc4c886bf40cd23c0013e2bb9dea77289 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -22,6 +24,11 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew
      */
     protected $_productEavIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    private $cacheContext;
+
     /**
      * @param Eav\Action\Row $productEavIndexerRow
      * @param Eav\Action\Rows $productEavIndexerRows
@@ -46,6 +53,7 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew
     public function execute($ids)
     {
         $this->_productEavIndexerRows->execute($ids);
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
     }
 
     /**
@@ -56,6 +64,12 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew
     public function executeFull()
     {
         $this->_productEavIndexerFull->execute();
+        $this->getCacheContext()->registerTags(
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Catalog\Model\Product::CACHE_TAG
+            ]
+        );
     }
 
     /**
@@ -79,4 +93,19 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew
     {
         $this->_productEavIndexerRow->execute($id);
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php
index 47d525ede8c1f142c192fe270fb6a87057133639..e423d9553bcb39e3adb6bd8328311428297817e8 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -22,6 +24,11 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
      */
     protected $_productFlatIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    private $cacheContext;
+
     /**
      * @param Flat\Action\Row $productFlatIndexerRow
      * @param Flat\Action\Rows $productFlatIndexerRows
@@ -46,6 +53,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
     public function execute($ids)
     {
         $this->_productFlatIndexerRows->execute($ids);
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
     }
 
     /**
@@ -56,6 +64,12 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
     public function executeFull()
     {
         $this->_productFlatIndexerFull->execute();
+        $this->getCacheContext()->registerTags(
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Catalog\Model\Product::CACHE_TAG
+            ]
+        );
     }
 
     /**
@@ -79,4 +93,19 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame
     {
         $this->_productFlatIndexerRow->execute($id);
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price.php
index ea763354a70d7a24cc5c77403f6028563dc82159..f8ed6cb6d2fe4ce43b646e48fcee628c41e4f3ec 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Price.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -22,6 +24,11 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
      */
     protected $_productPriceIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    private $cacheContext;
+
     /**
      * @param Price\Action\Row $productPriceIndexerRow
      * @param Price\Action\Rows $productPriceIndexerRows
@@ -46,6 +53,7 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     public function execute($ids)
     {
         $this->_productPriceIndexerRows->execute($ids);
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
     }
 
     /**
@@ -56,6 +64,12 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     public function executeFull()
     {
         $this->_productPriceIndexerFull->execute();
+        $this->getCacheContext()->registerTags(
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Catalog\Model\Product::CACHE_TAG
+            ]
+        );
     }
 
     /**
@@ -79,4 +93,19 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     {
         $this->_productPriceIndexerRow->execute($id);
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Locator/RegistryLocator.php b/app/code/Magento/Catalog/Model/Locator/RegistryLocator.php
index 433fe2b324bdd5129aa1a35c6e8e5e30e68bb9ad..3b288b00b6e467d49715013c73ffc879a9943380 100644
--- a/app/code/Magento/Catalog/Model/Locator/RegistryLocator.php
+++ b/app/code/Magento/Catalog/Model/Locator/RegistryLocator.php
@@ -5,7 +5,10 @@
  */
 namespace Magento\Catalog\Model\Locator;
 
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Framework\Exception\NotFoundException;
 use Magento\Framework\Registry;
+use Magento\Store\Api\Data\StoreInterface;
 
 /**
  * Class RegistryLocator
@@ -15,7 +18,17 @@ class RegistryLocator implements LocatorInterface
     /**
      * @var Registry
      */
-    protected $registry;
+    private $registry;
+
+    /**
+     * @var ProductInterface
+     */
+    private $product;
+
+    /**
+     * @var StoreInterface
+     */
+    private $store;
 
     /**
      * @param Registry $registry
@@ -27,30 +40,46 @@ class RegistryLocator implements LocatorInterface
 
     /**
      * {@inheritdoc}
+     * @throws NotFoundException
      */
     public function getProduct()
     {
-        return $this->registry->registry('current_product');
+        if (null !== $this->product) {
+            return $this->product;
+        }
+
+        if ($product = $this->registry->registry('current_product')) {
+            return $this->product = $product;
+        }
+
+        throw new NotFoundException(__('Product was not registered'));
     }
 
     /**
      * {@inheritdoc}
+     * @throws NotFoundException
      */
     public function getStore()
     {
-        return $this->registry->registry('current_store');
-    }
+        if (null !== $this->store) {
+            return $this->store;
+        }
 
+        if ($store = $this->registry->registry('current_store')) {
+            return $this->store = $store;
+        }
+
+        throw new NotFoundException(__('Store was not registered'));
+    }
 
     /**
      * {@inheritdoc}
      */
     public function getWebsiteIds()
     {
-        return $this->registry->registry('current_product')->getWebsiteIds();
+        return $this->getProduct()->getWebsiteIds();
     }
 
-
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/Catalog/Model/Product/Link/Converter.php b/app/code/Magento/Catalog/Model/Product/Link/Converter.php
index 7fa80daeb92db0116ebbf631a7744c7e6b5cb883..351afe7ddec65f9cb3b3c9ba8e94c78aeba915d5 100644
--- a/app/code/Magento/Catalog/Model/Product/Link/Converter.php
+++ b/app/code/Magento/Catalog/Model/Product/Link/Converter.php
@@ -19,7 +19,7 @@ class Converter
     protected function indexBySku(array $products)
     {
         $converted = [];
-        foreach($products as $product) {
+        foreach ($products as $product) {
             $converted[$product->getSku()] = $product;
         }
         return $converted;
@@ -34,7 +34,7 @@ class Converter
         $basicData = $entity->getProductLinks();
         $associatedProducts = $entity->getTypeInstance()->getAssociatedProducts($entity);
         $associatedProducts = $this->indexBySku($associatedProducts);
-
+        $linksAsArray = [];
         /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $link */
         foreach ($basicData as $link) {
             $info = $link->getData();
@@ -46,4 +46,4 @@ class Converter
         }
         return $linksAsArray;
     }
-}
\ No newline at end of file
+}
diff --git a/app/code/Magento/Catalog/Model/Product/Link/Resolver.php b/app/code/Magento/Catalog/Model/Product/Link/Resolver.php
index daedf3d335ca3020e1b4f9cb869504b59485b710..3de971b6b2a9e2ec3d2ceb4bdefa3b9e8c5351c9 100644
--- a/app/code/Magento/Catalog/Model/Product/Link/Resolver.php
+++ b/app/code/Magento/Catalog/Model/Product/Link/Resolver.php
@@ -17,13 +17,16 @@ class Resolver
      */
     protected $links = null;
 
+    /**
+     * Resolver constructor.
+     * @param \Magento\Framework\App\RequestInterface $request
+     */
     public function __construct(
         \Magento\Framework\App\RequestInterface $request
     ) {
         $this->request = $request;
     }
 
-
     /**
      * Get stored value.
      * Fallback to request if none.
@@ -42,6 +45,7 @@ class Resolver
      * Override link data from request
      *
      * @param array|null $links
+     * @return void
      */
     public function override($links)
     {
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index e8b5dea903b9e4c9c0cf77673ae69db5ada199e2..14ee790b382344285422dfa8583312b835a9d5fe 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -15,6 +15,7 @@ use Magento\Framework\Api\ImageContentValidatorInterface;
 use Magento\Framework\Api\ImageProcessorInterface;
 use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\StateException;
 use Magento\Framework\Exception\ValidatorException;
@@ -546,6 +547,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
             );
         } catch (ValidatorException $e) {
             throw new CouldNotSaveException(__($e->getMessage()));
+        } catch (LocalizedException $e) {
+            throw $e;
         } catch (\Exception $e) {
             throw new \Magento\Framework\Exception\CouldNotSaveException(__('Unable to save product'));
         }
diff --git a/app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php b/app/code/Magento/Catalog/Plugin/Block/Topmenu.php
similarity index 74%
rename from app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php
rename to app/code/Magento/Catalog/Plugin/Block/Topmenu.php
index 608c7ee74b7cdda6409432f968734f2d1171a088..098b3282a1b107e56703ee4889f9ce005f25d223 100644
--- a/app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php
+++ b/app/code/Magento/Catalog/Plugin/Block/Topmenu.php
@@ -3,17 +3,16 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Catalog\Observer;
+namespace Magento\Catalog\Plugin\Block;
 
 use Magento\Catalog\Model\Category;
 use Magento\Framework\Data\Collection;
 use Magento\Framework\Data\Tree\Node;
-use Magento\Framework\Event\ObserverInterface;
 
 /**
- * Observer that add Categories Tree to Topmenu
+ * Plugin for top menu block
  */
-class AddCatalogToTopmenuItemsObserver implements ObserverInterface
+class Topmenu
 {
     /**
      * Catalog category
@@ -38,11 +37,11 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface
     private $layerResolver;
 
     /**
+     * Initialize dependencies.
+     *
      * @param \Magento\Catalog\Helper\Category $catalogCategory
-     * @param \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState
      * @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Catalog\Helper\Category $catalogCategory
      * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
      */
     public function __construct(
@@ -58,26 +57,27 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface
     }
 
     /**
-     * Checking whether the using static urls in WYSIWYG allowed event
+     * Build category tree for menu block.
      *
-     * @param \Magento\Framework\Event\Observer $observer
+     * @param \Magento\Theme\Block\Html\Topmenu $subject
+     * @param string $outermostClass
+     * @param string $childrenWrapClass
+     * @param int $limit
      * @return void
+     * @SuppressWarnings("PMD.UnusedFormalParameter")
      */
-    public function execute(\Magento\Framework\Event\Observer $observer)
-    {
-        $block = $observer->getEvent()->getBlock();
-        $menuRootNode = $observer->getEvent()->getMenu();
-        $block->addIdentity(Category::CACHE_TAG);
-
+    public function beforeGetHtml(
+        \Magento\Theme\Block\Html\Topmenu $subject,
+        $outermostClass = '',
+        $childrenWrapClass = '',
+        $limit = 0
+    ) {
         $rootId = $this->storeManager->getStore()->getRootCategoryId();
         $storeId = $this->storeManager->getStore()->getId();
-
         /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
         $collection = $this->getCategoryTree($storeId, $rootId);
-
         $currentCategory = $this->getCurrentCategory();
-
-        $mapping = [$rootId => $menuRootNode];  // use nodes stack to avoid recursion
+        $mapping = [$rootId => $subject->getMenu()];  // use nodes stack to avoid recursion
         foreach ($collection as $category) {
             if (!isset($mapping[$category->getParentId()])) {
                 continue;
@@ -94,8 +94,28 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface
             $parentCategoryNode->addChild($categoryNode);
 
             $mapping[$category->getId()] = $categoryNode; //add node in stack
+        }
+    }
 
-            $block->addIdentity(Category::CACHE_TAG . '_' . $category->getId());
+    /**
+     * Add list of associated identities to the top menu block for caching purposes.
+     *
+     * @param \Magento\Theme\Block\Html\Topmenu $subject
+     * @return void
+     */
+    public function beforeGetIdentities(\Magento\Theme\Block\Html\Topmenu $subject)
+    {
+        $subject->addIdentity(Category::CACHE_TAG);
+        $rootId = $this->storeManager->getStore()->getRootCategoryId();
+        $storeId = $this->storeManager->getStore()->getId();
+        /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
+        $collection = $this->getCategoryTree($storeId, $rootId);
+        $mapping = [$rootId => $subject->getMenu()];  // use nodes stack to avoid recursion
+        foreach ($collection as $category) {
+            if (!isset($mapping[$category->getParentId()])) {
+                continue;
+            }
+            $subject->addIdentity(Category::CACHE_TAG . '_' . $category->getId());
         }
     }
 
diff --git a/app/code/Magento/Catalog/Setup/UpgradeData.php b/app/code/Magento/Catalog/Setup/UpgradeData.php
index 2e05d5b0ac770bdeaacd056a52819a0c582ca1e5..542fea6770fab226e2bb7d22643d0dc74f66218e 100644
--- a/app/code/Magento/Catalog/Setup/UpgradeData.php
+++ b/app/code/Magento/Catalog/Setup/UpgradeData.php
@@ -257,6 +257,12 @@ class UpgradeData implements UpgradeDataInterface
                 'frontend_label',
                 'Small'
             );
+            $categorySetup->updateAttribute(
+                ProductAttributeInterface::ENTITY_TYPE_CODE,
+                'image',
+                'frontend_input_renderer',
+                null
+            );
 
             //Design tab
             $categorySetup->updateAttribute(
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ImageExtractorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ImageExtractorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe255ea63ca667bc2959b0256b93df6038a528ab
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ImageExtractorTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class ImageExtractorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\ImageExtractor
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->model = $objectManager->getObject(\Magento\Catalog\Model\ImageExtractor::class);
+    }
+
+    public function testProcess()
+    {
+        $expectedArray = include(__DIR__ . '/_files/converted_view.php');
+        $this->assertEquals($expectedArray, $this->model->process($this->getDomElement(), 'media'));
+    }
+
+    /**
+     * Get mocked dom element
+     *
+     * @return \DOMElement
+     */
+    private function getDomElement()
+    {
+        $doc = new \DOMDocument();
+        $doc->load(__DIR__ . '/_files/valid_view.xml');
+        return $doc->getElementsByTagName('images')->item(0);
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php
deleted file mode 100644
index d0d3cb3d2fa18f2d329437202eb99f2e88db97db..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Catalog\Test\Unit\Model\Indexer\Category;
-
-class AffectCacheTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Model\Indexer\Category\AffectCache
-     */
-    protected $plugin;
-
-    /**
-     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var \Magento\Framework\Indexer\ActionInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $subjectMock;
-
-    /**
-     *  Set up
-     */
-    protected function setUp()
-    {
-        $this->subjectMock = $this->getMockForAbstractClass('Magento\Framework\Indexer\ActionInterface',
-            [], '', false, true, true, []);
-        $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext',
-            [], [], '', false);
-        $this->plugin = new \Magento\Catalog\Model\Indexer\Category\AffectCache($this->contextMock);
-    }
-
-    /**
-     * test beforeExecute
-     */
-    public function testBeforeExecute()
-    {
-        $expectedIds = [5, 6, 7];
-        $this->contextMock->expects($this->once())
-            ->method('registerEntities')
-            ->with($this->equalTo(\Magento\Catalog\Model\Category::ENTITY),
-                $this->equalTo($expectedIds))
-            ->will($this->returnValue($this->contextMock));
-        $actualIds = $this->plugin->beforeExecute($this->subjectMock, $expectedIds);
-        $this->assertEquals([$expectedIds], $actualIds);
-    }
-}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php
index 1f7edb65e9432ef02500ece8a2f4b57fb6da2718..0be219fdecd91f9b51436a06ca0bc1c990b8fb63 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php
@@ -32,6 +32,11 @@ class FlatTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexerRegistryMock;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->fullMock = $this->getMock(
@@ -73,6 +78,15 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             $this->rowsMock,
             $this->indexerRegistryMock
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\Catalog\Model\Indexer\Category\Flat::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->model, $this->cacheContextMock);
     }
 
     public function testExecuteWithIndexerInvalid()
@@ -105,6 +119,10 @@ class FlatTest extends \PHPUnit_Framework_TestCase
 
         $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
 
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
+
         $this->model->execute($ids);
     }
 
@@ -127,6 +145,10 @@ class FlatTest extends \PHPUnit_Framework_TestCase
 
         $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
 
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
+
         $this->model->execute($ids);
     }
 
@@ -137,4 +159,25 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Catalog\Model\Indexer\Category\Flat\State::INDEXER_ID)
             ->will($this->returnValue($this->indexerMock));
     }
+
+    public function testExecuteFull()
+    {
+        /** @var \Magento\Catalog\Model\Indexer\Category\Flat\Action\Full $categoryIndexerFlatFull */
+        $categoryIndexerFlatFull = $this->getMock(
+            \Magento\Catalog\Model\Indexer\Category\Flat\Action\Full::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->fullMock->expects($this->once())
+            ->method('create')
+            ->willReturn($categoryIndexerFlatFull);
+        $categoryIndexerFlatFull->expects($this->once())
+            ->method('reindexAll');
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with([\Magento\Catalog\Model\Category::CACHE_TAG]);
+        $this->model->executeFull();
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php
index 72f53360b9a17279b83b2cac8c39112d46713511..2dd1d30500cd5c302b45f57432bf9ddf25dcd713 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php
@@ -32,6 +32,11 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexerRegistryMock;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->fullMock = $this->getMock(
@@ -73,6 +78,15 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             $this->rowsMock,
             $this->indexerRegistryMock
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\Catalog\Model\Indexer\Category\Product::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->model, $this->cacheContextMock);
     }
 
     public function testExecuteWithIndexerWorking()
@@ -115,6 +129,10 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
         $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
 
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids);
+
         $this->model->execute($ids);
     }
 
@@ -125,4 +143,25 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Catalog\Model\Indexer\Category\Product::INDEXER_ID)
             ->will($this->returnValue($this->indexerMock));
     }
+
+    public function testExecuteFull()
+    {
+        /** @var \Magento\Catalog\Model\Indexer\Category\Product\Action\Full $productIndexerFlatFull */
+        $productIndexerFlatFull = $this->getMock(
+            \Magento\Catalog\Model\Indexer\Category\Product\Action\Full::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->fullMock->expects($this->once())
+            ->method('create')
+            ->willReturn($productIndexerFlatFull);
+        $productIndexerFlatFull->expects($this->once())
+            ->method('execute');
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with([\Magento\Catalog\Model\Category::CACHE_TAG]);
+        $this->model->executeFull();
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php
deleted file mode 100644
index a69eb70638a41b8e4c4fa1eeeaa081c3e7d01ac6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Catalog\Test\Unit\Model\Indexer\Product;
-
-class AffectCacheTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\PageCache\Model\Indexer\Product\RefreshPlugin
-     */
-    protected $plugin;
-
-    /**
-     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $contextMock;
-
-    /**
-     * @var \Magento\Framework\Indexer\ActionInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $subjectMock;
-
-    /**
-     *  Set up
-     */
-    protected function setUp()
-    {
-        $this->subjectMock = $this->getMockForAbstractClass('Magento\Framework\Indexer\ActionInterface',
-            [], '', false, true, true, []);
-        $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext',
-            [], [], '', false);
-        $this->plugin = new \Magento\Catalog\Model\Indexer\Product\AffectCache($this->contextMock);
-    }
-
-    /**
-     * test beforeExecute
-     */
-    public function testBeforeExecute()
-    {
-        $expectedIds = [1, 2, 3];
-        $this->contextMock->expects($this->once())
-            ->method('registerEntities')
-            ->with($this->equalTo(\Magento\Catalog\Model\Product::ENTITY),
-                $this->equalTo($expectedIds))
-            ->will($this->returnValue($this->contextMock));
-        $actualIds = $this->plugin->beforeExecute($this->subjectMock, $expectedIds);
-        $this->assertEquals([$expectedIds], $actualIds);
-    }
-}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php
index 0b80262ef9223acaee11274839f3f9fdd2eb2c0c..9910ca7f06ba635c560436139461a2c259c6b8a8 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php
@@ -32,6 +32,11 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexerRegistryMock;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->fullMock = $this->getMock(
@@ -73,6 +78,15 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
             $this->rowsMock,
             $this->indexerRegistryMock
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\Catalog\Model\Indexer\Category\Product::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->model, $this->cacheContextMock);
     }
 
     public function testExecuteWithIndexerWorking()
@@ -115,6 +129,10 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
 
         $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
 
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
+
         $this->model->execute($ids);
     }
 
@@ -125,4 +143,30 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Catalog\Model\Indexer\Product\Category::INDEXER_ID)
             ->will($this->returnValue($this->indexerMock));
     }
+
+    public function testExecuteFull()
+    {
+        /** @var \Magento\Catalog\Model\Indexer\Category\Product\Action\Full $productIndexerFlatFull */
+        $productIndexerFlatFull = $this->getMock(
+            \Magento\Catalog\Model\Indexer\Category\Product\Action\Full::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->fullMock->expects($this->once())
+            ->method('create')
+            ->willReturn($productIndexerFlatFull);
+        $productIndexerFlatFull->expects($this->once())
+            ->method('execute');
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with(
+                [
+                    \Magento\Catalog\Model\Category::CACHE_TAG,
+                    \Magento\Catalog\Model\Product::CACHE_TAG
+                ]
+            );
+        $this->model->executeFull();
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php
index 34801d07e557b0fad7d4e2409e923f05fb489925..446fde618b8c96fec75393950d112d7f7c39acf6 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php
@@ -27,6 +27,11 @@ class EavTest extends \PHPUnit_Framework_TestCase
      */
     protected $_productEavIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->_productEavIndexerRow = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Action\Row')
@@ -41,22 +46,44 @@ class EavTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->_model = new \Magento\Catalog\Model\Indexer\Product\Eav(
+        $this->model = new \Magento\Catalog\Model\Indexer\Product\Eav(
             $this->_productEavIndexerRow,
             $this->_productEavIndexerRows,
             $this->_productEavIndexerFull
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\Catalog\Model\Indexer\Product\Eav::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->model, $this->cacheContextMock);
+    }
+
+    public function testExecute()
+    {
+        $ids = [1, 2, 3];
+        $this->_productEavIndexerRow->expects($this->any())
+            ->method('execute')
+            ->with($ids);
+
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
+
+        $this->model->execute($ids);
     }
 
-    public function testExecuteAndExecuteList()
+    public function testExecuteList()
     {
         $ids = [1, 2, 3];
         $this->_productEavIndexerRow->expects($this->any())
             ->method('execute')
             ->with($ids);
 
-        $this->_model->execute($ids);
-        $this->_model->executeList($ids);
+        $this->model->executeList($ids);
     }
 
     public function testExecuteFull()
@@ -64,7 +91,16 @@ class EavTest extends \PHPUnit_Framework_TestCase
         $this->_productEavIndexerFull->expects($this->once())
             ->method('execute');
 
-        $this->_model->executeFull();
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with(
+                [
+                    \Magento\Catalog\Model\Category::CACHE_TAG,
+                    \Magento\Catalog\Model\Product::CACHE_TAG
+                ]
+            );
+
+        $this->model->executeFull();
     }
 
     public function testExecuteRow()
@@ -74,6 +110,6 @@ class EavTest extends \PHPUnit_Framework_TestCase
             ->method('execute')
             ->with($id);
 
-        $this->_model->executeRow($id);
+        $this->model->executeRow($id);
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php
index cb4d485cfd1ac0d417ab6d828673cda0858c69d9..f9eb1b1d29099c4a902c7babec37cd5cc12b0436 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php
@@ -29,6 +29,11 @@ class FlatTest extends \PHPUnit_Framework_TestCase
      */
     private $productFlatIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->productFlatIndexerRow = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Flat\Action\Row')
@@ -52,21 +57,50 @@ class FlatTest extends \PHPUnit_Framework_TestCase
                 'productFlatIndexerFull' => $this->productFlatIndexerFull
             ]
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\Catalog\Model\Indexer\Product\Flat::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->model, $this->cacheContextMock);
     }
 
-    public function testExecuteAndExecuteList()
+    public function testExecute()
     {
-        $except = ['test'];
-        $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($except));
+        $ids = [1, 2, 3];
+        $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($ids));
 
-        $this->model->execute($except);
-        $this->model->executeList($except);
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
+
+        $this->model->execute($ids);
+    }
+
+    public function testExecuteList()
+    {
+        $ids = [1, 2, 3];
+        $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($ids));
+
+        $this->model->executeList($ids);
     }
 
     public function testExecuteFull()
     {
         $this->productFlatIndexerFull->expects($this->any())->method('execute');
 
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with(
+                [
+                    \Magento\Catalog\Model\Category::CACHE_TAG,
+                    \Magento\Catalog\Model\Product::CACHE_TAG
+                ]
+            );
+
         $this->model->executeFull();
     }
 
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Locator/RegistryLocatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Locator/RegistryLocatorTest.php
index 86df3eaf30ebb1c02dd51cd3514d6ee458cafbf4..d66bb4192a693887abb1f81ed61745af9b6b880d 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Locator/RegistryLocatorTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Locator/RegistryLocatorTest.php
@@ -9,6 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface;
 use Magento\Catalog\Model\Locator\RegistryLocator;
 use Magento\Framework\Registry;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Store\Api\Data\StoreInterface;
 
 /**
  * Class RegistryLocatorTest
@@ -26,36 +27,75 @@ class RegistryLocatorTest extends \PHPUnit_Framework_TestCase
     protected $model;
 
     /**
-     * @var Registry
+     * @var Registry|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $registryMock;
 
     /**
-     * @var ProductInterface
+     * @var ProductInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $productMock;
 
+    /**
+     * @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
     protected function setUp()
     {
         $this->objectManager = new ObjectManager($this);
-        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+        $this->registryMock = $this->getMockBuilder(Registry::class)
             ->setMethods(['registry'])
             ->getMock();
-        $this->productMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
+        $this->productMock = $this->getMockBuilder(ProductInterface::class)
+            ->getMockForAbstractClass();
+        $this->storeMock = $this->getMockBuilder(StoreInterface::class)
             ->getMockForAbstractClass();
 
+        $this->model = $this->objectManager->getObject(RegistryLocator::class, [
+            'registry' => $this->registryMock,
+        ]);
+    }
+
+    public function testGetProduct()
+    {
         $this->registryMock->expects($this->once())
             ->method('registry')
             ->with('current_product')
             ->willReturn($this->productMock);
 
-        $this->model = $this->objectManager->getObject('Magento\Catalog\Model\Locator\RegistryLocator', [
-            'registry' => $this->registryMock,
-        ]);
+        $this->assertInstanceOf(ProductInterface::class, $this->model->getProduct());
+        // Lazy loading
+        $this->assertInstanceOf(ProductInterface::class, $this->model->getProduct());
     }
 
-    public function testGetProduct()
+    public function testGetStore()
+    {
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->with('current_store')
+            ->willReturn($this->storeMock);
+
+        $this->assertInstanceOf(StoreInterface::class, $this->model->getStore());
+        // Lazy loading
+        $this->assertInstanceOf(StoreInterface::class, $this->model->getStore());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NotFoundException
+     * @expectedExceptionMessage Product was not registered
+     */
+    public function testGetProductWithException()
+    {
+        $this->assertInstanceOf(ProductInterface::class, $this->model->getProduct());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NotFoundException
+     * @expectedExceptionMessage Store was not registered
+     */
+    public function testGetStoreWithException()
     {
-        $this->assertInstanceOf('Magento\Catalog\Api\Data\ProductInterface', $this->model->getProduct());
+        $this->assertInstanceOf(StoreInterface::class, $this->model->getStore());
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ConverterTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..07e0e6467ced7874cfa568f39527aeafb9742931
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ConverterTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\Product\Link;
+
+use Magento\Catalog\Model\Product\Link\Converter;
+
+class ConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Converter
+     */
+    protected $converter;
+
+    protected function setUp()
+    {
+        $this->converter = new Converter();
+    }
+
+    public function testConvertLinksToGroupedArray()
+    {
+        $linkedProductSku = 'linkedProductSample';
+        $linkedProductId = '2016';
+        $linkType = 'associated';
+        $linkMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductLinkInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getData', 'getLinkType', 'getLinkedProductSku', 'getExtensionAttributes'])
+            ->getMockForAbstractClass();
+        $basicData = [$linkMock];
+        $linkedProductMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $associatedProducts = [$linkedProductSku => $linkedProductMock];
+        $info = [100, 300, 500];
+        $infoFinal = [100, 300, 500, 'id' => $linkedProductId, 'qty' => 33];
+        $linksAsArray = [$linkType => [$infoFinal]];
+
+        $typeMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Type\AbstractType::class)
+            ->setMethods(['getAssociatedProducts'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productMock->expects($this->once())
+            ->method('getProductLinks')
+            ->willReturn($basicData);
+        $productMock->expects($this->once())
+            ->method('getTypeInstance')
+            ->willReturn($typeMock);
+        $typeMock->expects($this->once())
+            ->method('getAssociatedProducts')
+            ->with($productMock)
+            ->willReturn($associatedProducts);
+        $linkedProductMock->expects($this->once())
+            ->method('getSku')
+            ->willReturn($linkedProductSku);
+        $linkMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($info);
+        $linkMock->expects($this->exactly(2))
+            ->method('getLinkType')
+            ->willReturn($linkType);
+        $linkMock->expects($this->once())
+            ->method('getLinkedProductSku')
+            ->willReturn($linkedProductSku);
+        $linkedProductMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($linkedProductId);
+        $attributeMock = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class)
+            ->setMethods(['__toArray'])
+            ->getMockForAbstractClass();
+        $linkMock->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($attributeMock);
+        $attributeMock->expects($this->once())
+            ->method('__toArray')
+            ->willReturn(['qty' => 33]);
+        
+        $this->assertEquals($linksAsArray, $this->converter->convertLinksToGroupedArray($productMock));
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ResolverTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..58b5a5968bece650b7bfdfdd8e1e1565396ac016
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Link/ResolverTest.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\Product\Link;
+
+use Magento\Catalog\Model\Product\Link\Resolver;
+
+class ResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var Resolver
+     */
+    protected $resolver;
+
+    protected function setUp()
+    {
+        $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
+            ->getMockForAbstractClass();
+
+        $this->resolver = new Resolver($this->requestMock);
+    }
+
+    public function testGetLinksEmpty()
+    {
+        $someLinks = [1, 2, 3];
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('links', [])
+            ->willReturn($someLinks);
+        $this->assertEquals($someLinks, $this->resolver->getLinks());
+
+    }
+
+    public function testGetLinksOverridden()
+    {
+        $overriddenLinks = [3, 5, 7];
+        $this->requestMock->expects($this->never())
+            ->method('getParam');
+
+        $this->resolver->override($overriddenLinks);
+        $this->assertEquals($overriddenLinks, $this->resolver->getLinks());
+
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/_files/converted_view.php b/app/code/Magento/Catalog/Test/Unit/Model/_files/converted_view.php
new file mode 100644
index 0000000000000000000000000000000000000000..49d865253ced4917fabaa7c245ef238421a05e46
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/_files/converted_view.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+return [
+    "media" => [
+        "Magento_Catalog" => [
+            "images" => [
+                "swatch_thumb_base" => [
+                    "type" => "swatch_thumb",
+                    "width" => 75,
+                    "height" => 75,
+                    "background" => [255, 25, 2]
+                ]
+            ]
+        ]
+    ]
+];
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/_files/valid_view.xml b/app/code/Magento/Catalog/Test/Unit/Model/_files/valid_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c6a1aec333fab172f6094a3c8903dea8e0b17ff4
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/_files/valid_view.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
+    <media>
+        <images module="Magento_Catalog">
+            <image id="swatch_thumb_base" type="swatch_thumb">
+                <width>75</width>
+                <height>75</height>
+                <background>[255, 25, 2]</background>
+            </image>
+        </images>
+    </media>
+</view>
diff --git a/app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php b/app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php
similarity index 81%
rename from app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php
rename to app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php
index 393cf8223d2a2d40ed54802515cdc91fa5fc804a..e0fe2deb232f68b989abb72463268d531e5e81cd 100644
--- a/app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php
@@ -6,16 +6,16 @@
 
 // @codingStandardsIgnoreFile
 
-namespace Magento\Catalog\Test\Unit\Observer;
+namespace Magento\Catalog\Test\Unit\Plugin\Block;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
-class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase
+class TopmenuTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver
+     * @var \Magento\Catalog\Plugin\Block\Topmenu
      */
-    protected $_observer;
+    protected $block;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Helper\Category
@@ -100,8 +100,8 @@ class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase
         $collection->expects($this->once())->method('getIterator')
             ->willReturn(new \ArrayIterator([]));
 
-        $this->_observer = (new ObjectManager($this))->getObject(
-            'Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver',
+        $this->block = (new ObjectManager($this))->getObject(
+            \Magento\Catalog\Plugin\Block\Topmenu::class,
             [
                 'catalogCategory' => $this->_catalogCategory,
                 'menuCategoryData' => $this->menuCategoryData,
@@ -142,23 +142,11 @@ class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $blockMock = $this->_getCleanMock('\Magento\Theme\Block\Html\Topmenu');
-
-        $eventMock = $this->getMock('\Magento\Framework\Event', ['getBlock'], [], '', false);
-        $eventMock->expects($this->once())
-            ->method('getBlock')
-            ->will($this->returnValue($blockMock));
-
-        $observerMock = $this->getMock('\Magento\Framework\Event\Observer', ['getEvent', 'getMenu'], [], '', false);
-        $observerMock->expects($this->any())
-            ->method('getEvent')
-            ->will($this->returnValue($eventMock));
-
-        return $observerMock;
+        return $blockMock;
     }
 
     public function testAddCatalogToTopMenuItems()
     {
-        $observer = $this->_preparationData();
-        $this->_observer->execute($observer);
+        $this->block->beforeGetHtml($this->_preparationData());
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
index 72ebbf5529a581c5030fa7c79bae622769369519..648775613d37fa2d73ede066cb6a1ea622c4eb48 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
@@ -66,7 +66,7 @@ abstract class AbstractModifierTest extends \PHPUnit_Framework_TestCase
                 'getExistsStoreValueFlag'
             ])->getMockForAbstractClass();
         $this->storeMock = $this->getMockBuilder(StoreInterface::class)
-            ->setMethods(['load', 'getId'])
+            ->setMethods(['load', 'getId', 'getConfig'])
             ->getMockForAbstractClass();
         $this->arrayManagerMock = $this->getMockBuilder(ArrayManager::class)
             ->disableOriginalConstructor()
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
index 92b551a820194879de22d9ce789ed62c6d4f04f4..f3c441f1aec06c6bfa1fb9141ef6936a6d404b29 100644
--- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
@@ -56,6 +56,9 @@ class Websites extends \Magento\Ui\Component\Listing\Columns\Column
             foreach ($dataSource['data']['items'] as & $item) {
                 $websites = [];
                 foreach ($item[$fieldName] as $websiteId) {
+                    if (!isset($websiteNames[$websiteId])) {
+                        continue;
+                    }
                     $websites[] = $websiteNames[$websiteId];
                 }
                 $item[$fieldName] = implode(', ', $websites);
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
index 473d1d423067478ea94d0c8b5afcc88c68de40c2..61141072f7725e165cb29938e7878b6b240ef6a6 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
@@ -319,8 +319,7 @@ class CustomOptions extends AbstractModifier
                                 'sortOrder' => 20,
                                 'actions' => [
                                     [
-                                        'targetName' => static::FORM_NAME . '.' . static::FORM_NAME . '.'
-                                            . static::GROUP_CUSTOM_OPTIONS_NAME . '.' . static::GRID_OPTIONS_NAME,
+                                        'targetName' => 'ns = ${ $.ns }, index = ' . static::GRID_OPTIONS_NAME,
                                         'actionName' => 'addChild',
                                     ]
                                 ]
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
index ca9f88a81e1f925f866df8ddd30c1f27375059b1..454cf335632e6935a4d1ca693a03b14fb5dff891 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
@@ -18,6 +18,7 @@ use Magento\Eav\Model\Config;
 use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory as GroupCollectionFactory;
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Api\SortOrderBuilder;
+use Magento\Framework\App\Request\DataPersistorInterface;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\Filter\Translit;
 use Magento\Framework\Stdlib\ArrayManager;
@@ -155,6 +156,11 @@ class Eav extends AbstractModifier
      */
     private $attributesToEliminate;
 
+    /**
+     * @var DataPersistorInterface
+     */
+    private $dataPersistor;
+
     /**
      * @param LocatorInterface $locator
      * @param EavValidationRules $eavValidationRules
@@ -172,6 +178,7 @@ class Eav extends AbstractModifier
      * @param Translit $translitFilter
      * @param ArrayManager $arrayManager
      * @param ScopeOverriddenValue $scopeOverriddenValue
+     * @param DataPersistorInterface $dataPersistor
      * @param array $attributesToDisable
      * @param array $attributesToEliminate
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -193,6 +200,7 @@ class Eav extends AbstractModifier
         Translit $translitFilter,
         ArrayManager $arrayManager,
         ScopeOverriddenValue $scopeOverriddenValue,
+        DataPersistorInterface $dataPersistor,
         $attributesToDisable = [],
         $attributesToEliminate = []
     ) {
@@ -212,6 +220,7 @@ class Eav extends AbstractModifier
         $this->translitFilter = $translitFilter;
         $this->arrayManager = $arrayManager;
         $this->scopeOverriddenValue = $scopeOverriddenValue;
+        $this->dataPersistor = $dataPersistor;
         $this->attributesToDisable = $attributesToDisable;
         $this->attributesToEliminate = $attributesToEliminate;
     }
@@ -322,6 +331,10 @@ class Eav extends AbstractModifier
      */
     public function modifyData(array $data)
     {
+        if (!$this->locator->getProduct()->getId() && $this->dataPersistor->get('catalog_product')) {
+            return $this->resolvePersistentData($data);
+        }
+
         $productId = $this->locator->getProduct()->getId();
 
         /** @var string $groupCode */
@@ -340,6 +353,29 @@ class Eav extends AbstractModifier
         return $data;
     }
 
+    /**
+     * Resolve data persistence
+     *
+     * @param array $data
+     * @return array
+     */
+    private function resolvePersistentData(array $data)
+    {
+        $persistentData = (array)$this->dataPersistor->get('catalog_product');
+        $productId = $this->locator->getProduct()->getId();
+
+        if (empty($data[$productId][self::DATA_SOURCE_DEFAULT])) {
+            $data[$productId][self::DATA_SOURCE_DEFAULT] = [];
+        }
+
+        $data[$productId] = array_replace_recursive(
+            $data[$productId][self::DATA_SOURCE_DEFAULT],
+            $persistentData
+        );
+
+        return $data;
+    }
+
     /**
      * Get product type
      *
@@ -548,7 +584,7 @@ class Eav extends AbstractModifier
                 $meta = $this->customizePriceAttribute($attribute, $meta);
                 break;
             case 'gallery':
-                // Gallery attribute is being handled by "Images And Videos Tab"
+                // Gallery attribute is being handled by "Images And Videos" section
                 $meta = [];
                 break;
         }
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 7b85bbbb8aaec682b3f9d8ee9efd36cfc4d70a90..b4147229b81d6be08e7757d3546175a94bece238 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php
@@ -163,24 +163,18 @@ class General extends AbstractModifier
     protected function customizeStatusField(array $meta)
     {
         $switcherConfig = [
-            'arguments' => [
-                'data' => [
-                    'config' => [
-                        'dataType' => Form\Element\DataType\Number::NAME,
-                        'formElement' => Form\Element\Checkbox::NAME,
-                        'componentType' => Form\Field::NAME,
-                        'prefer' => 'toggle',
-                        'valueMap' => [
-                            'true' => '1',
-                            'false' => '2'
-                        ],
-                    ],
-                ],
+            'dataType' => Form\Element\DataType\Number::NAME,
+            'formElement' => Form\Element\Checkbox::NAME,
+            'componentType' => Form\Field::NAME,
+            'prefer' => 'toggle',
+            'valueMap' => [
+                'true' => '1',
+                'false' => '2'
             ],
         ];
 
         $path = $this->arrayManager->findPath(ProductAttributeInterface::CODE_STATUS, $meta, null, 'children');
-        $meta = $this->arrayManager->merge($path, $meta, $switcherConfig);
+        $meta = $this->arrayManager->merge($path . static::META_CONFIG_PATH, $meta, $switcherConfig);
 
         return $meta;
     }
@@ -203,7 +197,7 @@ class General extends AbstractModifier
                     [
                         'dataScope' => ProductAttributeInterface::CODE_WEIGHT,
                         'validation' => [
-                            'validate-number' => true,
+                            'validate-zero-or-greater' => true
                         ],
                         'additionalClasses' => 'admin__field-small',
                         'addafter' => $this->locator->getStore()->getConfig('general/locale/weight_unit'),
@@ -220,44 +214,33 @@ class General extends AbstractModifier
                     null,
                     'children'
                 );
-                $meta = $this->arrayManager->merge($containerPath, $meta, [
-                    'arguments' => [
-                        'data' => [
-                            'config' => [
-                                'component' => 'Magento_Ui/js/form/components/group',
-                            ],
-                        ],
-                    ],
+                $meta = $this->arrayManager->merge($containerPath . static::META_CONFIG_PATH, $meta, [
+                    'component' => 'Magento_Ui/js/form/components/group',
                 ]);
 
                 $hasWeightPath = $this->arrayManager->slicePath($weightPath, 0, -1) . '/'
                     . ProductAttributeInterface::CODE_HAS_WEIGHT;
                 $meta = $this->arrayManager->set(
-                    $hasWeightPath,
+                    $hasWeightPath . static::META_CONFIG_PATH,
                     $meta,
                     [
-                        'arguments' => [
-                            'data' => [
-                                'config' => [
-                                    'dataType' => 'boolean',
-                                    'formElement' => Form\Element\Select::NAME,
-                                    'componentType' => Form\Field::NAME,
-                                    'dataScope' => 'product_has_weight',
-                                    'label' => '',
-                                    'options' => [
-                                        [
-                                            'label' => __('This item has weight'),
-                                            'value' => 1
-                                        ],
-                                        [
-                                            'label' => __('This item has no weight'),
-                                            'value' => 0
-                                        ],
-                                    ],
-                                    'value' => (int)$this->locator->getProduct()->getTypeInstance()->hasWeight(),
-                                ],
+
+                        'dataType' => 'boolean',
+                        'formElement' => Form\Element\Select::NAME,
+                        'componentType' => Form\Field::NAME,
+                        'dataScope' => 'product_has_weight',
+                        'label' => '',
+                        'options' => [
+                            [
+                                'label' => __('This item has weight'),
+                                'value' => 1
                             ],
-                        ]
+                            [
+                                'label' => __('This item has no weight'),
+                                'value' => 0
+                            ],
+                        ],
+                        'value' => (int)$this->locator->getProduct()->getTypeInstance()->hasWeight(),
                     ]
                 );
             }
@@ -340,39 +323,53 @@ class General extends AbstractModifier
             ProductAttributeInterface::CODE_SEO_FIELD_META_KEYWORD,
             ProductAttributeInterface::CODE_SEO_FIELD_META_DESCRIPTION,
         ];
+        $textListeners = [
+            ProductAttributeInterface::CODE_SEO_FIELD_META_KEYWORD,
+            ProductAttributeInterface::CODE_SEO_FIELD_META_DESCRIPTION
+        ];
+
         foreach ($listeners as $listener) {
             $listenerPath = $this->arrayManager->findPath($listener, $meta, null, 'children');
             $importsConfig = [
-                'arguments' => [
-                    'data' => [
-                        'config' => [
-                            'component' => 'Magento_Catalog/js/components/import-handler',
-                            'imports' => [
-                                'handleChanges' => '${$.provider}:data.product.name',
-                            ],
-                            'autoImportIfEmpty' => true,
-                            'allowImport' => $this->locator->getProduct()->getId() ? false : true,
-                        ],
-                    ],
+                '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'
                 ],
             ];
 
-            $meta = $this->arrayManager->merge($listenerPath, $meta, $importsConfig);
+            if (!in_array($listener, $textListeners)) {
+                $importsConfig['elementTmpl'] = 'ui/form/element/input';
+            }
+
+            $meta = $this->arrayManager->merge($listenerPath . static::META_CONFIG_PATH, $meta, $importsConfig);
         }
 
+        $skuPath = $this->arrayManager->findPath(ProductAttributeInterface::CODE_SKU, $meta, null, 'children');
+        $meta = $this->arrayManager->merge(
+            $skuPath . static::META_CONFIG_PATH,
+            $meta,
+            [
+                'autoImportIfEmpty' => true,
+                'allowImport' => $this->locator->getProduct()->getId() ? false : true,
+            ]
+        );
+
         $namePath = $this->arrayManager->findPath(ProductAttributeInterface::CODE_NAME, $meta, null, 'children');
 
         return $this->arrayManager->merge(
-            $namePath,
+            $namePath . static::META_CONFIG_PATH,
             $meta,
             [
-                'arguments' => [
-                    'data' => [
-                        'config' => [
-                            'valueUpdate' => 'keyup'
-                        ],
-                    ],
-                ],
+                'valueUpdate' => 'keyup'
             ]
         );
     }
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/ProductDataProvider.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/ProductDataProvider.php
index 294b8188ea0106522e6a64f36b3c2dfd19f36221..a390bb6e9a9d99a97fb4ec2933ab515e3ce9665c 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/ProductDataProvider.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/ProductDataProvider.php
@@ -18,7 +18,7 @@ class ProductDataProvider extends AbstractDataProvider
     /**
      * @var PoolInterface
      */
-    protected $pool;
+    private $pool;
 
     /**
      * @param string $name
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 38c70fc3c1cf65508a93b76496df395519741039..b262f93d0a4c843d3086e93da9f8f855d1deda2e 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -46,6 +46,9 @@
     <type name="Magento\Customer\Model\ResourceModel\Visitor">
         <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
     </type>
+    <type name="Magento\Theme\Block\Html\Topmenu">
+        <plugin name="catalogTopmenu" type="Magento\Catalog\Plugin\Block\Topmenu" />
+    </type>
     <type name="Magento\Framework\Mview\View\StateInterface">
         <plugin name="setStatusForMview" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\MviewState" />
     </type>
@@ -194,10 +197,6 @@
         <plugin name="indexerCategoryFlatConfigGet" type="Magento\Catalog\Model\Indexer\Category\Flat\Plugin\IndexerConfigData" />
         <plugin name="indexerProductFlatConfigGet" type="Magento\Catalog\Model\Indexer\Product\Flat\Plugin\IndexerConfigData" />
     </type>
-    <type name="Magento\Catalog\Model\Indexer\Category\Flat">
-        <plugin name="page-cache-indexer-reindex-category-flat"
-                type="Magento\Catalog\Model\Indexer\Category\AffectCache" sortOrder="10"/>
-    </type>
     <type name="Magento\Catalog\Model\Indexer\Product\Price\AbstractAction">
         <arguments>
             <argument name="defaultPriceIndexer" xsi:type="object">Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice</argument>
@@ -213,14 +212,6 @@
             </argument>
         </arguments>
     </type>
-    <type name="Magento\Catalog\Model\Indexer\Category\Product">
-        <plugin name="page-cache-indexer-reindex-category-product"
-                type="Magento\Catalog\Model\Indexer\Product\AffectCache" sortOrder="10"/>
-    </type>
-    <type name="Magento\Catalog\Model\Indexer\Product\Category">
-        <plugin name="page-cache-indexer-reindex-product-category"
-                type="Magento\Catalog\Model\Indexer\Category\AffectCache" sortOrder="10"/>
-    </type>
     <type name="Magento\Catalog\Model\Product\LinkTypeProvider">
         <arguments>
             <argument name="linkTypes" xsi:type="array">
@@ -285,10 +276,6 @@
             <argument name="indexer" xsi:type="object" shared="false">Magento\Framework\Indexer\IndexerInterface</argument>
         </arguments>
     </type>
-    <type name="Magento\Catalog\Model\Indexer\Product\Flat">
-        <plugin name="page-cache-indexer-reindex-product-flat"
-                type="Magento\Catalog\Model\Indexer\Product\AffectCache" sortOrder="10"/>
-    </type>
     <type name="Magento\Framework\Model\ActionValidator\RemoveAction">
         <arguments>
             <argument name="protectedModels" xsi:type="array">
diff --git a/app/code/Magento/Catalog/etc/frontend/events.xml b/app/code/Magento/Catalog/etc/frontend/events.xml
index afb3c70a14ade23fc8caab37ab4f3b564ae1f917..5ef8c724683141c38d735fcd0e321615d562ce6a 100644
--- a/app/code/Magento/Catalog/etc/frontend/events.xml
+++ b/app/code/Magento/Catalog/etc/frontend/events.xml
@@ -12,7 +12,4 @@
     <event name="customer_logout">
         <observer name="catalog" instance="Magento\Catalog\Observer\Compare\BindCustomerLogoutObserver" shared="false" />
     </event>
-    <event name="page_block_html_topmenu_gethtml_before">
-        <observer name="catalog_add_topmenu_items" instance="Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver" />
-    </event>
 </config>
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml
index 6cb4325dd8ada0df072bd59158b465e06455876e..82b70fb8c71a885e0bd91f426c17ba17478d1899 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml
@@ -10,8 +10,8 @@
 ?>
 <fieldset class="fieldset">
     <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Manage Options (Values of Your Attribute)') ?></span></legend>
-    <div id="manage-options-panel">
-        <table class="admin__control-table">
+    <div id="manage-options-panel" data-index="attribute_options_select_container">
+        <table class="admin__control-table" data-index="attribute_options_select">
             <thead>
                 <tr id="attribute-options-table">
                     <th class="col-draggable"></th>
@@ -37,7 +37,7 @@
             <tr>
                 <th colspan="<?php /* @escapeNotVerified */ echo $storetotal; ?>" class="col-actions-add">
                     <?php if (!$block->getReadOnly() && !$block->canManageOptionDefaultOnly()):?>
-                        <button id="add_new_option_button" title="<?php /* @escapeNotVerified */ echo __('Add Option'); ?>"
+                        <button id="add_new_option_button" data-action="add_new_row" title="<?php /* @escapeNotVerified */ echo __('Add Option'); ?>"
                             type="button" class="action- scalable add">
                              <span><?php /* @escapeNotVerified */ echo __('Add Option'); ?></span>
                         </button>
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 38608556a92064e5d80b639b59f4f122afb60edd..fd69874c318e21606361d503cc55ea900ad604cf 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,26 +4,150 @@
  */
 
 define([
-    'Magento_Ui/js/form/element/abstract'
-], function (Abstract) {
+    'Magento_Ui/js/form/element/textarea'
+], function (Textarea) {
     'use strict';
 
-    return Abstract.extend({
+    return Textarea.extend({
         defaults: {
             allowImport: true,
             autoImportIfEmpty: false,
-            nameValue: '',
-            valueUpdate: 'input'
+            values: {
+                'name': '',
+                'description': '',
+                'sku': '',
+                'color': '',
+                'country_of_manufacture': '',
+                'gender': '',
+                'material': '',
+                'short_description': '',
+                'size': ''
+            },
+            valueUpdate: 'input',
+            mask: ''
         },
 
         /**
-         * Import value, if it's allowed
+         * 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();
+        },
+
+        /**
+         * Handle sku value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleSkuChanges: function (newValue) {
+            if (this.code !== 'sku') {
+                this.values.sku = newValue;
+                this.updateValue();
+            }
+        },
+
+        /**
+         * Handle color value changes, if it's allowed
+         *
+         * @param {String} newValue
          */
-        handleChanges: function (newValue) {
-            this.nameValue = newValue;
+        handleColorChanges: function (newValue) {
+            this.values.color = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Handle country value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleCountryChanges: function (newValue) {
+            this.values.country = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Handle gender value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleGenderChanges: function (newValue) {
+            this.values.gender = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Handle material value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleMaterialChanges: function (newValue) {
+            this.values.material = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Handle short description value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleShortDescriptionChanges: function (newValue) {
+            this.values['short_description'] = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Handle size value changes, if it's allowed
+         *
+         * @param {String} newValue
+         */
+        handleSizeChanges: function (newValue) {
+            this.values.size = newValue;
+            this.updateValue();
+        },
+
+        /**
+         * Update field value, if it's allowed
+         */
+        updateValue: function () {
+            var str = this.mask,
+                nonEmptyValueFlag = false,
+                placeholder,
+                property,
+                tmpElement;
+
+            if (!this.allowImport) {
+                return;
+            }
+
+            for (property in this.values) {
+                if (this.values.hasOwnProperty(property)) {
+                    placeholder = '';
+                    placeholder = placeholder.concat('{{', property, '}}');
+                    str = str.replace(placeholder, this.values[property]);
+                    nonEmptyValueFlag = nonEmptyValueFlag || !!this.values[property];
+                }
+            }
+            // strip tags
+            tmpElement = document.createElement('div');
+            tmpElement.innerHTML = str;
+            str =  tmpElement.textContent || tmpElement.innerText || '';
 
-            if (this.allowImport) {
-                this.value(newValue);
+            if (nonEmptyValueFlag) {
+                this.value(str);
             }
         },
 
@@ -53,7 +177,7 @@ define([
                 this.allowImport = true;
 
                 if (this.autoImportIfEmpty) {
-                    this.value(this.nameValue);
+                    this.updateValue();
                 }
             } else {
                 this.allowImport = false;
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js
index d3ee4b5dc7622bb56d99bf25796615de4b879a75..b366f61ba499447388b6572bc2d83a98fc8ab1e3 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js
@@ -137,7 +137,9 @@ define([
                 }
             };
 
-        Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true));
+        if ($('add_new_option_button')) {
+            Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true));
+        }
         $('manage-options-panel').on('click', '.delete-option', function (event) {
             attributeOption.remove(event);
         });
diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js
index ff06f34db85c69a978fccd1f472702f13b749f50..b095d24cf481067fd6edce586f8a9131dbcde3be 100644
--- a/app/code/Magento/Catalog/view/base/web/js/price-box.js
+++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js
@@ -184,7 +184,7 @@ define([
                     var type = $(element).data('priceType'),
                         amount = parseFloat($(element).data('priceAmount'));
 
-                    if (type && amount) {
+                    if (type && !_.isNaN(amount)) {
                         prices[type] = {
                             amount: amount
                         };
diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php
index 599b2d44e2ae38e45e7477a5c45edb426e0a164b..13e311d1fe5aeb4af1282edcf29215fe67570199 100644
--- a/app/code/Magento/CatalogInventory/Helper/Stock.php
+++ b/app/code/Magento/CatalogInventory/Helper/Stock.php
@@ -12,9 +12,11 @@ use Magento\CatalogInventory\Model\ResourceModel\Stock\StatusFactory;
 use Magento\CatalogInventory\Model\ResourceModel\Stock\Status;
 use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;
 use Magento\Catalog\Model\Product;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
 
 /**
  * Class Stock
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Stock
 {
@@ -47,6 +49,11 @@ class Stock
      */
     private $stockRegistryProvider;
 
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
     /**
      * @param StoreManagerInterface $storeManager
      * @param ScopeConfigInterface $scopeConfig
@@ -75,7 +82,7 @@ class Stock
     public function assignStatusToProduct(Product $product, $status = null)
     {
         if ($status === null) {
-            $websiteId = $product->getStore()->getWebsiteId();
+            $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
             $stockStatus = $this->stockRegistryProvider->getStockStatus($product->getId(), $websiteId);
             $status = $stockStatus->getStockStatus();
         }
@@ -90,7 +97,7 @@ class Stock
      */
     public function addStockStatusToProducts(AbstractCollection $productCollection)
     {
-        $websiteId = $this->storeManager->getStore($productCollection->getStoreId())->getWebsiteId();
+        $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
         foreach ($productCollection as $product) {
             $productId = $product->getId();
             $stockStatus = $this->stockRegistryProvider->getStockStatus($productId, $websiteId);
@@ -161,4 +168,18 @@ class Stock
         }
         return $this->stockStatusResource;
     }
+
+    /**
+     * @return StockConfigurationInterface
+     *
+     * @deprecated
+     */
+    private function getStockConfiguration()
+    {
+        if ($this->stockConfiguration === null) {
+            $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get('Magento\CatalogInventory\Api\StockConfigurationInterface');
+        }
+        return $this->stockConfiguration;
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php
index db78c8e17322bd12129cc488248cd0703bb83781..1915a576939ac0aca869e5072abb3e828820dea6 100644
--- a/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php
@@ -25,7 +25,6 @@ class Backorders extends AbstractValue
                 || $this->getValue() == \Magento\CatalogInventory\Model\Stock::BACKORDERS_NO
             )
         ) {
-            $this->stockIndex->rebuild();
             $this->_stockIndexerProcessor->markIndexerAsInvalid();
         }
         return parent::afterSave();
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
index 559e6235951dbae06698ce2def0eccbbd5dfd915..6edab6f3d4eb629e2947676c21d07fe827d52cdd 100644
--- a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
@@ -20,7 +20,6 @@ class Managestock extends AbstractValue
     public function afterSave()
     {
         if ($this->isValueChanged()) {
-            $this->stockIndex->rebuild();
             $this->_stockIndexerProcessor->markIndexerAsInvalid();
         }
         return parent::afterSave();
diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php
index 445057c4c08d8174768a9237359bdb4f830066cd..d1509eec3d4adce87cfd4b8ecf75f63485bbeff5 100644
--- a/app/code/Magento/CatalogInventory/Model/Configuration.php
+++ b/app/code/Magento/CatalogInventory/Model/Configuration.php
@@ -148,7 +148,9 @@ class Configuration implements StockConfigurationInterface
      */
     public function getDefaultScopeId()
     {
-        return (int) $this->storeManager->getWebsite()->getId();
+        // TODO: should be fixed in MAGETWO-46043
+        // "0" is id of admin website, which is used in backend during save entity
+        return 0;
     }
 
     /**
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
index 2fc215cb2e9766953431e42ebf5ffc14d7cac262..0e86e0ac793ac55f9c7771c3b8d37a3ba2da0f05 100644
--- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
@@ -1,13 +1,12 @@
 <?php
 /**
- * @category    Magento
- * @package     Magento_CatalogInventory
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\CatalogInventory\Model\Indexer;
 
+use Magento\Framework\Indexer\CacheContext;
+
 class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -25,6 +24,11 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
      */
     protected $_productStockIndexerFull;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    private $cacheContext;
+
     /**
      * @param Stock\Action\Row $productStockIndexerRow
      * @param Stock\Action\Rows $productStockIndexerRows
@@ -50,6 +54,7 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     public function execute($ids)
     {
         $this->_productStockIndexerRows->execute($ids);
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
     }
 
     /**
@@ -60,6 +65,12 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     public function executeFull()
     {
         $this->_productStockIndexerFull->execute();
+        $this->getCacheContext()->registerTags(
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Catalog\Model\Product::CACHE_TAG
+            ]
+        );
     }
 
     /**
@@ -85,4 +96,19 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram
     {
         $this->_productStockIndexerRow->execute($id);
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
index 82e9e1b1c94c607103230917753f0aa1c5afaede..df910254082185145212c325568a971a75a9bd85 100644
--- a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
+++ b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
@@ -24,6 +24,7 @@ class AroundProductRepositorySave
 
     /**
      * @var StoreManagerInterface
+     * @deprecated
      */
     protected $storeManager;
 
@@ -80,7 +81,7 @@ class AroundProductRepositorySave
 
         // set fields that the customer should not care about
         $stockItem->setProductId($product->getId());
-        $stockItem->setWebsiteId($this->storeManager->getStore($product->getStoreId())->getWebsiteId());
+        $stockItem->setWebsiteId($this->stockConfiguration->getDefaultScopeId());
 
         $this->stockRegistry->updateStockItemBySku($product->getSku(), $stockItem);
 
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
index 3bb9ef4c4d5c6f847d17365df179f54b0b678752..40245db2f3372234ad18a988140195e88a11b971 100644
--- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php
@@ -9,6 +9,7 @@ namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock;
 use Magento\Catalog\Model\ResourceModel\Product\Indexer\AbstractIndexer;
 use Magento\CatalogInventory\Model\Stock;
 use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
 
 /**
  * CatalogInventory Default Stock Status Indexer Resource Model
@@ -42,6 +43,11 @@ class DefaultStock extends AbstractIndexer implements StockInterface
      */
     private $queryProcessorComposite;
 
+    /**
+     * @var StockConfigurationInterface
+     */
+    protected $stockConfiguration;
+
     /**
      * Class constructor
      *
@@ -176,43 +182,29 @@ class DefaultStock extends AbstractIndexer implements StockInterface
      */
     protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false)
     {
-        $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
         $connection = $this->getConnection();
         $qtyExpr = $connection->getCheckSql('cisi.qty > 0', 'cisi.qty', 0);
         $select = $connection->select()->from(
             ['e' => $this->getTable('catalog_product_entity')],
             ['entity_id']
         );
-        $this->_addWebsiteJoinToSelect($select, true);
-        $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id');
-        $select->columns('cw.website_id')->join(
+        $select->join(
             ['cis' => $this->getTable('cataloginventory_stock')],
             '',
-            ['stock_id']
-        )->joinLeft(
+            ['website_id', 'stock_id']
+        )->joinInner(
             ['cisi' => $this->getTable('cataloginventory_stock_item')],
             'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
             []
-        )->columns(['qty' => new \Zend_Db_Expr('SUM(' . $qtyExpr . ')')])
-            ->where('cw.website_id != 0')
-            ->where('e.type_id = ?', $this->getTypeId())
-            ->group(['e.entity_id', 'cw.website_id']);
-
-        // add limitation of status
-        $condition = $connection->quoteInto(
-            '=?',
-            \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
-        );
-        $this->_addAttributeToSelect(
-            $select,
-            'status',
-            'e.' . $metadata->getLinkField(),
-            'cs.store_id',
-            $condition
-        );
+        )->columns(
+            ['qty' => $qtyExpr]
+        )->where(
+            'cis.website_id = ?',
+            $this->getStockConfiguration()->getDefaultScopeId()
+        )->where('e.type_id = ?', $this->getTypeId())
+            ->group(['e.entity_id', 'cis.website_id', 'cis.stock_id']);
 
         $select->columns(['status' => $this->getStatusExpression($connection, true)]);
-
         if ($entityIds !== null) {
             $select->where('e.entity_id IN(?)', $entityIds);
         }
@@ -325,6 +317,20 @@ class DefaultStock extends AbstractIndexer implements StockInterface
         return $statusExpr;
     }
 
+    /**
+     * @return StockConfigurationInterface
+     *
+     * @deprecated
+     */
+    protected function getStockConfiguration()
+    {
+        if ($this->stockConfiguration === null) {
+            $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get('Magento\CatalogInventory\Api\StockConfigurationInterface');
+        }
+        return $this->stockConfiguration;
+    }
+
     /**
      * @return QueryProcessorComposite
      */
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php
index f4877e6a3de68fd72a6550d1b6bf6c5b611593bb..17a3e0c9a99494de5efdb4f6825c33fae9e41e54 100644
--- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php
@@ -75,6 +75,7 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme
 
     /**
      * @var StoreManagerInterface
+     * @deprecated
      */
     protected $storeManager;
 
@@ -189,11 +190,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme
      * Set items out of stock basing on their quantities and config settings
      *
      * @param string|int $website
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @return void
      */
     public function updateSetOutOfStock($website = null)
     {
-        $websiteId = $this->storeManager->getWebsite($website)->getId();
+        $websiteId = $this->stockConfiguration->getDefaultScopeId();
         $this->_initConfig();
         $connection = $this->getConnection();
         $values = ['is_in_stock' => 0, 'stock_status_changed_auto' => 1];
@@ -223,11 +225,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme
      * Set items in stock basing on their quantities and config settings
      *
      * @param int|string $website
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @return void
      */
     public function updateSetInStock($website)
     {
-        $websiteId = $this->storeManager->getWebsite($website)->getId();
+        $websiteId = $this->stockConfiguration->getDefaultScopeId();
         $this->_initConfig();
         $connection = $this->getConnection();
         $values = ['is_in_stock' => 1];
@@ -255,11 +258,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme
      * Update items low stock date basing on their quantities and config settings
      *
      * @param int|string $website
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @return void
      */
     public function updateLowStockDate($website)
     {
-        $websiteId = $this->storeManager->getWebsite($website)->getId();
+        $websiteId = $this->stockConfiguration->getDefaultScopeId();
         $this->_initConfig();
 
         $connection = $this->getConnection();
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php
index d08bd31df9eeb517f3577ce3aff34de85c42479f..32d21f388f03e30510dfb1179fdf335654b4c0a4 100644
--- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php
@@ -57,13 +57,13 @@ class Item extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      *
      * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $item
      * @param int $productId
-     * @param int $websiteId
+     * @param int $stockId
      * @return $this
      */
-    public function loadByProductId(\Magento\CatalogInventory\Api\Data\StockItemInterface $item, $productId, $websiteId)
+    public function loadByProductId(\Magento\CatalogInventory\Api\Data\StockItemInterface $item, $productId, $stockId)
     {
-        $select = $this->_getLoadSelect('product_id', $productId, $item)->where('website_id = :website_id');
-        $data = $this->getConnection()->fetchRow($select, [':website_id' => $websiteId]);
+        $select = $this->_getLoadSelect('product_id', $productId, $item)->where('stock_id = :stock_id');
+        $data = $this->getConnection()->fetchRow($select, [':stock_id' => $stockId]);
         if ($data) {
             $item->setData($data);
         } else {
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php
index 551f5e0c3b8fffd04eaac0e5c18bd1a1977990d6..d1e038071ecc52a7adf9f5452076e95cd06358e5 100644
--- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php
@@ -13,6 +13,7 @@ use Magento\Framework\Data\ObjectFactory;
 use Magento\Store\Model\StoreManagerInterface;
 use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
 
 /**
  * Interface StockItemCriteriaMapper
@@ -20,6 +21,17 @@ use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
  */
 class StockItemCriteriaMapper extends GenericMapper
 {
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
+    /**
+     * @var StoreManagerInterface
+     * @deprecated
+     */
+    private $storeManager;
+
     /**
      * @param Logger $logger
      * @param FetchStrategyInterface $fetchStrategy
@@ -107,10 +119,11 @@ class StockItemCriteriaMapper extends GenericMapper
 
     /**
      * @inheritdoc
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function mapStockStatus($storeId = null)
     {
-        $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
+        $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
         $this->getSelect()->joinLeft(
             ['status_table' => $this->getTable('cataloginventory_stock_status')],
             'main_table.product_id=status_table.product_id' .
@@ -149,4 +162,18 @@ class StockItemCriteriaMapper extends GenericMapper
         }
         $this->addFieldToFilter('main_table.qty', [$methods[$comparisonMethod] => $qty]);
     }
+
+    /**
+     * @return StockConfigurationInterface
+     *
+     * @deprecated
+     */
+    private function getStockConfiguration()
+    {
+        if ($this->stockConfiguration === null) {
+            $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get('Magento\CatalogInventory\Api\StockConfigurationInterface');
+        }
+        return $this->stockConfiguration;
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php
index 75b325458ccaa2c9c4bfb3c0c16ffc381c7cab90..f7410de156fb42e4549b3d1910d5c5d9d5fb0d27 100644
--- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php
@@ -6,9 +6,11 @@
 namespace Magento\CatalogInventory\Model\ResourceModel\Stock;
 
 use Magento\CatalogInventory\Model\Stock;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
 
 /**
  * CatalogInventory Stock Status per website Resource Model
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
 {
@@ -16,6 +18,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      * Store model manager
      *
      * @var \Magento\Store\Model\StoreManagerInterface
+     * @deprecated
      */
     protected $_storeManager;
 
@@ -31,6 +34,11 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     protected $eavConfig;
 
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
     /**
      * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -190,11 +198,12 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      *
      * @param \Magento\Framework\DB\Select $select
      * @param \Magento\Store\Model\Website $website
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @return Status
      */
     public function addStockStatusToSelect(\Magento\Framework\DB\Select $select, \Magento\Store\Model\Website $website)
     {
-        $websiteId = $website->getId();
+        $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
         $select->joinLeft(
             ['stock_status' => $this->getMainTable()],
             'e.entity_id = stock_status.product_id AND stock_status.website_id=' . $websiteId,
@@ -211,7 +220,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     public function addStockDataToCollection($collection, $isFilterInStock)
     {
-        $websiteId = $this->_storeManager->getStore($collection->getStoreId())->getWebsiteId();
+        $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
         $joinCondition = $this->getConnection()->quoteInto(
             'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?',
             $websiteId
@@ -245,7 +254,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     public function addIsInStockFilterToCollection($collection)
     {
-        $websiteId = $this->_storeManager->getStore($collection->getStoreId())->getWebsiteId();
+        $websiteId = $this->getStockConfiguration()->getDefaultScopeId();
         $joinCondition = $this->getConnection()->quoteInto(
             'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?',
             $websiteId
@@ -325,4 +334,18 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         }
         return $statuses;
     }
+
+    /**
+     * @return StockConfigurationInterface
+     *
+     * @deprecated
+     */
+    private function getStockConfiguration()
+    {
+        if ($this->stockConfiguration === null) {
+            $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get('Magento\CatalogInventory\Api\StockConfigurationInterface');
+        }
+        return $this->stockConfiguration;
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/StockIndex.php b/app/code/Magento/CatalogInventory/Model/StockIndex.php
index a30bc203c638f251e167fa5f88eb6d9eaca6ef21..226293c8205e67acd32953463485713d64729128 100644
--- a/app/code/Magento/CatalogInventory/Model/StockIndex.php
+++ b/app/code/Magento/CatalogInventory/Model/StockIndex.php
@@ -78,6 +78,7 @@ class StockIndex implements StockIndexInterface
      *
      * @param int $productId
      * @param int $scopeId
+     * @deprecated
      * @return true
      * @SuppressWarnings(PHPMD.UnusedLocalVariable)
      */
@@ -108,6 +109,7 @@ class StockIndex implements StockIndexInterface
      *
      * @param int $productId
      * @param int $websiteId
+     * @deprecated
      * @return void
      */
     public function updateProductStockStatus($productId, $websiteId)
diff --git a/app/code/Magento/CatalogInventory/Model/StockState.php b/app/code/Magento/CatalogInventory/Model/StockState.php
index a5f60dce93ca7b45d3d4c4aa8783df95e72a7d80..0c8b84d473e45a47ab2ceaf69cf5089f5818a9b3 100644
--- a/app/code/Magento/CatalogInventory/Model/StockState.php
+++ b/app/code/Magento/CatalogInventory/Model/StockState.php
@@ -52,9 +52,9 @@ class StockState implements StockStateInterface
      */
     public function verifyStock($productId, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->verifyStock($stockItem);
     }
@@ -66,9 +66,9 @@ class StockState implements StockStateInterface
      */
     public function verifyNotification($productId, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->verifyNotification($stockItem);
     }
@@ -84,9 +84,9 @@ class StockState implements StockStateInterface
      */
     public function checkQty($productId, $qty, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->checkQty($stockItem, $qty);
     }
@@ -102,9 +102,9 @@ class StockState implements StockStateInterface
      */
     public function suggestQty($productId, $qty, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->suggestQty($stockItem, $qty);
     }
@@ -118,9 +118,9 @@ class StockState implements StockStateInterface
      */
     public function getStockQty($productId, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->getStockQty($stockItem);
     }
@@ -133,9 +133,9 @@ class StockState implements StockStateInterface
      */
     public function checkQtyIncrements($productId, $qty, $websiteId = null)
     {
-        if ($websiteId === null) {
+        // if ($websiteId === null) {
             $websiteId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $websiteId);
         return $this->stockStateProvider->checkQtyIncrements($stockItem, $qty);
     }
@@ -150,9 +150,9 @@ class StockState implements StockStateInterface
      */
     public function checkQuoteItemQty($productId, $itemQty, $qtyToCheck, $origQty, $scopeId = null)
     {
-        if ($scopeId === null) {
+        // if ($scopeId === null) {
             $scopeId = $this->stockConfiguration->getDefaultScopeId();
-        }
+        // }
         $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
         return $this->stockStateProvider->checkQuoteItemQty($stockItem, $itemQty, $qtyToCheck, $origQty);
     }
diff --git a/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php b/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php
index d700b296871aa2faf5fcc62a5ef3b6822c2cbe24..72c9b35394717deb7b22b24fa89236d5e559e1bd 100644
--- a/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php
+++ b/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php
@@ -17,6 +17,7 @@ class SaveInventoryDataObserver implements ObserverInterface
 {
     /**
      * @var StockIndexInterface
+     * @deprecated
      */
     protected $stockIndex;
 
@@ -96,14 +97,7 @@ class SaveInventoryDataObserver implements ObserverInterface
     public function execute(EventObserver $observer)
     {
         $product = $observer->getEvent()->getProduct();
-
         if ($product->getStockData() === null) {
-            if ($product->getIsChangedWebsites() || $product->dataHasChangedFor('status')) {
-                $this->stockIndex->rebuild(
-                    $product->getId(),
-                    $product->getStore()->getWebsiteId()
-                );
-            }
             return $this;
         }
 
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php
index 1f1c7a98f0907a6cea0b863477a6f57af1200f7d..df5ea40e933075bb07dd398ab3514e2cf18960d6 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php
@@ -37,6 +37,11 @@ class StockTest extends \PHPUnit_Framework_TestCase
      */
     protected $statusFactoryMock;
 
+    /**
+     * @var \Magento\CatalogInventory\Api\StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stockConfiguration;
+
     protected function setUp()
     {
         $this->stockRegistryProviderMock = $this->getMockBuilder(
@@ -55,12 +60,20 @@ class StockTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods(['create'])
             ->getMock();
+        $this->stockConfiguration = $this->getMockBuilder('Magento\CatalogInventory\Api\StockConfigurationInterface')
+            ->getMock();
         $this->stock = new Stock(
             $this->storeManagerMock,
             $this->scopeConfigMock,
             $this->statusFactoryMock,
             $this->stockRegistryProviderMock
         );
+
+        // Todo: \Magento\Framework\TestFramework\Unit\Helper\ObjectManager to do this automatically (MAGETWO-49793)
+        $reflection = new \ReflectionClass(get_class($this->stock));
+        $reflectionProperty = $reflection->getProperty('stockConfiguration');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->stock, $this->stockConfiguration);
     }
 
     public function testAssignStatusToProduct()
@@ -77,19 +90,12 @@ class StockTest extends \PHPUnit_Framework_TestCase
         $this->stockRegistryProviderMock->expects($this->any())
             ->method('getStockStatus')
             ->willReturn($stockStatusMock);
-        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $storeMock->expects($this->once())
-            ->method('getWebsiteId')
-            ->willReturn($websiteId);
+        $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn($websiteId);
+
         $productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
             ->disableOriginalConstructor()
-            ->setMethods(['setIsSalable', 'getStore', 'getId'])
+            ->setMethods(['setIsSalable', 'getId'])
             ->getMock();
-        $productMock->expects($this->any())
-            ->method('getStore')
-            ->willReturn($storeMock);
         $productMock->expects($this->once())
             ->method('setIsSalable')
             ->with($status);
@@ -134,12 +140,6 @@ class StockTest extends \PHPUnit_Framework_TestCase
         $productCollectionMock->expects($this->any())
             ->method('getIterator')
             ->willReturn($iteratorMock);
-        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->storeManagerMock->expects($this->once())
-            ->method('getStore')
-            ->willReturn($storeMock);
         $this->stockRegistryProviderMock->expects($this->once())
             ->method('getStockStatus')
             ->withAnyParameters()
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b180ba0e035173514ebb444bec4e2c4487567577
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Test\Unit\Model\Config\Backend;
+
+class ManagestockTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\CatalogInventory\Model\Indexer\Stock\Processor|\PHPUnit_Framework_MockObject_MockObject */
+    protected $stockIndexerProcessor;
+
+    /** @var \Magento\CatalogInventory\Model\Config\Backend\Managestock */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->stockIndexerProcessor = $this->getMockBuilder('Magento\CatalogInventory\Model\Indexer\Stock\Processor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
+            'Magento\CatalogInventory\Model\Config\Backend\Managestock',
+            [
+                'stockIndexerProcessor' => $this->stockIndexerProcessor,
+            ]
+        );
+    }
+
+    /**
+     * Data provider for testSaveAndRebuildIndex
+     * @return array
+     */
+    public function saveAndRebuildIndexDataProvider()
+    {
+        return [
+            [1, 1],
+            [0, 0],
+        ];
+    }
+
+    /**
+     * @dataProvider saveAndRebuildIndexDataProvider
+     *
+     * @param int $newStockValue new value for stock status
+     * @param int $callCount count matcher
+     */
+    public function testSaveAndRebuildIndex($newStockValue, $callCount)
+    {
+        $this->model->setValue($newStockValue);
+        $this->stockIndexerProcessor->expects($this->exactly($callCount))->method('markIndexerAsInvalid');
+        $this->model->afterSave();
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php
index 90b05b2d10649ce527debbea0f368d5e385f55bc..a0b2cc7225c9efe60c158b0e71946a22d5cb5512 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php
@@ -61,17 +61,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
 
     public function testGetDefaultWebsiteId()
     {
-        $id = 1;
-        $websiteMock = $this->getMockBuilder('Magento\Store\Model\Website')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $websiteMock->expects($this->once())
-            ->method('getId')
-            ->willReturn($id);
-        $this->storeManagerMock->expects($this->once())
-            ->method('getWebsite')
-            ->willReturn($websiteMock);
-        $this->assertEquals($id, $this->model->getDefaultScopeId());
+        $this->assertEquals(0, $this->model->getDefaultScopeId());
     }
 
     public function testGetIsQtyTypeIds()
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
index 534960b4397833d268c56ab62c9a45d46cc997f9..cb26fda9be79e928dac5585694e71778661bf0f6 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
@@ -154,11 +154,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
             ->method('getStockItem')
             ->willReturn(null);
 
-        $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store')
-            ->disableOriginalConstructor()->getMock();
-        $storeMock->expects($this->once())->method('getWebsiteId')->willReturn(1);
-        $this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
-
+        $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn(1);
         $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItem);
         $this->stockRegistry->expects($this->once())->method('updateStockItemBySku');
 
@@ -180,11 +176,10 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
     public function testAroundSave()
     {
         $productId = 5494;
-        $websiteId = 1;
         $storeId = 2;
         $sku = 'my product that needs saving';
         $defaultScopeId = 100;
-        $this->stockConfiguration->expects($this->once())
+        $this->stockConfiguration->expects($this->exactly(2))
             ->method('getDefaultScopeId')
             ->willReturn($defaultScopeId);
         $this->stockRegistry->expects($this->once())
@@ -209,17 +204,12 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase
             ->method('getStockItem')
             ->willReturn($storedStockItem);
 
-        $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store')
-            ->disableOriginalConstructor()->getMock();
-        $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);
-        $this->storeManager->expects($this->once())->method('getStore')->with($storeId)->willReturn($storeMock);
-
         $this->product->expects(($this->exactly(2)))->method('getId')->willReturn($productId);
         $this->product->expects(($this->atLeastOnce()))->method('getStoreId')->willReturn($storeId);
         $this->product->expects($this->atLeastOnce())->method('getSku')->willReturn($sku);
 
         $this->stockItem->expects($this->once())->method('setProductId')->with($productId);
-        $this->stockItem->expects($this->once())->method('setWebsiteId')->with($websiteId);
+        $this->stockItem->expects($this->once())->method('setWebsiteId')->with($defaultScopeId);
 
         $this->stockRegistry->expects($this->once())
             ->method('updateStockItemBySku')
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php
deleted file mode 100644
index 1b8347539485d11ff30b22ea3803201cf08004f2..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\CatalogInventory\Test\Unit\Observer;
-
-use Magento\CatalogInventory\Observer\SaveInventoryDataObserver;
-
-class SaveInventoryDataObserverTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var SaveInventoryDataObserver
-     */
-    protected $observer;
-
-    /**
-     * @var \Magento\CatalogInventory\Api\StockIndexInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $stockIndex;
-
-    /**
-     * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $event;
-
-    /**
-     * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $eventObserver;
-
-    protected function setUp()
-    {
-        $this->stockIndex = $this->getMockForAbstractClass(
-            'Magento\CatalogInventory\Api\StockIndexInterface',
-            ['rebuild'],
-            '',
-            false
-        );
-
-        $this->event = $this->getMockBuilder('Magento\Framework\Event')
-            ->disableOriginalConstructor()
-            ->setMethods(['getProduct'])
-            ->getMock();
-
-        $this->eventObserver = $this->getMockBuilder('Magento\Framework\Event\Observer')
-            ->disableOriginalConstructor()
-            ->setMethods(['getEvent'])
-            ->getMock();
-
-        $this->eventObserver->expects($this->atLeastOnce())
-            ->method('getEvent')
-            ->will($this->returnValue($this->event));
-
-        $this->observer = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
-            'Magento\CatalogInventory\Observer\SaveInventoryDataObserver',
-            [
-                'stockIndex' => $this->stockIndex,
-            ]
-        );
-    }
-
-    public function testSaveInventoryData()
-    {
-        $productId = 4;
-        $websiteId = 5;
-        $stockData = null;
-        $websitesChanged = true;
-        $statusChanged = true;
-
-        $store = $this->getMock('Magento\Store\Model\Store', ['getWebsiteId'], [], '', false);
-        $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId));
-
-        $product = $this->getMock(
-            'Magento\Catalog\Model\Product',
-            ['getStockData', 'getIsChangedWebsites', 'dataHasChangedFor', 'getId', 'getStore'],
-            [],
-            '',
-            false
-        );
-        $product->expects($this->once())->method('getStockData')->will($this->returnValue($stockData));
-        $product->expects($this->any())->method('getIsChangedWebsites')->will($this->returnValue($websitesChanged));
-        $product->expects($this->any())->method('dataHasChangedFor')->will($this->returnValue($statusChanged));
-        $product->expects($this->once())->method('getId')->will($this->returnValue($productId));
-        $product->expects($this->once())->method('getStore')->will($this->returnValue($store));
-
-        $this->stockIndex->expects($this->once())->method('rebuild')->will($this->returnValue(true));
-
-        $this->event->expects($this->once())
-            ->method('getProduct')
-            ->will($this->returnValue($product));
-
-        $this->observer->execute($this->eventObserver);
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
index 7571b3e9a9facba4bd8e45feee10dbe73df21676..73d1f23582ce537a3aaa62f25a467393ab76b464 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
@@ -7,7 +7,8 @@ namespace Magento\CatalogRule\Model\Indexer;
 
 use Magento\Framework\Mview\ActionInterface as MviewActionInterface;
 use Magento\Framework\Indexer\ActionInterface as IndexerActionInterface;
-use Magento\Framework\DataObject\IdentityInterface as IdentityInterface;
+use Magento\Framework\DataObject\IdentityInterface;
+use Magento\Framework\Indexer\CacheContext;
 
 abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInterface, IdentityInterface
 {
@@ -28,6 +29,11 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt
      */
     private $cacheManager;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext
+     */
+    protected $cacheContext;
+
     /**
      * @param IndexBuilder $indexBuilder
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
@@ -60,7 +66,7 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt
     {
         $this->indexBuilder->reindexFull();
         $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
-        //TODO: remove after fix fpc. MAGETWO-49121
+        //TODO: remove after fix fpc. MAGETWO-50668
         $this->getCacheManager()->clean($this->getIdentities());
     }
 
@@ -144,4 +150,19 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt
         }
         return $this->cacheManager;
     }
+
+    /**
+     * Get cache context
+     *
+     * @return \Magento\Framework\Indexer\CacheContext
+     * @deprecated
+     */
+    protected function getCacheContext()
+    {
+        if (!($this->cacheContext instanceof CacheContext)) {
+            return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class);
+        } else {
+            return $this->cacheContext;
+        }
+    }
 }
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php
index 08b35927226503fbc1b404500cc733a0a7d090b5..696f3c6ec803d0a69d68a9c840395abf2f2a3a34 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php
@@ -15,6 +15,7 @@ class ProductRuleIndexer extends AbstractIndexer
     protected function doExecuteList($ids)
     {
         $this->indexBuilder->reindexByIds(array_unique($ids));
+        $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
     }
 
     /**
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php
index 8d627bc80d313d1adfe27ca10f535b5a7c664e02..b5125501571e0817af278803845e37022efa633c 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php
@@ -17,6 +17,7 @@ class RuleProductIndexer extends AbstractIndexer
     protected function doExecuteList($ids)
     {
         $this->indexBuilder->reindexFull();
+        $this->getCacheContext()->registerTags($this->getIdentities());
     }
 
     /**
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php
index cd503d22c66f05e0dbb8b637ba26332051700379..c0d76d027f034b903cc4b26d982e5b48b21c9d1e 100644
--- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php
@@ -3,7 +3,6 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\CatalogRule\Test\Unit\Model\Indexer\Product;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -20,6 +19,11 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexer;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false);
@@ -30,7 +34,17 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase
                 'indexBuilder' => $this->indexBuilder,
             ]
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->indexer, $this->cacheContextMock);
     }
+
     /**
      * @param array $ids
      * @param array $idsForIndexer
@@ -38,8 +52,12 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase
      */
     public function testDoExecuteList($ids, $idsForIndexer)
     {
-        $this->indexBuilder->expects($this->once())->method('reindexByIds')->with($idsForIndexer);
-
+        $this->indexBuilder->expects($this->once())
+            ->method('reindexByIds')
+            ->with($idsForIndexer);
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerEntities')
+            ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids);
         $this->indexer->executeList($ids);
     }
 
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php
index 3af9eaff625d3f72813f4e330c52bac5aeb00da0..7522e34924284cd24d18c98e5850a4ff7844442c 100644
--- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php
@@ -20,6 +20,11 @@ class RuleProductIndexerTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexer;
 
+    /**
+     * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheContextMock;
+
     protected function setUp()
     {
         $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false);
@@ -30,13 +35,31 @@ class RuleProductIndexerTest extends \PHPUnit_Framework_TestCase
                 'indexBuilder' => $this->indexBuilder,
             ]
         );
+
+        $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false);
+
+        $cacheContextProperty = new \ReflectionProperty(
+            \Magento\CatalogRule\Model\Indexer\Rule\RuleProductIndexer::class,
+            'cacheContext'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($this->indexer, $this->cacheContextMock);
     }
 
     public function testDoExecuteList()
     {
+        $ids = [1, 2, 5];
         $this->indexBuilder->expects($this->once())->method('reindexFull');
-
-        $this->indexer->executeList([1, 2, 5]);
+        $this->cacheContextMock->expects($this->once())
+            ->method('registerTags')
+            ->with(
+                [
+                    \Magento\Catalog\Model\Category::CACHE_TAG,
+                    \Magento\Catalog\Model\Product::CACHE_TAG,
+                    \Magento\Framework\App\Cache\Type\Block::CACHE_TAG
+                ]
+            );
+        $this->indexer->executeList($ids);
     }
 
     public function testDoExecuteRow()
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 0dc343c88192b43e9f133ee589bfea81e247c018..9b75e6e6e0c325819d09f543cc445ae61eb7fb84 100644
--- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php
@@ -73,7 +73,7 @@ class DataProvider implements DataProviderInterface
         array $dimensions,
         Table $entityIdsTable
     ) {
-        $currentScope = $dimensions['scope']->getValue();
+        $currentScope = $this->scopeResolver->getScope($dimensions['scope']->getValue())->getId();
 
         $attribute = $this->eavConfig->getAttribute(Product::ENTITY, $bucket->getField());
 
diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
index 5161cc3e31a4d516108d8b46bb62c4f33abe1e5a..e6a6128cdc05866e912d6d0134fb439fbccd2b1a 100644
--- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
@@ -67,8 +67,7 @@ class DataProvider
         Table $entityIdsTable
     ) {
         if ($bucket->getField() == 'category_ids') {
-            $currentScope = $dimensions['scope']->getValue();
-            $currentScopeId = $this->scopeResolver->getScope($currentScope)->getId();
+            $currentScopeId = $this->scopeResolver->getScope($dimensions['scope']->getValue())->getId();
             $currentCategory = $this->layer->getCurrentCategory();
 
             $derivedTable = $this->resource->getConnection()->select();
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php
index 72b5b776750ec09afa2da08bf296bcd9a84f524b..26e4336f53d03f005003f1ae87d50d2728fae91a 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php
@@ -6,45 +6,58 @@
 
 namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin;
 
+use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct;
+use Magento\Framework\Model\AbstractModel;
+
 class Product extends AbstractPlugin
 {
     /**
      * Reindex on product save
      *
-     * @param \Magento\Catalog\Model\ResourceModel\Product $productResource
+     * @param ResourceProduct $productResource
      * @param \Closure $proceed
-     * @param \Magento\Framework\Model\AbstractModel $product
-     * @return \Magento\Catalog\Model\ResourceModel\Product
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @param AbstractModel $product
+     * @return ResourceProduct
      */
-    public function aroundSave(
-        \Magento\Catalog\Model\ResourceModel\Product $productResource,
-        \Closure $proceed,
-        \Magento\Framework\Model\AbstractModel $product
-    ) {
-        $productResource->addCommitCallback(function () use ($product) {
-            $this->reindexRow($product->getEntityId());
-        });
-        return $proceed($product);
+    public function aroundSave(ResourceProduct $productResource, \Closure $proceed, AbstractModel $product)
+    {
+        return $this->addCommitCallback($productResource, $proceed, $product);
     }
 
     /**
      * Reindex on product delete
      *
-     * @param \Magento\Catalog\Model\ResourceModel\Product $productResource
+     * @param ResourceProduct $productResource
      * @param \Closure $proceed
-     * @param \Magento\Framework\Model\AbstractModel $product
-     * @return \Magento\Catalog\Model\ResourceModel\Product
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @param AbstractModel $product
+     * @return ResourceProduct
      */
-    public function aroundDelete(
-        \Magento\Catalog\Model\ResourceModel\Product $productResource,
-        \Closure $proceed,
-        \Magento\Framework\Model\AbstractModel $product
-    ) {
-        $productResource->addCommitCallback(function () use ($product) {
-            $this->reindexRow($product->getEntityId());
-        });
-        return $proceed($product);
+    public function aroundDelete(ResourceProduct $productResource, \Closure $proceed, AbstractModel $product)
+    {
+        return $this->addCommitCallback($productResource, $proceed, $product);
+    }
+
+    /**
+     * @param ResourceProduct $productResource
+     * @param \Closure $proceed
+     * @param AbstractModel $product
+     * @return ResourceProduct
+     * @throws \Exception
+     */
+    private function addCommitCallback(ResourceProduct $productResource, \Closure $proceed, AbstractModel $product)
+    {
+        try {
+            $productResource->beginTransaction();
+            $result = $proceed($product);
+            $productResource->addCommitCallback(function () use ($product) {
+                $this->reindexRow($product->getEntityId());
+            });
+            $productResource->commit();
+        } catch (\Exception $e) {
+            $productResource->rollBack();
+            throw $e;
+        }
+
+        return $result;
     }
 }
diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
index 5bec5552e091376ce22351302c615d6acaa7c2fc..31ce6d550b116455052cf674e99155db3e3f7af2 100644
--- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
+++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php
@@ -6,20 +6,19 @@
 
 namespace Magento\CatalogSearch\Model\Search;
 
-use Magento\CatalogSearch\Model\Search\TableMapper;
 use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\DB\Select;
 use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
 use Magento\Framework\Search\Adapter\Mysql\IndexBuilderInterface;
 use Magento\Framework\Search\Request\Dimension;
-use Magento\Framework\Search\Request\Filter\BoolExpression;
-use Magento\Framework\Search\Request\FilterInterface;
-use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
 use Magento\Framework\Search\RequestInterface;
 use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
 use Magento\Store\Model\ScopeInterface;
 use Magento\Store\Model\StoreManagerInterface;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\CatalogInventory\Model\Stock;
+use Magento\Framework\App\ScopeResolverInterface;
 
 /**
  * Build base Query for Index
@@ -39,6 +38,7 @@ class IndexBuilder implements IndexBuilderInterface
 
     /**
      * @var StoreManagerInterface
+     * @deprecated
      */
     private $storeManager;
 
@@ -57,6 +57,16 @@ class IndexBuilder implements IndexBuilderInterface
      */
     private $tableMapper;
 
+    /**
+     * @var ScopeResolverInterface
+     */
+    private $dimensionScopeResolver;
+
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
     /**
      * @param \Magento\Framework\App\ResourceConnection $resource
      * @param ScopeConfigInterface $config
@@ -64,6 +74,7 @@ class IndexBuilder implements IndexBuilderInterface
      * @param ConditionManager $conditionManager
      * @param IndexScopeResolver $scopeResolver
      * @param TableMapper $tableMapper
+     * @param ScopeResolverInterface $dimensionScopeResolver
      */
     public function __construct(
         ResourceConnection $resource,
@@ -71,7 +82,8 @@ class IndexBuilder implements IndexBuilderInterface
         StoreManagerInterface $storeManager,
         ConditionManager $conditionManager,
         IndexScopeResolver $scopeResolver,
-        TableMapper $tableMapper
+        TableMapper $tableMapper,
+        ScopeResolverInterface $dimensionScopeResolver
     ) {
         $this->resource = $resource;
         $this->config = $config;
@@ -79,6 +91,7 @@ class IndexBuilder implements IndexBuilderInterface
         $this->conditionManager = $conditionManager;
         $this->scopeResolver = $scopeResolver;
         $this->tableMapper = $tableMapper;
+        $this->dimensionScopeResolver = $dimensionScopeResolver;
     }
 
     /**
@@ -115,16 +128,30 @@ class IndexBuilder implements IndexBuilderInterface
                 'search_index.entity_id = stock_index.product_id'
                 . $this->resource->getConnection()->quoteInto(
                     ' AND stock_index.website_id = ?',
-                    $this->storeManager->getWebsite()->getId()
+                    $this->getStockConfiguration()->getDefaultScopeId()
                 ),
                 []
             );
-            $select->where('stock_index.stock_status = ?', 1);
+            $select->where('stock_index.stock_status = ?', Stock::DEFAULT_STOCK_ID);
         }
 
         return $select;
     }
 
+    /**
+     * @return StockConfigurationInterface
+     *
+     * @deprecated
+     */
+    private function getStockConfiguration()
+    {
+        if ($this->stockConfiguration === null) {
+            $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get('Magento\CatalogInventory\Api\StockConfigurationInterface');
+        }
+        return $this->stockConfiguration;
+    }
+
     /**
      * Add filtering by dimensions
      *
@@ -158,7 +185,7 @@ class IndexBuilder implements IndexBuilderInterface
             $preparedDimensions[] = $this->conditionManager->generateCondition(
                 $dimension->getName(),
                 '=',
-                $dimension->getValue()
+                $this->dimensionScopeResolver->getScope($dimension->getValue())->getId()
             );
         }
 
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/ProductTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/ProductTest.php
index c6666a5a2e22e0a039bf33168550643fc81dc933..649b332fbf80309631444b4be5ba741082053289 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/ProductTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/ProductTest.php
@@ -6,22 +6,28 @@
 
 namespace Magento\CatalogSearch\Test\Unit\Model\Indexer\Fulltext\Plugin;
 
+use Magento\Catalog\Model\Product as ProductModel;
+use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel;
 use \Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin\Product;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\Indexer\IndexerInterface;
+use Magento\Framework\Indexer\IndexerRegistry;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class ProductTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Indexer\IndexerInterface
+     * @var \PHPUnit_Framework_MockObject_MockObject|IndexerInterface
      */
     protected $indexerMock;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\ResourceModel\Product
+     * @var \PHPUnit_Framework_MockObject_MockObject|ProductResourceModel
      */
     protected $subjectMock;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product
+     * @var \PHPUnit_Framework_MockObject_MockObject|ProductModel
      */
     protected $productMock;
 
@@ -31,7 +37,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     protected $proceed;
 
     /**
-     * @var \Magento\Framework\Indexer\IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject
+     * @var IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $indexerRegistryMock;
 
@@ -42,30 +48,34 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
-        $this->subjectMock = $this->getMock('Magento\Catalog\Model\ResourceModel\Product', [], [], '', false);
-        $this->indexerMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Indexer\IndexerInterface',
-            [],
-            '',
-            false,
-            false,
-            true,
-            ['getId', 'getState', '__wakeup']
-        );
-        $this->indexerRegistryMock = $this->getMock(
-            'Magento\Framework\Indexer\IndexerRegistry',
-            ['get'],
-            [],
-            '',
-            false
-        );
+        $this->productMock = $this->getMockBuilder(ProductModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->subjectMock = $this->getMockBuilder(ProductResourceModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $connection = $this->getMockBuilder(AdapterInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->subjectMock->method('getConnection')->willReturn($connection);
+
+        $this->indexerMock = $this->getMockBuilder(IndexerInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getState', '__wakeup'])
+            ->getMockForAbstractClass();
+        $this->indexerRegistryMock = $this->getMockBuilder(IndexerRegistry::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['get'])
+            ->getMock();
 
         $this->proceed = function () {
             return $this->subjectMock;
         };
 
-        $this->model = new Product($this->indexerRegistryMock);
+        $this->model = (new ObjectManager($this))->getObject(
+            Product::class,
+            ['indexerRegistry' => $this->indexerRegistryMock]
+        );
     }
 
     public function testAfterSaveNonScheduled()
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php
index 21e466383f9f1030b03da311019c4a6a153ff2e1..32176594936b2d996b1e14c758cf0671c76a73f5 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php
@@ -6,46 +6,62 @@
 
 namespace Magento\CatalogSearch\Test\Unit\Model\Search;
 
-use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
-use PHPUnit_Framework_MockObject_MockObject as MockObject;
-
 /**
  * Test for \Magento\CatalogSearch\Model\Search\IndexBuilder
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class IndexBuilderTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var  \Magento\CatalogSearch\Model\Search\TableMapper|MockObject */
+    /** @var  \Magento\CatalogSearch\Model\Search\TableMapper|\PHPUnit_Framework_MockObject_MockObject */
     private $tableMapper;
 
-    /** @var  \Magento\Framework\Search\Adapter\Mysql\ConditionManager|MockObject */
+    /** @var  \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject */
     private $conditionManager;
 
-    /** @var  \Magento\Search\Model\IndexScopeResolver|MockObject */
+    /** @var  \Magento\Search\Model\IndexScopeResolver|\PHPUnit_Framework_MockObject_MockObject */
     private $scopeResolver;
 
-    /** @var \Magento\Framework\DB\Adapter\AdapterInterface|MockObject */
+    /** @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $connection;
 
-    /** @var \Magento\Framework\DB\Select|MockObject */
+    /** @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject */
     private $select;
 
-    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|MockObject */
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $config;
 
-    /** @var \Magento\Store\Model\StoreManagerInterface|MockObject */
+    /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $storeManager;
 
-    /** @var \Magento\Framework\Search\RequestInterface|MockObject */
+    /** @var \Magento\Framework\Search\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $request;
 
-    /** @var \Magento\Search\Model\IndexScopeResolver|MockObject */
+    /** @var \Magento\Search\Model\IndexScopeResolver|\PHPUnit_Framework_MockObject_MockObject */
     private $resource;
 
+    /** @var \Magento\CatalogInventory\Api\StockConfigurationInterface|MockObject */
+    private $stockConfiguration;
+
     /**
      * @var \Magento\CatalogSearch\Model\Search\IndexBuilder
      */
     private $target;
 
+    /**
+     * @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dimensionScopeResolver;
+
+    /**
+     * @var \Magento\Framework\App\ScopeInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $scopeInterface;
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     * @return void
+     */
     protected function setUp()
     {
         $this->select = $this->getMockBuilder('\Magento\Framework\DB\Select')
@@ -118,8 +134,23 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
             ->method('addTables')
             ->with($this->select, $this->request)
             ->willReturnArgument(0);
+        $this->dimensionScopeResolver = $this->getMockForAbstractClass(
+            '\Magento\Framework\App\ScopeResolverInterface',
+            [],
+            '',
+            false
+        );
+        $this->scopeInterface = $this->getMockForAbstractClass(
+            '\Magento\Framework\App\ScopeInterface',
+            [],
+            '',
+            false
+        );
+        $this->stockConfiguration = $this
+            ->getMockBuilder('\Magento\CatalogInventory\Api\StockConfigurationInterface')
+            ->getMock();
 
-        $objectManagerHelper = new ObjectManagerHelper($this);
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->target = $objectManagerHelper->getObject(
             'Magento\CatalogSearch\Model\Search\IndexBuilder',
             [
@@ -129,8 +160,15 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
                 'conditionManager' => $this->conditionManager,
                 'scopeResolver' => $this->scopeResolver,
                 'tableMapper' => $this->tableMapper,
+                'dimensionScopeResolver' => $this->dimensionScopeResolver
             ]
         );
+
+        // Todo: \Magento\Framework\TestFramework\Unit\Helper\ObjectManager to do this automatically (MAGETWO-49793)
+        $reflection = new \ReflectionClass(get_class($this->target));
+        $reflectionProperty = $reflection->getProperty('stockConfiguration');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->target, $this->stockConfiguration);
     }
 
     public function testBuildWithOutOfStock()
@@ -167,18 +205,22 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->exactly(2))
             ->method('getDimensions')
             ->willReturn($dimensions);
+        $this->dimensionScopeResolver->expects($this->once())
+            ->method('getScope')
+            ->willReturn($this->scopeInterface);
+        $this->scopeInterface->expects($this->once())
+            ->method('getId')
+            ->willReturn('someValue');
 
         $this->mockBuild($index, $tableSuffix, false);
 
+        $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn(1);
         $this->config->expects($this->once())
             ->method('isSetFlag')
             ->with('cataloginventory/options/show_out_of_stock')
             ->will($this->returnValue(false));
         $this->connection->expects($this->once())->method('quoteInto')
             ->with(' AND stock_index.website_id = ?', 1)->willReturn(' AND stock_index.website_id = 1');
-        $website = $this->getMockBuilder('Magento\Store\Model\Website')->disableOriginalConstructor()->getMock();
-        $website->expects($this->once())->method('getId')->willReturn(1);
-        $this->storeManager->expects($this->once())->method('getWebsite')->willReturn($website);
         $this->select->expects($this->at(2))
             ->method('where')
             ->with('(someName=someValue)')
@@ -270,7 +312,7 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
     /**
      * @param $name
      * @param $value
-     * @return MockObject
+     * @return \PHPUnit_Framework_MockObject_MockObject
      */
     private function createDimension($name, $value)
     {
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 709009300b724a41dbca6c80773684af9c15e91e..860d5080b9bdffd0282c5b989c8373b886d498af 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -11,6 +11,7 @@
         "magento/module-eav": "100.0.*",
         "magento/module-backend": "100.0.*",
         "magento/module-theme": "100.0.*",
+        "magento/module-catalog-inventory": "100.0.*",
         "magento/framework": "100.0.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml
deleted file mode 100644
index e880a73ed296d5edc907b483235aa254f4ac628e..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?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="catalog_product_save_after">
-        <observer name="process_url_rewrite_saving" instance="\Magento\CatalogUrlRewrite\Observer\ProductProcessUrlRewriteSavingObserver"/>
-    </event>
-</config>
diff --git a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php
index 386e77580fa4abab025f3119b056f08b2be88084..6f2cd40e97f7ad19fb5cd217881403a11a594268 100644
--- a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php
+++ b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php
@@ -71,7 +71,9 @@ class Combine extends \Magento\Rule\Model\Condition\Combine
      */
     public function collectValidatedAttributes($productCollection)
     {
+        $alias = array_keys($productCollection->getSelect()->getPart('from'))[0];
         foreach ($this->getConditions() as $condition) {
+            $condition->setData('attribute', $alias . '.' . $condition->getData('attribute'));
             $condition->addToCollection($productCollection);
         }
         return $this;
diff --git a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php
index 34c14626d8bf7423d435c62e952c663a8b52f9ae..b0a3fdab8eb32c6c97ef798a94390f7a942f04a2 100644
--- a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php
+++ b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php
@@ -73,8 +73,13 @@ class CombineTest extends \PHPUnit_Framework_TestCase
     public function testCollectValidatedAttributes()
     {
         $collection = $this->getMockBuilder('\Magento\Catalog\Model\ResourceModel\Product\Collection')
-            ->disableOriginalConstructor()
+            ->disableOriginalConstructor()->setMethods(['getSelect'])
+            ->getMock();
+        $select = $this->getMockBuilder('\Magento\Framework\DB\Select')
+            ->disableOriginalConstructor()->setMethods(['getPart'])
             ->getMock();
+        $select->expects($this->any())->method('getPart')->with('from')->willReturn(['alias_table' => 'table_name']);
+        $collection->expects($this->any())->method('getSelect')->willReturn($select);
         $condition = $this->getMockBuilder('Magento\CatalogWidget\Model\Rule\Condition\Combine')
             ->disableOriginalConstructor()->setMethods(['addToCollection'])
             ->getMock();
diff --git a/app/code/Magento/Checkout/Block/Shipping/Price.php b/app/code/Magento/Checkout/Block/Shipping/Price.php
index 07cbe74ab9482507f13f427c56c6bd5e1d466950..8bba359ec316b3f68444d8e3d71e57c34b179e54 100644
--- a/app/code/Magento/Checkout/Block/Shipping/Price.php
+++ b/app/code/Magento/Checkout/Block/Shipping/Price.php
@@ -9,6 +9,10 @@ use Magento\Checkout\Block\Cart\AbstractCart;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 use Magento\Quote\Model\Quote\Address\Rate;
 
+/**
+ * Class Price
+ * @deprecated
+ */
 class Price extends AbstractCart
 {
     /**
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
index f4b924dee078e95642346000baf2a364b4e79e93..8e5392d5c6a2475f68ddcb2d5723cdfc72a7f347 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
@@ -7,7 +7,6 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <update handle="checkout_cart_item_renderers"/>
-    <update handle="checkout_shipping_price_renderer"/>
     <body>
         <referenceContainer name="page.messages">
             <block class="Magento\Checkout\Block\Cart\ValidationMessages" name="checkout.cart.validationmessages"/>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_sidebar_total_renderers.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_sidebar_total_renderers.xml
index 0da9a686ee7d8fbdb2983b74df66b0128a1eeb15..60e88c5a4ac1b34a0aeb7eebf9cb131feb5bfba1 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_sidebar_total_renderers.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_sidebar_total_renderers.xml
@@ -18,7 +18,7 @@
                                         <item name="subtotal" xsi:type="array">
                                             <item name="children" xsi:type="array">
                                                 <item name="subtotal.totals" xsi:type="array">
-                                                    <item name="component" xsi:type="string">uiComponent</item>
+                                                    <item name="component" xsi:type="string">Magento_Checkout/js/view/checkout/minicart/subtotal/totals</item>
                                                     <item name="config" xsi:type="array">
                                                         <item name="template" xsi:type="string">Magento_Checkout/minicart/subtotal/totals</item>
                                                     </item>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_shipping_price_renderer.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_shipping_price_renderer.xml
deleted file mode 100644
index 41a9ab6be8b0af068bba69ca3edae16056eca35a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_shipping_price_renderer.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
-    <referenceContainer name="root">
-        <block class="Magento\Checkout\Block\Shipping\Price" name="checkout.shipping.price" as="shipping.price" template="shipping/price.phtml"/>
-    </referenceContainer>
-</layout>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
index d1bf7e1d0830db69f00d21aa521c6a9855443074..3ee5bd0679827ce5562bc07c4c684c58ffcb1573 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
@@ -107,8 +107,9 @@ define(
              */
             objectToArray: function (object) {
                 var convertedArray = [];
+
                 $.each(object, function (key) {
-                    return object[key].length ? convertedArray.push(object[key]) : false;
+                    return typeof object[key] === 'string' ? convertedArray.push(object[key]) : false;
                 });
 
                 return convertedArray.slice(0);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/checkout/minicart/subtotal/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/view/checkout/minicart/subtotal/totals.js
new file mode 100644
index 0000000000000000000000000000000000000000..6ca3f6f9f2c14e87059485d156f78a4da6d19ec3
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/checkout/minicart/subtotal/totals.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'uiComponent',
+    'Magento_Customer/js/customer-data'
+], function (ko, Component, customerData) {
+    'use strict';
+
+    return Component.extend({
+        displaySubtotal: ko.observable(true),
+
+        /**
+         * @override
+         */
+        initialize: function () {
+            this._super();
+            this.cart = customerData.get('cart');
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html
index ff04b6d1375f826a8c0ae895f574bb43a258f163..baca55151c18a01a808d5fe02d9904c289002fe1 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html
@@ -5,5 +5,5 @@
  */
 -->
 <div class="amount">
-    <span data-bind="html: getCartParam('subtotal')"></span>
+    <span data-bind="html: cart().subtotal"></span>
 </div>
diff --git a/app/code/Magento/Cms/Model/Page/DataProvider.php b/app/code/Magento/Cms/Model/Page/DataProvider.php
index ba5eab8dddccdb6f42445df250a7dcf50dea2479..fb9a54be74457519f80832db9a578bc9264c64f7 100644
--- a/app/code/Magento/Cms/Model/Page/DataProvider.php
+++ b/app/code/Magento/Cms/Model/Page/DataProvider.php
@@ -61,11 +61,10 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
         if (isset($this->loadedData)) {
             return $this->loadedData;
         }
-        foreach ($this->collection->getAllIds() as $pageId) {
-            /** @var \Magento\Cms\Model\Page $page */
-            $page = $this->collection->getNewEmptyItem();
-            /** Load every record separately to make sure the list of associated stores is available */
-            $this->loadedData[$pageId] = $page->load($pageId)->getData();
+        $items = $this->collection->getItems();
+        /** @var $page \Magento\Cms\Model\Page */
+        foreach ($items as $page) {
+            $this->loadedData[$page->getId()] = $page->getData();
         }
 
         $data = $this->dataPersistor->get('cms_page');
diff --git a/app/code/Magento/Cms/Model/ResourceModel/AbstractCollection.php b/app/code/Magento/Cms/Model/ResourceModel/AbstractCollection.php
index 0715dc541820aa0e8a76f5bc1a4c7a269eb5d401..86c2a9984405ebd4fd0370a35f6302aaaa87959b 100644
--- a/app/code/Magento/Cms/Model/ResourceModel/AbstractCollection.php
+++ b/app/code/Magento/Cms/Model/ResourceModel/AbstractCollection.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Cms\Model\ResourceModel;
 
+use Magento\Store\Model\Store;
+
 /**
  * Abstract collection of CMS pages and blocks
  */
@@ -61,24 +63,30 @@ abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel
             $connection = $this->getConnection();
             $select = $connection->select()->from(['cms_entity_store' => $this->getTable($tableName)])
                 ->where('cms_entity_store.' . $linkField . ' IN (?)', $linkedIds);
-            $result = $connection->fetchPairs($select);
+            $result = $connection->fetchAll($select);
             if ($result) {
+                $storesData = [];
+                foreach ($result as $storeData) {
+                    $storesData[$storeData[$linkField]][] = $storeData['store_id'];
+                }
+
                 foreach ($this as $item) {
                     $linkedId = $item->getData($linkField);
-                    if (!isset($result[$linkedId])) {
+                    if (!isset($storesData[$linkedId])) {
                         continue;
                     }
-                    if ($result[$linkedId] == 0) {
+                    $storeIdKey = array_search(Store::DEFAULT_STORE_ID, $storesData[$linkedId], true);
+                    if ($storeIdKey !== false) {
                         $stores = $this->storeManager->getStores(false, true);
                         $storeId = current($stores)->getId();
                         $storeCode = key($stores);
                     } else {
-                        $storeId = $result[$linkedId];
+                        $storeId = current($storesData[$linkedId]);
                         $storeCode = $this->storeManager->getStore($storeId)->getCode();
                     }
                     $item->setData('_first_store_id', $storeId);
                     $item->setData('store_code', $storeCode);
-                    $item->setData('store_id', [$result[$linkedId]]);
+                    $item->setData('store_id', $storesData[$linkedId]);
                 }
             }
         }
@@ -103,7 +111,7 @@ abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel
     /**
      * Add filter by store
      *
-     * @param int|array|\Magento\Store\Model\Store $store
+     * @param int|array|Store $store
      * @param bool $withAdmin
      * @return $this
      */
@@ -112,13 +120,13 @@ abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel
     /**
      * Perform adding filter by store
      *
-     * @param int|array|\Magento\Store\Model\Store $store
+     * @param int|array|Store $store
      * @param bool $withAdmin
      * @return void
      */
     protected function performAddStoreFilter($store, $withAdmin = true)
     {
-        if ($store instanceof \Magento\Store\Model\Store) {
+        if ($store instanceof Store) {
             $store = [$store->getId()];
         }
 
@@ -127,7 +135,7 @@ abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel
         }
 
         if ($withAdmin) {
-            $store[] = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
+            $store[] = Store::DEFAULT_STORE_ID;
         }
 
         $this->addFilter('store', ['in' => $store], 'public');
diff --git a/app/code/Magento/Cms/Model/ResourceModel/Page/Grid/Collection.php b/app/code/Magento/Cms/Model/ResourceModel/Page/Grid/Collection.php
index d9c71585911dbd2728a9a344b06c9e32c693a14f..8e7765b304c8baad11b4616e0d3b050837da7a1f 100644
--- a/app/code/Magento/Cms/Model/ResourceModel/Page/Grid/Collection.php
+++ b/app/code/Magento/Cms/Model/ResourceModel/Page/Grid/Collection.php
@@ -20,11 +20,6 @@ class Collection extends PageCollection implements SearchResultInterface
      */
     protected $aggregations;
 
-    /**
-     * @var \Magento\Framework\View\Element\UiComponent\DataProvider\Document[]
-     */
-    private $loadedData;
-
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
@@ -145,25 +140,4 @@ class Collection extends PageCollection implements SearchResultInterface
     {
         return $this;
     }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getItems()
-    {
-        if (isset($this->loadedData)) {
-            return $this->loadedData;
-        }
-        /** @var \Magento\Cms\Model\Page $page */
-        $page = $this->_entityFactory->create(\Magento\Cms\Model\Page::class);
-        /** Load every record separately to make sure the list of associated stores is available */
-        /** @var \Magento\Framework\View\Element\UiComponent\DataProvider\Document $pageDocument */
-        foreach (parent::getItems() as $pageDocument) {
-            $this->loadedData[$pageDocument->getId()] = $pageDocument->setData(
-                $page->load($pageDocument->getId())->getData()
-            );
-        }
-
-        return $this->loadedData;
-    }
 }
diff --git a/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Block/CollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Block/CollectionTest.php
index c637747b78459d4138d37e785680ccecbb5f4565..fd62f62a72159e3fc2f7c3a32da35b985cbbdb35 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Block/CollectionTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Block/CollectionTest.php
@@ -15,15 +15,34 @@ class CollectionTest extends AbstractCollectionTest
      */
     protected $collection;
 
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Framework\Model\Entity\MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataPoolMock;
+
     protected function setUp()
     {
         parent::setUp();
 
+        $this->storeManagerMock  = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->getMockForAbstractClass();
+
+        $this->metadataPoolMock  = $this->getMockBuilder('Magento\Framework\Model\Entity\MetadataPool')
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->collection = $this->objectManager->getObject(
             'Magento\Cms\Model\ResourceModel\Block\Collection',
             [
                 'resource' => $this->resource,
-                'connection' => $this->connection
+                'connection' => $this->connection,
+                'storeManager' => $this->storeManagerMock,
+                'metadataPool' => $this->metadataPoolMock,
             ]
         );
     }
@@ -60,4 +79,60 @@ class CollectionTest extends AbstractCollectionTest
 
         $this->assertSame($this->collection, $this->collection->addFieldToFilter($field, $value));
     }
+
+    /**
+     * @param \Magento\Framework\DataObject $item
+     * @param array $storesData
+     * @dataProvider getItemsDataProvider
+     * @throws \Exception
+     */
+    public function testAfterLoad($item, $storesData)
+    {
+        $linkField = 'row_id';
+
+        $expectedResult = [];
+        foreach ($storesData as $storeData) {
+            $expectedResult[$storeData[$linkField]][] = $storeData['store_id'];
+        }
+
+        $entityMetadataMock = $this->getMockBuilder('Magento\Framework\Model\Entity\EntityMetadata')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $entityMetadataMock->expects($this->any())->method('getLinkField')->willReturn($linkField);
+        $this->metadataPoolMock->expects($this->any())->method('getMetadata')->willReturn($entityMetadataMock);
+
+        $this->select->expects($this->any())->method('from')->willReturnSelf();
+        $this->connection->expects($this->any())->method('fetchAll')->willReturn($storesData);
+
+        $storeDataMock = $this->getMockBuilder('Magento\Store\Api\Data\StoreInterface')->getMockForAbstractClass();
+        $storeDataMock->expects($this->any())->method('getId')->willReturn(current($expectedResult[$item->getId()]));
+        $storeDataMock->expects($this->any())->method('getCode')->willReturn('some_code');
+        $this->storeManagerMock->expects($this->any())->method('getStores')->willReturn([$storeDataMock]);
+        $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeDataMock);
+
+        $this->collection->addItem($item);
+
+        $this->assertEmpty($item->getStoreId());
+        $this->collection->load();
+        $this->assertEquals($expectedResult[$item->getId()], $item->getStoreId());
+    }
+
+    public function getItemsDataProvider()
+    {
+        return [
+            [
+                new \Magento\Framework\DataObject(['id' => 1, 'row_id' => 1]),
+                [
+                    ['row_id' => 1, 'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID],
+                ],
+            ],
+            [
+                new \Magento\Framework\DataObject(['id' => 2, 'row_id' => 2]),
+                [
+                    ['row_id' => 2, 'store_id' => 1],
+                    ['row_id' => 2, 'store_id' => 2],
+                ],
+            ],
+        ];
+    }
 }
diff --git a/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/CollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/CollectionTest.php
index 8ded27a352df708c6804e5701fc69a95ead2fab0..916e1f96c844778c83dd5a75f3b1a68fd4aa35f6 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/CollectionTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/CollectionTest.php
@@ -15,15 +15,34 @@ class CollectionTest extends AbstractCollectionTest
      */
     protected $collection;
 
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Framework\Model\Entity\MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataPoolMock;
+
     protected function setUp()
     {
         parent::setUp();
 
+        $this->storeManagerMock  = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->getMockForAbstractClass();
+
+        $this->metadataPoolMock  = $this->getMockBuilder('Magento\Framework\Model\Entity\MetadataPool')
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->collection = $this->objectManager->getObject(
             'Magento\Cms\Model\ResourceModel\Page\Collection',
             [
                 'resource' => $this->resource,
-                'connection' => $this->connection
+                'connection' => $this->connection,
+                'storeManager' => $this->storeManagerMock,
+                'metadataPool' => $this->metadataPoolMock,
             ]
         );
     }
@@ -60,4 +79,60 @@ class CollectionTest extends AbstractCollectionTest
 
         $this->assertSame($this->collection, $this->collection->addFieldToFilter($field, $value));
     }
+
+    /**
+     * @param \Magento\Framework\DataObject $item
+     * @param array $storesData
+     * @dataProvider getItemsDataProvider
+     * @throws \Exception
+     */
+    public function testAfterLoad($item, $storesData)
+    {
+        $linkField = 'row_id';
+
+        $expectedResult = [];
+        foreach ($storesData as $storeData) {
+            $expectedResult[$storeData[$linkField]][] = $storeData['store_id'];
+        }
+
+        $entityMetadataMock = $this->getMockBuilder('Magento\Framework\Model\Entity\EntityMetadata')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $entityMetadataMock->expects($this->any())->method('getLinkField')->willReturn($linkField);
+        $this->metadataPoolMock->expects($this->any())->method('getMetadata')->willReturn($entityMetadataMock);
+
+        $this->select->expects($this->any())->method('from')->willReturnSelf();
+        $this->connection->expects($this->any())->method('fetchAll')->willReturn($storesData);
+
+        $storeDataMock = $this->getMockBuilder('Magento\Store\Api\Data\StoreInterface')->getMockForAbstractClass();
+        $storeDataMock->expects($this->any())->method('getId')->willReturn(current($expectedResult[$item->getId()]));
+        $storeDataMock->expects($this->any())->method('getCode')->willReturn('some_code');
+        $this->storeManagerMock->expects($this->any())->method('getStores')->willReturn([$storeDataMock]);
+        $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeDataMock);
+
+        $this->collection->addItem($item);
+
+        $this->assertEmpty($item->getStoreId());
+        $this->collection->load();
+        $this->assertEquals($expectedResult[$item->getId()], $item->getStoreId());
+    }
+
+    public function getItemsDataProvider()
+    {
+        return [
+            [
+                new \Magento\Framework\DataObject(['id' => 1, 'row_id' => 1]),
+                [
+                    ['row_id' => 1, 'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID],
+                ],
+            ],
+            [
+                new \Magento\Framework\DataObject(['id' => 2, 'row_id' => 2]),
+                [
+                    ['row_id' => 2, 'store_id' => 1],
+                    ['row_id' => 2, 'store_id' => 2],
+                ],
+            ],
+        ];
+    }
 }
diff --git a/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/Grid/CollectionTest.php b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/Grid/CollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..408c9c662b863e6440bd64d9ece1d8581239c601
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Unit/Model/ResourceModel/Page/Grid/CollectionTest.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Test\Unit\Model\ResourceModel\Page\Grid;
+
+use Magento\Cms\Model\ResourceModel\Page\Grid\Collection;
+use Magento\Framework\Api\Search\AggregationInterface;
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
+use Magento\Framework\Data\Collection\EntityFactoryInterface;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\Event\ManagerInterface;
+use Magento\Framework\Model\Entity\MetadataPool;
+use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Store\Model\StoreManagerInterface;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\DB\Select;
+
+/**
+ * Class CollectionTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var EntityFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityFactoryMock;
+
+    /**
+     * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loggerMock;
+
+    /**
+     * @var FetchStrategyInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $fetchStrategyMock;
+
+    /**
+     * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
+    /**
+     * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataPoolMock;
+
+    /**
+     * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $connectionMock;
+
+    /**
+     * @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resourceMock;
+
+    /**
+     * @var AggregationInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $aggregationsMock;
+
+    /**
+     * @var Select
+     */
+    protected $selectMock;
+
+    /**
+     * @var Collection
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->entityFactoryMock = $this->getMockBuilder(EntityFactoryInterface::class)
+            ->getMockForAbstractClass();
+        $this->loggerMock = $this->getMockBuilder(LoggerInterface::class)
+            ->getMockForAbstractClass();
+        $this->fetchStrategyMock = $this->getMockBuilder(FetchStrategyInterface::class)
+            ->getMockForAbstractClass();
+        $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class)
+            ->getMockForAbstractClass();
+        $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
+            ->getMockForAbstractClass();
+        $this->metadataPoolMock = $this->getMockBuilder(MetadataPool::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock = $this->getMockBuilder(AbstractDb::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->aggregationsMock = $this->getMockBuilder(AggregationInterface::class)
+            ->getMockForAbstractClass();
+        $this->connectionMock = $this->getMockBuilder(AdapterInterface::class)
+            ->getMockForAbstractClass();
+        $this->selectMock = $this->getMockBuilder(Select::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->resourceMock->expects($this->any())
+            ->method('getConnection')
+            ->willReturn($this->connectionMock);
+        $this->connectionMock->expects($this->once())
+            ->method('select')
+            ->willReturn($this->selectMock);
+
+        $this->model = (new ObjectManager($this))->getObject(Collection::class, [
+            'entityFactory' => $this->entityFactoryMock,
+            'logger' => $this->loggerMock,
+            'fetchStrategy' => $this->fetchStrategyMock,
+            'eventManager' => $this->eventManagerMock,
+            'storeManager' => $this->storeManagerMock,
+            'metadataPool' => $this->metadataPoolMock,
+            'mainTable' => null,
+            'eventPrefix' => 'test_event_prefix',
+            'eventObject' => 'test_event_object',
+            'resourceModel' => null,
+            'resource' => $this->resourceMock,
+        ]);
+    }
+
+    public function testSetterGetter()
+    {
+        $this->model->setAggregations($this->aggregationsMock);
+        $this->assertInstanceOf(AggregationInterface::class, $this->model->getAggregations());
+    }
+
+    public function testSetSearchCriteria()
+    {
+        $this->assertEquals($this->model, $this->model->setSearchCriteria());
+    }
+}
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
index dbc98c4b59d52a82d3af8c01851f7ac9625e6f22..2b57747de4fcaee6268c3e77d800f45df7a95549 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
@@ -6,7 +6,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
-    <update handle="styles"/>
     <body>
         <referenceContainer name="content">
             <uiComponent name="cms_page_form"/>
diff --git a/app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CmsUrlRewrite/etc/events.xml
similarity index 100%
rename from app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml
rename to app/code/Magento/CmsUrlRewrite/etc/events.xml
diff --git a/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml b/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml
deleted file mode 100644
index 79798b599e2942ed6994b1c0e00b51d39de7e6bd..0000000000000000000000000000000000000000
--- a/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?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="cms_page_save_after">
-        <observer name="process_url_rewrite_saving" instance="Magento\CmsUrlRewrite\Observer\ProcessUrlRewriteSavingObserver" />
-    </event>
-</config>
diff --git a/app/code/Magento/Config/Model/Config/Backend/Cache.php b/app/code/Magento/Config/Model/Config/Backend/Cache.php
index 361cbcd25510c23a46c9e107a09c865b18d05be3..ba437c0f971b2ada295c37ce0e9871b218aa4c1a 100644
--- a/app/code/Magento/Config/Model/Config/Backend/Cache.php
+++ b/app/code/Magento/Config/Model/Config/Backend/Cache.php
@@ -22,12 +22,13 @@ class Cache extends \Magento\Framework\App\Config\Value
     /**
      * Clean cache, value was changed
      *
-     * @return void
+     * @return $this
      */
     public function afterSave()
     {
         if ($this->isValueChanged()) {
             $this->_cacheManager->clean($this->_cacheTags);
         }
+        return $this;
     }
 }
diff --git a/app/code/Magento/Config/Model/Config/Backend/Datashare.php b/app/code/Magento/Config/Model/Config/Backend/Datashare.php
index dff894cb559605e6f04937fc939f127e3a2ca1cf..bd0bfaa478abc5713d73a830126b64e6028bba1d 100644
--- a/app/code/Magento/Config/Model/Config/Backend/Datashare.php
+++ b/app/code/Magento/Config/Model/Config/Backend/Datashare.php
@@ -14,9 +14,10 @@ namespace Magento\Config\Model\Config\Backend;
 class Datashare extends \Magento\Framework\App\Config\Value
 {
     /**
-     * @return void
+     * @return $this
      */
     public function afterSave()
     {
+        return $this;
     }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php
index bd8bea9f25a57386f3fbba84cb2ea1ddf0c49983..df7ceda95692d9f92df1c983619931f202845868 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php
@@ -129,6 +129,11 @@ class Configurable
     {
         $associatedProductIds = $this->request->getPost('associated_product_ids', []);
         $variationsMatrix = $this->getVariationMatrix();
+
+        if ($associatedProductIds || $variationsMatrix) {
+            $this->variationHandler->prepareAttributeSet($product);
+        }
+
         if (!empty($variationsMatrix)) {
             $generatedProductIds = $this->variationHandler->generateSimpleProducts($product, $variationsMatrix);
             $associatedProductIds = array_merge($associatedProductIds, $generatedProductIds);
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 94414111a8101bf329fcd3f86ccd9097a66e5102..11673eccad5425a2dfbab3ec83404459ea2d18b8 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -508,8 +508,9 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
             $collection = $this->getUsedProductCollection($product)
                 ->addAttributeToSelect('name')
                 ->addAttributeToSelect('price')
-//                ->addAttributeToSelect('msrp')
-//                ->addAttributeToSelect('media_gallery')
+                ->addAttributeToSelect('weight')
+                ->addAttributeToSelect('image')
+                ->addAttributeToSelect('status')
                 ->addFilterByRequiredOptions()
                 ->setStoreId($product->getStoreId());
 
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
index 86d5aa130637b59f9d4ad431eda589679aebda31..9a40931c05d024f4f25cf793b30f1b4d30bb6019 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
@@ -66,7 +66,6 @@ class VariationHandler
      */
     public function generateSimpleProducts($parentProduct, $productsData)
     {
-        $this->prepareAttributeSetToBeBaseForNewVariations($parentProduct);
         $generatedProductIds = [];
         $productsData = $this->duplicateImagesForVariations($productsData);
         foreach ($productsData as $simpleProductData) {
@@ -93,11 +92,22 @@ class VariationHandler
     /**
      * Prepare attribute set comprising all selected configurable attributes
      *
+     * @deprecated since 2.1.0
      * @param \Magento\Catalog\Model\Product $product
-     *
      * @return void
      */
     protected function prepareAttributeSetToBeBaseForNewVariations(\Magento\Catalog\Model\Product $product)
+    {
+        $this->prepareAttributeSet($product);
+    }
+
+    /**
+     * Prepare attribute set comprising all selected configurable attributes
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return void
+     */
+    public function prepareAttributeSet(\Magento\Catalog\Model\Product $product)
     {
         $attributes = $this->configurableProduct->getUsedProductAttributes($product);
         $attributeSetId = $product->getNewVariationsAttributeSetId();
@@ -156,7 +166,8 @@ class VariationHandler
             $product->setData($attribute->getAttributeCode(), $parentProduct->getData($attribute->getAttributeCode()));
         }
 
-        $postData['stock_data'] = $parentProduct->getStockData();
+        $keysFilter = ['item_id', 'product_id', 'stock_id', 'type_id', 'website_id'];
+        $postData['stock_data'] = array_diff_key((array)$parentProduct->getStockData(), array_flip($keysFilter));
         $postData['stock_data']['manage_stock'] = $postData['quantity_and_stock_status']['qty'] === '' ? 0 : 1;
         if (!isset($postData['stock_data']['is_in_stock'])) {
             $stockStatus = $parentProduct->getQuantityAndStockStatus();
diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php
index 551df288ebcb03e2941a618ec28e667265b0af99..6f2b989e5e9bfaa9fa91643b1958be6a99c0fdc1 100644
--- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php
@@ -28,19 +28,11 @@ class Configurable extends \Magento\CatalogInventory\Model\ResourceModel\Indexer
         $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
         $connection = $this->getConnection();
         $idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable();
-        $select = $connection->select()->from(['e' => $this->getTable('catalog_product_entity')], ['entity_id']);
-        $this->_addWebsiteJoinToSelect($select, true);
-        $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id');
-        $select->columns(
-            'cw.website_id'
-        )->join(
-            ['cis' => $this->getTable('cataloginventory_stock')],
-            '',
-            ['stock_id']
-        )->joinLeft(
-            ['cisi' => $this->getTable('cataloginventory_stock_item')],
-            'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
-            []
+        $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable);
+        $select->reset(
+            \Magento\Framework\DB\Select::COLUMNS
+        )->columns(
+            ['e.entity_id', 'cis.website_id', 'cis.stock_id']
         )->joinLeft(
             ['l' => $this->getTable('catalog_product_super_link')],
             'l.parent_id = e.' . $metadata->getLinkField(),
@@ -51,24 +43,14 @@ class Configurable extends \Magento\CatalogInventory\Model\ResourceModel\Indexer
             []
         )->joinLeft(
             ['i' => $idxTable],
-            'i.product_id = l.product_id AND cw.website_id = i.website_id AND cis.stock_id = i.stock_id',
+            'i.product_id = l.product_id AND cis.website_id = i.website_id AND cis.stock_id = i.stock_id',
             []
         )->columns(
             ['qty' => new \Zend_Db_Expr('0')]
-        )->where(
-            'cw.website_id != 0'
-        )->where(
-            'e.type_id = ?',
-            $this->getTypeId()
-        )->group(
-            ['e.entity_id', 'cw.website_id', 'cis.stock_id']
         );
-        $psExpr = $this->_addAttributeToSelect($select, 'status', 'e.' . $metadata->getLinkField(), 'cs.store_id');
-        $psCond = $connection->quoteInto($psExpr . '=?', ProductStatus::STATUS_ENABLED);
-
         $statusExpr = $this->getStatusExpression($connection);
 
-        $optExpr = $connection->getCheckSql("{$psCond} AND le.required_options = 0", 'i.stock_status', 0);
+        $optExpr = $connection->getCheckSql("le.required_options = 0", 'i.stock_status', 0);
         $stockStatusExpr = $connection->getLeastSql(["MAX({$optExpr})", "MIN({$statusExpr})"]);
 
         $select->columns(['status' => $stockStatusExpr]);
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
index ee8fa65e2a3dd91bcd749ebc7837ada0a2ea4efd..17139915dd8fed0ed9c657f5210e8c5749d76a24 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
@@ -48,9 +48,9 @@ class ConfigurablePriceResolver implements PriceResolverInterface
             $productPrice = $this->priceResolver->resolvePrice($subProduct);
             $price = $price ? min($price, $productPrice) : $productPrice;
         }
-        if (!$price) {
+        if ($price === null) {
             throw new \Magento\Framework\Exception\LocalizedException(
-                __('Configurable product "%1" do not have sub-products', $product->getName())
+                __('Configurable product "%1" does not have sub-products', $product->getName())
             );
         }
         return (float)$price;
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php
index 055cc18ffbd02409698e97c200c6c6f4d1a3b863..f8b42171dd674cd09c17c3949fa20805fb35c871 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php
@@ -57,7 +57,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
     {
         $this->variationHandler = $this->getMockBuilder(VariationHandler::class)
             ->disableOriginalConstructor()
-            ->setMethods(['generateSimpleProducts'])
+            ->setMethods(['generateSimpleProducts', 'prepareAttributeSet'])
             ->getMock();
 
         $this->request = $this->getMockBuilder(Http::class)
@@ -183,6 +183,10 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->method('setConfigurableProductOptions')
             ->with($attributes);
 
+        $this->variationHandler->expects(static::once())
+            ->method('prepareAttributeSet')
+            ->with($this->product);
+
         $this->variationHandler->expects(static::once())
             ->method('generateSimpleProducts')
             ->with($this->product, $variationMatrix)
@@ -248,6 +252,9 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->method('setConfigurableProductOptions')
             ->with($attributes);
 
+        $this->variationHandler->expects(static::never())
+            ->method('prepareAttributeSet');
+
         $this->variationHandler->expects(static::never())
             ->method('generateSimpleProducts');
 
@@ -277,6 +284,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->method('getExtensionAttributes');
         $this->request->expects(static::once())
             ->method('getPost');
+        $this->variationHandler->expects(static::never())
+            ->method('prepareAttributeSet');
         $this->variationHandler->expects(static::never())
             ->method('generateSimpleProducts');
         $this->plugin->afterInitialize($this->subject, $this->product);
@@ -294,6 +303,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->method('getExtensionAttributes');
         $this->request->expects(static::once())
             ->method('getPost');
+        $this->variationHandler->expects(static::never())
+            ->method('prepareAttributeSet');
         $this->variationHandler->expects(static::never())
             ->method('generateSimpleProducts');
         $this->plugin->afterInitialize($this->subject, $this->product);
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/VariationHandlerTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/VariationHandlerTest.php
index 85f4154a1b81341797734603ac4efae95ae59013..7efc0794f11b80edb6893871b727298672142f6a 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/VariationHandlerTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/VariationHandlerTest.php
@@ -18,27 +18,27 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
     /**
      * @var VariationHandler
      */
-    protected $_model;
+    protected $model;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\Entity\Attribute\SetFactory
      */
-    protected $_attributeSetFactory;
+    protected $attributeSetFactory;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\EntityFactory
      */
-    protected $_entityFactoryMock;
+    protected $entityFactoryMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\ProductFactory
      */
-    protected $_productFactoryMock;
+    protected $productFactoryMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Api\StockConfigurationInterface
      */
-    protected $_stockConfiguration;
+    protected $stockConfiguration;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\ConfigurableProduct\Model\Product\Type\Configurable
@@ -48,41 +48,41 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
      */
-    protected $_objectHelper;
+    protected $objectHelper;
 
     /**
      * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $_product;
+    private $product;
 
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
     protected function setUp()
     {
-        $this->_objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->_productFactoryMock = $this->getMock(
+        $this->objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->productFactoryMock = $this->getMock(
             'Magento\Catalog\Model\ProductFactory',
             ['create'],
             [],
             '',
             false
         );
-        $this->_entityFactoryMock = $this->getMock(
+        $this->entityFactoryMock = $this->getMock(
             'Magento\Eav\Model\EntityFactory',
             ['create'],
             [],
             '',
             false
         );
-        $this->_attributeSetFactory = $this->getMock(
+        $this->attributeSetFactory = $this->getMock(
             'Magento\Eav\Model\Entity\Attribute\SetFactory',
             ['create'],
             [],
             '',
             false
         );
-        $this->_stockConfiguration = $this->getMock(
+        $this->stockConfiguration = $this->getMock(
             'Magento\CatalogInventory\Api\StockConfigurationInterface',
             [],
             [],
@@ -97,20 +97,68 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $this->_product = $this->getMock('Magento\Catalog\Model\Product', ['getMediaGallery'], [], '', false);
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', ['getMediaGallery'], [], '', false);
 
-        $this->_model = $this->_objectHelper->getObject(
+        $this->model = $this->objectHelper->getObject(
             'Magento\ConfigurableProduct\Model\Product\VariationHandler',
             [
-                'productFactory' => $this->_productFactoryMock,
-                'entityFactory' => $this->_entityFactoryMock,
-                'attributeSetFactory' => $this->_attributeSetFactory,
-                'stockConfiguration' => $this->_stockConfiguration,
+                'productFactory' => $this->productFactoryMock,
+                'entityFactory' => $this->entityFactoryMock,
+                'attributeSetFactory' => $this->attributeSetFactory,
+                'stockConfiguration' => $this->stockConfiguration,
                 'configurableProduct' => $this->configurableProduct
             ]
         );
     }
 
+    public function testPrepareAttributeSet()
+    {
+
+        $productMock = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->setMethods(['getNewVariationsAttributeSetId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeMock = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute')
+            ->setMethods(['isInSet', 'setAttributeSetId', 'setAttributeGroupId', 'save'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeSetMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Set')
+            ->setMethods(['load', 'addSetInfo', 'getDefaultGroupId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $eavEntityMock = $this->getMockBuilder('\Magento\Eav\Model\Entity')
+            ->setMethods(['setType', 'getTypeId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $productMock->expects($this->once())
+            ->method('getNewVariationsAttributeSetId')
+            ->willReturn('new_attr_set_id');
+        $this->configurableProduct->expects($this->once())
+            ->method('getUsedProductAttributes')
+            ->with($productMock)
+            ->willReturn([$attributeMock]);
+        $this->attributeSetFactory->expects($this->once())->method('create')->willReturn($attributeSetMock);
+        $attributeSetMock->expects($this->once())->method('load')->with('new_attr_set_id')->willReturnSelf();
+        $this->entityFactoryMock->expects($this->once())->method('create')->willReturn($eavEntityMock);
+        $eavEntityMock->expects($this->once())->method('setType')->with('catalog_product')->willReturnSelf();
+        $eavEntityMock->expects($this->once())->method('getTypeId')->willReturn('type_id');
+        $attributeSetMock->expects($this->once())->method('addSetInfo')->with('type_id', [$attributeMock]);
+        $attributeMock->expects($this->once())->method('isInSet')->with('new_attr_set_id')->willReturn(false);
+        $attributeMock->expects($this->once())->method('setAttributeSetId')->with('new_attr_set_id')->willReturnSelf();
+        $attributeSetMock->expects($this->once())
+            ->method('getDefaultGroupId')
+            ->with('new_attr_set_id')
+            ->willReturn('default_group_id');
+        $attributeMock->expects($this->once())
+            ->method('setAttributeGroupId')
+            ->with('default_group_id')
+            ->willReturnSelf();
+        $attributeMock->expects($this->once())->method('save')->willReturnSelf();
+
+        $this->model->prepareAttributeSet($productMock);
+    }
+
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
@@ -169,18 +217,6 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
             )
             ->disableOriginalConstructor()
             ->getMock();
-        $attributeMock = $this->getMockBuilder('\Magento\Eav\Model\Entity\Attribute')
-            ->setMethods(['isInSet', 'setAttributeSetId', 'setAttributeGroupId', 'save'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $attributeSetMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Set')
-            ->setMethods(['load', 'addSetInfo', 'getDefaultGroupId'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $eavEntityMock = $this->getMockBuilder('\Magento\Eav\Model\Entity')
-            ->setMethods(['setType', 'getTypeId'])
-            ->disableOriginalConstructor()
-            ->getMock();
         $productTypeMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Type')
             ->setMethods(['getSetAttributes'])
             ->disableOriginalConstructor()
@@ -194,29 +230,10 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->configurableProduct->expects($this->once())->method('getUsedProductAttributes')
-            ->willReturn([$attributeMock]);
-        $parentProductMock->expects($this->any())
+        $parentProductMock->expects($this->once())
             ->method('getNewVariationsAttributeSetId')
             ->willReturn('new_attr_set_id');
-        $this->_attributeSetFactory->expects($this->once())->method('create')->willReturn($attributeSetMock);
-        $attributeSetMock->expects($this->once())->method('load')->with('new_attr_set_id')->willReturnSelf();
-        $this->_entityFactoryMock->expects($this->once())->method('create')->willReturn($eavEntityMock);
-        $eavEntityMock->expects($this->once())->method('setType')->with('catalog_product')->willReturnSelf();
-        $eavEntityMock->expects($this->once())->method('getTypeId')->willReturn('type_id');
-        $attributeSetMock->expects($this->once())->method('addSetInfo')->with('type_id', [$attributeMock]);
-        $attributeMock->expects($this->once())->method('isInSet')->with('new_attr_set_id')->willReturn(false);
-        $attributeMock->expects($this->once())->method('setAttributeSetId')->with('new_attr_set_id')->willReturnSelf();
-        $attributeSetMock->expects($this->once())
-            ->method('getDefaultGroupId')
-            ->with('new_attr_set_id')
-            ->willReturn('default_group_id');
-        $attributeMock->expects($this->once())
-            ->method('setAttributeGroupId')
-            ->with('default_group_id')
-            ->willReturnSelf();
-        $attributeMock->expects($this->once())->method('save')->willReturnSelf();
-        $this->_productFactoryMock->expects($this->once())->method('create')->willReturn($newSimpleProductMock);
+        $this->productFactoryMock->expects($this->once())->method('create')->willReturn($newSimpleProductMock);
         $newSimpleProductMock->expects($this->once())->method('setStoreId')->with(0)->willReturnSelf();
         $newSimpleProductMock->expects($this->once())->method('setTypeId')->with('simple')->willReturnSelf();
         $newSimpleProductMock->expects($this->once())
@@ -238,7 +255,7 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
             ->method('getQuantityAndStockStatus')
             ->willReturn(['is_in_stock' => 1]);
         $newSimpleProductMock->expects($this->once())->method('getStoreId')->willReturn('store_id');
-        $this->_stockConfiguration->expects($this->once())
+        $this->stockConfiguration->expects($this->once())
             ->method('getManageStock')
             ->with('store_id')
             ->willReturn(1);
@@ -249,41 +266,41 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
         $newSimpleProductMock->expects($this->once())->method('save')->willReturnSelf();
         $newSimpleProductMock->expects($this->once())->method('getId')->willReturn('product_id');
 
-        $this->assertEquals(['product_id'], $this->_model->generateSimpleProducts($parentProductMock, $productsData));
+        $this->assertEquals(['product_id'], $this->model->generateSimpleProducts($parentProductMock, $productsData));
     }
 
     public function testProcessMediaGalleryWithImagesAndGallery()
     {
-        $this->_product->expects($this->atLeastOnce())->method('getMediaGallery')->with('images')->willReturn([]);
+        $this->product->expects($this->atLeastOnce())->method('getMediaGallery')->with('images')->willReturn([]);
         $productData['image'] = 'test';
         $productData['media_gallery']['images'] = [
             [
                 'file' => 'test',
             ],
         ];
-        $result = $this->_model->processMediaGallery($this->_product, $productData);
+        $result = $this->model->processMediaGallery($this->product, $productData);
         $this->assertEquals($productData, $result);
     }
 
     public function testProcessMediaGalleryIfImageIsEmptyButProductMediaGalleryIsNotEmpty()
     {
-        $this->_product->expects($this->atLeastOnce())->method('getMediaGallery')->with('images')->willReturn([]);
+        $this->product->expects($this->atLeastOnce())->method('getMediaGallery')->with('images')->willReturn([]);
         $productData['image'] = false;
         $productData['media_gallery']['images'] = [
             [
                 'name' => 'test',
             ],
         ];
-        $result = $this->_model->processMediaGallery($this->_product, $productData);
+        $result = $this->model->processMediaGallery($this->product, $productData);
         $this->assertEquals($productData, $result);
     }
 
     public function testProcessMediaGalleryIfProductDataHasNoImagesAndGallery()
     {
-        $this->_product->expects($this->once())->method('getMediaGallery')->with('images')->willReturn([]);
+        $this->product->expects($this->once())->method('getMediaGallery')->with('images')->willReturn([]);
         $productData['image'] = false;
         $productData['media_gallery']['images'] = false;
-        $result = $this->_model->processMediaGallery($this->_product, $productData);
+        $result = $this->model->processMediaGallery($this->product, $productData);
         $this->assertEquals($productData, $result);
     }
 
@@ -294,7 +311,7 @@ class VariationHandlerTest extends \PHPUnit_Framework_TestCase
      */
     public function testProcessMediaGalleryForFillingGallery($productData, $expected)
     {
-        $this->assertEquals($expected, $this->_model->processMediaGallery($this->_product, $productData));
+        $this->assertEquals($expected, $this->model->processMediaGallery($this->product, $productData));
     }
 
     /**
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
index 5ada8354ef0aa20987b733b7d49bbc8c9162ee65..d37335e7a0842f8418308ca8d915376f0ae50ffd 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php
@@ -65,10 +65,15 @@ class CartItemProcessorTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $this->productOptionExtensionAttributes = $this->getMockBuilder(ProductOptionExtensionAttributes::class)
-            ->disableOriginalConstructor()
-            ->setMethods(['setConfigurableItemOptions'])
-            ->getMock();
+        $this->productOptionExtensionAttributes = $this->getMockForAbstractClass(
+            ProductOptionExtensionAttributes::class,
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['setConfigurableItemOptions']
+        );
 
         $this->model = new \Magento\ConfigurableProduct\Model\Quote\Item\CartItemProcessor(
             $this->objectFactoryMock,
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb13fcf140c49dc687dcf6568e9a64fb369c71c2
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Price;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver
+     */
+    protected $resolver;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Model\Product\Type\Configurable
+     */
+    protected $configurable;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface
+     */
+    protected $priceResolver;
+
+    protected function setUp()
+    {
+        $className = 'Magento\ConfigurableProduct\Model\Product\Type\Configurable';
+        $this->configurable = $this->getMock($className, ['getUsedProducts'], [], '', false);
+
+        $className = 'Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface';
+        $this->priceResolver = $this->getMockForAbstractClass($className, [], '', false, true, true, ['resolvePrice']);
+
+        $objectManager = new ObjectManager($this);
+        $this->resolver = $objectManager->getObject(
+            'Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver',
+            [
+                'priceResolver' => $this->priceResolver,
+                'configurable' => $this->configurable,
+            ]
+        );
+    }
+
+    /**
+     * situation: There are no used products, thus there are no prices
+     *
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     */
+    public function testResolvePriceWithNoPrices()
+    {
+        $product = $this->getMockForAbstractClass(
+            'Magento\Framework\Pricing\SaleableInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getName']
+        );
+        $product->expects($this->once())->method('getName')->willReturn('Kiwi');
+
+        $this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([]);
+
+        $this->resolver->resolvePrice($product);
+    }
+
+    /**
+     * situation: one product is supplying the price, which could be a price of zero (0)
+     *
+     * @dataProvider testResolvePriceDataProvider
+     */
+    public function testResolvePrice($expectedValue)
+    {
+        $price = $expectedValue;
+
+        $product = $this->getMockForAbstractClass(
+            'Magento\Framework\Pricing\SaleableInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getName']
+        );
+        $product->expects($this->never())->method('getName');
+
+        $this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([$product]);
+        $this->priceResolver->expects($this->atLeastOnce())->method('resolvePrice')->willReturn($price);
+
+        $this->assertEquals($expectedValue, $this->resolver->resolvePrice($product));
+    }
+
+    /**
+     * @return array
+     */
+    public function testResolvePriceDataProvider()
+    {
+        return [
+            'price of zero' => [0.00],
+            'price of five' => [5],
+        ];
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php
index ce7524a783e9649fda851b7ec0b18e3ae2f13f6f..5832c18744b661712a040b2f9f7e98490bdb21e8 100644
--- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php
+++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php
@@ -199,6 +199,7 @@ class ConfigurableAttributeSetHandler extends AbstractModifier
                         'formElement' => Form\Element\Input::NAME,
                         'componentType' => Form\Field::NAME,
                         'dataScope' => 'configurableNewAttributeSetName',
+                        'additionalClasses' => 'new-attribute-set-name',
                         'label' => __('New Attribute Set Name'),
                         'sortOrder' => 40,
                         'validation' => ['required-entry' => true],
diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php
index 5810eefe9007cd14f4e83ec34fba84df2e5b9c95..fb2161d3c64cb1093d82487f6219a9cfd81a5d0a 100644
--- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php
+++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php
@@ -129,7 +129,7 @@ class ConfigurablePanel extends AbstractModifier
                             'config' => [
                                 'componentType' => Modal::NAME,
                                 'dataScope' => '',
-                                'provider' => $this->dataSourceName,
+                                'provider' => static::FORM_NAME . '.product_form_data_source',
                                 'options' => [
                                     'title' => __('Select Associated Product'),
                                     'buttons' => [
@@ -138,9 +138,7 @@ class ConfigurablePanel extends AbstractModifier
                                             'class' => 'action-primary',
                                             'actions' => [
                                                 [
-                                                    'targetName' => 'ns= ' . $this->associatedListingPrefix
-                                                        . static::ASSOCIATED_PRODUCT_LISTING
-                                                        . ', index=' . static::ASSOCIATED_PRODUCT_LISTING,
+                                                    'targetName' => 'index=' . static::ASSOCIATED_PRODUCT_LISTING,
                                                     'actionName' => 'save'
                                                 ],
                                                 'closeModal'
@@ -227,6 +225,10 @@ class ConfigurablePanel extends AbstractModifier
                                             . 'configurable_associated_product_listing.product_columns.ids',
                                         'modalWithGrid' => 'ns=' . $this->formName . ', index='
                                             . static::ASSOCIATED_PRODUCT_MODAL,
+                                        'productsFilters' => $this->associatedListingPrefix
+                                            . 'configurable_associated_product_listing'
+                                            . '.' . $this->associatedListingPrefix
+                                            . 'configurable_associated_product_listing.listing_top.listing_filters',
                                     ],
                                 ],
                             ],
@@ -292,13 +294,12 @@ class ConfigurablePanel extends AbstractModifier
                                 'displayAsLink' => true,
                                 'actions' => [
                                     [
-                                        'targetName' => 'ns=' . $this->formName . ', index='
+                                        'targetName' => 'ns=' . static::FORM_NAME . ', index='
                                             . static::ASSOCIATED_PRODUCT_MODAL,
                                         'actionName' => 'openModal',
                                     ],
                                     [
-                                        'targetName' => 'ns=' . $this->associatedListingPrefix
-                                            . static::ASSOCIATED_PRODUCT_LISTING
+                                        'targetName' => 'ns=' . static::ASSOCIATED_PRODUCT_LISTING
                                             . ', index=' . static::ASSOCIATED_PRODUCT_LISTING,
                                         'actionName' => 'showGridAssignProduct',
                                     ],
@@ -325,13 +326,13 @@ class ConfigurablePanel extends AbstractModifier
                                 'actions' => [
                                     [
                                         'targetName' =>
-                                            $this->dataScopeName . '.configurableModal',
+                                            'product_form.product_form.configurableModal',
                                         'actionName' => 'trigger',
                                         'params' => ['active', true],
                                     ],
                                     [
                                         'targetName' =>
-                                            $this->dataScopeName . '.configurableModal',
+                                            'product_form.product_form.configurableModal',
                                         'actionName' => 'openModal',
                                     ],
                                 ],
@@ -369,7 +370,7 @@ class ConfigurablePanel extends AbstractModifier
                         'isEmpty' => true,
                         'itemTemplate' => 'record',
                         'dataScope' => 'data',
-                        'dataProviderFromGrid' => $this->associatedListingPrefix . static::ASSOCIATED_PRODUCT_LISTING,
+                        'dataProviderFromGrid' => static::ASSOCIATED_PRODUCT_LISTING,
                         'dataProviderChangeFromGrid' => 'change_product',
                         'dataProviderFromWizard' => 'variations',
                         'map' => [
@@ -394,10 +395,9 @@ class ConfigurablePanel extends AbstractModifier
                         'sortOrder' => 20,
                         'columnsHeader' => false,
                         'columnsHeaderAfterRender' => true,
-                        'modalWithGrid' => 'ns=' . $this->formName . ', index='
+                        'modalWithGrid' => 'ns=' . static::FORM_NAME . ', index='
                             . static::ASSOCIATED_PRODUCT_MODAL,
-                        'gridWithProducts' => 'ns=' . $this->associatedListingPrefix
-                            . static::ASSOCIATED_PRODUCT_LISTING
+                        'gridWithProducts' => 'ns=' . static::ASSOCIATED_PRODUCT_LISTING
                             . ', index=' . static::ASSOCIATED_PRODUCT_LISTING,
                     ],
                 ],
@@ -439,10 +439,6 @@ class ConfigurablePanel extends AbstractModifier
                             'elementTmpl' => 'Magento_ConfigurableProduct/components/file-uploader',
                             'fileInputName' => 'image',
                             'isMultipleFiles' => false,
-                            'imports' => [
-                                'thumbnailUrl' => '${$.provider}:${$.parentScope}.thumbnail_image',
-                                'thumbnail' => '${$.provider}:${$.parentScope}.thumbnail'
-                            ],
                             'uploaderConfig' => [
                                 'url' => $this->urlBuilder->addSessionParam()->getUrl(
                                     'catalog/product_gallery/upload'
diff --git a/app/code/Magento/ConfigurableProduct/i18n/en_US.csv b/app/code/Magento/ConfigurableProduct/i18n/en_US.csv
index ec07c74c8868b7ff8906f3cdf68327e8e26eab7b..59ae9a201670772f1fe3220bbb27adb99e1d3876 100644
--- a/app/code/Magento/ConfigurableProduct/i18n/en_US.csv
+++ b/app/code/Magento/ConfigurableProduct/i18n/en_US.csv
@@ -30,7 +30,7 @@ Summary,Summary
 "You need to choose options for your item.","You need to choose options for your item."
 "Some product variations fields are not valid.","Some product variations fields are not valid."
 "Configuration must have specified attributes","Configuration must have specified attributes"
-"Configurable product ""%1"" do not have sub-products","Configurable product ""%1"" do not have sub-products"
+"Configurable product ""%1"" does not have sub-products","Configurable product ""%1"" does not have sub-products"
 "This group contains attributes used in configurable products. Please move these attributes to another group and try again.","This group contains attributes used in configurable products. Please move these attributes to another group and try again."
 "This attribute is used in configurable products. You cannot remove it from the attribute set.","This attribute is used in configurable products. You cannot remove it from the attribute set."
 "Associated Products","Associated Products"
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml
index 0dfcf167bda4d1061b690d9469f1b754fa7b550a..a684ccef60f15e1ffb38b8c5a5556ea653fe6edf 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml
@@ -9,9 +9,13 @@
 /* @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Steps\AttributeValues */
 ?>
 <div data-bind="scope: '<?= /* @noEscape */  $block->getComponentName()?>'">
-    <h2 class="steps-wizard-title"><?= /* @noEscape */  __('Step 2: Attribute Values') ?></h2>
+    <h2 class="steps-wizard-title"><?php echo $block->escapeHtml(
+            __('Step 2: Attribute Values')
+        ); ?></h2>
     <div class="steps-wizard-info">
-        <span><?= $block->escapeHtml(__('Select from the following attribute values for this product. Each unique combination of values creates a unique product SKU.')) ?></span>
+        <span><?php echo $block->escapeHtml(
+                __('Select values from each attribute to include in this product. Each unique combination of values creates a unigue product SKU.')
+            );?></span>
     </div>
     <div data-bind="foreach: attributes, sortableList: attributes">
 
@@ -25,7 +29,9 @@
                     <div class="attribute-entity-title" data-bind="text: label"></div>
                     <div class="attribute-options-block">
                         (<span class="attribute-length" data-bind="text: $data.options().length"></span>
-                        <?= /* @noEscape */  __('Options') ?>)
+                        <?php echo $block->escapeHtml(
+                            __('Options')
+                        ); ?>)
                     </div>
                 </div>
 
@@ -34,19 +40,25 @@
                             class="action-select-all action-tertiary"
                             data-bind="click: $parent.selectAllAttributes"
                             title="<?= $block->escapeHtml(__('Select All')) ?>">
-                        <span><?= /* @noEscape */  __('Select All') ?></span>
+                        <span><?php echo $block->escapeHtml(
+                                __('Select All')
+                            ); ?></span>
                     </button>
                     <button type="button"
                             class="action-deselect-all action-tertiary"
                             data-bind="click: $parent.deSelectAllAttributes"
                             title="<?= $block->escapeHtml(__('Deselect All')) ?>">
-                        <span><?= /* @noEscape */  __('Deselect All') ?></span>
+                        <span><?php echo $block->escapeHtml(
+                                __('Deselect All')
+                            ); ?></span>
                     </button>
                     <button type="button"
                             class="action-remove-all action-tertiary"
                             data-bind="click: $parent.removeAttribute.bind($parent)"
                             title="<?= $block->escapeHtml(__('Remove Attribute')) ?>">
-                        <span><?= /* @noEscape */  __('Remove Attribute') ?></span>
+                        <span><?php echo $block->escapeHtml(
+                                __('Remove Attribute')
+                            ); ?></span>
                     </button>
                 </div>
             </div>
@@ -74,14 +86,18 @@
                                     title="<?= $block->escapeHtml(__('Save Option')) ?>"
                                     data-action="save"
                                     data-bind="click: $parents[1].saveOption.bind($parent)">
-                                <span><?= /* @noEscape */  __('Save Option') ?></span>
+                                <span><?php echo $block->escapeHtml(
+                                        __('Save Option')
+                                    ); ?></span>
                             </button>
                             <button type="button"
                                     class="action-remove"
                                     title="<?= $block->escapeHtml(__('Remove Option')) ?>"
                                     data-action="remove"
                                     data-bind="click: $parents[1].removeOption.bind($parent)">
-                                <span><?= /* @noEscape */  __('Remove Option') ?></span>
+                                <span><?php echo $block->escapeHtml(
+                                        _('Remove Option')
+                                    ); ?></span>
                             </button>
                         </div>
                     </li>
@@ -90,8 +106,10 @@
             <button class="action-create-new action-tertiary"
                     type="button"
                     data-action="addOption"
-                    data-bind="click: $parent.createOption">
-                <span><?= /* @escapeNotVerified */  __('Create New Value') ?></span>
+                    data-bind="click: $parent.createOption, visible: canCreateOption">
+                <span><?php echo $block->escapeHtml(
+                        __('Create New Value')
+                    ); ?></span>
             </button>
         </div>
     </div>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml
index c3e410ac833ddff6cd933100526a9c6caeeb367d..24bfcabcacea23446cc716f8f2c72e6344f84fd5 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/bulk.phtml
@@ -10,547 +10,592 @@
 ?>
 
 <div data-bind="scope: '<?= /* @noEscape */  $block->getComponentName()?>'" data-role="bulk-step">
-    <h2 class="steps-wizard-title"><?= /* @noEscape */  __('Step 3: Bulk Images, Price and Quantity') ?></h2>
+    <h2 class="steps-wizard-title"><?php echo $block->escapeHtml(__('Step 3: Bulk Images, Price and Quantity')); ?></h2>
     <div class="steps-wizard-info">
-        <?= /* @noEscape */  __('Based on your selections <span class="new-products-count" data-bind="text:countVariations"></span>
-        new products will be created. Use this step to customize images and price for your new products.') ?>
+        <?php /* @escapeNotVerified */ echo __('Based on your selections %1 new products will be created. Use this step to customize images and price for your new products.', '<span class="new-products-count" data-bind="text:countVariations"></span>') ?>
     </div>
 
     <div data-bind="with: sections().images" class="steps-wizard-section">
         <div data-role="section">
-        <div class="steps-wizard-section-title">
-            <span><?= /* @noEscape */  __('Images') ?></span>
-        </div>
+            <div class="steps-wizard-section-title">
+            <span><?php echo $block->escapeHtml(
+                    __('Images')
+                ); ?></span>
+            </div>
 
-        <ul class="steps-wizard-section-list">
-            <li>
-                <div class="admin__field admin__field-option">
-                    <input type="radio"
-                           id="apply-single-set-radio"
-                           class="admin__control-radio"
-                           value="single"
-                           data-bind="checked:type">
-                    <label for="apply-single-set-radio" class="admin__field-label">
-                        <span><?= /* @noEscape */  __('Apply single set of images to all SKUs') ?></span>
-                    </label>
-                </div>
-            </li>
-            <li>
-                <div class="admin__field admin__field-option">
-                    <input type="radio"
-                           id="apply-unique-images-radio"
-                           class="admin__control-radio"
-                           value="each"
-                           data-bind="checked:type">
-                    <label for="apply-unique-images-radio" class="admin__field-label">
-                        <span><?= /* @noEscape */  __('Apply unique images by attribute to each SKU') ?></span>
-                    </label>
-                </div>
-            </li>
-            <li>
-                <div class="admin__field admin__field-option">
-                    <input type="radio"
-                           id="skip-images-uploading-radio"
-                           class="admin__control-radio"
-                           value="none"
-                           checked
-                           data-bind="checked:type">
-                    <label for="skip-images-uploading-radio" class="admin__field-label">
-                        <span><?= /* @noEscape */  __('Skip image uploading at this time') ?></span>
-                    </label>
-                </div>
-            </li>
-        </ul>
-
-        <div data-role="step-gallery-single"
-             class="attribute-image-selector"
-             data-bind="visible: type() == 'single'">
-            <div data-role="gallery"
-                 class="gallery"
-                 data-images="[]"
-                 data-types="<?php echo $block->escapeHtml(
-                     $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
-                 ) ?>"
-                >
-                <div class="image image-placeholder">
-                    <div data-role="uploader" class="uploader">
-                        <div class="image-browse">
-                            <span><?= /* @noEscape */  __('Browse Files...') ?></span>
-                            <input type="file"
-                                   id=""
-                                   name="image"
-                                   class="admin__control-file"
-                                   multiple="multiple"
-                                   data-url="<?= /* @noEscape */ $block->getUrl('catalog/product_gallery/upload') ?>" />
-                        </div>
+            <ul class="steps-wizard-section-list">
+                <li>
+                    <div class="admin__field admin__field-option">
+                        <input type="radio"
+                               id="apply-single-set-radio"
+                               class="admin__control-radio"
+                               value="single"
+                               data-bind="checked:type">
+                        <label for="apply-single-set-radio" class="admin__field-label">
+                        <span><?php echo $block->escapeHtml(
+                                __('Apply single set of images to all SKUs')
+                            ); ?></span>
+                        </label>
                     </div>
-                    <div class="product-image-wrapper">
-                        <p class="image-placeholder-text"><?= /* @noEscape */  __('Browse to find or drag image here') ?></p>
+                </li>
+                <li>
+                    <div class="admin__field admin__field-option">
+                        <input type="radio"
+                               id="apply-unique-images-radio"
+                               class="admin__control-radio"
+                               value="each"
+                               data-bind="checked:type">
+                        <label for="apply-unique-images-radio" class="admin__field-label">
+                            <span><?php echo $block->escapeHtml(__('Apply unique images by attribute to each SKU')) ?></span>
+                        </label>
                     </div>
-                </div>
-
-                <?php foreach ($block->getImageTypes() as $typeData):
-                    ?>
-                    <input name="<?php echo $block->escapeHtml($typeData['name']) ?>"
-                           class="image-<?php echo $block->escapeHtml($typeData['code']) ?>"
-                           type="hidden"
-                           value="<?php echo $block->escapeHtml($typeData['value']) ?>"/>
-                    <?php
-                    endforeach;
-                 ?>
+                </li>
+                <li>
+                    <div class="admin__field admin__field-option">
+                        <input type="radio"
+                               id="skip-images-uploading-radio"
+                               class="admin__control-radio"
+                               value="none"
+                               checked
+                               data-bind="checked:type">
+                        <label for="skip-images-uploading-radio" class="admin__field-label">
+                            <span><?php echo $block->escapeHtml(__('Skip image uploading at this time')) ?></span>
+                        </label>
+                    </div>
+                </li>
+            </ul>
 
-                <script data-template="uploader" type="text/x-magento-template">
-                    <div id="<%- data.id %>" class="file-row">
-                        <span class="file-info"><%- data.name %> (<%- data.size %>)</span>
-                        <div class="progressbar-container">
-                            <div class="progressbar upload-progress" style="width: 0%;"></div>
+            <div data-role="step-gallery-single"
+                 class="attribute-image-selector"
+                 data-bind="visible: type() == 'single'">
+                <div data-role="gallery"
+                     class="gallery"
+                     data-images="[]"
+                     data-types="<?php echo $block->escapeHtml(
+                         $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
+                     ) ?>"
+                >
+                    <div class="image image-placeholder">
+                        <div data-role="uploader" class="uploader">
+                            <div class="image-browse">
+                                <span><?php echo $block->escapeHtml(__('Browse Files...')) ?></span>
+                                <input type="file"
+                                       id=""
+                                       name="image"
+                                       class="admin__control-file"
+                                       multiple="multiple"
+                                       data-url="<?= /* @noEscape */ $block->getUrl('catalog/product_gallery/upload') ?>" />
+                            </div>
                         </div>
-                        <div class="spinner">
-                            <span></span><span></span><span></span><span></span>
-                            <span></span><span></span><span></span><span></span>
+                        <div class="product-image-wrapper">
+                            <p class="image-placeholder-text"><?php echo $block->escapeHtml(__('Browse to find or drag image here')) ?></p>
                         </div>
                     </div>
-                </script>
-
-                <script data-template="gallery-content" type="text/x-magento-template">
-                    <div class="image item <% if (data.disabled == 1) { %>hidden-for-front<% } %>"
-                         data-role="image">
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][position]"
-                               value="<%- data.position %>"/>
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][file]"
-                               value="<%- data.file %>"/>
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][value_id]"
-                               value="<%- data.value_id %>"/>
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][label]"
-                               value="<%- data.label %>"/>
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][disabled]"
-                               value="<%- data.disabled %>"/>
-                        <input type="hidden"
-                               name="product[media_gallery][images][<%- data.file_id %>][removed]"/>
-                        <div class="product-image-wrapper">
-                            <img class="product-image" data-role="image-element" src="<%- data.url %>" alt="<%- data.label %>"/>
-                            <div class="actions">
-                                <button type="button"
-                                        class="action-remove"
-                                        data-role="delete-button"
-                                        title="<?= $block->escapeHtml(__('Remove image')) ?>">
-                                    <span><?= /* @noEscape */  __('Remove image') ?></span>
-                                </button>
-                                <div class="draggable-handle"></div>
+
+                    <?php foreach ($block->getImageTypes() as $typeData):
+                        ?>
+                        <input name="<?php echo $block->escapeHtml($typeData['name']) ?>"
+                               class="image-<?php echo $block->escapeHtml($typeData['code']) ?>"
+                               type="hidden"
+                               value="<?php echo $block->escapeHtml($typeData['value']) ?>"/>
+                        <?php
+                    endforeach;
+                    ?>
+
+                    <script data-template="uploader" type="text/x-magento-template">
+                        <div id="<%- data.id %>" class="file-row">
+                            <span class="file-info"><%- data.name %> (<%- data.size %>)</span>
+                            <div class="progressbar-container">
+                                <div class="progressbar upload-progress" style="width: 0%;"></div>
                             </div>
-                            <div class="image-fade"><span><?= /* @noEscape */  __('Hidden') ?></span></div>
-                        </div>
-                        <div class="item-description">
-                            <div class="item-title" data-role="img-title"><%- data.label %></div>
-                            <div class="item-size">
-                                <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
+                            <div class="spinner">
+                                <span></span><span></span><span></span><span></span>
+                                <span></span><span></span><span></span><span></span>
                             </div>
                         </div>
-                        <ul class="item-roles" data-role="roles-labels">
-                            <?php
-                            foreach ($block->getMediaAttributes() as $attribute):
-                                ?>
-                                <li data-role-code="<?php echo $block->escapeHtml(
-                                    $attribute->getAttributeCode()
-                                ) ?>" class="item-role item-role-<?php echo $block->escapeHtml(
-                                    $attribute->getAttributeCode()
-                                ) ?>">
-                                    <?php /* @noEscape */ echo $attribute->getFrontendLabel() ?>
-                                </li>
+                    </script>
+
+                    <script data-template="gallery-content" type="text/x-magento-template">
+                        <div class="image item <% if (data.disabled == 1) { %>hidden-for-front<% } %>"
+                             data-role="image">
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][position]"
+                                   value="<%- data.position %>"/>
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][file]"
+                                   value="<%- data.file %>"/>
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][value_id]"
+                                   value="<%- data.value_id %>"/>
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][label]"
+                                   value="<%- data.label %>"/>
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][disabled]"
+                                   value="<%- data.disabled %>"/>
+                            <input type="hidden"
+                                   name="product[media_gallery][images][<%- data.file_id %>][removed]"/>
+                            <div class="product-image-wrapper">
+                                <img class="product-image" data-role="image-element" src="<%- data.url %>" alt="<%- data.label %>"/>
+                                <div class="actions">
+                                    <button type="button"
+                                            class="action-remove"
+                                            data-role="delete-button"
+                                            title="<?= $block->escapeHtml(__('Remove image')) ?>">
+                                        <span><?php echo $block->escapeHtml(__('Remove image')) ?></span>
+                                    </button>
+                                    <div class="draggable-handle"></div>
+                                </div>
+                                <div class="image-fade"><span><?php echo $block->escapeHtml(__('Hidden')) ?></span></div>
+                            </div>
+                            <div class="item-description">
+                                <div class="item-title" data-role="img-title"><%- data.label %></div>
+                                <div class="item-size">
+                                    <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
+                                </div>
+                            </div>
+                            <ul class="item-roles" data-role="roles-labels">
                                 <?php
-                            endforeach;
-                            ?>
-                        </ul>
-                    </div>
-                </script>
+                                foreach ($block->getMediaAttributes() as $attribute):
+                                    ?>
+                                    <li data-role-code="<?php echo $block->escapeHtml(
+                                        $attribute->getAttributeCode()
+                                    ) ?>" class="item-role item-role-<?php echo $block->escapeHtml(
+                                        $attribute->getAttributeCode()
+                                    ) ?>">
+                                        <?php /* @noEscape */ echo $attribute->getFrontendLabel() ?>
+                                    </li>
+                                    <?php
+                                endforeach;
+                                ?>
+                            </ul>
+                        </div>
+                    </script>
 
-                <script data-template="image" type="text/x-magento-template">
-                    <div class="image">
-                        <div class="product-image-wrapper">
-                            <img class="product-image"
-                                 data-role="image-element"
-                                 src="<%- data.url %>"
-                                 data-position="<%- data.position %>"
-                                 alt="<%- data.label %>" />
-
-                            <div class="actions">
-                                <button type="button"
-                                        class="action-remove"
-                                        data-role="delete-button"
-                                        title="<?= $block->escapeHtml(__('Remove image')) ?>">
-                                    <span><?= /* @noEscape */  __('Remove image') ?></span>
-                                </button>
-
-                                <div class="draggable-handle"></div>
-                            </div>
+                    <script data-template="image" type="text/x-magento-template">
+                        <div class="image">
+                            <div class="product-image-wrapper">
+                                <img class="product-image"
+                                     data-role="image-element"
+                                     src="<%- data.url %>"
+                                     data-position="<%- data.position %>"
+                                     alt="<%- data.label %>" />
+
+                                <div class="actions">
+                                    <button type="button"
+                                            class="action-remove"
+                                            data-role="delete-button"
+                                            title="<?= $block->escapeHtml(__('Remove image')) ?>">
+                                        <span><?php echo $block->escapeHtml(__('Remove image')) ?></span>
+                                    </button>
+
+                                    <div class="draggable-handle"></div>
+                                </div>
 
-                            <div class="image-fade"><span><?= /* @noEscape */  __('Hidden') ?></span></div>
+                                <div class="image-fade"><span><?php echo $block->escapeHtml(__('Hidden')) ?></span></div>
+                            </div>
+                            <!--<ul class="item-roles">
+                                <li class="item-role item-role-base">Base</li>
+                            </ul>-->
                         </div>
-                        <!--<ul class="item-roles">
-                            <li class="item-role item-role-base">Base</li>
-                        </ul>-->
-                    </div>
-                </script>
+                    </script>
 
-                <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
-                    <div class="image-panel ui-tabs-panel ui-widget-content ui-corner-bottom" data-role="dialog">
-                    </div>
-                </script>
+                    <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
+                        <div class="image-panel ui-tabs-panel ui-widget-content ui-corner-bottom" data-role="dialog">
+                        </div>
+                    </script>
 
-                <script class="dialog-template" type="text/x-magento-template" data-title="Image Options">
-                    <div class="image-panel-preview">
-                        <img src="<%- data.url %>" alt="<%- data.label %>" />
-                    </div>
-                    <div class="image-panel-controls">
-                        <strong class="image-name"><%- data.label %></strong>
+                    <script class="dialog-template" type="text/x-magento-template" data-title="Image Options">
+                        <div class="image-panel-preview">
+                            <img src="<%- data.url %>" alt="<%- data.label %>" />
+                        </div>
+                        <div class="image-panel-controls">
+                            <strong class="image-name"><%- data.label %></strong>
 
-                        <fieldset class="admin__fieldset fieldset-image-panel">
-                            <div class="admin__field field-image-description">
-                                <label class="admin__field-label" for="image-description">
-                                    <span><?php /* @escapeNotVerified */ echo __('Alt Text')?></span>
-                                </label>
+                            <fieldset class="admin__fieldset fieldset-image-panel">
+                                <div class="admin__field field-image-description">
+                                    <label class="admin__field-label" for="image-description">
+                                        <span><?php echo $block->escapeHtml(__('Alt Text')) ?></span>
+                                    </label>
 
-                                <div class="admin__field-control">
+                                    <div class="admin__field-control">
                             <textarea data-role="image-description"
                                       rows="3"
                                       class="admin__control-textarea"
                                       name="product[media_gallery][images][<%- data.file_id %>][label]"
-                                ><%- data.label %></textarea>
+                            ><%- data.label %></textarea>
+                                    </div>
                                 </div>
-                            </div>
 
-                            <div class="admin__field field-image-role">
-                                <label class="admin__field-label">
-                                    <span><?php /* @noEscape */ echo __('Role')?></span>
-                                </label>
-                                <div class="admin__field-control">
-                                    <ul class="multiselect-alt">
-                                        <?php
-                                        foreach ($block->getMediaAttributes() as $attribute) :
-                                            ?>
-                                            <li class="item">
-                                                <label>
-                                                    <input class="image-type"
-                                                           data-role="type-selector"
-                                                           type="checkbox"
-                                                           value="<?php echo $block->escapeHtml(
-                                                               $attribute->getAttributeCode()
-                                                           ) ?>"
-                                                        />
-                                                    <?php /* @noEscape */ echo $attribute->getFrontendLabel()?>
-                                                </label>
-                                            </li>
+                                <div class="admin__field field-image-role">
+                                    <label class="admin__field-label">
+                                    <span><?php echo $block->escapeHtml(
+                                            __('Role')
+                                        ); ?></span>
+                                    </label>
+                                    <div class="admin__field-control">
+                                        <ul class="multiselect-alt">
                                             <?php
-                                        endforeach;
-                                        ?>
-                                    </ul>
+                                            foreach ($block->getMediaAttributes() as $attribute) :
+                                                ?>
+                                                <li class="item">
+                                                    <label>
+                                                        <input class="image-type"
+                                                               data-role="type-selector"
+                                                               type="checkbox"
+                                                               value="<?php echo $block->escapeHtml(
+                                                                   $attribute->getAttributeCode()
+                                                               ) ?>"
+                                                        />
+                                                        <?php echo $block->escapeHtml(
+                                                            $attribute->getFrontendLabel()
+                                                        ); ?>
+                                                    </label>
+                                                </li>
+                                                <?php
+                                            endforeach;
+                                            ?>
+                                        </ul>
+                                    </div>
                                 </div>
-                            </div>
 
-                            <div class="admin__field admin__field-inline field-image-size" data-role="size">
-                                <label class="admin__field-label">
-                                    <span><?php /* @noEscape */ echo __('Image Size') ?></span>
-                                </label>
-                                <div class="admin__field-value" data-message="<?php /* @noEscape */ echo __('{size}') ?>"></div>
-                            </div>
+                                <div class="admin__field admin__field-inline field-image-size" data-role="size">
+                                    <label class="admin__field-label">
+                                    <span><?php echo $block->escapeHtml(
+                                            __('Image Size')
+                                        ); ?></span>
+                                    </label>
+                                    <div class="admin__field-value" data-message="<?php echo $block->escapeHtml(
+                                        __('{size}')
+                                    );?>"></div>
+                                </div>
 
-                            <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
-                                <label class="admin__field-label">
-                                    <span><?php /* @noEscape */ echo __('Image Resolution') ?></span>
-                                </label>
-                                <div class="admin__field-value" data-message="<?php /* @noEscape */ echo __('{width}^{height} px') ?>"></div>
-                            </div>
+                                <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
+                                    <label class="admin__field-label">
+                                    <span><?php echo $block->escapeHtml(
+                                            __('Image Resolution')
+                                        ); ?></span>
+                                    </label>
+                                    <div class="admin__field-value" data-message="<?php echo $block->escapeHtml(
+                                        __('{width}^{height} px')
+                                    );?>"></div>
+                                </div>
 
-                            <div class="admin__field field-image-hide">
-                                <div class="admin__field-control">
-                                    <div class="admin__field admin__field-option">
-                                        <input type="checkbox"
-                                               id="hide-from-product-page"
-                                               data-role="visibility-trigger"
-                                               value="1"
-                                               class="admin__control-checkbox"
-                                               name="product[media_gallery][images][<%- data.file_id %>][disabled]"
-                                        <% if (data.disabled == 1) { %>checked="checked"<% } %> />
-
-                                        <label for="hide-from-product-page" class="admin__field-label">
-                                            <?php /* @noEscape */ echo __('Hide from Product Page')?>
-                                        </label>
+                                <div class="admin__field field-image-hide">
+                                    <div class="admin__field-control">
+                                        <div class="admin__field admin__field-option">
+                                            <input type="checkbox"
+                                                   id="hide-from-product-page"
+                                                   data-role="visibility-trigger"
+                                                   value="1"
+                                                   class="admin__control-checkbox"
+                                                   name="product[media_gallery][images][<%- data.file_id %>][disabled]"
+                                            <% if (data.disabled == 1) { %>checked="checked"<% } %> />
+
+                                            <label for="hide-from-product-page" class="admin__field-label">
+                                                <?php echo $block->escapeHtml(
+                                                    __('Hide from Product Page')
+                                                ); ?>
+                                            </label>
+                                        </div>
                                     </div>
                                 </div>
-                            </div>
-                        </fieldset>
-                    </div>
-                </script>
+                            </fieldset>
+                        </div>
+                    </script>
+                </div>
             </div>
-        </div>
 
-        <div data-role="step-gallery-each" class="attribute-image-selector" data-bind="visible: type() == 'each'">
-            <fieldset class="admin__fieldset bulk-attribute-values">
-                <div class="admin__field _required">
-                    <label class="admin__field-label" for="apply-images-attributes">
-                        <span><?= /* @noEscape */  __('Select attribute')?></span>
-                    </label>
-                    <div class="admin__field-control">
-                        <select
-                            id="apply-images-attributes"
-                            class="admin__control-select"
-                            data-bind="
+            <div data-role="step-gallery-each" class="attribute-image-selector" data-bind="visible: type() == 'each'">
+                <fieldset class="admin__fieldset bulk-attribute-values">
+                    <div class="admin__field _required">
+                        <label class="admin__field-label" for="apply-images-attributes">
+                        <span><?php echo $block->escapeHtml(
+                                __('Select attribute')
+                            ); ?></span>
+                        </label>
+                        <div class="admin__field-control">
+                            <select
+                                id="apply-images-attributes"
+                                class="admin__control-select"
+                                data-bind="
                                 options: $parent.attributes,
                                 optionsText: 'label',
                                 value: attribute,
-                                optionsCaption: '<?= /* @noEscape */  __("Select")?>'
+                                optionsCaption: '<?php echo $block->escapeHtml(
+                                    __("Select")
+                                ); ?>'
                                 ">
-                        </select>
-                    </div>
-                </div>
-            </fieldset>
-
-            <ul class="items attributes-selector-list" data-bind="if:attribute, visible: attribute">
-                <!-- ko foreach: {data: attribute().chosen, afterRender: $parent.bindGalleries} -->
-                <li class="item" data-bind="attr:{'data-role':'step-gallery-option-' + id}">
-                    <label class="attribute-label">
-                        <span data-bind="text:label"></span>
-                    </label>
-
-                    <div data-role="gallery"
-                         class="gallery"
-                         data-images="[]"
-                         data-types="<?php /* @noEscape */ echo $block->escapeHtml(
-                             $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
-                         ) ?>"
-                        >
-                        <div class="image image-placeholder">
-                            <div data-role="uploader" class="uploader">
-                                <div class="image-browse">
-                                    <span><?= /* @noEscape */  __('Browse Files...') ?></span>
-                                    <input type="file" name="image" multiple="multiple"
-                                           data-url="<?= /* @noEscape */ $block->getUrl('catalog/product_gallery/upload') ?>" />
-                                </div>
-                            </div>
-                            <div class="product-image-wrapper">
-                                <p class="image-placeholder-text"><?= /* @noEscape */  __('Browse to find or drag image here') ?></p>
-                            </div>
-                            <div class="spinner">
-                               <span></span><span></span><span></span><span></span>
-                               <span></span><span></span><span></span><span></span>
-                            </div>
+                            </select>
                         </div>
+                    </div>
+                </fieldset>
 
-                        <?php foreach ($block->getImageTypes() as $typeData):
-                            ?>
-                            <input name="<?php echo $block->escapeHtml($typeData['name']) ?>"
-                                   class="image-<?php echo $block->escapeHtml($typeData['code']) ?>"
-                                   type="hidden"
-                                   value="<?php echo $block->escapeHtml($typeData['value']) ?>"/>
-                            <?php
-                            endforeach;
-                         ?>
+                <ul class="items attributes-selector-list" data-bind="if:attribute, visible: attribute">
+                    <!-- ko foreach: {data: attribute().chosen, afterRender: $parent.bindGalleries} -->
+                    <li class="item" data-bind="attr:{'data-role':'step-gallery-option-' + id}">
+                        <label class="attribute-label">
+                            <span data-bind="text:label"></span>
+                        </label>
 
-                        <script data-template="uploader" type="text/x-magento-template">
-                            <div id="<%- data.id %>" class="file-row">
-                                <span class="file-info"><%- data.name %> (<%- data.size %>)</span>
-                                <div class="progressbar-container">
-                                    <div class="progressbar upload-progress" style="width: 0%;"></div>
+                        <div data-role="gallery"
+                             class="gallery"
+                             data-images="[]"
+                             data-types="<?php  echo $block->escapeHtml(
+                                 $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
+                             ) ?>"
+                        >
+                            <div class="image image-placeholder">
+                                <div data-role="uploader" class="uploader">
+                                    <div class="image-browse">
+                                    <span><?php echo $block->escapeHtml(
+                                            __('Browse Files...')
+                                        ); ?></span>
+                                        <input type="file" name="image" multiple="multiple"
+                                               data-url="<?= /* @noEscape */ $block->getUrl('catalog/product_gallery/upload') ?>" />
+                                    </div>
+                                </div>
+                                <div class="product-image-wrapper">
+                                    <p class="image-placeholder-text"><?php echo $block->escapeHtml(
+                                            __('Browse to find or drag image here')
+                                        ); ?></p>
                                 </div>
                                 <div class="spinner">
                                     <span></span><span></span><span></span><span></span>
                                     <span></span><span></span><span></span><span></span>
                                 </div>
                             </div>
-                        </script>
-
-                        <script data-template="gallery-content" type="text/x-magento-template">
-                            <div class="image item <% if (data.disabled == 1) { %>hidden-for-front<% } %>"
-                                 data-role="image">
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][position]"
-                                       value="<%- data.position %>" class="position"/>
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][file]"
-                                       value="<%- data.file %>"/>
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][value_id]"
-                                       value="<%- data.value_id %>"/>
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][label]"
-                                       value="<%- data.label %>"/>
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][disabled]"
-                                       value="<%- data.disabled %>"/>
-                                <input type="hidden"
-                                       name="product[media_gallery][images][<%- data.file_id %>][removed]"
-                                       value=""
-                                       class="is-removed"/>
-                                <div class="product-image-wrapper">
-                                    <img class="product-image" data-role="image-element" src="<%- data.url %>" alt="<%- data.label %>"/>
-                                    <div class="actions">
-                                        <button type="button"
-                                                class="action-remove"
-                                                data-role="delete-button"
-                                                title="<?= $block->escapeHtml(__('Remove image')) ?>">
-                                            <span><?php /* @noEscape */ echo  __('Remove image') ?></span>
-                                        </button>
-                                        <div class="draggable-handle"></div>
+
+                            <?php foreach ($block->getImageTypes() as $typeData):
+                                ?>
+                                <input name="<?php echo $block->escapeHtml($typeData['name']) ?>"
+                                       class="image-<?php echo $block->escapeHtml($typeData['code']) ?>"
+                                       type="hidden"
+                                       value="<?php echo $block->escapeHtml($typeData['value']) ?>"/>
+                                <?php
+                            endforeach;
+                            ?>
+
+                            <script data-template="uploader" type="text/x-magento-template">
+                                <div id="<%- data.id %>" class="file-row">
+                                    <span class="file-info"><%- data.name %> (<%- data.size %>)</span>
+                                    <div class="progressbar-container">
+                                        <div class="progressbar upload-progress" style="width: 0%;"></div>
                                     </div>
-                                    <div class="image-fade"><span><?= /* @noEscape */  __('Hidden') ?></span></div>
-                                </div>
-                                <div class="item-description">
-                                    <div class="item-title" data-role="img-title"><%- data.label %></div>
-                                    <div class="item-size">
-                                        <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
+                                    <div class="spinner">
+                                        <span></span><span></span><span></span><span></span>
+                                        <span></span><span></span><span></span><span></span>
                                     </div>
                                 </div>
-                                <ul class="item-roles" data-role="roles-labels">
-                                    <?php
-                                    foreach ($block->getMediaAttributes() as $attribute):
-                                        ?>
-                                        <li data-role-code="<?php echo $block->escapeHtml(
-                                            $attribute->getAttributeCode()
-                                        ) ?>" class="item-role item-role-<?php echo $block->escapeHtml(
-                                            $attribute->getAttributeCode()
-                                        ) ?>">
-                                            <?php echo $block->escapeHtml($attribute->getFrontendLabel()) ?>
-                                        </li>
+                            </script>
+
+                            <script data-template="gallery-content" type="text/x-magento-template">
+                                <div class="image item <% if (data.disabled == 1) { %>hidden-for-front<% } %>"
+                                     data-role="image">
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][position]"
+                                           value="<%- data.position %>" class="position"/>
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][file]"
+                                           value="<%- data.file %>"/>
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][value_id]"
+                                           value="<%- data.value_id %>"/>
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][label]"
+                                           value="<%- data.label %>"/>
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][disabled]"
+                                           value="<%- data.disabled %>"/>
+                                    <input type="hidden"
+                                           name="product[media_gallery][images][<%- data.file_id %>][removed]"
+                                           value=""
+                                           class="is-removed"/>
+                                    <div class="product-image-wrapper">
+                                        <img class="product-image" data-role="image-element" src="<%- data.url %>" alt="<%- data.label %>"/>
+                                        <div class="actions">
+                                            <button type="button"
+                                                    class="action-remove"
+                                                    data-role="delete-button"
+                                                    title="<?= $block->escapeHtml(__('Remove image')) ?>">
+                                            <span><?php echo $block->escapeHtml(
+                                                    __('Remove image')
+                                                ); ?></span>
+                                            </button>
+                                            <div class="draggable-handle"></div>
+                                        </div>
+                                        <div class="image-fade"><span><?php echo $block->escapeHtml(
+                                                    __('Hidden')
+                                                ); ?></span></div>
+                                    </div>
+                                    <div class="item-description">
+                                        <div class="item-title" data-role="img-title"><%- data.label %></div>
+                                        <div class="item-size">
+                                            <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
+                                        </div>
+                                    </div>
+                                    <ul class="item-roles" data-role="roles-labels">
                                         <?php
-                                    endforeach;
-                                    ?>
-                                </ul>
-                            </div>
-                        </script>
-
-                        <script data-template="image" type="text/x-magento-template">
-                            <div class="image">
-                                <div class="product-image-wrapper">
-                                    <img class="product-image"
-                                         src="<%- data.url %>"
-                                         data-role="image-element"
-                                         data-position="<%- data.position %>"
-                                         alt="<%- data.label %>" />
-                                    <div class="actions">
-                                        <button type="button"
-                                                class="action-remove"
-                                                data-role="delete-button"
-                                                title="<?= $block->escapeHtml(__('Remove image')) ?>">
-                                            <span><?= /* @noEscape */  __('Remove image') ?></span>
-                                        </button>
-                                        <div class="draggable-handle"></div>
+                                        foreach ($block->getMediaAttributes() as $attribute):
+                                            ?>
+                                            <li data-role-code="<?php echo $block->escapeHtml(
+                                                $attribute->getAttributeCode()
+                                            ) ?>" class="item-role item-role-<?php echo $block->escapeHtml(
+                                                $attribute->getAttributeCode()
+                                            ) ?>">
+                                                <?php echo $block->escapeHtml($attribute->getFrontendLabel()) ?>
+                                            </li>
+                                            <?php
+                                        endforeach;
+                                        ?>
+                                    </ul>
+                                </div>
+                            </script>
+
+                            <script data-template="image" type="text/x-magento-template">
+                                <div class="image">
+                                    <div class="product-image-wrapper">
+                                        <img class="product-image"
+                                             src="<%- data.url %>"
+                                             data-role="image-element"
+                                             data-position="<%- data.position %>"
+                                             alt="<%- data.label %>" />
+                                        <div class="actions">
+                                            <button type="button"
+                                                    class="action-remove"
+                                                    data-role="delete-button"
+                                                    title="<?= $block->escapeHtml(__('Remove image')) ?>">
+                                                <span><?php echo $block->escapeHtml(__('Remove image')) ?></span>
+                                            </button>
+                                            <div class="draggable-handle"></div>
+                                        </div>
+                                        <div class="image-fade"><span><?php echo $block->escapeHtml(__('Hidden')) ?></span></div>
                                     </div>
-                                    <div class="image-fade"><span><?= /* @noEscape */  __('Hidden') ?></span></div>
+                                    <!--<ul class="item-roles">
+                                        <li class="item-role item-role-base">Base</li>
+                                    </ul>-->
                                 </div>
-                                <!--<ul class="item-roles">
-                                    <li class="item-role item-role-base">Base</li>
-                                </ul>-->
-                            </div>
-                        </script>
-
-                        <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
-                            <div class="image-panel ui-tabs-panel ui-widget-content ui-corner-bottom" data-role="dialog">
-                            </div>
-                        </script>
+                            </script>
 
-                        <script class="dialog-template" type="text/x-magento-template" data-title="Image Options">
-                            <div class="image-panel-preview">
-                                <img src="<%- data.url %>" alt="<%- data.label %>" />
-                            </div>
-                            <div class="image-panel-controls">
-                                <strong class="image-name"><%- data.label %></strong>
-
-                                <fieldset class="admin__fieldset fieldset-image-panel">
-                                    <div class="admin__field field-image-description">
-                                        <label class="admin__field-label" for="image-description">
-                                            <span><?php /* @noEscape */ echo __('Alt Text')?></span>
-                                        </label>
+                            <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
+                                <div class="image-panel ui-tabs-panel ui-widget-content ui-corner-bottom" data-role="dialog">
+                                </div>
+                            </script>
 
-                                        <div class="admin__field-control">
+                            <script class="dialog-template" type="text/x-magento-template" data-title="Image Options">
+                                <div class="image-panel-preview">
+                                    <img src="<%- data.url %>" alt="<%- data.label %>" />
+                                </div>
+                                <div class="image-panel-controls">
+                                    <strong class="image-name"><%- data.label %></strong>
+
+                                    <fieldset class="admin__fieldset fieldset-image-panel">
+                                        <div class="admin__field field-image-description">
+                                            <label class="admin__field-label" for="image-description">
+                                            <span><?php echo $block->escapeHtml(
+                                                    __('Alt Text')
+                                                );?></span>
+                                            </label>
+
+                                            <div class="admin__field-control">
                                             <textarea data-role="image-description"
                                                       rows="3"
                                                       class="admin__control-textarea"
                                                       name="product[media_gallery][images][<%- data.file_id %>][label]"
-                                                ><%- data.label %></textarea>
+                                            ><%- data.label %></textarea>
+                                            </div>
                                         </div>
-                                    </div>
 
-                                    <div class="admin__field field-image-role">
-                                        <label class="admin__field-label">
-                                            <span><?php /* @noEscape */ echo __('Role')?></span>
-                                        </label>
-                                        <div class="admin__field-control">
-                                            <ul class="multiselect-alt">
-                                                <?php
-                                                foreach ($block->getMediaAttributes() as $attribute) :
-                                                    ?>
-                                                    <li class="item">
-                                                        <label>
-                                                            <input class="image-type"
-                                                                   data-role="type-selector"
-                                                                   type="checkbox"
-                                                                   value="<?php echo $block->escapeHtml(
-                                                                       $attribute->getAttributeCode()
-                                                                   ) ?>"
-                                                                />
-                                                            <?php echo $block->escapeHtml(
-                                                                $attribute->getFrontendLabel()
-                                                            ) ?>
-                                                        </label>
-                                                    </li>
+                                        <div class="admin__field field-image-role">
+                                            <label class="admin__field-label">
+                                            <span><?php echo $block->escapeHtml(
+                                                    __('Role')
+                                                );?></span>
+                                            </label>
+                                            <div class="admin__field-control">
+                                                <ul class="multiselect-alt">
                                                     <?php
-                                                endforeach;
-                                                ?>
-                                            </ul>
+                                                    foreach ($block->getMediaAttributes() as $attribute) :
+                                                        ?>
+                                                        <li class="item">
+                                                            <label>
+                                                                <input class="image-type"
+                                                                       data-role="type-selector"
+                                                                       type="checkbox"
+                                                                       value="<?php echo $block->escapeHtml(
+                                                                           $attribute->getAttributeCode()
+                                                                       ) ?>"
+                                                                />
+                                                                <?php echo $block->escapeHtml(
+                                                                    $attribute->getFrontendLabel()
+                                                                ) ?>
+                                                            </label>
+                                                        </li>
+                                                        <?php
+                                                    endforeach;
+                                                    ?>
+                                                </ul>
+                                            </div>
                                         </div>
-                                    </div>
 
-                                    <div class="admin__field admin__field-inline field-image-size" data-role="size">
-                                        <label class="admin__field-label">
-                                            <span><?php /* @noEscape */ echo __('Image Size') ?></span>
-                                        </label>
-                                        <div class="admin__field-value" data-message="<?php /* @noEscape */ echo __('{size}') ?>"></div>
-                                    </div>
+                                        <div class="admin__field admin__field-inline field-image-size" data-role="size">
+                                            <label class="admin__field-label">
+                                            <span><?php echo $block->escapeHtml(
+                                                    __('Image Size')
+                                                ); ?></span>
+                                            </label>
+                                            <div class="admin__field-value" data-message="<?php echo $block->escapeHtml(
+                                                __('{size}')
+                                            ); ?>"></div>
+                                        </div>
 
-                                    <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
-                                        <label class="admin__field-label">
-                                            <span><?php /* @noEscape */ echo __('Image Resolution') ?></span>
-                                        </label>
-                                        <div class="admin__field-value" data-message="<?php /* @noEscape */ echo __('{width}^{height} px') ?>"></div>
-                                    </div>
+                                        <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
+                                            <label class="admin__field-label">
+                                            <span><?php echo $block->escapeHtml(
+                                                    __('Image Resolution')
+                                                ); ?></span>
+                                            </label>
+                                            <div class="admin__field-value" data-message="<?php echo $block->escapeHtml(
+                                                __('{width}^{height} px')
+                                            ); ?>"></div>
+                                        </div>
 
-                                    <div class="admin__field field-image-hide">
-                                        <div class="admin__field-control">
-                                            <div class="admin__field admin__field-option">
-                                                <input type="checkbox"
-                                                       id="hide-from-product-page"
-                                                       data-role="visibility-trigger"
-                                                       value="1"
-                                                       class="admin__control-checkbox"
-                                                       name="product[media_gallery][images][<%- data.file_id %>][disabled]"
-                                                <% if (data.disabled == 1) { %>checked="checked"<% } %> />
-
-                                                <label for="hide-from-product-page" class="admin__field-label">
-                                                    <?php /* @noEscape */ echo __('Hide from Product Page')?>
-                                                </label>
+                                        <div class="admin__field field-image-hide">
+                                            <div class="admin__field-control">
+                                                <div class="admin__field admin__field-option">
+                                                    <input type="checkbox"
+                                                           id="hide-from-product-page"
+                                                           data-role="visibility-trigger"
+                                                           value="1"
+                                                           class="admin__control-checkbox"
+                                                           name="product[media_gallery][images][<%- data.file_id %>][disabled]"
+                                                    <% if (data.disabled == 1) { %>checked="checked"<% } %> />
+
+                                                    <label for="hide-from-product-page" class="admin__field-label">
+                                                        <?php echo $block->escapeHtml(
+                                                            __('Hide from Product Page')
+                                                        ); ?>
+                                                    </label>
+                                                </div>
                                             </div>
                                         </div>
-                                    </div>
-                                </fieldset>
-                            </div>
-                        </script>
-                    </div>
-                </li>
-                <!-- /ko -->
-            </ul>
+                                    </fieldset>
+                                </div>
+                            </script>
+                        </div>
+                    </li>
+                    <!-- /ko -->
+                </ul>
+            </div>
         </div>
     </div>
-</div>
 
     <div data-bind="with: sections().price" class="steps-wizard-section">
         <div data-role="section">
             <div class="steps-wizard-section-title">
-                <span><?php /* @noEscape */ echo  __('Price') ?></span>
+                <span><?php echo $block->escapeHtml(
+                        __('Price')
+                    ); ?></span>
             </div>
             <ul class="steps-wizard-section-list">
                 <li>
@@ -562,7 +607,9 @@
                                data-bind="checked:type" />
                         <label for="apply-single-price-radio"
                                class="admin__field-label">
-                            <span><?php /* @noEscape */ echo __('Apply single price to all SKUs') ?></span>
+                            <span><?php echo $block->escapeHtml(
+                                    __('Apply single price to all SKUs')
+                                ); ?></span>
                         </label>
                     </div>
                 </li>
@@ -575,7 +622,9 @@
                                data-bind="checked:type" />
                         <label for="apply-unique-prices-radio"
                                class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Apply unique prices by attribute to each SKU') ?></span>
+                            <span><?php echo $block->escapeHtml(
+                                    __('Apply unique prices by attribute to each SKU')
+                                ); ?></span>
                         </label>
                     </div>
                 </li>
@@ -588,33 +637,39 @@
                                checked
                                data-bind="checked:type" />
                         <label for="skip-pricing-radio" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Skip price at this time') ?></span>
+                            <span><?php echo $block->escapeHtml(
+                                    __('Skip price at this time')
+                                ); ?></span>
                         </label>
                     </div>
                 </li>
             </ul>
             <form data-role="attributes-values-form">
-            <fieldset class="admin__fieldset bulk-attribute-values" data-bind="visible: type() == 'single'">
-                <div class="admin__field _required">
-                    <label for="apply-single-price-input" class="admin__field-label">
-                        <span><?php /* @noEscape */ echo  __('Price') ?></span>
-                    </label>
-                    <div class="admin__field-control">
-                        <div class="currency-addon">
-                            <input class="admin__control-text required-entry validate-zero-or-greater" type="text"
-                                   data-bind="value:value, uniqueName: true" id="apply-single-price-input"/>
-                            <span class="currency-symbol" data-bind="text:currencySymbol"></span>
+                <fieldset class="admin__fieldset bulk-attribute-values" data-bind="visible: type() == 'single'">
+                    <div class="admin__field _required">
+                        <label for="apply-single-price-input" class="admin__field-label">
+                        <span><?php echo $block->escapeHtml(
+                                __('Price')
+                            ); ?></span>
+                        </label>
+                        <div class="admin__field-control">
+                            <div class="currency-addon">
+                                <input class="admin__control-text required-entry validate-zero-or-greater" type="text"
+                                       data-bind="value:value, uniqueName: true" id="apply-single-price-input"/>
+                                <span class="currency-symbol" data-bind="text:currencySymbol"></span>
+                            </div>
                         </div>
                     </div>
-                </div>
-            </fieldset>
+                </fieldset>
             </form>
 
             <div data-bind="visible: type() == 'each'">
                 <fieldset class="admin__fieldset bulk-attribute-values">
                     <div class="admin__field _required">
                         <label for="select-each-price" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Select attribute') ?></span>
+                            <span><?php echo $block->escapeHtml(
+                                    __('Select attribute')
+                                ); ?></span>
                         </label>
                         <div class="admin__field-control">
                             <select id="select-each-price" class="admin__control-select" data-bind="
@@ -653,7 +708,7 @@
     <div data-bind="with: sections().quantity" class="steps-wizard-section">
         <div data-role="section">
             <div class="steps-wizard-section-title">
-                <span><?php /* @noEscape */ echo  __('Quantity') ?></span>
+                <span><?php echo $block->escapeHtml(__('Quantity')) ?></span>
             </div>
             <ul class="steps-wizard-section-list">
                 <li>
@@ -664,7 +719,7 @@
                                value="single"
                                data-bind="checked: type" />
                         <label for="apply-single-inventory-radio" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Apply single quantity to each SKUs') ?></span>
+                            <span><?php echo $block->escapeHtml(__('Apply single quantity to each SKUs')) ?></span>
                         </label>
                     </div>
                 </li>
@@ -676,7 +731,7 @@
                                value="each"
                                data-bind="checked: type" />
                         <label for="apply-unique-inventory-radio" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Apply unique quantity by attribute to each SKU') ?></span>
+                            <span><?php echo $block->escapeHtml(__('Apply unique quantity by attribute to each SKU')) ?></span>
                         </label>
                     </div>
                 </li>
@@ -689,33 +744,33 @@
                                checked
                                data-bind="checked: type" />
                         <label for="skip-inventory-radio" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Skip quantity at this time') ?></span>
+                            <span><?php echo $block->escapeHtml(__('Skip quantity at this time')) ?></span>
                         </label>
                     </div>
                 </li>
             </ul>
 
             <form data-role="attributes-values-form">
-            <fieldset class="admin__fieldset bulk-attribute-values" data-bind="visible: type() == 'single'">
-                <div class="admin__field _required">
-                    <label for="apply-single-inventory-input" class="admin__field-label">
-                        <span><?php /* @noEscape */ echo  __('Quantity') ?></span>
-                    </label>
-                    <div class="admin__field-control">
-                        <input type="text"
-                               id="apply-single-inventory-input"
-                               class="admin__control-text required-entry validate-zero-or-greater"
-                               data-bind="value: value, uniqueName: true" />
+                <fieldset class="admin__fieldset bulk-attribute-values" data-bind="visible: type() == 'single'">
+                    <div class="admin__field _required">
+                        <label for="apply-single-inventory-input" class="admin__field-label">
+                            <span><?php echo $block->escapeHtml(__('Quantity')) ?></span>
+                        </label>
+                        <div class="admin__field-control">
+                            <input type="text"
+                                   id="apply-single-inventory-input"
+                                   class="admin__control-text required-entry validate-zero-or-greater"
+                                   data-bind="value: value, uniqueName: true" />
+                        </div>
                     </div>
-                </div>
-            </fieldset>
+                </fieldset>
             </form>
 
             <div data-bind="visible: type() == 'each'">
                 <fieldset class="admin__fieldset bulk-attribute-values">
                     <div class="admin__field _required">
                         <label for="apply-single-price-input-qty" class="admin__field-label">
-                            <span><?php /* @noEscape */ echo  __('Select attribute') ?></span>
+                            <span><?php echo $block->escapeHtml(__('Select attribute')) ?></span>
                         </label>
                         <div class="admin__field-control">
                             <select id="apply-single-price-input-qty" class="admin__control-select" data-bind="
@@ -727,26 +782,26 @@
                     </div>
                 </fieldset>
                 <form data-role="attributes-values-form">
-                <fieldset class="admin__fieldset bulk-attribute-values" data-bind="if:attribute">
-                    <!-- ko foreach: attribute().chosen -->
-                    <div class="admin__field _required">
-                        <label data-bind="attr: {for: 'apply-qty-input-' + $index()}" class="admin__field-label">
-                            <span data-bind="text:label"></span>
-                        </label>
-                        <div class="admin__field-control">
-                            <input id="apply-single-price-input-value"
-                                   class="admin__control-text required-entry validate-zero-or-greater" type="text"
-                                   data-bind="value:sections()[$parent.label], uniqueName: true,
+                    <fieldset class="admin__fieldset bulk-attribute-values" data-bind="if:attribute">
+                        <!-- ko foreach: attribute().chosen -->
+                        <div class="admin__field _required">
+                            <label data-bind="attr: {for: 'apply-qty-input-' + $index()}" class="admin__field-label">
+                                <span data-bind="text:label"></span>
+                            </label>
+                            <div class="admin__field-control">
+                                <input id="apply-single-price-input-value"
+                                       class="admin__control-text required-entry validate-zero-or-greater" type="text"
+                                       data-bind="value:sections()[$parent.label], uniqueName: true,
                                    attr: {id: 'apply-qty-input-' + $index()}"/>
+                            </div>
                         </div>
-                    </div>
-                    <!-- /ko -->
-                </fieldset>
+                        <!-- /ko -->
+                    </fieldset>
                 </form>
             </div>
         </div>
     </div>
-</form>
+    </form>
 </div>
 
 <script type="text/x-magento-init">
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/select_attributes.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/select_attributes.phtml
index 7028eadb72c848ae6c21ac6c797afe6705d52e9a..ffb27ccd3c85561dfd377f7dd4cb6301339e70ab 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/select_attributes.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/select_attributes.phtml
@@ -12,9 +12,13 @@
     <div class="select-attributes-actions" data-type="skipKO">
         <?= /* @noEscape */  $block->getAddNewAttributeButton(); ?>
     </div>
-    <h2 class="steps-wizard-title"><?= /* @noEscape */  __('Step 1: Select Attributes') ?></h2>
+    <h2 class="steps-wizard-title"><?php echo $block->escapeHtml(
+            __('Step 1: Select Attributes')
+        ); ?></h2>
     <div class="selected-attributes" data-bind="scope: '<?= /* @noEscape */  $block->getComponentName()?>'">
-        <?= /* @noEscape */  __('Selected Attributes:') ?>
+        <?php echo $block->escapeHtml(
+            __('Selected Attributes:')
+        ); ?>
         <span data-bind="text: selectedAttributes() || '--'"></span>
     </div>
 </div>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml
index e5ab81c99cc19fd9434babddc0c6a2df847c4f54..37bde42041b6dc10b0cff20137890730fd68c092 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml
@@ -9,34 +9,36 @@
 /* @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Steps\Summary */
 ?>
 <div data-bind="scope: '<?= /* @noEscape */  $block->getComponentName()?>'">
-    <h2 class="steps-wizard-title"><?= /* @noEscape */  __('Step 4: Summary') ?></h2>
+    <h2 class="steps-wizard-title"><?php echo $block->escapeHtml(
+            __('Step 4: Summary')
+        ); ?></h2>
 
     <div class="admin__data-grid-wrap admin__data-grid-wrap-static">
         <!-- ko if: gridNew().length -->
-            <!-- ko template: {name: getGridTemplate(), data: {
-                grid: gridNew,
-                id: getGridId(),
-                title: $t('New Product Review'),
-                note: $t('Here are the products you\'re about to create.')
-            }} --><!-- /ko -->
+        <!-- ko template: {name: getGridTemplate(), data: {
+            grid: gridNew,
+            id: getGridId(),
+            title: $t('New Product Review'),
+            note: $t('Here are the products you\'re about to create.')
+        }} --><!-- /ko -->
         <!-- /ko -->
 
         <!-- ko if: gridExisting().length -->
-            <!-- ko template: {name: getGridTemplate(), data: {
-                grid: gridExisting,
-                id: getGridId(),
-                title: $t('Associated Products'),
-                note: $t('You created these products for this configuration.')
-            }} --><!-- /ko -->
+        <!-- ko template: {name: getGridTemplate(), data: {
+            grid: gridExisting,
+            id: getGridId(),
+            title: $t('Associated Products'),
+            note: $t('You created these products for this configuration.')
+        }} --><!-- /ko -->
         <!-- /ko -->
 
         <!-- ko if: gridDeleted().length -->
-            <!-- ko template: {name: getGridTemplate(), data: {
-                grid: gridDeleted,
-                id: getGridId(),
-                title: $t('Disassociated Products'),
-                note: $t('These products are not associated.')
-            }} --><!-- /ko -->
+        <!-- ko template: {name: getGridTemplate(), data: {
+            grid: gridDeleted,
+            id: getGridId(),
+            title: $t('Disassociated Products'),
+            note: $t('These products are not associated.')
+        }} --><!-- /ko -->
         <!-- /ko -->
     </div>
 </div>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/wizard.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/wizard.phtml
index 0736fa20fd21e6cf07512e665ce79c3d40c8ceb0..930a264ea8952623bb6f1e5e45a42516e12a9c1c 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/wizard.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/wizard.phtml
@@ -26,7 +26,7 @@ $currencySymbol = $block->getCurrencySymbol();
                 "components": {
                     "<?= /* @noEscape */ $block->getData('config/form') ?>.<?= /* @noEscape */ $block->getModal() ?>": {
                         "component": "Magento_ConfigurableProduct/js/components/modal-configurable",
-                        "options": {"type": "slide", "title": "<?= /* @escapeNotVerified */  __('Create Product Configurations') ?>"},
+                        "options": {"type": "slide", "title": "<?php echo $block->escapeHtml(__('Create Product Configurations')); ?>"},
                         "formName": "<?= /* @noEscape */ $block->getForm() ?>",
                         "isTemplate": false,
                         "stepWizard": "<?= /* @noEscape */ $block->getData('config/nameStepWizard') ?>",
@@ -47,7 +47,7 @@ $currencySymbol = $block->getCurrencySymbol();
                         "formName": "<?= /* @noEscape */ $block->getForm() ?>",
                         "attributeSetHandler": "<?= /* @noEscape */ $block->getForm() ?>.configurable_attribute_set_handler_modal",
                         "wizardModalButtonName": "<?= /* @noEscape */ $block->getForm() ?>.configurable.configurable_products_button_set.create_configurable_products_button",
-                        "wizardModalButtonTitle": "<?= /* @noEscape */  __('Edit Configurations') ?>",
+                        "wizardModalButtonTitle": "<?php echo $block->escapeHtml(__('Edit Configurations')); ?>",
                         "productAttributes": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($attributes) ?>,
                         "productUrl": "<?= /* @noEscape */ $block->getUrl('catalog/product/edit', ['id' => '%id%']) ?>",
                         "variations": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($productMatrix) ?>,
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/associated-product-insert-listing.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/associated-product-insert-listing.js
index 0c2847683474f813a72d884e5fbb6d002f94400f..ecc960bdb9ea59f09903dea3a118f65642993e8e 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/associated-product-insert-listing.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/associated-product-insert-listing.js
@@ -24,7 +24,8 @@ define([
                 productsProvider: '${ $.productsProvider }',
                 productsColumns: '${ $.productsColumns }',
                 productsMassAction: '${ $.productsMassAction }',
-                modalWithGrid: '${ $.modalWithGrid }'
+                modalWithGrid: '${ $.modalWithGrid }',
+                productsFilters: '${ $.productsFilters }'
             },
             exports: {
                 externalProviderParams: '${ $.externalProvider }:params'
@@ -58,7 +59,9 @@ define([
          * @returns {Array}
          */
         getUsedProductIds: function () {
-            return this.source.get(this.dataScopeAssociatedProduct);
+            var usedProductsIds = this.source.get(this.dataScopeAssociatedProduct);
+
+            return usedProductsIds.slice();
         },
 
         /**
@@ -72,6 +75,7 @@ define([
 
             if (this.gridInitialized) {
                 this.paramsUpdated = false;
+                this.productsFilters().clear();
                 this._setFilters(this.externalProviderParams);
                 this._setVisibilityMassActionColumn();
             }
@@ -142,11 +146,13 @@ define([
                 usedProductIds,
                 attributes;
 
+            params = _.omit(params);
+
             if (!this.paramsUpdated) {
                 this.gridInitialized = true;
                 this.paramsUpdated = true;
 
-                attrCodes = this._getAttributesCodes(),
+                attrCodes = this._getAttributesCodes();
                 usedProductIds = this.getUsedProductIds();
 
                 if (this.currentProductId) {
@@ -173,6 +179,8 @@ define([
                     }));
 
                     params.filters = attributes;
+                } else {
+                    params.filters = {};
                 }
 
                 params['attributes_codes'] = attrCodes;
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
index 46c0443b16a069e5d68d1519d0782ac349e9d4d1..7614f41250af2c128c58d28d7528b333d61e0623 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
@@ -113,7 +113,7 @@ define([
             var tmpArray;
 
             this.reRender = false;
-            tmpArray = this.unionInsertData();
+            tmpArray = this.getUnionInsertData();
             tmpArray.splice(index, 1);
 
             if (!tmpArray.length) {
@@ -130,7 +130,7 @@ define([
         generateAssociatedProducts: function () {
             var productsIds = [];
 
-            this.unionInsertData().each(function (data) {
+            this.getUnionInsertData().each(function (data) {
                 if (data.id !== null) {
                     productsIds.push(data.id);
                 }
@@ -153,6 +153,22 @@ define([
             return this;
         },
 
+        /**
+         * Get union insert data from source
+         *
+         * @returns {Array}
+         */
+        getUnionInsertData: function () {
+            var source = this.source.get(this.dataScope + '.' + this.index),
+                result = [];
+
+            _.each(source, function (data) {
+                result.push(data);
+            });
+
+            return result;
+        },
+
         /**
          * Process union insert data.
          *
@@ -217,7 +233,7 @@ define([
                 return;
             }
 
-            tmpArray = this.unionInsertData();
+            tmpArray = this.getUnionInsertData();
 
             changes = this._checkGridData(data);
             this.cacheGridData = data;
@@ -241,7 +257,7 @@ define([
          * @param {Object} data
          */
         processingChangeDataFromGrid: function (data) {
-            var tmpArray = this.unionInsertData(),
+            var tmpArray = this.getUnionInsertData(),
                 mappedData = this.mappingValue(data.product);
 
             mappedData[this.canEditField] = 0;
@@ -295,7 +311,7 @@ define([
          * @param {Object} data
          */
         processingInsertDataFromWizard: function (data) {
-            var tmpArray = this.unionInsertData(),
+            var tmpArray = this.getUnionInsertData(),
                 productIdsToDelete = this.source.get(this.dataScopeAssociatedProduct),
                 index,
                 product = {};
@@ -466,7 +482,7 @@ define([
          * @param {Number} rowIndex
          */
         toggleStatusProduct: function (rowIndex) {
-            var tmpArray = this.unionInsertData(),
+            var tmpArray = this.getUnionInsertData(),
                 status = parseInt(tmpArray[rowIndex].status, 10);
 
             if (status === 1) {
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
index 5fafc70d1a74118863273a27dd154a733d33991c..d38e2760f1dc7fc6d31772481ab9cc64b757413e 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
@@ -23,7 +23,7 @@ define([
             state: {},
             priceFormat: {},
             optionTemplate: '<%- data.label %>' +
-            '<% if (data.finalPrice.value) { %>' +
+            "<% if (typeof data.finalPrice.value !== 'undefined') { %>" +
             ' <%- data.finalPrice.formatted %>' +
             '<% } %>',
             mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',
diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php
index d1adf3bf1c85a45d61302343d23b49373954a1c3..2429e45d643417e3007f3b93a88eefaf6f240d4f 100644
--- a/app/code/Magento/Customer/Model/AccountManagement.php
+++ b/app/code/Magento/Customer/Model/AccountManagement.php
@@ -673,6 +673,7 @@ class AccountManagement implements AccountManagementInterface
             }
             // Existing password hash will be used from secured customer data registry when saving customer
         }
+
         // Make sure we have a storeId to associate this customer with.
         if (!$customer->getStoreId()) {
             if ($customer->getWebsiteId()) {
@@ -680,14 +681,18 @@ class AccountManagement implements AccountManagementInterface
             } else {
                 $storeId = $this->storeManager->getStore()->getId();
             }
-
             $customer->setStoreId($storeId);
         }
 
+        // Associate website_id with customer
+        if (!$customer->getWebsiteId()) {
+            $websiteId = $this->storeManager->getStore($customer->getStoreId())->getWebsiteId();
+            $customer->setWebsiteId($websiteId);
+        }
+
         // Update 'created_in' value with actual store name
         if ($customer->getId() === null) {
-            $storeName = $this->storeManager->getStore($customer->getStoreId())
-                ->getName();
+            $storeName = $this->storeManager->getStore($customer->getStoreId())->getName();
             $customer->setCreatedIn($storeName);
         }
 
diff --git a/app/code/Magento/Customer/Model/Observer/Grid.php b/app/code/Magento/Customer/Model/Observer/Grid.php
index 684bb60c4bc50ff9bd33bb174bf3fe0c29aa3d5f..c7f3d09acd81f0a3493e1e0a6d06ebb6b4c17b47 100644
--- a/app/code/Magento/Customer/Model/Observer/Grid.php
+++ b/app/code/Magento/Customer/Model/Observer/Grid.php
@@ -7,6 +7,9 @@ namespace Magento\Customer\Model\Observer;
 
 use Magento\Customer\Model\ResourceModel\Customer\Grid as CustomerGrid;
 
+/**
+ * @deprecated
+ */
 class Grid
 {
     /**
@@ -25,6 +28,8 @@ class Grid
 
     /**
      * @return void
+     *
+     * @deprecated
      */
     public function syncCustomerGrid()
     {
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Customer/Grid.php b/app/code/Magento/Customer/Model/ResourceModel/Customer/Grid.php
index 407eb9c9c008194201fcad984db609e4acac0bf3..12faa3c920f6a2ab2d05a0448a8e35ae9254dafb 100644
--- a/app/code/Magento/Customer/Model/ResourceModel/Customer/Grid.php
+++ b/app/code/Magento/Customer/Model/ResourceModel/Customer/Grid.php
@@ -10,6 +10,9 @@ use Magento\Framework\Indexer\IndexerRegistry;
 use Magento\Framework\Indexer\ScopeResolver\FlatScopeResolver;
 use Magento\Customer\Model\Customer;
 
+/**
+ * @deprecated
+ */
 class Grid
 {
     /** @var Resource */
@@ -42,6 +45,8 @@ class Grid
      * Synchronize customer grid
      *
      * @return void
+     *
+     * @deprecated
      */
     public function syncCustomerGrid()
     {
@@ -56,6 +61,8 @@ class Grid
      * Retrieve customer IDs for reindex
      *
      * @return array
+     *
+     * @deprecated
      */
     protected function getCustomerIdsForReindex()
     {
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php b/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..d31e3c2930522ed610c9e23f4fbcaf4e2e81d0a9
--- /dev/null
+++ b/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Customer\Model\ResourceModel\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'customer_grid_flat',
+        $resourceModel = '\Magento\Customer\Model\ResourceModel\Customer'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
index c5f87d16cefe49dd927987de902ede5893af20eb..1bfcac2c81ff8d0b39428951d799bae4ce3046a3 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php
@@ -543,7 +543,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase
             ->method('getName')
             ->willReturn($storeName);
 
-        $this->storeManager->expects($this->once())
+        $this->storeManager->expects($this->exactly(2))
             ->method('getStore')
             ->with($storeId)
             ->willReturn($storeMock);
@@ -1529,4 +1529,71 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase
             ['test2@example.com', 1, 'test', AccountManagement::ACCOUNT_CONFIRMATION_REQUIRED],
         ];
     }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     */
+    public function testCreateAccountWithPasswordHashForGuest()
+    {
+        $storeId = 1;
+        $storeName = 'store_name';
+        $websiteId = 1;
+        $hash = '4nj54lkj5jfi03j49f8bgujfgsd';
+
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($storeId);
+        $storeMock->expects($this->once())
+            ->method('getWebsiteId')
+            ->willReturn($websiteId);
+        $storeMock->expects($this->once())
+            ->method('getName')
+            ->willReturn($storeName);
+
+        $this->storeManager->expects($this->exactly(3))
+            ->method('getStore')
+            ->willReturn($storeMock);
+
+        $customerMock = $this->getMockBuilder('Magento\Customer\Api\Data\CustomerInterface')
+            ->getMockForAbstractClass();
+        $customerMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn(null);
+        $customerMock->expects($this->exactly(3))
+            ->method('getStoreId')
+            ->willReturn(null);
+        $customerMock->expects($this->exactly(2))
+            ->method('getWebsiteId')
+            ->willReturn(null);
+        $customerMock->expects($this->once())
+            ->method('setStoreId')
+            ->with($storeId)
+            ->willReturnSelf();
+        $customerMock->expects($this->once())
+            ->method('setWebsiteId')
+            ->with($websiteId)
+            ->willReturnSelf();
+        $customerMock->expects($this->once())
+            ->method('setCreatedIn')
+            ->with($storeName)
+            ->willReturnSelf();
+        $customerMock->expects($this->once())
+            ->method('getAddresses')
+            ->willReturn(null);
+        $customerMock->expects($this->once())
+            ->method('setAddresses')
+            ->with(null)
+            ->willReturnSelf();
+
+        $this->customerRepository
+            ->expects($this->once())
+            ->method('save')
+            ->with($customerMock, $hash)
+            ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('Exception message')));
+
+        $this->accountManagement->createAccountWithPasswordHash($customerMock, $hash);
+    }
 }
diff --git a/app/code/Magento/Customer/etc/crontab.xml b/app/code/Magento/Customer/etc/crontab.xml
index 57cbf4c3f8fd2ad5fce458d25dd7d864dc1189eb..472a49feb39fc2b99a8f4a9530c8bed192c70423 100644
--- a/app/code/Magento/Customer/etc/crontab.xml
+++ b/app/code/Magento/Customer/etc/crontab.xml
@@ -11,9 +11,4 @@
             <schedule>0 0 * * *</schedule>
         </job>
     </group>
-    <group id="index">
-        <job name="update_last_visit_at" instance="Magento\Customer\Model\Observer\Grid" method="syncCustomerGrid">
-            <schedule>*/5 * * * *</schedule>
-        </job>
-    </group>
 </config>
diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml
index f5c66d78c5b8114ba535c41730d940edf9828424..647ec87efca25a1e583df18d3d469f586996b2c2 100644
--- a/app/code/Magento/Customer/etc/di.xml
+++ b/app/code/Magento/Customer/etc/di.xml
@@ -180,12 +180,6 @@
             <argument name="entitySnapshot" xsi:type="object">EavVersionControlSnapshot</argument>
         </arguments>
     </type>
-    <virtualType name="Magento\Customer\Model\ResourceModel\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">customer_grid_flat</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Customer\Model\ResourceModel\Customer</argument>
-        </arguments>
-    </virtualType>
     <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
         <arguments>
             <argument name="collections" xsi:type="array">
diff --git a/app/code/Magento/Directory/etc/adminhtml/system.xml b/app/code/Magento/Directory/etc/adminhtml/system.xml
index a22bef73a275a75400edcd35c4ee3f84f8ec7ef9..5e61820f49c60429b965533f664ef36f307552c8 100644
--- a/app/code/Magento/Directory/etc/adminhtml/system.xml
+++ b/app/code/Magento/Directory/etc/adminhtml/system.xml
@@ -13,7 +13,7 @@
             <resource>Magento_Backend::currency</resource>
             <group id="options" translate="label" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Currency Options</label>
-                <field id="base" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
+                <field id="base" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Base Currency</label>
                     <frontend_model>Magento\Directory\Block\Adminhtml\Frontend\Currency\Base</frontend_model>
                     <source_model>Magento\Config\Model\Config\Source\Locale\Currency</source_model>
diff --git a/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js b/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js
index 5e619b76c7ecd8ba22fd1e8ff3f25786ac93d33e..8fc6508cd877d752eb94640abeebbc895ec1a716 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js
+++ b/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js
@@ -22,7 +22,7 @@ define([
          * Change visibility for samplesFieldset & linksFieldset based on current statuses of checkbox.
          */
         changeVisibility: function () {
-            if (this.samplesFieldset && this.linksFieldset) {
+            if (this.samplesFieldset() && this.linksFieldset()) {
                 if (this.checked() && !this.disabled()) {
                     this.samplesFieldset().visible(true);
                     this.linksFieldset().visible(true);
diff --git a/app/code/Magento/Eav/Model/Entity/Type.php b/app/code/Magento/Eav/Model/Entity/Type.php
index 7318e443fe3ada57c0b331ef48324ed4b6013521..6b3547a4f4b9828d126305820b8f4d8644a59849 100644
--- a/app/code/Magento/Eav/Model/Entity/Type.php
+++ b/app/code/Magento/Eav/Model/Entity/Type.php
@@ -278,7 +278,11 @@ class Type extends \Magento\Framework\Model\AbstractModel
      */
     public function getEntityTable()
     {
-        return isset($this->_data['entity_table']) ? $this->_data['entity_table'] : null;
+        if (isset($this->_data['entity_table'])) {
+            return $this->getResource()->getTable($this->_data['entity_table']);
+        }
+
+        return null;
     }
 
     /**
diff --git a/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php b/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php
index dc1a5ef3166f0711f6918b660bcbc0513681d952..3c3afd7a784b65ea1d2d23ee694104b43fc861ea 100644
--- a/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php
+++ b/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php
@@ -58,7 +58,7 @@ abstract class AbstractSave implements ObserverInterface
     {
         $this->_initEntity($observer);
 
-        if ($this->_isGoogleExperimentActive()) {
+        if ($this->_isGoogleExperimentActive() && $this->isDataAvailable()) {
             $this->_processCode();
         }
 
@@ -112,11 +112,10 @@ abstract class AbstractSave implements ObserverInterface
      */
     protected function _initRequestParams()
     {
-        $params = $this->_request->getParam('google_experiment');
-        if (!is_array($params) || !isset($params['experiment_script']) || !isset($params['code_id'])) {
+        if (!$this->isDataAvailable()) {
             throw new \InvalidArgumentException('Wrong request parameters');
         }
-        $this->_params = $params;
+        $this->_params = $this->getRequestData();
     }
 
     /**
@@ -181,4 +180,21 @@ abstract class AbstractSave implements ObserverInterface
     {
         $this->_modelCode->delete();
     }
+
+    /**
+     * @return array
+     */
+    private function isDataAvailable()
+    {
+        $params = $this->getRequestData();
+        return is_array($params) && isset($params['experiment_script']) && isset($params['code_id']);
+    }
+
+    /**
+     * @return mixed
+     */
+    private function getRequestData()
+    {
+        return $this->_request->getParam('google_experiment');
+    }
 }
diff --git a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Category/SaveGoogleExperimentScriptObserverTest.php b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Category/SaveGoogleExperimentScriptObserverTest.php
index 14f0cd8f43727b985f8283ff5e703a9c71fc38e7..f6f6b4670bffcf9f1e5e6b7a43531cbcd4ce21b9 100644
--- a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Category/SaveGoogleExperimentScriptObserverTest.php
+++ b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Category/SaveGoogleExperimentScriptObserverTest.php
@@ -85,7 +85,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -113,8 +113,6 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @param array $params
-     * @expectedException \InvalidArgumentException
-     * @expectedExceptionMessage Wrong request parameters
      * @dataProvider dataProviderWrongRequestForCreating
      */
     public function testCreatingCodeIfRequestIsNotValid($params)
@@ -174,7 +172,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -223,7 +221,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -254,7 +252,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
diff --git a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/CmsPage/SaveGoogleExperimentScriptObserverTest.php b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/CmsPage/SaveGoogleExperimentScriptObserverTest.php
index 485fc36343df1d8a6e440af7ed3bc0daafac9cb3..4e1f0245176b951ddfc1642de6206e7baaf0bd0e 100644
--- a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/CmsPage/SaveGoogleExperimentScriptObserverTest.php
+++ b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/CmsPage/SaveGoogleExperimentScriptObserverTest.php
@@ -70,7 +70,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         $this->_helperMock->expects($this->once())->method('isGoogleExperimentActive')->will($this->returnValue(true));
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -98,8 +98,6 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @param array $params
-     * @expectedException \InvalidArgumentException
-     * @expectedExceptionMessage Wrong request parameters
      * @dataProvider dataProviderWrongRequestForCreating
      */
     public function testCreatingCodeIfRequestIsNotValid($params)
@@ -143,7 +141,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         $this->_helperMock->expects($this->once())->method('isGoogleExperimentActive')->will($this->returnValue(true));
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -184,7 +182,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         $this->_helperMock->expects($this->once())->method('isGoogleExperimentActive')->will($this->returnValue(true));
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -215,7 +213,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
diff --git a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php
index fe25ce77646eb82e55ee201dd3021ff2342691e2..34821ca212159b4dde351da10099040da9f17395 100644
--- a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php
+++ b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php
@@ -85,7 +85,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -113,8 +113,6 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @param array $params
-     * @expectedException \InvalidArgumentException
-     * @expectedExceptionMessage Wrong request parameters
      * @dataProvider dataProviderWrongRequestForCreating
      */
     public function testCreatingCodeIfRequestIsNotValid($params)
@@ -174,7 +172,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -223,7 +221,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
@@ -254,7 +252,7 @@ class SaveGoogleExperimentScriptObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_requestMock->expects(
-            $this->once()
+            $this->exactly(3)
         )->method(
             'getParam'
         )->with(
diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php
index 9587a195b5e7c67d06f8a76b89d6957b5d62c403..8a3f0f1d0e900a5f4d3283076bb6ed8831c9f47a 100644
--- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php
@@ -26,23 +26,12 @@ class Grouped extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stoc
     {
         $connection = $this->getConnection();
         $idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable();
-        $select = $connection->select()->from(
-            ['e' => $this->getTable('catalog_product_entity')],
-            ['entity_id']
-        );
-        $this->_addWebsiteJoinToSelect($select, true);
-        $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id');
         $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
-        $select->columns(
-            'cw.website_id'
-        )->join(
-            ['cis' => $this->getTable('cataloginventory_stock')],
-            '',
-            ['stock_id']
-        )->joinLeft(
-            ['cisi' => $this->getTable('cataloginventory_stock_item')],
-            'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id',
-            []
+        $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable);
+        $select->reset(
+            \Magento\Framework\DB\Select::COLUMNS
+        )->columns(
+            ['e.entity_id', 'cis.website_id', 'cis.stock_id']
         )->joinLeft(
             ['l' => $this->getTable('catalog_product_link')],
             'e.' . $metadata->getLinkField() . ' = l.product_id AND l.link_type_id=' .
@@ -54,31 +43,15 @@ class Grouped extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stoc
             []
         )->joinLeft(
             ['i' => $idxTable],
-            'i.product_id = l.linked_product_id AND cw.website_id = i.website_id AND cis.stock_id = i.stock_id',
+            'i.product_id = l.linked_product_id AND cis.website_id = i.website_id AND cis.stock_id = i.stock_id',
             []
         )->columns(
             ['qty' => new \Zend_Db_Expr('0')]
-        )->where(
-            'cw.website_id != 0'
-        )->where(
-            'e.type_id = ?',
-            $this->getTypeId()
-        )->group(
-            ['e.entity_id', 'cw.website_id', 'cis.stock_id']
-        );
-
-        // add limitation of status
-        $productStatusExpr = $this->_addAttributeToSelect(
-            $select,
-            'status',
-            'e.' . $metadata->getLinkField(),
-            'cs.store_id'
         );
-        $productStatusCond = $connection->quoteInto($productStatusExpr . '=?', ProductStatus::STATUS_ENABLED);
 
         $statusExpression = $this->getStatusExpression($connection);
 
-        $optExpr = $connection->getCheckSql("{$productStatusCond} AND le.required_options = 0", 'i.stock_status', 0);
+        $optExpr = $connection->getCheckSql("le.required_options = 0", 'i.stock_status', 0);
         $stockStatusExpr = $connection->getLeastSql(["MAX({$optExpr})", "MIN({$statusExpression})"]);
 
         $select->columns(['status' => $stockStatusExpr]);
diff --git a/app/code/Magento/Indexer/Model/Processor/InvalidateCache.php b/app/code/Magento/Indexer/Model/Processor/CleanCache.php
similarity index 64%
rename from app/code/Magento/Indexer/Model/Processor/InvalidateCache.php
rename to app/code/Magento/Indexer/Model/Processor/CleanCache.php
index d4cc663612845011019d7832736b5ca0041dd53b..b5dec17899819a074ecf5f6ae1dba30f12c44ebc 100644
--- a/app/code/Magento/Indexer/Model/Processor/InvalidateCache.php
+++ b/app/code/Magento/Indexer/Model/Processor/CleanCache.php
@@ -3,13 +3,9 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Indexer\Model\Processor;
 
-/**
- * Class InvalidateCache
- */
-class InvalidateCache
+class CleanCache
 {
     /**
      * @var \Magento\Framework\Indexer\CacheContext
@@ -21,24 +17,16 @@ class InvalidateCache
      */
     protected $eventManager;
 
-    /**
-     * @var \Magento\Framework\Module\Manager
-     */
-    protected $moduleManager;
-
     /**
      * @param \Magento\Framework\Indexer\CacheContext $context
      * @param \Magento\Framework\Event\Manager $eventManager
-     * @param \Magento\Framework\Module\Manager $moduleManager
      */
     public function __construct(
         \Magento\Framework\Indexer\CacheContext $context,
-        \Magento\Framework\Event\Manager $eventManager,
-        \Magento\Framework\Module\Manager $moduleManager
+        \Magento\Framework\Event\Manager $eventManager
     ) {
         $this->context = $context;
         $this->eventManager = $eventManager;
-        $this->moduleManager = $moduleManager;
     }
 
     /**
@@ -50,8 +38,18 @@ class InvalidateCache
      */
     public function afterUpdateMview(\Magento\Indexer\Model\Processor $subject)
     {
-        if ($this->moduleManager->isEnabled('Magento_PageCache')) {
-            $this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]);
-        }
+        $this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]);
+    }
+
+    /**
+     * Clear cache after reindex all
+     *
+     * @param \Magento\Indexer\Model\Processor $subject
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterReindexAllInvalid(\Magento\Indexer\Model\Processor $subject)
+    {
+        $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->context]);
     }
 }
diff --git a/app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php b/app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php
similarity index 54%
rename from app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php
rename to app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php
index 0a9ad31ba273a50773a8c6189ebd6a441aa2a610..511eb798e55289b8d94e576ffe326a929ddf63b3 100644
--- a/app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php
+++ b/app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php
@@ -3,10 +3,9 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Indexer\Test\Unit\Model\Processor;
 
-class InvalidateCacheTest extends \PHPUnit_Framework_TestCase
+class CleanCacheTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * Tested plugin
@@ -36,13 +35,6 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase
      */
     protected $eventManagerMock;
 
-    /**
-     * Module manager mock
-     *
-     * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $moduleManager;
-
     /**
      * Set up
      */
@@ -51,25 +43,19 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase
         $this->subjectMock = $this->getMock('Magento\Indexer\Model\Processor', [], [], '', false);
         $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext', [], [], '', false);
         $this->eventManagerMock = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false);
-        $this->moduleManager = $this->getMock('Magento\Framework\Module\Manager', [], [], '', false);
-        $this->plugin = new \Magento\Indexer\Model\Processor\InvalidateCache(
+        $this->plugin = new \Magento\Indexer\Model\Processor\CleanCache(
             $this->contextMock,
-            $this->eventManagerMock,
-            $this->moduleManager
+            $this->eventManagerMock
         );
     }
 
     /**
-     * Test afterUpdateMview with enabled PageCache module
+     * Test afterUpdateMview
      *
      * @return void
      */
-    public function testAfterUpdateMviewPageCacheEnabled()
+    public function testAfterUpdateMview()
     {
-        $this->moduleManager->expects($this->once())
-            ->method('isEnabled')
-            ->with($this->equalTo('Magento_PageCache'))
-            ->will($this->returnValue(true));
         $this->eventManagerMock->expects($this->once())
             ->method('dispatch')
             ->with(
@@ -78,20 +64,4 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase
             );
         $this->plugin->afterUpdateMview($this->subjectMock);
     }
-
-    /**
-     * Test afterUpdateMview with disabled PageCache module
-     *
-     * @return void
-     */
-    public function testAfterUpdateMviewPageCacheDisabled()
-    {
-        $this->moduleManager->expects($this->once())
-            ->method('isEnabled')
-            ->with($this->equalTo('Magento_PageCache'))
-            ->will($this->returnValue(false));
-        $this->eventManagerMock->expects($this->never())
-            ->method('dispatch');
-        $this->plugin->afterUpdateMview($this->subjectMock);
-    }
 }
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index e70c92907e7aee19d7de54688b4696ae89df57c4..2c374d77111510c9d14a5ed3f846e09be67d3891 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -4,7 +4,6 @@
     "require": {
         "php": "~5.5.22|~5.6.0|~7.0.0",
         "magento/module-backend": "100.0.*",
-        "magento/module-page-cache": "100.0.*",
         "magento/framework": "100.0.*"
     },
     "type": "magento2-module",
diff --git a/app/code/Magento/Indexer/etc/di.xml b/app/code/Magento/Indexer/etc/di.xml
index 87a99325e4ae60d9bee2056a988064848ff4a322..019dad475a5531e87f14c8e4f52d8456bb0a49b7 100644
--- a/app/code/Magento/Indexer/etc/di.xml
+++ b/app/code/Magento/Indexer/etc/di.xml
@@ -39,8 +39,8 @@
         </arguments>
     </type>
     <type name="Magento\Indexer\Model\Processor">
-        <plugin name="page-cache-indexer-reindex-invalidate"
-                type="Magento\Indexer\Model\Processor\InvalidateCache" sortOrder="10"/>
+        <plugin name="page-cache-indexer-reindex-clean-cache"
+                type="Magento\Indexer\Model\Processor\CleanCache" sortOrder="10"/>
     </type>
 
     <type name="Magento\Framework\Console\CommandList">
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
index 799420efcc0d59c265c7298dcc1630e144bfbce7..2251ed525db604133ae17ece56080d3ebc62dba7 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
@@ -53,10 +53,16 @@ class TokensExchange extends \Magento\Integration\Controller\Adminhtml\Integrati
             $this->_setActivationInProcessMsg($isReauthorize, $integration->getName());
             $this->_view->renderLayout();
             $popupContent = $this->_response->getBody();
+            $consumer = $this->_oauthService->loadConsumer($integration->getConsumerId());
+            if (!$consumer->getId()) {
+                throw new \Magento\Framework\Oauth\Exception(
+                    __('A consumer with ID %1 does not exist', $integration->getConsumerId())
+                );
+            }
             /** Initialize response body */
             $result = [
                 IntegrationModel::IDENTITY_LINK_URL => $integration->getIdentityLinkUrl(),
-                IntegrationModel::CONSUMER_ID => $integration->getConsumerId(),
+                'oauth_consumer_key' => $consumer->getKey(),
                 'popup_content' => $popupContent,
             ];
             $this->getResponse()->representJson($this->jsonHelper->jsonEncode($result));
diff --git a/app/code/Magento/Integration/Model/OauthService.php b/app/code/Magento/Integration/Model/OauthService.php
index 9ce2df70a547b5029307d9b89e4cdb90fb03d164..16dbf5aa04b1013b62d3572f7092696b8eec0800 100644
--- a/app/code/Magento/Integration/Model/OauthService.php
+++ b/app/code/Magento/Integration/Model/OauthService.php
@@ -192,7 +192,7 @@ class OauthService implements \Magento\Integration\Api\OauthServiceInterface
     public function postToConsumer($consumerId, $endpointUrl)
     {
         try {
-            $consumer = $this->_consumerFactory->create()->load($consumerId);
+            $consumer = $this->loadConsumer($consumerId);
             if (!$consumer->getId()) {
                 throw new \Magento\Framework\Oauth\Exception(
                     __('A consumer with ID %1 does not exist', $consumerId)
diff --git a/app/code/Magento/Integration/Model/ResourceModel/Oauth/Consumer.php b/app/code/Magento/Integration/Model/ResourceModel/Oauth/Consumer.php
index 2fcd1910b1bccad50b36fb878e44c70076f7f1f8..9b677099e49e72b23df6925abeae88c9017fd0fc 100644
--- a/app/code/Magento/Integration/Model/ResourceModel/Oauth/Consumer.php
+++ b/app/code/Magento/Integration/Model/ResourceModel/Oauth/Consumer.php
@@ -37,8 +37,8 @@ class Consumer extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     public function _afterDelete(\Magento\Framework\Model\AbstractModel $object)
     {
         $connection = $this->getConnection();
-        $connection->delete($this->getTable('oauth_nonce'), ['consumer_id' => $object->getId()]);
-        $connection->delete($this->getTable('oauth_token'), ['consumer_id' => $object->getId()]);
+        $connection->delete($this->getTable('oauth_nonce'), ['consumer_id = ?' => (int)$object->getId()]);
+        $connection->delete($this->getTable('oauth_token'), ['consumer_id = ?' => (int)$object->getId()]);
         return parent::_afterDelete($object);
     }
 
diff --git a/app/code/Magento/Integration/Test/Unit/Controller/Adminhtml/Integration/TokensDialogTest.php b/app/code/Magento/Integration/Test/Unit/Controller/Adminhtml/Integration/TokensDialogTest.php
index fc28ff0f63dd52d34ded0e5ac415add915902d5d..7f6912c5d3270ecf5da2f702f66d1bb3956e09b9 100644
--- a/app/code/Magento/Integration/Test/Unit/Controller/Adminhtml/Integration/TokensDialogTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Controller/Adminhtml/Integration/TokensDialogTest.php
@@ -84,6 +84,9 @@ class TokensDialogTest extends \Magento\Integration\Test\Unit\Controller\Adminht
 
         $this->_oauthSvcMock->expects($this->once())->method('deleteIntegrationToken');
         $this->_oauthSvcMock->expects($this->once())->method('postToConsumer');
+        $consumerMock = $this->getMock(\Magento\Integration\Model\Oauth\Consumer::class, [], [], '' , false);
+        $consumerMock->expects($this->once())->method('getId')->willReturn(1);
+        $this->_oauthSvcMock->expects($this->once())->method('loadConsumer')->willReturn($consumerMock);
 
         $this->_messageManager->expects($this->once())->method('addNotice');
         $this->_messageManager->expects($this->never())->method('addError');
diff --git a/app/code/Magento/Integration/view/adminhtml/web/js/integration.js b/app/code/Magento/Integration/view/adminhtml/web/js/integration.js
index 40aa90c281f1166a23547f4fb7d91e644f1c329f..776339f15c2d72425f53fa802629f4c2e15a4e2f 100644
--- a/app/code/Magento/Integration/view/adminhtml/web/js/integration.js
+++ b/app/code/Magento/Integration/view/adminhtml/web/js/integration.js
@@ -133,11 +133,11 @@ define([
                 TOP: screen.height - 510 - 300
             },
 
-            invokePopup: function (identityCallbackUrl, consumerId, jqInfoDialog) {
+            invokePopup: function (identityCallbackUrl, consumerKey, jqInfoDialog) {
                 // Callback should be invoked only once. Reset callback flag on subsequent invocations.
                 IdentityLogin.isCalledBack = false;
                 IdentityLogin.jqInfoDialog = jqInfoDialog;
-                var param = $.param({"consumer_id": consumerId, "success_call_back": IdentityLogin.successCallbackUrl});
+                var param = $.param({"oauth_consumer_key": consumerKey, "success_call_back": IdentityLogin.successCallbackUrl});
                 IdentityLogin.win = window.open(identityCallbackUrl + '?' + param, '',
                     'top=' + IdentityLogin.Constants.TOP +
                         ', left=' + IdentityLogin.Constants.LEFT +
@@ -205,7 +205,7 @@ define([
                     }
 
                     var identityLinkUrl = null,
-                        consumerId = null,
+                        consumerKey = null,
                         popupHtml = null,
                         popup = $('#integration-popup-container');
 
@@ -215,15 +215,15 @@ define([
                             result;
 
                         identityLinkUrl = resultObj['identity_link_url'];
-                        consumerId      = resultObj['consumer_id'];
+                        consumerKey      = resultObj['oauth_consumer_key'];
                         popupHtml       = resultObj['popup_content'];
                         
                     } catch (e) {
                         //This is expected if result is not json. Do nothing.
                     }
 
-                    if (identityLinkUrl && consumerId && popupHtml) {
-                        IdentityLogin.invokePopup(identityLinkUrl, consumerId, popup);
+                    if (identityLinkUrl && consumerKey && popupHtml) {
+                        IdentityLogin.invokePopup(identityLinkUrl, consumerKey, popup);
                     } else {
                         popupHtml = result;
                     }
diff --git a/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..9df2cff55f271884ce2af57553739dad1ded277c
--- /dev/null
+++ b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Multishipping\Model\Cart\Controller;
+
+class CartPlugin
+{
+    /**
+     * @var \Magento\Quote\Api\CartRepositoryInterface
+     */
+    private $cartRepository;
+
+    /**
+     * @var \Magento\Checkout\Model\Session
+     */
+    private $checkoutSession;
+
+    /**
+     * @param \Magento\Quote\Api\CartRepositoryInterface $cartRepository
+     * @param \Magento\Checkout\Model\Session $checkoutSession
+     */
+    public function __construct(
+        \Magento\Quote\Api\CartRepositoryInterface $cartRepository,
+        \Magento\Checkout\Model\Session $checkoutSession
+    ) {
+        $this->cartRepository = $cartRepository;
+        $this->checkoutSession = $checkoutSession;
+    }
+
+    /**
+     * @param \Magento\Checkout\Controller\Cart $subject
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeDispatch(
+        \Magento\Checkout\Controller\Cart $subject,
+        \Magento\Framework\App\RequestInterface $request
+    ) {
+        /** @var \Magento\Quote\Model\Quote $quote */
+        $quote = $this->checkoutSession->getQuote();
+
+        // Clear shipping addresses and item assignments after Multishipping flow
+        if ($quote->isMultipleShippingAddresses()) {
+            foreach ($quote->getAllShippingAddresses() as $address) {
+                $quote->removeAddress($address->getId());
+            }
+            $quote->getShippingAddress();
+            $quote->setIsMultiShipping(false);
+            $quote->collectTotals();
+
+            $this->cartRepository->save($quote);
+        }
+    }
+}
diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Cart/Controller/CartPluginTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Cart/Controller/CartPluginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b6ba1b447a394d1efa0dd10ccd597b44e4fbec0
--- /dev/null
+++ b/app/code/Magento/Multishipping/Test/Unit/Model/Cart/Controller/CartPluginTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Multishipping\Test\Unit\Model\Cart\Controller;
+
+class CartPluginTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Multishipping\Model\Cart\Controller\CartPlugin
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cartRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $checkoutSessionMock;
+
+    protected function setUp()
+    {
+        $this->cartRepositoryMock = $this->getMock('\Magento\Quote\Api\CartRepositoryInterface');
+        $this->checkoutSessionMock = $this->getMock('\Magento\Checkout\Model\Session', [], [], '', false);
+        $this->model = new \Magento\Multishipping\Model\Cart\Controller\CartPlugin(
+            $this->cartRepositoryMock,
+            $this->checkoutSessionMock
+        );
+    }
+
+    public function testBeforeDispatch()
+    {
+        $addressId = 100;
+        $quoteMock = $this->getMock(
+            '\Magento\Quote\Model\Quote',
+            [
+                'isMultipleShippingAddresses',
+                'getAllShippingAddresses',
+                'removeAddress',
+                'getShippingAddress',
+                'setIsMultiShipping',
+                'collectTotals'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->checkoutSessionMock->expects($this->once())->method('getQuote')->willReturn($quoteMock);
+
+        $addressMock = $this->getMock('\Magento\Quote\Model\Quote\Address', [], [], '', false);
+        $addressMock->expects($this->once())->method('getId')->willReturn($addressId);
+
+        $quoteMock->expects($this->once())->method('isMultipleShippingAddresses')->willReturn(true);
+        $quoteMock->expects($this->once())->method('getAllShippingAddresses')->willReturn([$addressMock]);
+        $quoteMock->expects($this->once())->method('removeAddress')->with($addressId)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('getShippingAddress');
+        $quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
+
+        $this->cartRepositoryMock->expects($this->once())->method('save')->with($quoteMock);
+
+        $this->model->beforeDispatch(
+            $this->getMock('\Magento\Checkout\Controller\Cart', [], [], '', false),
+            $this->getMock('\Magento\Framework\App\RequestInterface')
+        );
+    }
+}
diff --git a/app/code/Magento/Multishipping/etc/frontend/di.xml b/app/code/Magento/Multishipping/etc/frontend/di.xml
index 6d7ac0ea8aabc2e691a52c5efc5b1a33db774d79..3f1ee5dcaa34fbb1c31a2fd7bf7476438c695313 100644
--- a/app/code/Magento/Multishipping/etc/frontend/di.xml
+++ b/app/code/Magento/Multishipping/etc/frontend/di.xml
@@ -42,4 +42,7 @@
     <type name="Magento\Checkout\Model\Cart">
         <plugin name="multishipping_session_mapper" type="Magento\Multishipping\Model\Checkout\Type\Multishipping\Plugin" sortOrder="50" />
     </type>
+    <type name="Magento\Checkout\Controller\Cart">
+        <plugin name="multishipping_clear_addresses" type="Magento\Multishipping\Model\Cart\Controller\CartPlugin" />
+    </type>
 </config>
diff --git a/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php b/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php
deleted file mode 100644
index c8f2d0e23f20d3da3ff7aa291ca5067e11e1133e..0000000000000000000000000000000000000000
--- a/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\PageCache\Observer;
-
-use Magento\Framework\Event\ObserverInterface;
-
-/**
- * An observer to invalidate full page cache when the content given is changed
- */
-class InvalidateCacheIfChanged implements ObserverInterface
-{
-    /**
-     * @var \Magento\Framework\App\Cache\TypeListInterface
-     */
-    protected $typeList;
-
-    /**
-     * Application config object
-     *
-     * @var \Magento\PageCache\Model\Config
-     */
-    protected $config;
-
-    /**
-     * @param \Magento\PageCache\Model\Config $config
-     * @param \Magento\Framework\App\Cache\TypeListInterface $typeList
-     */
-    public function __construct(
-        \Magento\PageCache\Model\Config $config,
-        \Magento\Framework\App\Cache\TypeListInterface $typeList
-    ) {
-        $this->config = $config;
-        $this->typeList = $typeList;
-    }
-
-    /**
-     * Invalidate full page cache if content is changed
-     *
-     * @param \Magento\Framework\Event\Observer $observer
-     * @return void
-     */
-    public function execute(\Magento\Framework\Event\Observer $observer)
-    {
-        if ($this->config->isEnabled()) {
-            $object = $observer->getEvent()->getObject();
-            if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
-                if ($object->getIdentities()) {
-                    $this->typeList->invalidate('full_page');
-                }
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php b/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php
deleted file mode 100644
index 9e6af22857295967436f6ce7d944b8aeb6d42040..0000000000000000000000000000000000000000
--- a/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\PageCache\Test\Unit\Observer;
-
-class InvalidateCacheIfChangedTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var \Magento\PageCache\Observer\InvalidateCacheIfChanged */
-    protected $model;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\PageCache\Model\Config */
-    protected $configMock;
-
-    /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\TypeListInterface */
-    protected $typeListMock;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Event\Observer */
-    protected $observerMock;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject\IdentityInterface */
-    protected $objectMock;
-
-    /**
-     * Set up all mocks and data for test
-     */
-    protected function setUp()
-    {
-        $this->configMock = $this->getMock(
-            'Magento\PageCache\Model\Config',
-            ['getType', 'isEnabled'],
-            [],
-            '',
-            false
-        );
-        $this->typeListMock = $this->getMock('Magento\Framework\App\Cache\TypeList', [], [], '', false);
-
-        $this->model = new \Magento\PageCache\Observer\InvalidateCacheIfChanged(
-            $this->configMock,
-            $this->typeListMock
-        );
-
-        $this->observerMock = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
-        $eventMock = $this->getMock('Magento\Framework\Event', ['getObject'], [], '', false);
-        $this->objectMock = $this->getMockForAbstractClass(
-            'Magento\Framework\DataObject\IdentityInterface',
-            [],
-            '',
-            false
-        );
-        $eventMock->expects($this->any())->method('getObject')->willReturn($this->objectMock);
-        $this->observerMock->expects($this->any())->method('getEvent')->willReturn($eventMock);
-    }
-
-    /**
-     * @dataProvider invalidateCacheDataProvider
-     * @param bool $cacheState
-     */
-    public function testExecuteChanged($cacheState)
-    {
-        $this->configMock->expects($this->once())->method('isEnabled')->will($this->returnValue($cacheState));
-
-        if ($cacheState) {
-            $this->typeListMock->expects($this->once())->method('invalidate')->with($this->equalTo('full_page'));
-            $this->objectMock->expects($this->once())->method('getIdentities')->will($this->returnValue(['tag_1']));
-        }
-        $this->model->execute($this->observerMock);
-    }
-
-    /**
-     * @dataProvider invalidateCacheDataProvider
-     * @param bool $cacheState
-     */
-    public function testExecuteNoChanged($cacheState)
-    {
-        $this->configMock->expects($this->once())->method('isEnabled')->will($this->returnValue($cacheState));
-        $this->typeListMock->expects($this->never())->method('invalidate');
-
-        if ($cacheState) {
-            $this->objectMock->expects($this->once())->method('getIdentities')->will($this->returnValue([]));
-        }
-        $this->model->execute($this->observerMock);
-    }
-
-    public function invalidateCacheDataProvider()
-    {
-        return [[true], [false]];
-    }
-}
diff --git a/app/code/Magento/PageCache/etc/events.xml b/app/code/Magento/PageCache/etc/events.xml
index 617709c400a1500c59bafa3f0b11ded2ddbcdf06..7ac67a931c7ac8bbbe3b5e397a7ade7b3a039633 100644
--- a/app/code/Magento/PageCache/etc/events.xml
+++ b/app/code/Magento/PageCache/etc/events.xml
@@ -13,7 +13,7 @@
         <observer name="invalidate_builtin" instance="Magento\PageCache\Observer\FlushCacheByTags" />
     </event>
     <event name="clean_cache_after_reindex">
-        <observer name="reindex_cache_flush" instance="Magento\PageCache\Observer\InvalidateCacheIfChanged" />
+        <observer name="reindex_cache_flush" instance="Magento\PageCache\Observer\FlushCacheByTags" />
     </event>
     <event name="adminhtml_cache_flush_system">
         <observer name="flush_system_pagecache" instance="Magento\PageCache\Observer\FlushAllCache" />
diff --git a/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php b/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php
index 7f9d88cb36e4883669f5797e71ad98317c2a3820..b68803a50d191a1df97e3795712c322324c3c903 100644
--- a/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php
+++ b/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php
@@ -113,7 +113,8 @@ class EmulateCustomerObserver implements ObserverInterface
             }
             $this->_customerSession
                 ->setCustomerId($customer->getId())
-                ->setCustomerGroupId($customer->getGroupId());
+                ->setCustomerGroupId($customer->getGroupId())
+                ->setIsCustomerEmulated(true);
         }
         return $this;
     }
diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php
index 2f0a59d448e2427cb8c501a2e35fd262f1ae45b9..854113a33edc7b8d89b10be5457d0fdebdf2a66f 100644
--- a/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php
+++ b/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php
@@ -57,7 +57,9 @@ class EmulateCustomerObserverTest extends \PHPUnit_Framework_TestCase
             'setDefaultTaxBillingAddress',
             'setCustomerId',
             'setCustomerGroupId',
-            'isLoggedIn'
+            'isLoggedIn',
+            'setIsCustomerEmulated',
+            '__wakeUp'
         ];
         $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', $methods, [], '', false);
         $this->sessionHelperMock = $this->getMock('Magento\Persistent\Helper\Session', [], [], '', false);
@@ -168,7 +170,15 @@ class EmulateCustomerObserverTest extends \PHPUnit_Framework_TestCase
             ->method('setCustomerId')
             ->with($customerId)
             ->will($this->returnSelf());
-        $this->customerSessionMock->expects($this->once())->method('setCustomerGroupId')->with($customerGroupId);
+        $this->customerSessionMock
+            ->expects($this->once())
+            ->method('setCustomerGroupId')
+            ->with($customerGroupId)->will($this->returnSelf());
+        $this->customerSessionMock
+            ->expects($this->once())
+            ->method('setIsCustomerEmulated')
+            ->with(true)
+            ->will($this->returnSelf());
         $this->model->execute($this->observerMock);
     }
 
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
index f57ba1ce79e1ed0680ae4bfd83a02f770494679c..806b4a75d377efa73cc41ceb7ae5faf698f8a639 100755
--- a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
+++ b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
@@ -37,7 +37,7 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
      data-types="<?php echo $block->escapeHtml(
          $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
      ) ?>"
-    >
+>
 
     <?php
     if (!$block->getElement()->getReadonly()):
@@ -47,7 +47,9 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
             ?>
             <div class="product-image-wrapper">
                 <p class="image-placeholder-text">
-                    <?php /* @noEscape */ echo __('Browse to find or drag image here'); ?>
+                    <?php echo $block->escapeHtml(
+                        __('Browse to find or drag image here')
+                    ); ?>
                 </p>
             </div>
         </div>
@@ -141,32 +143,42 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
                             class="action-remove"
                             data-role="delete-button"
                             title="<% if (data.media_type == 'external-video') {%>
-                            <?php /* @noEscape */echo __('Delete video') ?>
+                            <?php echo $block->escapeHtml(
+                                __('Delete video')
+                            ); ?>
                         <%} else {%>
-                            <?php /* @noEscape */ echo __('Delete image') ?>
+                            <?php echo $block->escapeHtml(
+                                __('Delete image')
+                            ); ?>
                         <%}%>">
                     <span>
                         <% if (data.media_type == 'external-video') { %>
-                        <?php /* @noEscape */ echo __('Delete video') ?>
+                        <?php echo $block->escapeHtml(
+                            __('Delete video')
+                        ); ?>
                         <% } else {%>
-                        <?php /* @noEscape */ echo __('Delete image') ?>
+                        <?php echo $block->escapeHtml(
+                            __('Delete image')
+                        ); ?>
                         <%} %>
                     </span>
                     </button>
                     <div class="draggable-handle"></div>
                 </div>
-                <div class="image-fade"><span><?php /* @noEscape */ echo __('Hidden') ?></span></div>
+                <div class="image-fade"><span><?php echo $block->escapeHtml(
+                            __('Hidden')
+                        ); ?></span></div>
             </div>
 
             <div class="item-description">
-              <% if (data.media_type !== 'external-video') {%>
+                <% if (data.media_type !== 'external-video') {%>
                 <div class="item-title" data-role="img-title"><%- data.label %></div>
                 <div class="item-size">
-                  <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
-                  </div>
-              <% } else { %>
+                    <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
+                </div>
+                <% } else { %>
                 <div class="item-title" data-role="img-title"><%- data.video_title %></div>
-              <% } %>
+                <% } %>
             </div>
 
             <ul class="item-roles" data-role="roles-labels">
@@ -188,114 +200,126 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
     </script>
 
     <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
-      <div class="image-panel" data-role="dialog">
-      </div>
+        <div class="image-panel" data-role="dialog">
+        </div>
     </script>
 
     <script data-role="img-dialog-tmpl" type="text/x-magento-template">
-            <div class="image-panel-preview">
-                <img src="<%- data.url %>" alt="<%- data.label %>" />
-            </div>
-            <div class="image-panel-controls">
-                <strong class="image-name"><%- data.label %></strong>
+        <div class="image-panel-preview">
+            <img src="<%- data.url %>" alt="<%- data.label %>" />
+        </div>
+        <div class="image-panel-controls">
+            <strong class="image-name"><%- data.label %></strong>
 
-                <fieldset class="admin__fieldset fieldset-image-panel">
-                    <div class="admin__field field-image-description">
-                        <label class="admin__field-label" for="image-description">
-                            <span><?php /* @escapeNotVerified */ echo __('Alt Text')?></span>
-                        </label>
+            <fieldset class="admin__fieldset fieldset-image-panel">
+                <div class="admin__field field-image-description">
+                    <label class="admin__field-label" for="image-description">
+                        <span><?php /* @escapeNotVerified */ echo __('Alt Text')?></span>
+                    </label>
 
-                        <div class="admin__field-control">
+                    <div class="admin__field-control">
                             <textarea data-role="image-description"
                                       rows="3"
                                       class="admin__control-textarea"
                                       name="<?php /* @escapeNotVerified */
                                       echo $elementName
                                       ?>[<%- data.file_id %>][label]"><%- data.label %></textarea>
-                        </div>
                     </div>
+                </div>
 
-                    <div class="admin__field field-image-role">
-                        <label class="admin__field-label">
-                            <span><?php /* @noEscape */ echo __('Role')?></span>
-                        </label>
-                        <div class="admin__field-control">
-                            <ul class="multiselect-alt">
-                                <?php
-                                foreach ($block->getMediaAttributes() as $attribute) :
-                                    ?>
-                                    <li class="item">
-                                        <label>
-                                            <input class="image-type"
-                                                   data-role="type-selector"
-                                                   data-form-part="<?php /* @escapeNotVerified */ echo $formName ?>"
-                                                   type="checkbox"
-                                                   value="<?php echo $block->escapeHtml(
-                                                       $attribute->getAttributeCode()
-                                                   ) ?>"
-                                                />
-                                            <?php /* @escapeNotVerified */ echo $block->escapeHtml(
-                                                $attribute->getFrontendLabel()
-                                            ) ?>
-                                        </label>
-                                    </li>
-                                <?php
-                                endforeach;
+                <div class="admin__field field-image-role">
+                    <label class="admin__field-label">
+                            <span><?php echo $block->escapeHtml(
+                                    __('Role')
+                                ); ?></span>
+                    </label>
+                    <div class="admin__field-control">
+                        <ul class="multiselect-alt">
+                            <?php
+                            foreach ($block->getMediaAttributes() as $attribute) :
                                 ?>
-                            </ul>
-                        </div>
+                                <li class="item">
+                                    <label>
+                                        <input class="image-type"
+                                               data-role="type-selector"
+                                               data-form-part="<?php /* @escapeNotVerified */ echo $formName ?>"
+                                               type="checkbox"
+                                               value="<?php echo $block->escapeHtml(
+                                                   $attribute->getAttributeCode()
+                                               ) ?>"
+                                        />
+                                        <?php /* @escapeNotVerified */ echo $block->escapeHtml(
+                                            $attribute->getFrontendLabel()
+                                        ) ?>
+                                    </label>
+                                </li>
+                                <?php
+                            endforeach;
+                            ?>
+                        </ul>
                     </div>
+                </div>
 
-                    <div class="admin__field admin__field-inline field-image-size" data-role="size">
-                        <label class="admin__field-label">
-                            <span><?php /* @escapeNotVerified */ echo __('Image Size') ?></span>
-                        </label>
-                        <div class="admin__field-value" data-message="<?php /* @escapeNotVerified */ echo __('{size}') ?>"></div>
-                    </div>
+                <div class="admin__field admin__field-inline field-image-size" data-role="size">
+                    <label class="admin__field-label">
+                        <span><?php /* @escapeNotVerified */ echo __('Image Size') ?></span>
+                    </label>
+                    <div class="admin__field-value" data-message="<?php /* @escapeNotVerified */ echo __('{size}') ?>"></div>
+                </div>
 
-                    <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
-                        <label class="admin__field-label">
-                            <span><?php /* @escapeNotVerified */ echo __('Image Resolution') ?></span>
-                        </label>
-                        <div class="admin__field-value" data-message="<?php /* @escapeNotVerified */ echo __('{width}^{height} px') ?>"></div>
-                    </div>
+                <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
+                    <label class="admin__field-label">
+                        <span><?php /* @escapeNotVerified */ echo __('Image Resolution') ?></span>
+                    </label>
+                    <div class="admin__field-value" data-message="<?php /* @escapeNotVerified */ echo __('{width}^{height} px') ?>"></div>
+                </div>
 
-                    <div class="admin__field field-image-hide">
-                        <div class="admin__field-control">
-                            <div class="admin__field admin__field-option">
-                                <input type="checkbox"
-                                       id="hide-from-product-page"
-                                       data-role="visibility-trigger"
-                                       data-form-part="<?php /* @escapeNotVerified */ echo $formName ?>"
-                                       value="1"
-                                       class="admin__control-checkbox"
-                                       name="<?php /* @escapeNotVerified */ echo $elementName ?>[<%- data.file_id %>][disabled]"
-                                <% if (data.disabled == 1) { %>checked="checked"<% } %> />
+                <div class="admin__field field-image-hide">
+                    <div class="admin__field-control">
+                        <div class="admin__field admin__field-option">
+                            <input type="checkbox"
+                                   id="hide-from-product-page"
+                                   data-role="visibility-trigger"
+                                   data-form-part="<?php /* @escapeNotVerified */ echo $formName ?>"
+                                   value="1"
+                                   class="admin__control-checkbox"
+                                   name="<?php /* @escapeNotVerified */ echo $elementName ?>[<%- data.file_id %>][disabled]"
+                            <% if (data.disabled == 1) { %>checked="checked"<% } %> />
 
-                                <label for="hide-from-product-page" class="admin__field-label">
-                                    <?php /* @noEscape */ echo __('Hide from Product Page')?>
-                                </label>
-                            </div>
+                            <label for="hide-from-product-page" class="admin__field-label">
+                                <?php echo $block->escapeHtml(
+                                    __('Hide from Product Page')
+                                ); ?>
+                            </label>
                         </div>
                     </div>
-                </fieldset>
-            </div>
+                </div>
+            </fieldset>
+        </div>
     </script>
     <div id="<?php /* @noEscape */ echo $block->getNewVideoBlockName();?>" style="display:none">
         <?php /* @escapeNotVerified */ echo $block->getFormHtml();?>
         <div id="video-player-preview-location" class="video-player-sidebar">
             <div class="video-player-container"></div>
             <div class="video-information title">
-                <label><?php /* @noEscape */ echo __('Title:') ?> </label><span></span>
+                <label><?php echo $block->escapeHtml(
+                        __('Title:')
+                    ); ?> </label><span></span>
             </div>
             <div class="video-information uploaded">
-                <label><?php /* @noEscape */ echo __('Uploaded:') ?> </label><span></span>
+                <label><?php echo $block->escapeHtml(
+                        __('Uploaded:')
+                    ); ?> </label><span></span>
             </div>
             <div class="video-information uploader">
-                <label><?php /* @noEscape */ echo __('Uploader:') ?> </label><span></span>
+                <label><?php echo $block->escapeHtml(
+                        __('Uploader:')
+                    ); ?> </label><span></span>
             </div>
             <div class="video-information duration">
-                <label><?php /* @noEscape */ echo __('Duration:') ?> </label><span></span>
+                <label><?php echo $block->escapeHtml(
+                        __('Duration:')
+                    ); ?> </label><span></span>
             </div>
         </div>
     </div>
@@ -305,4 +329,3 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
 <script>
     jQuery('body').trigger('contentUpdated');
 </script>
-
diff --git a/app/code/Magento/Quote/Model/Cart/TotalsConverter.php b/app/code/Magento/Quote/Model/Cart/TotalsConverter.php
index f0f61ea2439ac97105eff0b1b0525cedd631e3df..f196493e27bc405aed53ee50106154443de9eb60 100644
--- a/app/code/Magento/Quote/Model/Cart/TotalsConverter.php
+++ b/app/code/Magento/Quote/Model/Cart/TotalsConverter.php
@@ -27,7 +27,6 @@ class TotalsConverter
         $this->factory = $factory;
     }
 
-
     /**
      * @param \Magento\Quote\Model\Quote\Address\Total[] $addressTotals
      * @return \Magento\Quote\Api\Data\TotalSegmentInterface[]
@@ -44,7 +43,7 @@ class TotalsConverter
                 TotalSegmentInterface::AREA => $addressTotal->getArea(),
             ];
             if (is_object($addressTotal->getTitle())) {
-                $pureData[TotalSegmentInterface::TITLE] = $addressTotal->getTitle()->getText();
+                $pureData[TotalSegmentInterface::TITLE] = $addressTotal->getTitle()->render();
             }
             /** @var \Magento\Quote\Model\Cart\TotalSegment $total */
             $total = $this->factory->create();
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total.php b/app/code/Magento/Quote/Model/Quote/Address/Total.php
index e841d9b7d76150499cfcc15ab41668468fbb4458..aeaa71fb8daad7c4fa8d832e66cad83dadb45f34 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total.php
@@ -114,6 +114,7 @@ class Total extends \Magento\Framework\DataObject
     }
 
     //@codeCoverageIgnoreStart
+
     /**
      * Get all total amount values
      *
@@ -133,4 +134,33 @@ class Total extends \Magento\Framework\DataObject
     {
         return $this->baseTotalAmounts;
     }
+    
+    //@codeCoverageIgnoreEnd
+
+    /**
+     * Set the full info, which is used to capture tax related information.
+     * If a string is used, it is assumed to be serialized.
+     *
+     * @param array|string $info
+     * @return $this
+     */
+    public function setFullInfo($info)
+    {
+        $this->setData('full_info', $info);
+        return $this;
+    }
+
+    /**
+     * Returns the full info, which is used to capture tax related information.
+     *
+     * @return array
+     */
+    public function getFullInfo()
+    {
+        $fullInfo = $this->getData('full_info');
+        if (is_string($fullInfo)) {
+            $fullInfo = unserialize($fullInfo);
+        }
+        return $fullInfo;
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
index f1660c9f9d6427fb617c2de9d87ae2a8026be3aa..88edeb5b99dd6c32e43994796eb48a6646ba5bc9 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
@@ -60,9 +60,10 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
         $addressWeight = $address->getWeight();
         $freeMethodWeight = $address->getFreeMethodWeight();
 
-        $address->setFreeShipping(
-            $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems())
-        );
+        $isAllFree = $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems());
+        if ($isAllFree && !$address->getFreeShipping()) {
+            $address->setFreeShipping(true);
+        }
         $total->setTotalAmount($this->getCode(), 0);
         $total->setBaseTotalAmount($this->getCode(), 0);
 
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Subtotal.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Subtotal.php
index e164146318bc86c88e0627967b140a91d968b4ae..7d4afa813165188890536f7287fa28c311b20e94 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Subtotal.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Subtotal.php
@@ -71,6 +71,8 @@ class Subtotal extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
          */
         $this->quoteValidator->validateQuoteAmount($quote, $total->getSubtotal());
         $this->quoteValidator->validateQuoteAmount($quote, $total->getBaseSubtotal());
+        $address->setSubtotal($total->getSubtotal());
+        $address->setBaseSubtotal($total->getBaseSubtotal());
         return $this;
     }
 
diff --git a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php
index eff7bdc30b7c327357f946d31e08d83548022ab5..a3d0507c394850f171d312467e4b5757a905bb02 100644
--- a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php
+++ b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php
@@ -5,22 +5,18 @@
  */
 namespace Magento\Quote\Model\QuoteRepository;
 
-use Magento\Quote\Model\Quote\Address\BillingAddressPersister;
-use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister;
-use Magento\Quote\Model\Quote\Item\CartItemPersister;
 use Magento\Quote\Api\Data\CartInterface;
 use Magento\Framework\Exception\InputException;
-use Magento\Quote\Model\ResourceModel\Quote;
 
 class SaveHandler
 {
     /**
-     * @var CartItemPersister
+     * @var \Magento\Quote\Model\Quote\Item\CartItemPersister
      */
     private $cartItemPersister;
 
     /**
-     * @var BillingAddressPersister
+     * @var \Magento\Quote\Model\Quote\Address\BillingAddressPersister
      */
     private $billingAddressPersister;
 
@@ -30,21 +26,21 @@ class SaveHandler
     private $quoteResourceModel;
 
     /**
-     * @var ShippingAssignmentPersister
+     * @var \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister
      */
     private $shippingAssignmentPersister;
 
     /**
-     * @param Quote $quoteResource
-     * @param CartItemPersister $cartItemPersister
-     * @param BillingAddressPersister $billingAddressPersister
-     * @param ShippingAssignmentPersister $shippingAssignmentPersister
+     * @param \Magento\Quote\Model\ResourceModel\Quote $quoteResource
+     * @param \Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister
+     * @param \Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister
+     * @param \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister
      */
     public function __construct(
-        Quote $quoteResource,
-        CartItemPersister $cartItemPersister,
-        BillingAddressPersister $billingAddressPersister,
-        ShippingAssignmentPersister $shippingAssignmentPersister
+        \Magento\Quote\Model\ResourceModel\Quote $quoteResource,
+        \Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister,
+        \Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister,
+        \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister
     ) {
         $this->quoteResourceModel = $quoteResource;
         $this->cartItemPersister = $cartItemPersister;
@@ -65,8 +61,9 @@ class SaveHandler
     {
         /** @var \Magento\Quote\Model\Quote $quote */
         // Quote Item processing
-        if ($quote->getItems()) {
-            foreach ($quote->getItems() as $item) {
+        $items = $quote->getItems();
+        if ($items) {
+            foreach ($items as $item) {
                 /** @var \Magento\Quote\Model\Quote\Item $item */
                 if (!$item->isDeleted()) {
                     $quote->setLastAddedItem($this->cartItemPersister->save($quote, $item));
@@ -75,20 +72,32 @@ class SaveHandler
         }
 
         // Billing Address processing
-        if ($quote->getBillingAddress() && $quote->getIsActive()) {
-            $this->billingAddressPersister->save($quote, $quote->getBillingAddress());
+        $billingAddress = $quote->getBillingAddress();
+        if ($billingAddress && $quote->getIsActive()) {
+            $this->billingAddressPersister->save($quote, $billingAddress);
         }
 
+        $this->processShippingAssignment($quote);
+
+        $this->quoteResourceModel->save($quote->collectTotals());
+        return $quote;
+    }
+
+    /**
+     * @param \Magento\Quote\Model\Quote $quote
+     * @return void
+     * @throws InputException
+     */
+    private function processShippingAssignment($quote)
+    {
         // Shipping Assignments processing
-        if ($quote->getExtensionAttributes() && $quote->getExtensionAttributes()->getShippingAssignments()) {
-            $shippingAssignments = $quote->getExtensionAttributes()->getShippingAssignments();
+        $extensionAttributes = $quote->getExtensionAttributes();
+        if (!$quote->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) {
+            $shippingAssignments = $extensionAttributes->getShippingAssignments();
             if (count($shippingAssignments) > 1) {
                 throw new InputException(__("Only 1 shipping assignment can be set"));
             }
             $this->shippingAssignmentPersister->save($quote, $shippingAssignments[0]);
         }
-
-        $this->quoteResourceModel->save($quote->collectTotals());
-        return $quote;
     }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/ShippingTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/ShippingTest.php
index 47d844093e6219a466e1a7fa83b043f35cf690ab..ae905becfa6d5f0e73dbf5554eaa3b9cc673cb26 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/ShippingTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/ShippingTest.php
@@ -200,9 +200,7 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $this->cartItem->expects($this->atLeastOnce())
             ->method('getQty')
             ->willReturn(2);
-        $this->address->expects($this->once())
-            ->method('getFreeShipping')
-            ->willReturn(true);
+        $this->freeShippingAssertions();
         $this->cartItem->expects($this->once())
             ->method('setRowWeight')
             ->with(0);
@@ -255,4 +253,18 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
 
         $this->shippingModel->collect($this->quote, $this->shippingAssignment, $this->total);
     }
+
+    protected function freeShippingAssertions()
+    {
+        $this->address->expects($this->at(0))
+            ->method('getFreeShipping')
+            ->willReturn(false);
+        $this->address->expects($this->at(1))
+            ->method('getFreeShipping')
+            ->willReturn(true);
+        $this->cartItem->expects($this->atLeastOnce())
+            ->method('getFreeShipping')
+            ->willReturn(true);
+
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php
index 00f653922db5c4c89e173a32fd9ce29bd34b5ece..efe6a81ce9242f510561f54cd6b484a336b37dbf 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php
@@ -167,4 +167,48 @@ class TotalTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals(0, $this->model->getBaseTotalAmount('great'));
     }
+
+    /**
+     * Verify handling of serialized, non-serialized input into and out of getFullInfo()
+     *
+     * @param $input
+     * @param $expected
+     * @dataProvider getFullInfoDataProvider
+     */
+    public function testGetFullInfo($input, $expected)
+    {
+        $this->model->setFullInfo($input);
+        $this->assertEquals($expected, $this->model->getFullInfo());
+    }
+
+    /**
+     * @return array
+     */
+    public function getFullInfoDataProvider()
+    {
+        $myArray = ['team' => 'kiwis'];
+        $serializedInput = serialize($myArray);
+
+        return [
+            'simple array' => [
+                $myArray,
+                $myArray,
+            ],
+
+            'serialized array' => [
+                $serializedInput,
+                $myArray,
+            ],
+
+            'null input/output' => [
+                null,
+                null,
+            ],
+
+            'float input' => [
+                1.23,
+                1.23,
+            ],
+        ];
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
index 6c495fb5b29d263ba1e9c5bf7dacd871c78c2ac4..f341bacef4713c939b970e4e7285e97eabe537a0 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
@@ -52,6 +52,9 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Catalog\Model\CustomOptions\CustomOptionProcessor|\PHPUnit_Framework_MockObject_MockObject */
     protected $customOptionProcessor;
 
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $shippingAddressMock;
+
     /**
      * @return void
      */
@@ -74,6 +77,13 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->shippingAddressMock = $this->getMock(
+            \Magento\Quote\Model\Quote\Address::class,
+            ['setCollectShippingRates'],
+            [],
+            '',
+            false
+        );
 
         $this->repository = new \Magento\Quote\Model\Quote\Item\Repository(
             $this->quoteRepositoryMock,
@@ -176,6 +186,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->productMock);
         $this->quoteMock->expects($this->never())->method('getItemById');
         $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
         $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
         $exceptionMessage = 'Could not save quote';
@@ -223,6 +239,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->productMock);
         $this->quoteMock->expects($this->never())->method('getItemById');
         $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
         $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
         $this->quoteMock
@@ -256,6 +278,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->productMock);
         $this->quoteMock->expects($this->never())->method('getItemById');
         $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
         $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
         $this->quoteMock->expects($this->once())
@@ -323,6 +351,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         $this->quoteItemMock->expects($this->never())->method('getId');
         $exceptionMessage = 'Could not save quote';
         $exception = new \Magento\Framework\Exception\CouldNotSaveException(__($exceptionMessage));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->quoteMock)
@@ -361,6 +395,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             ->expects($this->never())->method('get');
         $this->quoteItemMock->expects($this->never())->method('addProduct');
         $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
         $this->quoteMock
             ->expects($this->once())
@@ -424,6 +464,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         $this->productRepositoryMock
             ->expects($this->never())->method('get');
         $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+        $this->quoteMock->expects($this->once())
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true);
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
         $this->quoteMock
             ->expects($this->once())
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..76504b5064a2b987219c7df8dcf0ca61a18e9246
--- /dev/null
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Test\Unit\Model\QuoteRepository;
+
+use Magento\Quote\Model\QuoteRepository\SaveHandler;
+
+class SaveHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var SaveHandler
+     */
+    private $saveHandler;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cartItemPersister;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $billingAddressPersister;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $quoteResourceModel;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentPersister;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $quoteMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $itemMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $billingAddressMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extensionAttributeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentMock;
+
+    protected function setUp()
+    {
+        $this->quoteResourceModel = $this->getMock(\Magento\Quote\Model\ResourceModel\Quote::class, [], [], '', false);
+        $this->cartItemPersister = $this->getMock(
+            \Magento\Quote\Model\Quote\Item\CartItemPersister::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->billingAddressPersister  = $this->getMock(
+            \Magento\Quote\Model\Quote\Address\BillingAddressPersister::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->shippingAssignmentPersister = $this->getMock(
+            \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $methods = [
+            'getItems', 'setLastAddedItem', 'getBillingAddress', 'getIsActive',
+            'getExtensionAttributes', 'isVirtual', 'collectTotals'
+        ];
+        $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, $methods, [], '', false);
+        $this->itemMock = $this->getMock(\Magento\Quote\Model\Quote\Item::class, [], [], '', false);
+        $this->billingAddressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false);
+        $this->extensionAttributeMock = $this->getMock(\Magento\Quote\Api\Data\CartExtensionInterface::class);
+        $this->shippingAssignmentMock =
+            $this->getMock(
+                \Magento\Quote\Api\Data\CartExtension::class,
+                ['getShippingAssignments', 'setShippingAssignments'],
+                [],
+                '',
+                false
+            );
+        $this->saveHandler = new SaveHandler(
+            $this->quoteResourceModel,
+            $this->cartItemPersister,
+            $this->billingAddressPersister,
+            $this->shippingAssignmentPersister
+        );
+
+    }
+
+    public function testSaveForVirtualQuote()
+    {
+        $this->quoteMock->expects($this->once())->method('getItems')->willReturn([$this->itemMock]);
+        $this->itemMock->expects($this->once())->method('isDeleted')->willReturn(false);
+        $this->cartItemPersister
+            ->expects($this->once())
+            ->method('save')
+            ->with($this->quoteMock, $this->itemMock)
+            ->willReturn($this->itemMock);
+        $this->quoteMock->expects($this->once())->method('setLastAddedItem')->with($this->itemMock);
+        $this->quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($this->billingAddressMock);
+        $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn(true);
+        $this->billingAddressPersister
+            ->expects($this->once())
+            ->method('save')
+            ->with($this->quoteMock, $this->billingAddressMock);
+        $this->quoteMock
+            ->expects($this->once())
+            ->method('getExtensionAttributes')
+            ->willReturn($this->extensionAttributeMock);
+        $this->extensionAttributeMock
+            ->expects($this->never())
+            ->method('getShippingAssignments');
+        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(true);
+        $this->quoteMock->expects($this->once())->method('collectTotals')->willReturn($this->quoteMock);
+        $this->quoteResourceModel->expects($this->once())->method('save')->with($this->quoteMock);
+        $this->assertEquals($this->quoteMock, $this->saveHandler->save($this->quoteMock));
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5c0689c140225ebcf3e743602e48a432b0bf3f4
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Creditmemo\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_creditmemo_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Creditmemo'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Order/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..4455879910ac83ddade0510937a61584773606ee
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Creditmemo/Order/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Creditmemo\Order\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_creditmemo_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Creditmemo'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..97a8cda9ab1eb2b3e64a73682dd4971189a2ccb6
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Invoice\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_invoice_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Invoice'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Orders/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Orders/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae4788c4daea365854e698c25a3041d089d528eb
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Orders/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Invoice\Orders\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_invoice_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Invoice'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3141f521623fdb35e0f5e921636bdb68ae9e2cb
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Shipment\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_shipment_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Shipment'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Order/Grid/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..941b510a7f6320fe978a50904ef0cc74b99e85c5
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Order/Grid/Collection.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\ResourceModel\Order\Shipment\Order\Grid;
+
+use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
+use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
+use Magento\Framework\Event\ManagerInterface as EventManager;
+use Psr\Log\LoggerInterface as Logger;
+
+class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
+{
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param Logger $logger
+     * @param FetchStrategy $fetchStrategy
+     * @param EventManager $eventManager
+     * @param string $mainTable
+     * @param string $resourceModel
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        Logger $logger,
+        FetchStrategy $fetchStrategy,
+        EventManager $eventManager,
+        $mainTable = 'sales_shipment_grid',
+        $resourceModel = '\Magento\Sales\Model\ResourceModel\Order\Shipment'
+    ) {
+        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
+    }
+}
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index 32c1a17c90dfefc4a75e7c21abda71fb0ac3d2eb..209e46c3240b675f32622f3547331856bf87a1eb 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -780,42 +780,6 @@
             <argument name="state" xsi:type="object">Magento\Framework\App\State\Proxy</argument>
         </arguments>
     </type>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Invoice\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_invoice_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Invoice</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Shipment\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_shipment_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Shipment</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Creditmemo\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_creditmemo_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Creditmemo</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Invoice\Orders\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_invoice_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Invoice</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Shipment\Order\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_shipment_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Shipment</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Magento\Sales\Model\ResourceModel\Order\Creditmemo\Order\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
-        <arguments>
-            <argument name="mainTable" xsi:type="string">sales_creditmemo_grid</argument>
-            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order\Creditmemo</argument>
-        </arguments>
-    </virtualType>
     <virtualType name="orderMetadata" type="Magento\Sales\Model\ResourceModel\Metadata">
         <arguments>
             <argument name="resourceClassName" xsi:type="string">Magento\Sales\Model\ResourceModel\Order</argument>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml
index ad0e314930e095aa0cdeca00280924c35b525342..acf10ccbaa08726485065b67733c2cd52263c477 100755
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml
@@ -11,11 +11,11 @@ $taxAmount = $block->getTotal()->getValue();
 <?php if (($taxAmount == 0 && $this->helper('Magento\Tax\Helper\Data')->displayZeroTax()) || ($taxAmount > 0)): ?>
 <?php global $taxIter; $taxIter++; ?>
 <?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary()): ?>
-<?php $isTop = 1; ?>
-            <?php foreach ($block->getTotal()->getFullInfo() as $info): ?>
+        <?php $isTop = 1; ?>
+        <?php foreach ($block->getTotal()->getFullInfo() as $info): ?>
                 <?php if (isset($info['hidden']) && $info['hidden']) {
-    continue;
-} ?>
+                    continue;
+                } ?>
                 <?php $percent = $info['percent']; ?>
                 <?php $amount = $info['amount']; ?>
                 <?php $rates = $info['rates']; ?>
@@ -39,7 +39,7 @@ $taxAmount = $block->getTotal()->getValue();
                 <?php $isFirst = 0; ?>
                 <?php $isTop = 0; ?>
                 <?php endforeach; ?>
-            <?php endforeach; ?>
+        <?php endforeach; ?>
 <?php endif;?>
 <?php $class = "{$block->getTotal()->getCode()} " . ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() ? 'summary-total' : ''); ?>
 <tr<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary()): ?> onclick="expandDetails(this, '.summary-details-<?php /* @escapeNotVerified */ echo $taxIter;?>')"<?php endif; ?> class="<?php /* @escapeNotVerified */ echo $class;?> row-totals">
diff --git a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
index 93c628c9a2e2603e3deecadc37a00eafcd419e3f..09f925f4f6ecdbf6d6c857e3529605c5cf74250a 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
@@ -78,7 +78,7 @@ class ValueProvider
         $applyOptions = [
             ['label' => __('Percent of product price discount'), 'value' =>  Rule::BY_PERCENT_ACTION],
             ['label' => __('Fixed amount discount'), 'value' => Rule::BY_FIXED_ACTION],
-            ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::BY_PERCENT_ACTION],
+            ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::CART_FIXED_ACTION],
             ['label' => __('Buy X get Y free (discount amount is Y)'), 'value' => Rule::BUY_X_GET_Y_ACTION]
         ];
 
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php
index d93c504af9e71c7490c304f6b5fd43e87c335daa..ec3d3c86d7288b7292fe630478812669286bbc8e 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php
@@ -1,4 +1,9 @@
 <?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
 return [
     'rule_information' =>
         [
@@ -101,7 +106,7 @@ return [
                                                             ],
                                                             [
                                                                 'label' => __('Fixed amount discount for whole cart'),
-                                                                'value' => 'by_percent',
+                                                                'value' => 'cart_fixed',
                                                             ],
                                                             [
                                                                 'label' => __(
diff --git a/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php b/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php
index f85e2d308d7d1205110833074e33a864267745a9..5c6537030396357851e4b73984e5302119d64bde 100644
--- a/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php
+++ b/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php
@@ -16,7 +16,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
     protected $_idFieldName = 'id';
 
     /**
-     * @var \Magento\Framework\Stdlib\DateTime
+     * @var \Magento\Framework\Stdlib\DateTime\DateTime
      */
     protected $dateTime;
 
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
+     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
      * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
      * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
      */
@@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
+        \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
         \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
         \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
     ) {
@@ -108,9 +108,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
      */
     public function filterExpiredSessions($sessionLifeTime)
     {
+        $connection = $this->getConnection();
+        $gmtTimestamp = $this->dateTime->gmtTimestamp();
         $this->addFieldToFilter(
             'updated_at',
-            ['gt' => $this->dateTime->formatDate($this->dateTime->gmDate('U', null) - $sessionLifeTime)]
+            ['gt' => $connection->formatDate($gmtTimestamp - $sessionLifeTime)]
         );
         return $this;
     }
diff --git a/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php b/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php
index f1c1a867717d1d778570708a05be21ba3d40cc3c..5b455f8c686e3a6e76e065a03ee34c45a44160ce 100644
--- a/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php
+++ b/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php
@@ -16,7 +16,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
     protected $_idFieldName = 'id';
 
     /**
-     * @var \Magento\Framework\Stdlib\DateTime
+     * @var \Magento\Framework\Stdlib\DateTime\DateTime
      */
     protected $dateTime;
 
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
+     * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
      * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
      * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
      */
@@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
+        \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
         \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
         \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
     ) {
@@ -102,9 +102,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
      */
     public function filterByLifetime($lifetime)
     {
+        $connection = $this->getConnection();
+        $gmtTimestamp = $this->dateTime->gmtTimestamp();
         $this->addFieldToFilter(
             'created_at',
-            ['gt' => $this->dateTime->formatDate($this->dateTime->gmDate('U', null) - $lifetime)]
+            ['gt' => $connection->formatDate($gmtTimestamp - $lifetime)]
         );
 
         return $this;
diff --git a/app/code/Magento/Security/Setup/InstallSchema.php b/app/code/Magento/Security/Setup/InstallSchema.php
index 02143411a5d50c0e78311b6dfe42578a25cf7a93..db090066d9cbd054989d6b2c87dfffc74e94e622 100644
--- a/app/code/Magento/Security/Setup/InstallSchema.php
+++ b/app/code/Magento/Security/Setup/InstallSchema.php
@@ -88,9 +88,9 @@ class InstallSchema implements InstallSchemaInterface
             )
             ->addColumn(
                 'ip',
-                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-                null,
-                ['unsigned' => true, 'nullable' => false],
+                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
+                15,
+                ['nullable' => false],
                 'Remote user IP'
             )
             ->addIndex(
@@ -151,9 +151,9 @@ class InstallSchema implements InstallSchemaInterface
             )
             ->addColumn(
                 'ip',
-                \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-                null,
-                ['unsigned' => true, 'nullable' => false],
+                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
+                15,
+                ['nullable' => false],
                 'Remote user IP'
             )
             ->addIndex(
diff --git a/app/code/Magento/Security/Setup/UpgradeSchema.php b/app/code/Magento/Security/Setup/UpgradeSchema.php
new file mode 100644
index 0000000000000000000000000000000000000000..f17f0f496024832f0abb52de893a20adf9e2978c
--- /dev/null
+++ b/app/code/Magento/Security/Setup/UpgradeSchema.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Security\Setup;
+
+use Magento\Framework\Setup\UpgradeSchemaInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\SchemaSetupInterface;
+
+/**
+ * Upgrade the Catalog module DB scheme
+ */
+class UpgradeSchema implements UpgradeSchemaInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $setup->startSetup();
+
+        if (version_compare($context->getVersion(), '2.0.1', '<')) {
+            $setup->getConnection()->changeColumn(
+                $setup->getTable(\Magento\Security\Setup\InstallSchema::ADMIN_SESSIONS_DB_TABLE_NAME),
+                'ip',
+                'ip',
+                [
+                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
+                    'length' => 15,
+                    'nullable' => false,
+                    'comment' => 'Remote user IP'
+                ]
+            );
+
+            $setup->getConnection()->changeColumn(
+                $setup->getTable(\Magento\Security\Setup\InstallSchema::PASSWORD_RESET_REQUEST_EVENT_DB_TABLE_NAME),
+                'ip',
+                'ip',
+                [
+                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
+                    'length' => 15,
+                    'nullable' => false,
+                    'comment' => 'Remote user IP'
+                ]
+            );
+        }
+
+        $setup->endSetup();
+    }
+}
diff --git a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php
index 633ab04dd03b5802440b9d0342a415784df9c9ba..c5229e573d08e6446bae09e647b85fc69f2d2134 100644
--- a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php
+++ b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php
@@ -6,8 +6,6 @@
 
 namespace Magento\Security\Test\Unit\Model\ResourceModel\AdminSessionInfo;
 
-use Magento\Security\Model\ConfigInterface;
-
 /**
  * Test class for \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection testing
  */
@@ -16,7 +14,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection */
     protected $collectionMock;
 
-    /** @var \Magento\Framework\Stdlib\DateTime */
+    /** @var \Magento\Framework\Stdlib\DateTime\DateTime */
     protected $dateTimeMock;
 
     /** @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb */
@@ -29,7 +27,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->dateTimeMock = $this->getMock(
-            '\Magento\Framework\Stdlib\DateTime',
+            \Magento\Framework\Stdlib\DateTime\DateTime::class,
             [],
             [],
             '',
@@ -136,14 +134,14 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $timestamp = time();
 
         $this->dateTimeMock->expects($this->once())
-            ->method('gmDate')
+            ->method('gmtTimestamp')
             ->willReturn($timestamp);
 
         $this->collectionMock->expects($this->once())
             ->method('addFieldToFilter')
             ->with(
                 'updated_at',
-                ['gt' => $this->dateTimeMock->formatDate($timestamp - $sessionLifeTime)]
+                ['gt' => $this->collectionMock->getConnection()->formatDate($timestamp - $sessionLifeTime)]
             )
             ->willReturnSelf();
 
diff --git a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php
index 4492326851582eef1b340f1bef52026a09a8ee35..6f9664031bbf70bb1033be719b7ad5322a6914ba 100644
--- a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php
+++ b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php
@@ -6,8 +6,6 @@
 
 namespace Magento\Security\Test\Unit\Model\ResourceModel\PasswordResetRequestEvent;
 
-use Magento\Security\Model\ConfigInterface;
-
 /**
  * Test class for \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection testing
  */
@@ -16,7 +14,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Security\Model\ResourceModel\PasswordResetRequestEvent\Collection */
     protected $collectionMock;
 
-    /** @var \Magento\Framework\Stdlib\DateTime */
+    /** @var \Magento\Framework\Stdlib\DateTime\DateTime */
     protected $dateTimeMock;
 
     /** @var \Magento\Framework\DB\Select */
@@ -61,7 +59,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->dateTimeMock = $this->getMock(
-            '\Magento\Framework\Stdlib\DateTime',
+            '\Magento\Framework\Stdlib\DateTime\DateTime',
             [],
             [],
             '',
@@ -175,14 +173,14 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $timestamp = time();
 
         $this->dateTimeMock->expects($this->once())
-            ->method('gmDate')
+            ->method('gmtTimestamp')
             ->willReturn($timestamp);
 
         $this->collectionMock->expects($this->once())
             ->method('addFieldToFilter')
             ->with(
                 'created_at',
-                ['gt' => $this->dateTimeMock->formatDate($timestamp - $lifetime)]
+                ['gt' => $this->collectionMock->getConnection()->formatDate($timestamp - $lifetime)]
             )
             ->willReturnSelf();
 
diff --git a/app/code/Magento/Security/etc/module.xml b/app/code/Magento/Security/etc/module.xml
index d0bdba4a6f79cbf0bfe0cff841ef91d0c3faaa0a..85ad00b5c0729e90016f938afeef49e9ddf32f44 100644
--- a/app/code/Magento/Security/etc/module.xml
+++ b/app/code/Magento/Security/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_Security" setup_version="2.0.0">
+    <module name="Magento_Security" setup_version="2.0.1">
         <sequence>
             <module name="Magento_Backend"/>
             <module name="Magento_Store"/>
diff --git a/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php b/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
index de762ec60c0e5305959dbc57f43611ed645d44fb..47712fe4894d944dca587f2b9bd811d299d5c47a 100644
--- a/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
+++ b/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
@@ -7,6 +7,10 @@ namespace Magento\Tax\Block\Checkout\Shipping;
 
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 
+/**
+ * Class Price
+ * @deprecated
+ */
 class Price extends \Magento\Checkout\Block\Shipping\Price
 {
     /**
diff --git a/app/code/Magento/Tax/Model/Config/Price/IncludePrice.php b/app/code/Magento/Tax/Model/Config/Price/IncludePrice.php
index 3a3c9b2b3bc680d628237abe167cdc74719749ac..40030a70e62b8ed7c833b945d6e91382b3949bb4 100644
--- a/app/code/Magento/Tax/Model/Config/Price/IncludePrice.php
+++ b/app/code/Magento/Tax/Model/Config/Price/IncludePrice.php
@@ -8,11 +8,13 @@ namespace Magento\Tax\Model\Config\Price;
 class IncludePrice extends \Magento\Framework\App\Config\Value
 {
     /**
-     * @return void
+     * @return $this
      */
     public function afterSave()
     {
-        parent::afterSave();
+        $result = parent::afterSave();
         $this->_cacheManager->clean(['checkout_quote']);
+
+        return $result;
     }
 }
diff --git a/app/code/Magento/Tax/view/frontend/layout/checkout_shipping_price_renderer.xml b/app/code/Magento/Tax/view/frontend/layout/checkout_shipping_price_renderer.xml
deleted file mode 100644
index c2a5428cc5beabe2cc41f76372bbc1957b64e477..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/layout/checkout_shipping_price_renderer.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
-    <body>
-        <block class="Magento\Tax\Block\Checkout\Shipping\Price" name="checkout.shipping.price" as="shipping.price" template="Magento_Tax::checkout/shipping/price.phtml"/>
-    </body>
-</page>
diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml
index 92d0b199ae7071b6f482aa9d153a68362d6e1f0c..4cdfbac691e6aadf18530ac41203b7790788bc39 100644
--- a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml
@@ -39,10 +39,10 @@
 
 <?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $_value != 0): ?>
     <?php $isTop = 1; ?>
-    <?php foreach (unserialize($block->getTotal()->getFullInfo()) as $info): ?>
+    <?php foreach ($block->getTotal()->getFullInfo() as $info): ?>
         <?php if (isset($info['hidden']) && $info['hidden']) {
-    continue;
-} ?>
+            continue;
+        } ?>
         <?php $percent = $info['percent']; ?>
         <?php $amount = $info['amount']; ?>
         <?php $rates = $info['rates']; ?>
diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php
index d0205f51453bc4d003e6347af7b5754ac40d6d4c..52a4714fea8db053b49790a548538644866744cc 100644
--- a/app/code/Magento/Theme/Block/Html/Topmenu.php
+++ b/app/code/Magento/Theme/Block/Html/Topmenu.php
@@ -330,7 +330,9 @@ class Topmenu extends Template implements IdentityInterface
      */
     public function addIdentity($identity)
     {
-        $this->identities[] = $identity;
+        if (!in_array($identity, $this->identities)) {
+            $this->identities[] = $identity;
+        }
     }
 
     /**
@@ -364,4 +366,14 @@ class Topmenu extends Template implements IdentityInterface
     {
         return array_merge(parent::getCacheTags(), $this->getIdentities());
     }
+
+    /**
+     * Get menu object.
+     *
+     * @return Node
+     */
+    public function getMenu()
+    {
+        return $this->_menu;
+    }
 }
diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js
index 6d71b3b36d13f792b4e557b0a7a3a89e5b9755e9..abe587777dd9c0f0b786faffcb09686d3f6378a4 100644
--- a/app/code/Magento/Theme/view/base/requirejs-config.js
+++ b/app/code/Magento/Theme/view/base/requirejs-config.js
@@ -51,7 +51,14 @@ var config = {
     },
     "deps": [
         "jquery/jquery-migrate"
-    ]
+    ],
+    "config": {
+        "mixins": {
+            "jquery/jstree/jquery.jstree": {
+                "mage/backend/jstree-mixin": true
+            }
+        }
+    }
 };
 
 require(['jquery'], function ($) {
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
index 4bbde097b143d822ffa8159ff395c32798bee371..f384cdd3f9dd113815416218f8d428789fb52399 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
@@ -60,14 +60,29 @@ class Date extends AbstractDataType
     public function prepare()
     {
         $config = $this->getData('config');
+
+        if (!isset($config['timeOffset'])) {
+            $config['timeOffset'] = (new \DateTime(
+                'now',
+                new \DateTimeZone(
+                    $this->localeDate->getConfigTimezone()
+                )
+            ))->getOffset();
+        }
+
+        if (!isset($config['timeFormat'])) {
+            $config['timeFormat'] = $this->localeDate->getTimeFormat(\IntlDateFormatter::SHORT);
+        }
+
         if (!isset($config['dateFormat'])) {
-            $config['dateFormat'] = $this->localeDate->getDateTimeFormat(\IntlDateFormatter::MEDIUM);
-            $this->setData('config', $config);
+            $config['dateFormat'] = $this->localeDate->getDateFormat(\IntlDateFormatter::MEDIUM);
         }
+
+        $this->setData('config', $config);
+
         parent::prepare();
     }
 
-
     /**
      * Get locale
      *
diff --git a/app/code/Magento/Ui/view/base/templates/stepswizard.phtml b/app/code/Magento/Ui/view/base/templates/stepswizard.phtml
index b6f74dda267eb9dcbf30932a6659989a934b8046..82cc34b42b12088f781629fac0a8a53948437d0e 100644
--- a/app/code/Magento/Ui/view/base/templates/stepswizard.phtml
+++ b/app/code/Magento/Ui/view/base/templates/stepswizard.phtml
@@ -64,7 +64,7 @@
                             "component": "Magento_Ui/js/lib/step-wizard",
                             "initData": <?= /* @escapeNotVerified */  $this->helper("Magento\Framework\Json\Helper\Data")->jsonEncode($block->getInitData()) ?>,
                             "stepsNames": <?= /* @escapeNotVerified */  $this->helper("Magento\Framework\Json\Helper\Data")->jsonEncode($block->getStepComponents()) ?>,
-                            "modalClass": "<?= /* @noEscape */ $block->getData('config/modal')?>"
+                            "modalClass": "<?= /* @noEscape */ $block->getData('config/dataScope')?>"
                         }
                     }
                 }
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
index 45d9048cf60b73861fd8b5be88fd2d0c1516ab96..f6b86377d6fd2fcd095b2c22ba4dd0802ad8a3d0 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
@@ -1,5 +1,5 @@
 /**
- * Copyright © 2016 Magento. All rights reserved.
+ * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 define([
@@ -11,9 +11,60 @@ define([
 
     return Abstract.extend({
         defaults: {
+            options: {},
+
+            timeOffset: 0,
+
+            showsTime: false,
+
+            dateFormat: 'MM/dd/y', // ICU Date Format
+            timeFormat: 'HH:mm', // ICU Time Format
+
+            /**
+             * Format of date that comes from the
+             * server (ICU Date Format).
+             *
+             * Used only in date picker mode
+             * (this.showsTime == false).
+             *
+             * @type {String}
+             */
+            inputDateFormat: 'y-MM-dd',
+
+            /**
+             * Format of date that should be sent to the
+             * server (ICU Date Format).
+             *
+             * Used only in date picker mode
+             * (this.showsTime == false).
+             *
+             * @type {String}
+             */
+            outputDateFormat: 'MM/dd/y',
+
+            /**
+             * Date/time format that is used to display date in
+             * the input field.
+             *
+             * @type {String}
+             */
+            datetimeFormat: '',
+
             elementTmpl: 'ui/form/element/date',
-            dateFormat: 'MM/dd/YYYY',
-            options: {}
+
+            listens: {
+                'value': 'onValueChange',
+                'shiftedValue': 'onShiftedValueChange'
+            },
+
+            /**
+             * Date/time value shifted to corresponding timezone
+             * according to this.timeOffset property. This value
+             * will be sent to the server.
+             *
+             * @type {String}
+             */
+            shiftedValue: ''
         },
 
         /**
@@ -23,24 +74,91 @@ define([
          */
         initConfig: function () {
             this._super();
-            this.dateFormat = utils.normalizeDate(this.dateFormat);
+
+            utils.extend(this.options, {
+                showsTime: this.showsTime,
+                timeFormat: this.timeFormat,
+                dateFormat: this.dateFormat
+            });
+
+            this.prepareDatetimeFormats();
 
             return this;
         },
 
         /**
-         * Formats provided value according to 'dateFormat' property.
+         * @inheritdoc
+         */
+        initObservable: function () {
+            return this._super().observe(['shiftedValue']);
+        },
+
+        /**
+         * Prepares and sets date/time value that will be displayed
+         * in the input field.
          *
-         * @returns {String}
+         * @param {String} value
          */
-        normalizeData: function () {
-            var value = this._super();
+        onValueChange: function (value) {
+            var dateFormat,
+                shiftedValue;
 
             if (value) {
-                value = moment(value).format(this.dateFormat);
+                if (this.showsTime) {
+                    shiftedValue = moment.utc(value).add(this.timeOffset, 'seconds');
+                } else {
+                    dateFormat = this.shiftedValue() ? this.outputDateFormat : this.inputDateFormat;
+
+                    shiftedValue = moment(value, dateFormat);
+                }
+
+                shiftedValue = shiftedValue.format(this.datetimeFormat);
+
+                if (shiftedValue !== this.shiftedValue()) {
+                    this.shiftedValue(shiftedValue);
+                }
+            }
+        },
+
+        /**
+         * Prepares and sets date/time value that will be sent
+         * to the server.
+         *
+         * @param {String} shiftedValue
+         */
+        onShiftedValueChange: function (shiftedValue) {
+            var value;
+
+            if (shiftedValue) {
+                if (this.showsTime) {
+                    value = moment.utc(shiftedValue, this.datetimeFormat);
+                    value = value.subtract(this.timeOffset, 'seconds').toISOString();
+                } else {
+                    value = moment(shiftedValue, this.datetimeFormat);
+                    value = value.format(this.outputDateFormat);
+                }
+
+                if (value !== this.value()) {
+                    this.value(value);
+                }
+            }
+        },
+
+        /**
+         * Prepares and converts all date/time formats to be compatible
+         * with moment.js library.
+         */
+        prepareDatetimeFormats: function () {
+            this.datetimeFormat = this.dateFormat;
+
+            if (this.showsTime) {
+                this.datetimeFormat += ' ' + this.timeFormat;
             }
 
-            return value;
+            this.datetimeFormat = utils.normalizeDate(this.datetimeFormat);
+
+            this.inputDateFormat = utils.normalizeDate(this.inputDateFormat);
+            this.outputDateFormat = utils.normalizeDate(this.outputDateFormat);
         }
     });
 });
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js
index 6d7c937f62ee051f7994ab7a54b4464bfa2f4d02..b3db5d11b98a51bc166082a10ae351949f317d9c 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js
@@ -2,6 +2,7 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 define([
     'Magento_Ui/js/lib/view/utils/async',
     'underscore',
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/single/radio.html b/app/code/Magento/Ui/view/base/web/templates/form/components/single/radio.html
index 0cd5828e6ce5c9d2ad20357326e4cfd92ea10d99..0328957c8f6efa6df49c990f9f23571b02e7efba 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/single/radio.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/components/single/radio.html
@@ -12,7 +12,7 @@
            ko-focused="focused"
            ko-value="value"
            keyboard="keyboard"
-           attr="id: uid, name: inputName"/>
+           attr="id: uid, name: inputName, 'data-index': index"/>
 
     <label class="admin__field-label" text="description" attr="for: uid"/>
 </div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/date.html b/app/code/Magento/Ui/view/base/web/templates/form/element/date.html
index 1644c4d6c0da147f34f587bf203692efdd4dd269..542b81fb918f1900b8b61498cf0a8f64c23872e8 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/element/date.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/element/date.html
@@ -6,10 +6,10 @@
 -->
 <input class="admin__control-text" type="text" data-bind="
     hasFocus: focused,
-    datepicker: { storage: value, options: options },
+    datepicker: { storage: shiftedValue, options: options },
     valueUpdate: valueUpdate,
     attr: {
-        value: value,
+        value: shiftedValue,
         name: inputName,
         placeholder: placeholder,
         'aria-describedby': noticeId,
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
index efcfda9cb67bbc8c76d3775d4ba8f3fe4ac2882d..d91faf2da5dd699989cc87cd7794b1a395516598 100644
--- a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
@@ -6,6 +6,8 @@
  */
 namespace Magento\User\Controller\Adminhtml\Auth;
 
+use Magento\Security\Model\SecurityManager;
+
 class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth
 {
     /**
@@ -31,12 +33,15 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth
      * Forgot administrator password action
      *
      * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     public function execute()
     {
         $email = (string)$this->getRequest()->getParam('email');
         $params = $this->getRequest()->getParams();
 
+        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultRedirectFactory->create();
         if (!empty($email) && !empty($params)) {
             // Validate received data to be an email address
             if (\Zend_Validate::is($email, 'EmailAddress')) {
@@ -47,7 +52,6 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth
                     );
                 } catch (\Magento\Framework\Exception\SecurityViolationException $exception) {
                     $this->messageManager->addErrorMessage($exception->getMessage());
-                    $resultRedirect = $this->resultRedirectFactory->create();
                     return $resultRedirect->setPath('admin');
                 }
                 $collection = $this->_objectManager->get('Magento\User\Model\ResourceModel\User\Collection');
@@ -55,20 +59,28 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth
                 $collection->addFieldToFilter('email', $email);
                 $collection->load(false);
 
-                if ($collection->getSize() > 0) {
-                    foreach ($collection as $item) {
-                        /** @var \Magento\User\Model\User $user */
-                        $user = $this->_userFactory->create()->load($item->getId());
-                        if ($user->getId()) {
-                            $newPassResetToken = $this->_objectManager->get(
-                                'Magento\User\Helper\Data'
-                            )->generateResetPasswordLinkToken();
-                            $user->changeResetPasswordLinkToken($newPassResetToken);
-                            $user->save();
-                            $user->sendPasswordResetConfirmationEmail();
+                try {
+                    if ($collection->getSize() > 0) {
+                        foreach ($collection as $item) {
+                            /** @var \Magento\User\Model\User $user */
+                            $user = $this->_userFactory->create()->load($item->getId());
+                            if ($user->getId()) {
+                                $newPassResetToken = $this->_objectManager->get(
+                                    'Magento\User\Helper\Data'
+                                )->generateResetPasswordLinkToken();
+                                $user->changeResetPasswordLinkToken($newPassResetToken);
+                                $user->save();
+                                $user->sendPasswordResetConfirmationEmail();
+                            }
+                            break;
                         }
-                        break;
                     }
+                } catch (\Exception $exception) {
+                    $this->messageManager->addExceptionMessage(
+                        $exception,
+                        __('We\'re unable to send the password reset email.')
+                    );
+                    return $resultRedirect->setPath('admin');
                 }
                 // @codingStandardsIgnoreStart
                 $this->messageManager->addSuccess(__('We\'ll email you a link to reset your password.'));
diff --git a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php
index d5c0bcc678f6a4af813fe88d6f2419f9561a5134..038f5cdcfc444802259049eac10e371fba17edec 100644
--- a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php
+++ b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php
@@ -12,6 +12,7 @@ use Magento\Webapi\Model\Soap\Wsdl;
 use Magento\Webapi\Model\Soap\WsdlFactory;
 use Magento\Framework\Webapi\Authorization;
 use Magento\Webapi\Model\ServiceMetadata;
+use Magento\Framework\Exception\AuthorizationException;
 
 /**
  * WSDL generator.
@@ -364,4 +365,21 @@ class Generator extends AbstractSchemaGenerator
     {
         return $this->serviceMetadata->getServiceMetadata($serviceName);
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getAllowedServicesMetadata($requestedServices)
+    {
+        $allowedServicesMetadata = parent::getAllowedServicesMetadata($requestedServices);
+        if (!$allowedServicesMetadata) {
+            throw new AuthorizationException(
+                __(
+                    AuthorizationException::NOT_AUTHORIZED,
+                    ['resources' => implode(', ', $requestedServices)]
+                )
+            );
+        }
+        return $allowedServicesMetadata;
+    }
 }
diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php
index fbf2485d37542a489d3a8e6b8bf447a6d94e81c5..2235df9aff0772f05eb7ea71d0ebf60010893570 100644
--- a/app/code/Magento/Widget/Model/Widget.php
+++ b/app/code/Magento/Widget/Model/Widget.php
@@ -309,7 +309,7 @@ class Widget
             } elseif (trim($value) == '') {
                 $widget = $this->getConfigAsObject($type);
                 $parameters = $widget->getParameters();
-                if (is_object($parameters[$name])) {
+                if (isset($parameters[$name]) && is_object($parameters[$name])) {
                     $value = $parameters[$name]->getValue();
                 }
             }
diff --git a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
index e67a095157a16042eb6b881eff8c06f6ba6e258a..728cc082bbe0887792b024b93585e14b0185cf54 100644
--- a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
+++ b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
@@ -276,9 +276,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
             'WISHLIST:' . __METHOD__,
             ['group' => 'WISHLIST', 'method' => __METHOD__]
         );
-        $productIds = [];
 
-        $this->_productIds = array_merge($this->_productIds, array_keys($productIds));
         /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
         $productCollection = $this->_productCollectionFactory->create();
 
@@ -289,7 +287,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab
         $productCollection->addPriceData()
             ->addTaxPercents()
             ->addIdFilter($this->_productIds)
-            ->addAttributeToSelect('name')
+            ->addAttributeToSelect(['name', 'visibility'])
             ->addOptionsToResult()
             ->addUrlRewrite();
 
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml b/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
index ac5a6aea6b7c4fe1294bfb2c07345150515b5296..6c4156291d3219fdb96552feb9218181db4c32e7 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
@@ -7,6 +7,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <head>
+        <css src="jquery/jstree/themes/default/style.css"/>
         <css src="css/styles-old.css"/>
         <css src="css/styles.css"/>
     </head>
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module-old.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module-old.less
index 9a23471f828bd61393ba0aee53abeb4c44b2ef85..187712e090aa1c58d508d2b0853f15b3b65ebf17 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module-old.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/_module-old.less
@@ -320,6 +320,32 @@
     cursor: not-allowed;
 }
 
+//  ToDo: remove after "Product Attributes Mass update" implementation
+.attributes-edit-form {
+    .field {
+        .control {
+            input[type='text'][disabled] ~ .addafter,
+            select[disabled] ~ .addafter,
+            .attribute-change-checkbox {
+                background: none;
+                color: #676056;
+                cursor: inherit;
+                opacity: 1;
+
+                strong {
+                    background: none;
+                }
+            }
+        }
+    }
+
+    .weight-switcher {
+        .addafter {
+            margin-top: 30px;
+        }
+    }
+}
+
 .field .control input[type='text'][disabled] ~ .addafter strong,
 .field .control select[disabled] ~ .addafter strong {
     background-color: #e9e9e9;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
index 7c758b5ddca71e5d511d01b5b38a47bd57d4daa6..abc9067338072dead69a9b1e2f2f13bb9cba691f 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less
@@ -241,6 +241,8 @@ option:empty {
     }
 
     .admin__control-text {
+        margin: .1rem;
+        padding: @field-control__padding-top - .1rem @field-control__padding-horizontal - .1rem @field-control__padding-bottom - .1rem;
         width: 100%;
     }
 
diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less
index 613c55cebc297b1b363c67f92aa3e7253781e003..28cae989ae50a4641be6eb568536fcdcfcd5abca 100644
--- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less
+++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less
@@ -887,6 +887,7 @@
             background-color: #e9e9e9;
             border-color: #adadad;
             opacity: .5;
+
             &.admin__control-checkbox,
             &.admin__control-radio {
                 opacity: 0.01;
@@ -1387,6 +1388,7 @@
             line-height: 1.33;
             vertical-align: middle;
             white-space: normal;
+            word-break: break-all;
 
             &[data-config-scope] {
                 position: relative;
diff --git a/composer.json b/composer.json
index 73115b15a9f32a8af1a49a14a7658cd5daf9804c..3734cdd372bba9951c78de4769fa6773429b1290 100644
--- a/composer.json
+++ b/composer.json
@@ -33,7 +33,7 @@
         "zendframework/zend-http": "~2.4.6",
         "magento/zendframework1": "1.12.16",
         "colinmollenhour/credis": "1.6",
-        "colinmollenhour/php-redis-session-abstract": "1.0",
+        "colinmollenhour/php-redis-session-abstract": "1.1",
         "composer/composer": "1.0.0-beta1",
         "monolog/monolog": "1.16.0",
         "oyejorge/less.php": "1.7.0.3",
diff --git a/composer.lock b/composer.lock
index 4aaae63b403d43bf5ce7a75886dc6c8cedb6adb0..2f0873b997487361830407de6878ee657eab5928 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": "d81a16c234a62403d9b5b06057393d9d",
-    "content-hash": "cd415001aebab7eb87bb62e2223509fc",
+    "hash": "666640f73320778f40be99a86695ef1c",
+    "content-hash": "1a3c1d3316e4448159bbcc436015ad2b",
     "packages": [
         {
             "name": "braintree/braintree_php",
@@ -95,16 +95,16 @@
         },
         {
             "name": "colinmollenhour/php-redis-session-abstract",
-            "version": "v1.0",
+            "version": "v1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git",
-                "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9"
+                "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9",
-                "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9",
+                "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/95330b7f29663dab81f53d1a438e4d927b6c5f66",
+                "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66",
                 "shasum": ""
             },
             "require": {
@@ -129,7 +129,7 @@
             ],
             "description": "A Redis-based session handler with optimistic locking",
             "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract",
-            "time": "2016-01-14 16:04:27"
+            "time": "2016-02-03 18:13:49"
         },
         {
             "name": "composer/composer",
@@ -208,16 +208,16 @@
         },
         {
             "name": "composer/semver",
-            "version": "1.3.0",
+            "version": "1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/semver.git",
-                "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747"
+                "reference": "84c47f3d8901440403217afc120683c7385aecb8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/semver/zipball/df4463baa9f44fe6cf0a6da4fde2934d4c0a2747",
-                "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747",
+                "url": "https://api.github.com/repos/composer/semver/zipball/84c47f3d8901440403217afc120683c7385aecb8",
+                "reference": "84c47f3d8901440403217afc120683c7385aecb8",
                 "shasum": ""
             },
             "require": {
@@ -266,28 +266,28 @@
                 "validation",
                 "versioning"
             ],
-            "time": "2016-02-25 22:23:39"
+            "time": "2016-03-30 13:16:03"
         },
         {
             "name": "composer/spdx-licenses",
-            "version": "1.1.2",
+            "version": "1.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/spdx-licenses.git",
-                "reference": "9e1c3926bb0842812967213d7c92827bc5883671"
+                "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/9e1c3926bb0842812967213d7c92827bc5883671",
-                "reference": "9e1c3926bb0842812967213d7c92827bc5883671",
+                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/547659c3cacd3ccfe1b4714c2ff88cafc6b6793b",
+                "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.2"
+                "php": "^5.3.2 || ^7.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.5",
-                "phpunit/phpunit-mock-objects": "~2.3"
+                "phpunit/phpunit": "^4.5 || ^5.0.5",
+                "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
             },
             "type": "library",
             "extra": {
@@ -327,7 +327,7 @@
                 "spdx",
                 "validator"
             ],
-            "time": "2015-10-05 11:27:42"
+            "time": "2016-03-25 10:57:10"
         },
         {
             "name": "justinrainbow/json-schema",
@@ -1181,16 +1181,16 @@
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3"
+                "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3",
-                "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87",
+                "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87",
                 "shasum": ""
             },
             "require": {
@@ -1237,20 +1237,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2016-01-27 05:14:19"
+            "time": "2016-03-07 14:04:32"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "65cb36b6539b1d446527d60457248f30d045464d"
+                "reference": "f08ffdf229252cd2745558cb2112df43903bcae4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d",
-                "reference": "65cb36b6539b1d446527d60457248f30d045464d",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4",
+                "reference": "f08ffdf229252cd2745558cb2112df43903bcae4",
                 "shasum": ""
             },
             "require": {
@@ -1286,20 +1286,20 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "time": "2016-02-22 15:02:30"
+            "time": "2016-03-27 10:20:16"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.0.3",
+            "version": "v3.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723"
+                "reference": "c54e407b35bc098916704e9fd090da21da4c4f52"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723",
-                "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52",
+                "reference": "c54e407b35bc098916704e9fd090da21da4c4f52",
                 "shasum": ""
             },
             "require": {
@@ -1335,20 +1335,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2016-01-27 05:14:46"
+            "time": "2016-03-10 11:13:05"
         },
         {
             "name": "symfony/process",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe"
+                "reference": "fb467471952ef5cf8497c029980e556b47545333"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe",
-                "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe",
+                "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333",
+                "reference": "fb467471952ef5cf8497c029980e556b47545333",
                 "shasum": ""
             },
             "require": {
@@ -1384,7 +1384,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2016-02-02 13:33:15"
+            "time": "2016-03-23 13:11:46"
         },
         {
             "name": "tedivm/jshrink",
@@ -4112,16 +4112,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19"
+                "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19",
-                "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19",
+                "url": "https://api.github.com/repos/symfony/config/zipball/5273f4724dc5288fe7a33cb08077ab9852621f2c",
+                "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c",
                 "shasum": ""
             },
             "require": {
@@ -4161,20 +4161,20 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
-            "time": "2016-02-22 16:12:45"
+            "time": "2016-03-04 07:54:35"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "62251761a7615435b22ccf562384c588b431be44"
+                "reference": "f7b4a498e679fa440b16facb934680a1527ed48c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/62251761a7615435b22ccf562384c588b431be44",
-                "reference": "62251761a7615435b22ccf562384c588b431be44",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7b4a498e679fa440b16facb934680a1527ed48c",
+                "reference": "f7b4a498e679fa440b16facb934680a1527ed48c",
                 "shasum": ""
             },
             "require": {
@@ -4223,20 +4223,20 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "time": "2016-02-28 16:34:46"
+            "time": "2016-03-21 07:27:21"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v3.0.3",
+            "version": "v3.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stopwatch.git",
-                "reference": "4a204804952ff267ace88cf499e0b4bb302a475e"
+                "reference": "6015187088421e9499d8f8316bdb396f8b806c06"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4a204804952ff267ace88cf499e0b4bb302a475e",
-                "reference": "4a204804952ff267ace88cf499e0b4bb302a475e",
+                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6015187088421e9499d8f8316bdb396f8b806c06",
+                "reference": "6015187088421e9499d8f8316bdb396f8b806c06",
                 "shasum": ""
             },
             "require": {
@@ -4272,20 +4272,20 @@
             ],
             "description": "Symfony Stopwatch Component",
             "homepage": "https://symfony.com",
-            "time": "2016-01-03 15:35:16"
+            "time": "2016-03-04 07:55:57"
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.8.3",
+            "version": "v2.8.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995"
+                "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
-                "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
+                "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
                 "shasum": ""
             },
             "require": {
@@ -4321,7 +4321,7 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2016-02-23 07:41:20"
+            "time": "2016-03-04 07:54:35"
         },
         {
             "name": "theseer/fdomdocument",
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
index eff0dbba735f6295e4084f10bb8228f56ee04539..88d4e559e16d52967f1d452bfd95791765cd1255 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
@@ -25,7 +25,7 @@ abstract class BaseService extends \Magento\TestFramework\TestCase\WebapiAbstrac
             $this->_assertSoapException(
                 $serviceInfo,
                 $requestData,
-                'SOAP-ERROR: Parsing WSDL: Couldn\'t bind to service'
+                'Consumer is not authorized to access %resources'
             );
         } elseif (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
             $this->_assertRestUnauthorizedException($serviceInfo, $requestData);
@@ -111,7 +111,7 @@ abstract class BaseService extends \Magento\TestFramework\TestCase\WebapiAbstrac
             }
 
             if ($expectedMessage) {
-                $this->assertEquals($expectedMessage, $e->getMessage());
+                $this->assertContains($expectedMessage, $e->getMessage());
             }
         }
     }
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
index c7ef1d00e02fad6a9311240065b3c32a247e2065..8cd95ef23a47e75b7915e7c114c1968833d81125 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
@@ -110,8 +110,8 @@ class SoapErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstra
         } catch (\SoapFault $e) {
             $this->checkSoapFault(
                 $e,
-                'SOAP-ERROR: Parsing WSDL: Couldn\'t bind to service',
-                'WSDL'
+                'Consumer is not authorized to access %resources',
+                'env:Sender'
             );
         }
     }
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
index 2593e9d12f5f94c4e18f12e3f9720747994e1b56..9afdb1f26067a769726fd4d44f235d3c5958ba48 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
@@ -65,6 +65,16 @@ class WsdlGenerationFromDataObjectTest extends \Magento\TestFramework\TestCase\W
         $this->_checkFaultsDeclaration($wsdlContent);
     }
 
+    public function testNoAuthorizedServices()
+    {
+        $wsdlUrl = $this->_getBaseWsdlUrl() . 'testModule5AllSoapAndRestV2';
+        $connection = curl_init($wsdlUrl);
+        curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);
+        $responseContent = curl_exec($connection);
+        $this->assertEquals(curl_getinfo($connection, CURLINFO_HTTP_CODE), 401);
+        $this->assertContains("Consumer is not authorized to access %resources", $responseContent);
+    }
+
     public function testInvalidWsdlUrlNoServices()
     {
         $responseContent = $this->_getWsdlContent($this->_getBaseWsdlUrl());
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Cart/Item.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Cart/Item.php
index ee78eb61c5572f132017810cf6ed54d81f1eee78..cb46e728191bffb5a770a2809019fb2833f9f0d3 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Cart/Item.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Cart/Item.php
@@ -53,7 +53,7 @@ class Item extends \Magento\Catalog\Test\Fixture\Cart\Item
             $bundleOptions = $bundleSelection['bundle_options'][$attributeKey];
             $value = $bundleSelectionAttribute[$optionKey]->getName();
             $qty = $bundleOptions['assigned_products'][$optionKey]['data']['selection_qty'];
-            $price = $product->getPriceType() == 'Dynamic'
+            $price = $product->getPriceType() == 'Yes'
                 ? number_format($bundleSelectionAttribute[$optionKey]->getPrice(), 2)
                 : number_format($bundleOptions['assigned_products'][$optionKey]['data']['selection_price_value'], 2);
             $optionData = [
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 28fb86de9ffeb2e193177b9eda6282710bb43135..4a4aea603cf8619d0d12335f496b1e6a9e50fd33 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
@@ -98,7 +98,7 @@ class Curl extends ProductCurl implements BundleProductInterface
         parent::prepareProductDetails();
 
         if (!isset($this->fields['product']['price_type'])) {
-            $this->fields['product']['price_type'] = 'Dynamic';
+            $this->fields['product']['price_type'] = 'Yes';
         }
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.php
index 5568040980de8c3a3b3660ceb77f10a04d54ce17..ad4d946f850347d987870594aa4201df27970381 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.php
@@ -6,25 +6,15 @@
 
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Attribute;
 
-use Magento\Backend\Test\Block\Widget\FormTabs;
-use Magento\Backend\Test\Block\Widget\Tab;
-use Magento\Mtf\Client\Element;
+use Magento\Ui\Test\Block\Adminhtml\FormSections;
 use Magento\Mtf\Client\Element\SimpleElement;
-use Magento\Mtf\Client\Locator;
 use Magento\Mtf\Fixture\FixtureInterface;
 
 /**
  * Edit attribute form on catalog product edit page.
  */
-class AttributeForm extends FormTabs
+class AttributeForm extends FormSections
 {
-    /**
-     * Iframe locator.
-     *
-     * @var string
-     */
-    protected $iFrame = '#create_new_attribute_container';
-
     /**
      * Save button selector.
      *
@@ -32,24 +22,6 @@ class AttributeForm extends FormTabs
      */
     protected $saveButton = '#save';
 
-    /**
-     * Attribute to determine whether tab is opened.
-     *
-     * @var string
-     */
-    protected $isTabOpened = '.opened ';
-
-    /**
-     * Initialize block. Switch to frame.
-     *
-     * @return void
-     */
-    protected function init()
-    {
-        parent::init();
-        $this->browser->switchToFrame(new Locator($this->iFrame));
-    }
-
     /**
      * Fill the attribute form.
      *
@@ -67,28 +39,6 @@ class AttributeForm extends FormTabs
             }
         );
         parent::fill($fixture, $element);
-        $this->browser->switchToFrame();
-    }
-
-    /**
-     * Open tab.
-     *
-     * @param string $tabName
-     * @return Tab
-     */
-    public function openTab($tabName)
-    {
-        $selector = $this->getTabs()[$tabName]['selector'];
-        $strategy = isset($this->getTabs()[$tabName]['strategy'])
-            ? $this->getTabs()[$tabName]['strategy']
-            : Locator::SELECTOR_CSS;
-
-        $isTabOpened = $this->_rootElement->find($this->isTabOpened . $selector, $strategy);
-        if (!$isTabOpened->isVisible()) {
-            $this->_rootElement->find($selector, $strategy)->click();
-        }
-
-        return $this;
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.xml
index 5c5cf01bd9b907c70381ff9ecd2b729f046e73b4..bd1354d51a28cd1277714aab54849dae53de9c05 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/AttributeForm.xml
@@ -5,10 +5,10 @@
  * See COPYING.txt for license details.
  */
 -->
-<tabs>
+<sections>
     <properties>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>#edit_form</selector>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>.product_form_product_form_add_attribute_modal_create_new_attribute_modal_product_attribute_add_form</selector>
         <strategy>css selector</strategy>
         <fields>
             <frontend_label>
@@ -18,36 +18,32 @@
                 <input>select</input>
             </frontend_input>
             <is_required>
-                <input>select</input>
+                <input>switcher</input>
             </is_required>
             <options>
                 <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Edit\Options</class>
-                <selector>#manage-options-panel</selector>
+                <selector>[data-index="attribute_options_select_container"]</selector>
                 <strategy>css selector</strategy>
             </options>
         </fields>
     </properties>
     <advanced-properties>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>[data-target="#advanced_fieldset-content"]</selector>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>[data-index="advanced_fieldset"]</selector>
         <strategy>css selector</strategy>
         <fields>
-            <attribute_code>
-            </attribute_code>
+            <attribute_code/>
             <is_global>
                 <input>select</input>
             </is_global>
-            <default_value>
-                <selector>[name^='default_value_']</selector>
-            </default_value>
             <is_unique>
-                <input>select</input>
+                <input>switcher</input>
             </is_unique>
         </fields>
     </advanced-properties>
     <manage-labels>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>[data-target="#manage-titles-content"]</selector>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>[data-index="manage-titles"]</selector>
         <strategy>css selector</strategy>
         <fields>
             <manage_frontend_label>
@@ -56,40 +52,40 @@
         </fields>
     </manage-labels>
     <frontend-properties>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>[data-target="#front_fieldset-content"]</selector>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>[data-index="front_fieldset"]</selector>
         <strategy>css selector</strategy>
         <fields>
             <is_searchable>
-                <input>select</input>
+                <input>switcher</input>
             </is_searchable>
             <is_visible_in_advanced_search>
-                <input>select</input>
+                <input>switcher</input>
             </is_visible_in_advanced_search>
             <is_comparable>
-                <input>select</input>
+                <input>switcher</input>
             </is_comparable>
             <is_filterable>
                 <input>select</input>
             </is_filterable>
             <is_filterable_in_search>
-                <input>select</input>
+                <input>switcher</input>
             </is_filterable_in_search>
             <is_used_for_promo_rules>
-                <input>select</input>
+                <input>switcher</input>
             </is_used_for_promo_rules>
             <is_html_allowed_on_front>
-                <input>select</input>
+                <input>switcher</input>
             </is_html_allowed_on_front>
             <is_visible_on_front>
-                <input>select</input>
+                <input>switcher</input>
             </is_visible_on_front>
             <used_in_product_listing>
-                <input>select</input>
+                <input>switcher</input>
             </used_in_product_listing>
             <used_for_sort_by>
-                <input>select</input>
+                <input>switcher</input>
             </used_for_sort_by>
         </fields>
     </frontend-properties>
-</tabs>
+</sections>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/CustomAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/CustomAttribute.php
index 926d04335665cf35ffb7e6c23786bcfd13a56319..91d722f8ef4eb3e3404214a5827c74b76bb48eb3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/CustomAttribute.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/CustomAttribute.php
@@ -19,7 +19,7 @@ class CustomAttribute extends SimpleElement
      *
      * @var string
      */
-    protected $inputSelector = '.control [name]:not([type="hidden"]), table';
+    protected $inputSelector = '[name="product[%s]"]';
 
     /**
      * Attribute class to element type reference.
@@ -27,11 +27,12 @@ class CustomAttribute extends SimpleElement
      * @var array
      */
     protected $classReference = [
-        'input-text' => null,
+        'admin__control-text' => null,
         'textarea' => null,
         'hasDatepicker' => 'datepicker',
-        'select' => 'select',
-        'multiselect' => 'multiselect',
+        'admin__control-select' => 'select',
+        'admin__control-multiselect' => 'multiselect',
+        'admin__actions-switch-checkbox' => 'switcher'
     ];
 
     /**
@@ -43,10 +44,11 @@ class CustomAttribute extends SimpleElement
     public function setValue($data)
     {
         $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]);
-        $element = $this->getElementByClass($this->getElementClass());
+        $code = isset($data['code']) ? $data['code'] : $this->getAttributeCode($this->getAbsoluteSelector());
+        $element = $this->getElementByClass($this->getElementClass($code));
         $value = is_array($data) ? $data['value'] : $data;
         if ($value !== null) {
-            $this->find($this->inputSelector, Locator::SELECTOR_CSS, $element)->setValue($value);
+            $this->find(sprintf($this->inputSelector, $code), Locator::SELECTOR_CSS, $element)->setValue($value);
         }
     }
 
@@ -58,8 +60,9 @@ class CustomAttribute extends SimpleElement
     public function getValue()
     {
         $this->eventManager->dispatchEvent(['get_value'], [__METHOD__, $this->getAbsoluteSelector()]);
-        $inputType = $this->getElementByClass($this->getElementClass());
-        return $this->find($this->inputSelector, Locator::SELECTOR_CSS, $inputType)->getValue();
+        $code = $this->getAttributeCode($this->getAbsoluteSelector());
+        $inputType = $this->getElementByClass($this->getElementClass($code));
+        return $this->find(sprintf($this->inputSelector, $code), Locator::SELECTOR_CSS, $inputType)->getValue();
     }
 
     /**
@@ -68,7 +71,7 @@ class CustomAttribute extends SimpleElement
      * @param string $class
      * @return string
      */
-    protected function getElementByClass($class)
+    private function getElementByClass($class)
     {
         $element = null;
         foreach ($this->classReference as $key => $reference) {
@@ -82,10 +85,25 @@ class CustomAttribute extends SimpleElement
     /**
      * Get element class.
      *
+     * @param string $code
      * @return string
      */
-    protected function getElementClass()
+    private function getElementClass($code)
     {
-        return $this->find($this->inputSelector, Locator::SELECTOR_CSS)->getAttribute('class');
+        return $this->find(sprintf($this->inputSelector, $code), Locator::SELECTOR_CSS)->getAttribute('class');
+    }
+
+    /**
+     * Get attribute code.
+     *
+     * @param string $attributeSelector
+     * @return string
+     */
+    private function getAttributeCode($attributeSelector)
+    {
+        preg_match('/data-index="(.*)"/', $attributeSelector, $matches);
+        $code = !empty($matches[1]) ? $matches[1] : '';
+
+        return $code;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Edit/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Edit/Options.php
index 657166f1e184928c0cde9ac35c2bf35be7827f76..8c1f41f907e4889a7f9769ddcfe2d0f3da2502e6 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Edit/Options.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Attribute/Edit/Options.php
@@ -20,14 +20,14 @@ class Options extends SimpleElement
      *
      * @var string
      */
-    protected $addOption = '#add_new_option_button';
+    protected $addOption = 'button[data-action="add_new_row"]';
 
     /**
      * Option form selector.
      *
      * @var string
      */
-    protected $option = '.ui-sortable tr';
+    protected $option = '[data-index="attribute_options_select"] tbody tr';
 
     /**
      * Set value.
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes.php
index 4070630c913262ef332937834b506c5d50fc87b9..68bf3fe0d5069fd3eee1a3f6c480e70c7f4f3d68 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes.php
@@ -6,8 +6,6 @@
 
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section;
 
-use Magento\Mtf\Client\Locator;
-use Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Edit;
 use Magento\Ui\Test\Block\Adminhtml\Section;
 
 /**
@@ -15,27 +13,6 @@ use Magento\Ui\Test\Block\Adminhtml\Section;
  */
 class Attributes extends Section
 {
-    /**
-     * Attribute Search locator the Product page.
-     *
-     * @var string
-     */
-    protected $attributeSearch = "//div[contains(@data-role, 'product-details')]//*[@data-toggle='dropdown']/span";
-
-    /**
-     * Selector for 'New Attribute' button.
-     *
-     * @var string
-     */
-    protected $newAttributeButton = '[id^="create_attribute"]';
-
-    /**
-     * Selector for search input field.
-     *
-     * @var string
-     */
-    protected $searchAttribute = "//input[@data-role='product-attribute-search']";
-
     /**
      * Fixture mapping.
      *
@@ -51,33 +28,4 @@ class Attributes extends Section
         }
         return parent::dataMapping($fields, $parent);
     }
-
-    /**
-     * Click on 'New Attribute' button.
-     *
-     * @param string $tabName
-     * @return void
-     */
-    public function addNewAttribute($tabName)
-    {
-        $element = $this->_rootElement;
-        $selector = sprintf($this->attributeSearch, $tabName);
-        $element->waitUntil(
-            function () use ($element, $selector) {
-                return $element->find($selector, Locator::SELECTOR_XPATH)->isVisible() ? true : null;
-            }
-        );
-        $addAttributeToggle = $element->find($selector, Locator::SELECTOR_XPATH);
-        $addAttributeToggle->click();
-        if (!$addAttributeToggle->find($this->newAttributeButton)->isVisible()) {
-            $element->find($this->searchAttribute, Locator::SELECTOR_XPATH)->click();
-            $this->browser->waitUntil(
-                function () {
-                    $element = $this->browser->find($this->searchAttribute, Locator::SELECTOR_XPATH);
-                    return $element->isVisible() == true ? true : null;
-                }
-            );
-        }
-        $element->find($this->newAttributeButton)->click();
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Grid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c10d6c2a18fa7f591496a6f98dd2a70f1662bb5b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Grid.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes;
+
+use Magento\Ui\Test\Block\Adminhtml\DataGrid;
+
+/**
+ * Product attributes grid.
+ */
+class Grid extends DataGrid
+{
+    /**
+     * Grid fields map
+     *
+     * @var array
+     */
+    protected $filters = [
+        'label' => [
+            'selector' => '[name="frontend_label"]',
+        ]
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Options/Type/DropDown.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Options/Type/DropDown.php
index 1e433a329ec42cc136c1eefc2b984294792c7670..0dfb865d05aae09ee9e18e8278d58ee01b10bb01 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Options/Type/DropDown.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Options/Type/DropDown.php
@@ -21,13 +21,6 @@ class DropDown extends AbstractOptions
      */
     protected $addValueButton = '[data-action="add_new_row"]';
 
-    /**
-     * Title column locator.
-     *
-     * @var string
-     */
-    protected $optionTitle = '[data-name="title"]';
-
     /**
      * Fill the form.
      *
@@ -37,7 +30,6 @@ class DropDown extends AbstractOptions
      */
     public function fillOptions(array $fields, SimpleElement $element = null)
     {
-        $this->_rootElement->find($this->optionTitle)->click();
         $this->_rootElement->find($this->addValueButton)->click();
 
         return parent::fillOptions($fields, $element);
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/ProductDetails.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/ProductDetails.php
index 49c2c786d9afe9663f5cfc7ea08fbe449fd86c52..e0c1df99391052cd9681611eec895db60f790168 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/ProductDetails.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/ProductDetails.php
@@ -6,7 +6,6 @@
 
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section;
 
-use Magento\Catalog\Test\Fixture\Category;
 use Magento\Ui\Test\Block\Adminhtml\Section;
 use Magento\Mtf\Client\Element\SimpleElement;
 
@@ -21,6 +20,7 @@ class ProductDetails extends Section
      * @var string
      */
     protected $categoryIds = '.admin__field[data-index="category_ids"]';
+
     /**
      * Locator for following sibling of category element.
      *
@@ -28,6 +28,22 @@ class ProductDetails extends Section
      */
     protected $newCategoryRootElement = '.product_form_product_form_create_category_modal';
 
+    /**
+     * Fixture mapping.
+     *
+     * @param array|null $fields
+     * @param string|null $parent
+     * @return array
+     */
+    protected function dataMapping(array $fields = null, $parent = null)
+    {
+        if (isset($fields['custom_attribute'])) {
+            $this->placeholders = ['attribute_code' => $fields['custom_attribute']['value']['code']];
+            $this->applyPlaceholders();
+        }
+        return parent::dataMapping($fields, $parent);
+    }
+
     /**
      * Fill data to fields on section.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php
index 3306bd4f870c6eaf1b8e811db9bf760ae1d47c21..decc7996a7e1e7e97c46fb5d711deb7005dd4bcc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php
@@ -51,6 +51,13 @@ class FormPageActions extends ParentFormPageActions
      */
     protected $saveButton = '[data-ui-id="save-button"]';
 
+    /**
+     * "Add Attribute" button.
+     *
+     * @var string
+     */
+    private $addAttribute = '[data-ui-id="addattribute-button"]';
+
     /**
      * Click on "Save" button.
      *
@@ -105,4 +112,14 @@ class FormPageActions extends ParentFormPageActions
         $this->_rootElement->find($this->toggleButton, Locator::SELECTOR_CSS)->click();
         $this->_rootElement->find(sprintf($this->saveTypeItem, static::SAVE_CLOSE), Locator::SELECTOR_CSS)->click();
     }
+
+    /**
+     * Click "Add Attribute" button.
+     *
+     * @return void
+     */
+    public function addNewAttribute()
+    {
+        $this->_rootElement->find($this->addAttribute)->click();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/AddAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/AddAttribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..c30ee5ee9442809a38229bd3a9148fd1123b3b82
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/AddAttribute.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Modal;
+
+use Magento\Ui\Test\Block\Adminhtml\FormSections;
+
+/**
+ * Add new attribute modal.
+ */
+class AddAttribute extends FormSections
+{
+    /**
+     * Selector for "Create New Attribute" button.
+     *
+     * @var string
+     */
+    private $createNewAttribute = 'button[data-index="add_new_attribute_button"]';
+
+    /**
+     * Click on "Create new attribute" button.
+     *
+     * @return void
+     */
+    public function createNewAttribute()
+    {
+        $this->_rootElement->find($this->createNewAttribute)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/NewAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/NewAttribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..59e999bf791ad9d453ee6fa2b6e7afa3faa58c76
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Modal/NewAttribute.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Modal;
+
+use Magento\Ui\Test\Block\Adminhtml\FormSections;
+
+/**
+ * Product new attribute modal.
+ */
+class NewAttribute extends FormSections
+{
+    /**
+     * Selector for "Save" button.
+     *
+     * @var string
+     */
+    private $save = 'button#save';
+
+    /**
+     * Click "Save Attribute" button on attribute form.
+     *
+     * @return void
+     */
+    public function saveAttribute()
+    {
+        $this->_rootElement->find($this->save)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php
index b0f2b27042b03c54285163f3a03be28ec9dc19eb..24a2a2f7b8c8c1562bbf02180d65ca09a7b602aa 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php
@@ -11,13 +11,9 @@ use Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\AttributeForm;
 use Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\CustomAttribute;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Mtf\Client\Element\SimpleElement;
-use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes;
-use Magento\Mtf\Client\Element;
 use Magento\Mtf\Client\Locator;
 use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Fixture\InjectableFixture;
-use Magento\Catalog\Test\Fixture\Category;
-use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes\Search;
+use Magento\Ui\Test\Block\Adminhtml\DataGrid;
 
 /**
  * Product form on backend product page.
@@ -32,11 +28,11 @@ class ProductForm extends FormSections
     protected $attribute = './/*[contains(@class,"label")]/span[text()="%s"]';
 
     /**
-     * Attribute Search locator the Product page.
+     * Attributes Search modal locator.
      *
      * @var string
      */
-    protected $attributeSearch = '#product-attribute-search-container';
+    protected $attributeSearch = '.product_form_product_form_add_attribute_modal';
 
     /**
      * Custom Section locator.
@@ -50,28 +46,21 @@ class ProductForm extends FormSections
      *
      * @var string
      */
-    protected $attributeBlock = '#attribute-%s-container';
+    protected $attributeBlock = '[data-index="%s"]';
 
     /**
-     * Magento loader.
-     *
-     * @var string
-     */
-    protected $loader = '[data-role="loader"]';
-
-    /**
-     * New attribute form selector.
+     * Magento form loader.
      *
      * @var string
      */
-    protected $newAttributeForm = '#create_new_attribute';
+    protected $spinner = '[data-role="spinner"]';
 
     /**
-     * Magento form loader.
+     * New Attribute modal locator.
      *
      * @var string
      */
-    protected $spinner = '[data-role="spinner"]';
+    protected $newAttributeModal = '.product_form_product_form_add_attribute_modal_create_new_attribute_modal';
 
     /**
      * Fill the product form.
@@ -104,34 +93,11 @@ class ProductForm extends FormSections
                 $sections['product-details']['category_ids']['value'] = $category->getName();
             }
             $this->fillContainers($sections, $element);
-
-            if ($product->hasData('custom_attribute')) {
-                $this->createCustomAttribute($product);
-            }
         }
 
         return $this;
     }
 
-    /**
-     * Create custom attribute.
-     *
-     * @param InjectableFixture $product
-     * @param string $tabName
-     * @return void
-     */
-    protected function createCustomAttribute(InjectableFixture $product, $tabName = 'product-details')
-    {
-        $attribute = $product->getDataFieldConfig('custom_attribute')['source']->getAttribute();
-        $this->openSection('product-details');
-        if (!$this->checkAttributeLabel($attribute)) {
-            /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\ProductDetails $section */
-            $section = $this->openSection($tabName);
-            $section->addNewAttribute($tabName);
-            $this->getAttributeForm()->fill($attribute);
-        }
-    }
-
     /**
      * Open section or click on button to open modal window.
      *
@@ -176,28 +142,15 @@ class ProductForm extends FormSections
     }
 
     /**
-     * Call method that checking present attribute in search result.
-     *
-     * @param CatalogProductAttribute $productAttribute
-     * @return bool
-     */
-    public function checkAttributeInSearchAttributeForm(CatalogProductAttribute $productAttribute)
-    {
-        $this->waitPageToLoad();
-        return $this->getAttributesSearchForm()->isExistAttributeInSearchResult($productAttribute);
-    }
-
-    /**
-     * Get attributes search form.
+     * Get attributes search grid.
      *
-     * @return Search
+     * @return DataGrid
      */
-    protected function getAttributesSearchForm()
+    public function getAttributesSearchGrid()
     {
-        return $this->_rootElement->find(
-            $this->attributeSearch,
-            Locator::SELECTOR_CSS,
-            'Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes\Search'
+        return $this->blockFactory->create(
+            '\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes\Grid',
+            ['element' => $this->browser->find($this->attributeSearch)]
         );
     }
 
@@ -210,8 +163,7 @@ class ProductForm extends FormSections
     public function isCustomSectionVisible($sectionName)
     {
         $sectionName = strtolower($sectionName);
-        $selector = sprintf($this->customSection, $sectionName);
-        $this->waitForElementVisible($selector);
+        $selector = sprintf($this->attributeBlock, $sectionName);
 
         return $this->_rootElement->find($selector)->isVisible();
     }
@@ -228,31 +180,6 @@ class ProductForm extends FormSections
         $this->_rootElement->find(sprintf($this->customSection, $sectionName))->click();
     }
 
-    /**
-     * Click "Save" button on attribute form.
-     *
-     * @return void
-     */
-    public function saveAttributeForm()
-    {
-        $this->getAttributeForm()->saveAttributeForm();
-
-        $browser = $this->browser;
-        $element = $this->newAttributeForm;
-        $loader = $this->loader;
-        $this->_rootElement->waitUntil(
-            function () use ($browser, $element) {
-                return $browser->find($element)->isVisible() == false ? true : null;
-            }
-        );
-
-        $this->_rootElement->waitUntil(
-            function () use ($browser, $loader) {
-                return $browser->find($loader)->isVisible() == false ? true : null;
-            }
-        );
-    }
-
     /**
      * Get Attribute Form.
      *
@@ -262,7 +189,7 @@ class ProductForm extends FormSections
     {
         return $this->blockFactory->create(
             'Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\AttributeForm',
-            ['element' => $this->browser->find('body')]
+            ['element' => $this->browser->find($this->newAttributeModal)]
         );
     }
 
@@ -280,23 +207,4 @@ class ProductForm extends FormSections
             'Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\CustomAttribute'
         );
     }
-
-    /**
-     * Click "Add Attribute" button from specific section.
-     *
-     * @param string $sectionName
-     * @throws \Exception
-     */
-    public function addNewAttribute($sectionName = 'product-details')
-    {
-        $section = $this->getSection($sectionName);
-        if ($section instanceof Attributes) {
-            $this->openSection($sectionName);
-            $section->addNewAttribute($sectionName);
-        } else {
-            throw new \Exception(
-                "$sectionName hasn't 'Add attribute' button or is not instance of ProductSection class."
-            );
-        }
-    }
 }
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 eb7766dcc327b9590e89361a28fd4e9c6bc5861a..b98cdb8c848f3d6a55cda58f45ae066814a4657e 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
@@ -19,10 +19,6 @@
                 <selector>[data-index="attribute_set_id"]</selector>
                 <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\ProductDetails\AttributeSet</class>
             </attribute_set_id>
-            <attribute_id>
-                <selector>#product-attribute-search-container</selector>
-                <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes\Search</class>
-            </attribute_id>
             <tax_class_id>
                 <input>select</input>
             </tax_class_id>
@@ -44,7 +40,7 @@
             </quantity_and_stock_status>
             <custom_attribute>
                 <class>Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\CustomAttribute</class>
-                <selector>#attribute-%attribute_code%-container</selector>
+                <selector>[data-index="%attribute_code%"]</selector>
             </custom_attribute>
             <visibility>
                 <input>select</input>
@@ -132,6 +128,17 @@
             <short_description />
         </fields>
     </content>
+    <attributes>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\Attributes</class>
+        <selector>[data-index="attributes"]</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <custom_attribute>
+                <class>Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\CustomAttribute</class>
+                <selector>[data-index="%attribute_code%"]</selector>
+            </custom_attribute>
+        </fields>
+    </attributes>
     <gallery>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
         <selector>[data-index='block_gallery']</selector>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
index 773a18bac7e2ccce07d8c0e43e0277d072d25ddd..596dbd38664b3b097302e6f6f0e62d13fbe96017 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
@@ -79,6 +79,5 @@ class Sidebar extends ListCompare
             }
         );
         $this->_rootElement->find($this->clearAll)->click();
-        $this->browser->acceptAlert();
     }
 }
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 d3d8f790b225738d1714481f0712c0f7833f00fc..6116c66f06478cfca0831360d1546f25adcf6e0b 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
@@ -7,20 +7,23 @@
 namespace Magento\Catalog\Test\Constraint;
 
 use Magento\Catalog\Test\Fixture\CatalogAttributeSet;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Mtf\Fixture\InjectableFixture;
 use Magento\Mtf\Fixture\FixtureFactory;
 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\ObjectManager;
 
 /**
  * Check attribute on product form.
  */
 class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
 {
+    /**
+     *  Attributes section.
+     */
+    const ATTRIBUTES = 'attributes';
+
     /**
      * Fixture factory.
      *
@@ -89,7 +92,9 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
         $catalogProductAttribute = ($productAttributeOriginal !== null)
             ? array_merge($productAttributeOriginal->getData(), $attribute->getData())
             : $attribute->getData();
-
+        if ($catalogProductEdit->getProductForm()->isSectionVisible(self::ATTRIBUTES)) {
+            $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES);
+        }
         \PHPUnit_Framework_Assert::assertTrue(
             $catalogProductEdit->getProductForm()->checkAttributeLabel($catalogProductAttribute),
             "Product Attribute is absent on Product form."
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php
index 6ff16c2a96ad8255f2ef6dce1ee3bd071c03511d..63fa283baa4ea0a2929e09a34444b614c00f7c59 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeAbsenceInSearchOnProductForm.php
@@ -31,9 +31,13 @@ class AssertProductAttributeAbsenceInSearchOnProductForm extends AbstractConstra
     ) {
         $productGrid->open();
         $productGrid->getGridPageActionBlock()->addProduct('simple');
+        $newProductPage->getFormPageActions()->addNewAttribute();
+        $filter = [
+            'label' => $productAttribute->getFrontendLabel(),
+        ];
         \PHPUnit_Framework_Assert::assertFalse(
-            $newProductPage->getProductForm()->checkAttributeInSearchAttributeForm($productAttribute),
-            "Product attribute found in Attribute Search form."
+            $newProductPage->getProductForm()->getAttributesSearchGrid()->isRowVisible($filter),
+            'Attribute \'' . $productAttribute->getFrontendLabel() . '\' is found in Attributes grid.'
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeInGrid.php
index d23e92007df57e375cfef4dd130b63ca623a0a39..a1da3f696cca633b38a79b9220db4c84ef785b90 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeInGrid.php
@@ -11,8 +11,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex;
 use Magento\Mtf\Constraint\AbstractConstraint;
 
 /**
- * Class AssertProductAttributeInGrid
- * Assert that created product attribute is found in grid
+ * Assert that created product attribute is found in grid.
  */
 class AssertProductAttributeInGrid extends AbstractConstraint
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsRequired.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsRequired.php
index 403664ac3b82c693b38b14a6887bcf21ed809091..4f80e101e73ae6f9959796589dacfccb72fc24aa 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsRequired.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsRequired.php
@@ -39,10 +39,13 @@ class AssertProductAttributeIsRequired extends AbstractConstraint
     ) {
         $catalogProductIndex->open()->getProductGrid()->searchAndOpen(['sku' => $product->getSku()]);
         $productForm = $catalogProductEdit->getProductForm();
+        if (!$productForm->checkAttributeLabel($attribute)) {
+            $productForm->openSection('attributes');
+        }
         $productForm->getAttributeElement($attribute)->setValue('');
         $catalogProductEdit->getFormPageActions()->save();
-        $failedAttributes = $productForm->getRequireNoticeAttributes($product);
-        $actualMessage = $failedAttributes['product-details'][$attribute->getFrontendLabel()];
+        $failedFields = $productForm->getRequireNoticeFields($product);
+        $actualMessage = $failedFields['attributes'][$attribute->getFrontendLabel()];
 
         \PHPUnit_Framework_Assert::assertEquals(
             self::REQUIRE_MESSAGE,
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsUnique.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsUnique.php
index 46cdf8fe2cab0d06cfe978f34001a3507b75571a..3c11b613ea3f0dcda3173815850a59f5ad95d75b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsUnique.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsUnique.php
@@ -58,31 +58,16 @@ class AssertProductAttributeIsUnique extends AbstractConstraint
         $productForm = $catalogProductEdit->getProductForm();
         $productForm->fill($simpleProduct);
         $catalogProductEdit->getFormPageActions()->save();
-        $failedAttributes = $productForm->getRequireNoticeAttributes($simpleProduct);
+        $actualErrorMessage = $catalogProductEdit->getMessagesBlock()->getErrorMessage();
         $attributeLabel = $attribute->getFrontendLabel();
-        $actualMessage = $this->getActualMessage($failedAttributes, $attributeLabel);
 
         \PHPUnit_Framework_Assert::assertEquals(
             sprintf(self::UNIQUE_MESSAGE, $attributeLabel),
-            $actualMessage,
+            $actualErrorMessage,
             'JS error notice on product edit page is not equal to expected.'
         );
     }
 
-    /**
-     * Get actual message.
-     *
-     * @param array $errors
-     * @param string $attributeLabel
-     * @return mixed
-     */
-    protected function getActualMessage(array $errors, $attributeLabel)
-    {
-        return isset($errors['product-details'][$attributeLabel])
-            ? $errors['product-details'][$attributeLabel]
-            : null;
-    }
-
     /**
      * Create simple product fixture.
      *
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 ef25f951e1f7b644d86a936d1a8fa0534d5098ad..d2a53d1eb757a64323dbb64db2a49531ca655348 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
@@ -73,7 +73,7 @@
         <field name="id" group="null" />
         <field name="type_id" />
         <field name="attribute_set_id" group="product-details" source="Magento\Catalog\Test\Fixture\Product\AttributeSetId" />
-        <field name="custom_attribute" group="product-details" source="Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomAttribute" />
+        <field name="custom_attribute" source="Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomAttribute" />
         <field name="custom_options" is_required="0" group="customer-options" source="Magento\Catalog\Test\Fixture\Product\CustomOptions" repository="Magento\Catalog\Test\Repository\Product\CustomOptions" />
         <field name="website_ids" group="websites" />
         <field name="is_returnable" is_required="0" group="product-details" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml
index 1736cebd10e8e7ef5674fec29edfce7860986bf0..dc6b1e8213628f54597d2db52c9eb8b5a2b1fe66 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml
@@ -9,6 +9,8 @@
   <page name="CatalogProductEdit" area="Adminhtml" mca="catalog/product/edit" module="Magento_Catalog">
     <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages .messages" strategy="css selector"/>
     <block name="formPageActions" class="Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions" locator=".page-main-actions" strategy="css selector"/>
+    <block name="addAttributeModal" class="Magento\Catalog\Test\Block\Adminhtml\Product\Modal\AddAttribute" locator=".product_form_product_form_add_attribute_modal" strategy="css selector"/>
+    <block name="newAttributeModal" class="Magento\Catalog\Test\Block\Adminhtml\Product\Modal\NewAttribute" locator=".product_form_product_form_add_attribute_modal_create_new_attribute_modal" strategy="css selector"/>
     <block name="productForm" class="Magento\Catalog\Test\Block\Adminhtml\Product\ProductForm" locator="[id='page:main-container']" strategy="css selector"/>
   </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.xml
index 2134b0c13ef23838c1fc1193a41676a954d3e2d0..8ebc57837ec8f4f0e1d12e15db0ab17afb50cb5c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.xml
@@ -35,8 +35,8 @@
 
         <dataset name="tax_class_id">
             <field name="attribute_id" xsi:type="number">172</field>
-            <field name="frontend_label" xsi:type="string">Tax Class</field>
-            <field name="attribute_code" xsi:type="string">tax_class_id</field>
+            <field name="frontend_label" xsi:type="string">Tax Class%isolation%</field>
+            <field name="attribute_code" xsi:type="string">tax_class_id%isolation%</field>
             <field name="frontend_input" xsi:type="string">Dropdown</field>
             <field name="is_required" xsi:type="string">No</field>
             <field name="options" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
index 910d475e83a2051de6bc0eac0793400067c3b146..164053ada95253eeddf8b9e67f804634b967f18f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
@@ -26,6 +26,7 @@
                 <item name="qty" xsi:type="string">666</item>
                 <item name="is_in_stock" xsi:type="string">In Stock</item>
             </field>
+            <field name="product_has_weight" xsi:type="string">This item has no weight</field>
             <field name="price" xsi:type="array">
                 <item name="value" xsi:type="string">10</item>
             </field>
@@ -44,6 +45,7 @@
             <field name="tax_class_id" xsi:type="array">
                 <item name="dataset" xsi:type="string">taxable_goods</item>
             </field>
+            <field name="product_has_weight" xsi:type="string">This item has no weight</field>
             <field name="website_ids" xsi:type="array">
                 <item name="0" xsi:type="string">Main Website</item>
             </field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.xml
index f5086b3d40287af985578f62febb070f27dea64e..1e816de3b17fb74e7352777acc12c15faeb5583b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.xml
@@ -10,9 +10,9 @@
         <variation name="AddToCartCrossSellTestVariation1" method="test">
             <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
             <data name="products" xsi:type="string">simple1::catalogProductSimple::product_with_category,simple2::catalogProductSimple::product_with_category,config1::configurableProduct::two_options_with_fixed_price</data>
-            <data name="promotedProducts" xsi:type="string">simple1:simple2,config1;simple2:config1</data>
-            <data name="navigateProductsOrder" xsi:type="string">simple1,simple2,config1</data>
-            <data name="productsToVerify" xsi:type="string">simple1:simple2,config1;simple2:config1;config1:</data>
+            <data name="promotedProducts" xsi:type="string">simple1:simple2,config1;config1:simple2</data>
+            <data name="navigateProductsOrder" xsi:type="string">simple1,config1,simple2</data>
+            <data name="productsToVerify" xsi:type="string">simple1:simple2,config1;config1:simple2;simple2:</data>
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.xml
index 85bc8146d8649b84a573fa6c7625e9d74a0ab8d5..32c0f51f4f10663219ef4d8e2f5ada6a66ec6691 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.xml
@@ -10,9 +10,9 @@
         <variation name="NavigateUpSellProductsTestVariation1" method="test">
             <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
             <data name="products" xsi:type="string">simple1::catalogProductSimple::product_with_category,simple2::catalogProductSimple::product_with_category,config1::configurableProduct::two_options_with_fixed_price</data>
-            <data name="promotedProducts" xsi:type="string">simple1:simple2,config1;simple2:config1</data>
-            <data name="navigateProductsOrder" xsi:type="string">simple1,simple2,config1</data>
-            <data name="productsToVerify" xsi:type="string">simple1:simple2,config1;simple2:config1;config1:</data>
+            <data name="promotedProducts" xsi:type="string">simple1:simple2,config1;config1:simple2</data>
+            <data name="navigateProductsOrder" xsi:type="string">simple1,config1,simple2</data>
+            <data name="productsToVerify" xsi:type="string">simple1:simple2,config1;config1:simple2;simple2:</data>
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php
index 4b99c2bb8940e2a4908f41e00590c4470e7111da..55814088db48197c6b247518b042ca59ba38310a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php
@@ -8,7 +8,7 @@ namespace Magento\Catalog\Test\TestCase\Product;
 
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
-use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config;
 use Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Section\Downloadable;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\TestCase\Injectable;
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/AddNewAttributeFromProductPageStep.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/AddNewAttributeFromProductPageStep.php
index fbf36b230f2bd929592f3b91109dacd5ac5c5b97..10ec591099f9b474e9b64a1abb1e47b9ca452fb3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/AddNewAttributeFromProductPageStep.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/AddNewAttributeFromProductPageStep.php
@@ -21,22 +21,13 @@ class AddNewAttributeFromProductPageStep implements TestStepInterface
      */
     protected $catalogProductEdit;
 
-    /**
-     * Tab name for adding attribute.
-     *
-     * @var string
-     */
-    protected $tabName;
-
     /**
      * @constructor
      * @param CatalogProductEdit $catalogProductEdit
-     * @param string $tabName
      */
-    public function __construct(CatalogProductEdit $catalogProductEdit, $tabName)
+    public function __construct(CatalogProductEdit $catalogProductEdit)
     {
         $this->catalogProductEdit = $catalogProductEdit;
-        $this->tabName = $tabName;
     }
 
     /**
@@ -46,7 +37,8 @@ class AddNewAttributeFromProductPageStep implements TestStepInterface
      */
     public function run()
     {
-        $productForm = $this->catalogProductEdit->getProductForm();
-        $productForm->addNewAttribute($this->tabName);
+        $productForm = $this->catalogProductEdit->getFormPageActions();
+        $productForm->addNewAttribute();
+        $this->catalogProductEdit->getAddAttributeModal()->createNewAttribute();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/SaveAttributeOnProductPageStep.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/SaveAttributeOnProductPageStep.php
index 48c94b86e7a8edf88f79ef3df9fffac9557437af..c01b09a684ce683325d651e12c2e08a1133f52f1 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/SaveAttributeOnProductPageStep.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/SaveAttributeOnProductPageStep.php
@@ -16,13 +16,6 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
  */
 class SaveAttributeOnProductPageStep implements TestStepInterface
 {
-    /**
-     * Catalog product edit page.
-     *
-     * @var CatalogProductEdit
-     */
-    protected $catalogProductEdit;
-
     /**
      * Product attribute fixture.
      *
@@ -37,30 +30,37 @@ class SaveAttributeOnProductPageStep implements TestStepInterface
      */
     protected $objectManager;
 
+    /**
+     * Catalog product edit page.
+     *
+     * @var CatalogProductEdit
+     */
+    protected $catalogProductEdit;
+
     /**
      * @constructor
-     * @param CatalogProductEdit $catalogProductEdit
      * @param CatalogProductAttribute $attribute
      * @param ObjectManager $objectManager
+     * @param CatalogProductEdit $catalogProductEdit
      */
     public function __construct(
-        CatalogProductEdit $catalogProductEdit,
         CatalogProductAttribute $attribute,
-        ObjectManager $objectManager
+        ObjectManager $objectManager,
+        CatalogProductEdit $catalogProductEdit
     ) {
-        $this->catalogProductEdit = $catalogProductEdit;
         $this->attribute = $attribute;
         $this->objectManager = $objectManager;
+        $this->catalogProductEdit = $catalogProductEdit;
     }
 
     /**
-     * Click "Save" button on attribute form on product page.
+     * Click "Save" button on attribute form.
      *
-     * @return array
+     * @return void
      */
     public function run()
     {
-        $this->catalogProductEdit->getProductForm()->saveAttributeForm();
+        $this->catalogProductEdit->getNewAttributeModal()->saveAttribute();
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/testcase.xml
index f9cf350993613862ff92b789b8c94397cf9d17f1..40e9a20adf3b33069c3e7fa7804921afea16ebc8 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/testcase.xml
@@ -8,9 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/TestCase/etc/testcase.xsd">
     <scenario name="CreateProductAttributeEntityFromProductPageTest" firstStep="openProductOnBackend">
         <step name="openProductOnBackend" module="Magento_Catalog" next="addNewAttributeFromProductPage"/>
-        <step name="addNewAttributeFromProductPage" module="Magento_Catalog" next="fillAttributeFormOnProductPage">
-            <item name="tabName" value="product-details"/>
-        </step>
+        <step name="addNewAttributeFromProductPage" module="Magento_Catalog" next="fillAttributeFormOnProductPage"/>
         <step name="fillAttributeFormOnProductPage" module="Magento_Catalog" next="saveAttributeOnProductPage"/>
         <step name="saveAttributeOnProductPage" module="Magento_Catalog" next="setDefaultAttributeValue"/>
         <step name="setDefaultAttributeValue" module="Magento_Catalog" next="saveProduct"/>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.php
index 7d731915be33026f11ff96b2fb41d3fa8b398d46..d7fcc85e65f7fbfda4f51e2e08c35e5e876c842b 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.php
@@ -13,27 +13,26 @@ use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Mtf\Block\Form as ParentForm;
 
 /**
- * Class AffectedAttributeSet
- * Choose affected attribute set dialog popup window
+ * Choose affected attribute set dialog popup window.
  */
 class AffectedAttributeSet extends ParentForm
 {
     /**
-     * 'Confirm' button locator
+     * 'Confirm' button locator.
      *
      * @var string
      */
-    protected $confirmButton = '[data-role=action]';
+    protected $confirmButton = '[data-index="confirm_button"]';
 
     /**
-     * Locator buttons new name attribute set
+     * Add configurable attributes to the New Attribute Set.
      *
      * @var string
      */
-    protected $affectedAttributeSetNew = '#new-affected-attribute-set';
+    protected $affectedAttributeSetNew = 'input[data-index="affectedAttributeSetNew"]';
 
     /**
-     * Fill popup form
+     * Fill popup form.
      *
      * @param FixtureInterface $product
      * @param SimpleElement|null $element [optional]
@@ -55,7 +54,7 @@ class AffectedAttributeSet extends ParentForm
     }
 
     /**
-     * Click confirm button
+     * Click confirm button.
      *
      * @return void
      */
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.xml
index f5eeb1b659895e53b116864c1cdf753a3a78f4ab..69884c2660f9b3a5f0cd54d3d546be8651d140d0 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/AffectedAttributeSet.xml
@@ -8,7 +8,7 @@
 <mapping strict="0">
     <fields>
         <new_attribute_set_name>
-            <selector>[name='new-attribute-set-name']</selector>
+            <selector>.new-attribute-set-name input</selector>
         </new_attribute_set_name>
     </fields>
 </mapping>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..a09c9b4dd6e00a73132295a89f17b71d5ccac68c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit;
+
+use Magento\Ui\Test\Block\Adminhtml\FormSections;
+use Magento\Mtf\Client\Element\SimpleElement;
+use Magento\Mtf\Client\Locator;
+use Magento\Mtf\Fixture\FixtureInterface;
+
+/**
+ * New attribute form on configurable product page.
+ */
+class NewConfigurableAttributeForm extends FormSections
+{
+    /**
+     * Iframe locator.
+     *
+     * @var string
+     */
+    protected $iFrame = '#create_new_attribute_container';
+
+    /**
+     * Save button selector.
+     *
+     * @var string
+     */
+    protected $saveButton = '#save';
+
+    /**
+     * Attribute to check whether section is opened.
+     *
+     * @var string
+     */
+    private $isSectionOpened = 'active';
+
+    /**
+     * Fill the attribute form.
+     *
+     * @param FixtureInterface $fixture
+     * @param SimpleElement|null $element
+     * @return $this
+     */
+    public function fill(FixtureInterface $fixture, SimpleElement $element = null)
+    {
+        $this->browser->switchToFrame(new Locator($this->iFrame));
+        $browser = $this->browser;
+        $selector = $this->saveButton;
+        $this->browser->waitUntil(
+            function () use ($browser, $selector) {
+                return $browser->find($selector)->isVisible() ? true : null;
+            }
+        );
+        parent::fill($fixture, $element);
+        $this->browser->switchToFrame();
+    }
+
+    /**
+     * Open section.
+     *
+     * @param string $sectionName
+     * @return FormSections
+     */
+    public function openSection($sectionName)
+    {
+        $selector = $this->getContainerElement($sectionName)->getLocator()['value'];
+        $strategy = null !== $this->getContainerElement($sectionName)->getLocator()['using']
+            ? $this->getContainerElement($sectionName)->getLocator()['using']
+            : Locator::SELECTOR_CSS;
+        $sectionClass = $this->_rootElement->find($selector, $strategy)->getAttribute('class');
+        if (strpos($sectionClass, $this->isSectionOpened) === false) {
+            $this->_rootElement->find($selector, $strategy)->click();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Click on "Save" button.
+     *
+     * @return void
+     */
+    public function saveAttributeForm()
+    {
+        $this->browser->switchToFrame(new Locator($this->iFrame));
+        $this->browser->find($this->saveButton)->click();
+        $this->browser->switchToFrame();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e211a7882463d1039ec444500ccfa8cf6ccda7fe
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/NewConfigurableAttributeForm.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<sections>
+    <properties>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>#edit_form</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <frontend_label>
+                <selector>[name^='frontend_label']</selector>
+            </frontend_label>
+            <frontend_input>
+                <input>select</input>
+            </frontend_input>
+            <is_required>
+                <input>select</input>
+            </is_required>
+            <options>
+                <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Edit\Options</class>
+                <selector>#manage-options-panel</selector>
+                <strategy>css selector</strategy>
+            </options>
+        </fields>
+    </properties>
+    <advanced-properties>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>[data-target="#advanced_fieldset-content"]</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <attribute_code>
+            </attribute_code>
+            <is_global>
+                <input>select</input>
+            </is_global>
+            <default_value>
+                <selector>[name^='default_value_']</selector>
+            </default_value>
+            <is_unique>
+                <input>select</input>
+            </is_unique>
+        </fields>
+    </advanced-properties>
+    <manage-labels>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>[data-target="#manage-titles-content"]</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <manage_frontend_label>
+                <selector>[name^='frontend_label']</selector>
+            </manage_frontend_label>
+        </fields>
+    </manage-labels>
+    <frontend-properties>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>[data-target="#front_fieldset-content"]</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <is_searchable>
+                <input>select</input>
+            </is_searchable>
+            <is_visible_in_advanced_search>
+                <input>select</input>
+            </is_visible_in_advanced_search>
+            <is_comparable>
+                <input>select</input>
+            </is_comparable>
+            <is_filterable>
+                <input>select</input>
+            </is_filterable>
+            <is_filterable_in_search>
+                <input>select</input>
+            </is_filterable_in_search>
+            <is_used_for_promo_rules>
+                <input>select</input>
+            </is_used_for_promo_rules>
+            <is_html_allowed_on_front>
+                <input>select</input>
+            </is_html_allowed_on_front>
+            <is_visible_on_front>
+                <input>select</input>
+            </is_visible_on_front>
+            <used_in_product_listing>
+                <input>select</input>
+            </used_in_product_listing>
+            <used_for_sort_by>
+                <input>select</input>
+            </used_for_sort_by>
+        </fields>
+    </frontend-properties>
+</sections>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config.php
similarity index 83%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config.php
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config.php
index 805fe65d1ebec7e1406713d013a6722a2cc1420b..6fa06e0736c34caafbf3f960e07d0a46dd32f4c5 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config.php
@@ -4,21 +4,21 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations;
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations;
 
 use Magento\Backend\Test\Block\Template;
-use Magento\Backend\Test\Block\Widget\Tab;
+use Magento\Ui\Test\Block\Adminhtml\Section;
 use Magento\Mtf\Client\Element;
 use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Mtf\Client\Locator;
 
 /**
- * Adminhtml catalog super product configurable tab.
+ * Adminhtml catalog super product configurable section.
  */
-class Config extends Tab
+class Config extends Section
 {
     /** @var string */
-    protected $createConfigurationsButton = '[data-action=open-steps-wizard]';
+    protected $createConfigurationsButton = '[data-index="create_configurable_products_button"] > span';
 
     /**
      * Selector for trigger show/hide "Variations" tab.
@@ -46,7 +46,7 @@ class Config extends Tab
      *
      * @var string
      */
-    protected $variationsMatrix = '[data-role="product-variations-matrix"]';
+    protected $variationsMatrix = 'div[data-index="configurable-matrix"]';
 
     /**
      * Selector for template block.
@@ -62,6 +62,13 @@ class Config extends Tab
      */
     protected $variationsContent = '#product_info_tabs_super_config_content';
 
+    /**
+     * Locator for Configurations section.
+     *
+     * @var string
+     */
+    private $configurationsSection = '[data-index="configurable"]';
+
     /**
      * Fill variations fieldset.
      *
@@ -77,7 +84,6 @@ class Config extends Tab
             ? $fields['configurable_attributes_data']['value']
             : [];
 
-        $this->showContent();
         $attributesValue = isset($fields['configurable_attributes_data']['source'])
             ? $fields['configurable_attributes_data']['source']->getAttributesData()
             : [];
@@ -94,20 +100,6 @@ class Config extends Tab
         return $this;
     }
 
-    /**
-     * Show "Variations" tab content.
-     *
-     * @return void
-     */
-    public function showContent()
-    {
-        $content = $this->_rootElement->find($this->variationsTabContent);
-        if (!$content->isVisible()) {
-            $this->_rootElement->find($this->variationsTabTrigger)->click();
-            $this->waitForElementVisible($this->variationsTabContent);
-        }
-    }
-
     /**
      * Click 'Create Configurations' button.
      *
@@ -115,6 +107,7 @@ class Config extends Tab
      */
     public function createConfigurations()
     {
+        $this->_rootElement->find($this->configurationsSection)->hover();
         $this->_rootElement->find($this->createConfigurationsButton)->click();
     }
 
@@ -132,12 +125,12 @@ class Config extends Tab
     /**
      * Get block of attributes.
      *
-     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute
+     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute
      */
     public function getAttributeBlock()
     {
         return $this->blockFactory->create(
-            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute',
+            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute',
             ['element' => $this->_rootElement]
         );
     }
@@ -145,12 +138,12 @@ class Config extends Tab
     /**
      * Get block of variations.
      *
-     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Matrix
+     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Matrix
      */
     public function getVariationsBlock()
     {
         return $this->blockFactory->create(
-            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Matrix',
+            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Matrix',
             ['element' => $this->_rootElement->find($this->variationsMatrix)]
         );
     }
@@ -180,8 +173,6 @@ class Config extends Tab
     public function getFieldsData($fields = null, SimpleElement $element = null)
     {
         $data = [];
-
-        $this->showContent();
         $data['matrix'] = $this->getVariationsBlock()->getVariationsData();
 
         return ['configurable_attributes_data' => $data];
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute.php
similarity index 93%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute.php
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute.php
index 0459c4d67ecb8643b9498fa37decd3e9e0981bb3..9b91ecbbc15e9f747e52e20878cfd24b40d4d47c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute.php
@@ -4,9 +4,9 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config;
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config;
 
-use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute\AttributeSelector;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute\AttributeSelector;
 use Magento\Mtf\Block\Form;
 use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Mtf\Client\Locator;
@@ -152,6 +152,13 @@ class Attribute extends Form
      */
     protected $templateBlock = './ancestor::body';
 
+    /**
+     * List of selected attributes
+     *
+     * @var string
+     */
+    private $selectedAttributes = 'span[data-bind*="selectedAttributes"]';
+
     /**
      * Fill attributes
      *
@@ -170,7 +177,11 @@ class Attribute extends Form
 
         //select attributes
         $this->getAttributesGrid()->resetFilter();
-        $this->getAttributesGrid()->deselectAttributes();
+        $attributesList = $this->browser->find($this->selectedAttributes)->getText();
+        if ($attributesList != '--') {
+            $this->getAttributesGrid()->deselectAttributes();
+        }
+
         if ($this->_rootElement->find('[class$=no-data]')->isVisible()) {
             return;
         }
@@ -214,8 +225,9 @@ class Attribute extends Form
         );
 
         $this->browser->find($this->createNewVariationSet)->click();
-        $this->getEditAttributeForm()->fill($attributeFixture);
-        $this->getEditAttributeForm()->saveAttributeForm();
+        $newAttributeForm = $this->getNewAttributeForm();
+        $newAttributeForm->fill($attributeFixture);
+        $newAttributeForm->saveAttributeForm();
         $this->waitBlock($this->newAttributeFrame);
     }
 
@@ -322,14 +334,14 @@ class Attribute extends Form
     }
 
     /**
-     * Get attribute form block
+     * Get new attribute form block.
      *
-     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\AttributeForm
+     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\NewConfigurableAttributeForm
      */
-    protected function getEditAttributeForm()
+    protected function getNewAttributeForm()
     {
         return $this->blockFactory->create(
-            'Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\AttributeForm',
+            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\NewConfigurableAttributeForm',
             ['element' => $this->browser->find($this->newAttribute)]
         );
     }
@@ -344,7 +356,7 @@ class Attribute extends Form
         return $this->_rootElement->find(
             $this->variationSearchBlock,
             Locator::SELECTOR_CSS,
-            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute'
+            'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute'
             . '\AttributeSelector'
         );
     }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute.xml
similarity index 100%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute.xml
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute.xml
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/AttributeSelector.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/AttributeSelector.php
similarity index 94%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/AttributeSelector.php
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/AttributeSelector.php
index d62e39beb7396285fdc0c8460f8ada8705c3cac6..5a6ebf949ec08cfc30a6597779ef9f49c35302d0 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/AttributeSelector.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/AttributeSelector.php
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute;
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute;
 
 use Magento\Mtf\Client\Element\SuggestElement;
 
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/ToggleDropdown.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/ToggleDropdown.php
similarity index 97%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/ToggleDropdown.php
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/ToggleDropdown.php
index e1c6d9ca30164257dbd0bc0eace33ef3bf3f54de..ea0f83671d20bd13ce9cb0744a9adb9070bff0c8 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Attribute/ToggleDropdown.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Attribute/ToggleDropdown.php
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute;
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute;
 
 use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Mtf\Client\Locator;
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.php
similarity index 79%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.php
index 231ce9ae6b500c3f1e2490b6d7f571a982153fae..ed8cbc800b2e672008347881a5bd18e1e674135f 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.php
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 
-namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config;
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config;
 
 use Magento\Mtf\Client\ElementInterface;
 use Magento\Mtf\Client\Locator;
@@ -13,66 +13,59 @@ use Magento\Mtf\Block\Form;
 use Magento\Mtf\Client\Element\SimpleElement;
 
 /**
- * Class Matrix
- * Matrix row form
+ * Matrix row form.
  */
 class Matrix extends Form
 {
     /**
-     * Mapping for get optional fields
+     * Mapping for get optional fields.
      *
      * @var array
      */
     protected $mappingGetFields = [
         'name' => [
-            'selector' => 'td[data-column="name"] > a',
+            'selector' => 'td[data-index="name_container"] a',
             'strategy' => Locator::SELECTOR_CSS,
         ],
         'sku' => [
-            'selector' => 'td[data-column="sku"]',
+            'selector' => 'td[data-index="sku_container"] span[data-index="sku_text"]',
             'strategy' => Locator::SELECTOR_CSS,
         ],
         'price' => [
-            'selector' => 'td[data-column="price"]',
+            'selector' => 'td[data-index="price_container"] span[data-index="price_text"]',
             'strategy' => Locator::SELECTOR_CSS,
         ],
-        'quantity_and_stock_status' => [
-            'composite' => 1,
-            'fields' => [
-                'qty' => [
-                    'selector' => 'td[data-column="qty"]',
-                    'strategy' => Locator::SELECTOR_CSS,
-                ],
-            ],
+        'qty' => [
+            'selector' => 'td[data-index="quantity_container"] span[data-index="quantity_text"]',
+            'strategy' => Locator::SELECTOR_CSS,
         ],
         'weight' => [
-            'selector' => 'td[data-column="weight"]',
+            'selector' => 'td[data-index="price_weight"] span[data-index="weight_text"]',
             'strategy' => Locator::SELECTOR_CSS,
         ],
     ];
 
     /**
-     * Selector for variation row by number
+     * Selector for variation row by number.
      *
      * @var string
      */
-    protected $variationRowByNumber = './/tr[@data-role="row"][%d]';
+    protected $variationRowByNumber = './/tr[@class="data-row" or @class="data-row _odd-row"][%d]';
 
     /**
-     * Selector for variation row
+     * Selector for variation row.
      *
      * @var string
      */
-    protected $variationRow = 'tr[data-role="row"]';
+    protected $variationRow = './/tr[contains(@class, "data-row")]';
 
-    // @codingStandardsIgnoreStart
     /**
-     * Selector for row on product grid by product id
+     * Selector for row on product grid by product id.
      *
      * @var string
      */
-    protected $associatedProductGrid = 'div[data-grid-id="associated-products-container"]';
-    // @codingStandardsIgnoreEnd
+    protected $associatedProductGrid =
+        '[data-bind*="configurable_associated_product_listing.configurable_associated_product_listing"]';
 
     /**
      * Selector for template block.
@@ -86,14 +79,14 @@ class Matrix extends Form
      *
      * @var string
      */
-    protected $deleteVariation = '[data-bind*="removeProduct"]';
+    protected $deleteVariation = '[data-bind*="deleteRecord"]';
 
     /**
      * Choose a different Product button selector.
      *
      * @var string
      */
-    protected $chooseProduct = '[data-bind*="showGrid"]';
+    protected $chooseProduct = '[data-bind*="openModalWithGrid"]';
 
     /**
      * Action menu
@@ -152,7 +145,7 @@ class Matrix extends Form
     public function getVariationsData()
     {
         $data = [];
-        $variationRows = $this->_rootElement->getElements($this->variationRow);
+        $variationRows = $this->_rootElement->getElements($this->variationRow, Locator::SELECTOR_XPATH);
 
         foreach ($variationRows as $key => $variationRow) {
             /** @var SimpleElement $variationRow */
@@ -200,7 +193,7 @@ class Matrix extends Form
 
     public function deleteVariations()
     {
-        $variations = $this->_rootElement->getElements($this->variationRow);
+        $variations = $this->_rootElement->getElements($this->variationRow, Locator::SELECTOR_XPATH);
         foreach (array_reverse($variations) as $variation) {
             $variation->find($this->actionMenu)->hover();
             $variation->find($this->actionMenu)->click();
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.xml
similarity index 71%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.xml
rename to dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.xml
index ea25b923bafc55125e207da2908134169cbba12c..f2525ca789ddf64513391d186275229c0f5f27fb 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Section/Variations/Config/Matrix.xml
@@ -16,11 +16,9 @@
         <price>
             <selector>[name$="[price]"]</selector>
         </price>
-        <quantity_and_stock_status composite="1">
-            <qty>
-                <selector>[name$="[quantity_and_stock_status][qty]"]</selector>
-            </qty>
-        </quantity_and_stock_status>
+        <qty>
+            <selector>[name$="[qty]"]</selector>
+        </qty>
         <weight>
             <selector>[name$="[weight]"]</selector>
         </weight>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/FormPageActions.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/FormPageActions.php
index 01bcd91da8c03dd90f69aa29ea7b04f1179e9f7c..11c66f128b5b28504042b99e56f4948a77f2fac5 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/FormPageActions.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/FormPageActions.php
@@ -21,7 +21,7 @@ class FormPageActions extends \Magento\Catalog\Test\Block\Adminhtml\Product\Form
      *
      * @var string
      */
-    protected $affectedAttributeSetForm = '//div[@data-role="affected-attribute-set-selector"]/ancestor::*[@data-role="modal"]';
+    protected $affectedAttributeSetForm = '.product_form_product_form_configurable_attribute_set_handler_modal [data-role="focusable-scope"]';
     // @codingStandardsIgnoreEnd
 
     /**
@@ -48,7 +48,7 @@ class FormPageActions extends \Magento\Catalog\Test\Block\Adminhtml\Product\Form
     {
         return $this->blockFactory->create(
             '\Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\AffectedAttributeSet',
-            ['element' => $this->browser->find($this->affectedAttributeSetForm, Locator::SELECTOR_XPATH)]
+            ['element' => $this->browser->find($this->affectedAttributeSetForm)]
         );
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
index b8a51d8231d81bc2b3f68ac4745934d2ab29556c..80ea10808de0add0bce44d07402c9f98a137a0d1 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
@@ -35,7 +35,6 @@ class ProductForm extends \Magento\Catalog\Test\Block\Adminhtml\Product\ProductF
         return $this->fillContainers($sections, $element);
     }
 
-
     /**
      * Create data array for filling tabs.
      * Skip Advanced Price tab
@@ -45,10 +44,10 @@ class ProductForm extends \Magento\Catalog\Test\Block\Adminhtml\Product\ProductF
      */
     protected function getFixtureFieldsByContainers(InjectableFixture $fixture)
     {
-        $tabs = parent::getFixtureFieldsByContainers($fixture);
-        if (isset($tabs['advanced-pricing'])) {
-            unset($tabs['advanced-pricing']);
+        $sections = parent::getFixtureFieldsByContainers($fixture);
+        if (isset($sections['advanced-pricing'])) {
+            unset($sections['advanced-pricing']);
         }
-        return $tabs;
+        return $sections;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
index 7d13ef869364bbbc77168a6beefb77898a88a238..788105979cb2223906bfa98c3a6220cd21efab02 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
@@ -7,15 +7,15 @@
 -->
 <sections>
     <variations>
-        <class>\Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config</class>
-        <selector>[data-index='product-details']</selector>
+        <class>\Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config</class>
+        <selector>[data-index="configurable"]</selector>
         <strategy>css selector</strategy>
         <fields>
             <attributes_data>
-                <selector>#super_config-wrapper</selector>
+                <selector>[data-index="configurable"] fieldset</selector>
             </attributes_data>
             <matrix>
-                <selector>#product-variations-matrix</selector>
+                <selector>[data-index="configurable-matrix"]</selector>
             </matrix>
         </fields>
     </variations>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php
index 5a27cc69211bb0d91b61fd8597cca86003b72295..2763563c86df599d69dd70d176393d27ed03a248 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeAbsenceInVariationsSearch.php
@@ -6,8 +6,8 @@
 
 namespace Magento\ConfigurableProduct\Test\Constraint;
 
-use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config as VariationsTab;
-use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config\Attribute as AttributeBlock;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config as VariationsTab;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config\Attribute as AttributeBlock;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
@@ -44,8 +44,7 @@ class AssertProductAttributeAbsenceInVariationsSearch extends AbstractConstraint
 
         /** @var VariationsTab $variationsTab */
         $newProductPage->getProductForm()->fill($assertProduct);
-        $variationsTab = $newProductPage->getProductForm()->getTab(self::TAB_VARIATIONS);
-        $variationsTab->showContent();
+        $variationsTab = $newProductPage->getProductForm()->getSection(self::TAB_VARIATIONS);
         $variationsTab->createConfigurations();
         $attributesGrid = $variationsTab->getAttributeBlock()->getAttributesGrid();
         \PHPUnit_Framework_Assert::assertFalse(
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
index 383d76a2367e47c3b63108305b8dca5e84350c1e..251af2e1893a67b8de3dd99d7cfc4e310035afc6 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
@@ -9,7 +9,7 @@ namespace Magento\ConfigurableProduct\Test\Constraint;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
-use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config as TabVariation;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config as SectionVariation;
 use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct;
 use Magento\Mtf\Constraint\AbstractConstraint;
 
@@ -36,11 +36,11 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
         $productGrid->getGridPageActionBlock()->addProduct('configurable');
         $productBlockForm = $newProductPage->getProductForm();
         $productBlockForm->fill($assertProduct);
-        $productBlockForm->openTab('variations');
-        /** @var \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Variations\Config  $variationsTab */
-        $variationsTab = $productBlockForm->getTab('variations');
-        $variationsTab->createConfigurations();
-        $attributesGrid = $variationsTab->getAttributeBlock()->getAttributesGrid();
+        $productBlockForm->openSection('variations');
+        /** @var SectionVariation  $variationsSection */
+        $variationsSection = $productBlockForm->getSection('variations');
+        $variationsSection->createConfigurations();
+        $attributesGrid = $variationsSection->getAttributeBlock()->getAttributesGrid();
         \PHPUnit_Framework_Assert::assertTrue(
             $attributesGrid->isRowVisible(['frontend_label' => $attribute->getFrontendLabel()]),
             "Product attribute is absent on the product page."
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php
index dd7ca68f9b6fcea8e9b82b0d86d283757f3c183f..c800c8b1bfef5ca7a73f53ef6c76709dd886abfd 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php
@@ -45,21 +45,21 @@ class CreateConfigurableProductEntityTest extends Injectable
     /* end tags */
 
     /**
-     * Product page with a grid
+     * Product page with a grid.
      *
      * @var CatalogProductIndex
      */
     protected $productIndex;
 
     /**
-     * Page to create a product
+     * Page to create a product.
      *
      * @var CatalogProductNew
      */
     protected $productNew;
 
     /**
-     * Injection data
+     * Injection data.
      *
      * @param CatalogProductIndex $productIndex
      * @param CatalogProductNew $productNew
@@ -72,14 +72,13 @@ class CreateConfigurableProductEntityTest extends Injectable
     }
 
     /**
-     * Test create catalog Configurable product run
+     * Test create catalog Configurable product run.
      *
      * @param ConfigurableProduct $product
      * @return void
      */
     public function test(ConfigurableProduct $product)
     {
-        $this->markTestIncomplete('MAGETWO-50179');
         // Steps
         $this->productIndex->open();
         $this->productIndex->getGridPageActionBlock()->addProduct('configurable');
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateConfigurableProductStep.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateConfigurableProductStep.php
index e59e0d6b0d487431ec48696cd78f8eeba7ac8bc8..40dbe1f857f238d0ca7dd21fb1d062e7ba65cad3 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateConfigurableProductStep.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateConfigurableProductStep.php
@@ -9,6 +9,8 @@ namespace Magento\ConfigurableProduct\Test\TestStep;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
 use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct;
+use Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Section\Variations\Config;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\TestStep\TestStepInterface;
 
@@ -59,9 +61,15 @@ class UpdateConfigurableProductStep implements TestStepInterface
      */
     protected $attributeTypeAction = '';
 
+    /**
+     * @var CatalogProductIndex
+     */
+    private $productGrid;
+
     /**
      * @constructor
      * @param FixtureFactory $fixtureFactory
+     * @param CatalogProductIndex $productGrid
      * @param CatalogProductEdit $catalogProductEdit
      * @param ConfigurableProduct $product
      * @param ConfigurableProduct $updatedProduct
@@ -69,6 +77,7 @@ class UpdateConfigurableProductStep implements TestStepInterface
      */
     public function __construct(
         FixtureFactory $fixtureFactory,
+        CatalogProductIndex $productGrid,
         CatalogProductEdit $catalogProductEdit,
         ConfigurableProduct $product,
         ConfigurableProduct $updatedProduct,
@@ -79,6 +88,7 @@ class UpdateConfigurableProductStep implements TestStepInterface
         $this->initialProduct = $product;
         $this->product = $updatedProduct;
         $this->attributeTypeAction = $attributeTypeAction;
+        $this->productGrid = $productGrid;
     }
 
     /**
@@ -186,9 +196,17 @@ class UpdateConfigurableProductStep implements TestStepInterface
      */
     protected function updateProduct(ConfigurableProduct $product)
     {
+        //open product
+        $filter = ['sku' => $this->initialProduct->getSku()];
+        $this->productGrid->open();
+        $this->productGrid->getProductGrid()->searchAndOpen($filter);
+
+        //update
         $productForm = $this->catalogProductEdit->getProductForm();
-        $productForm->openTab('variations');
-        $productForm->getTab('variations')->deleteVariations();
+        $productForm->openSection('variations');
+        /** @var Config $variationsSection */
+        $variationsSection = $productForm->getSection('variations');
+        $variationsSection->deleteVariations();
         $this->catalogProductEdit->getProductForm()->fill($product);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
index 31c1155f66c1c195ab21abef8b6724ee88f13b9a..c902f9430bcf1ee341e6de84f4ddf7e34c406a8f 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
@@ -7,10 +7,9 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/TestCase/etc/testcase.xsd">
   <scenario name="UpdateConfigurableProductEntityTest" firstStep="createProduct">
-    <step name="createProduct" module="Magento_Catalog" next="openProductOnBackend">
+    <step name="createProduct" module="Magento_Catalog" next="updateConfigurableProduct">
       <item name="product" value="configurableProduct::default"/>
     </step>
-    <step name="openProductOnBackend" module="Magento_Catalog" next="updateConfigurableProduct"/>
     <step name="updateConfigurableProduct" module="Magento_ConfigurableProduct" next="saveProduct"/>
     <step name="saveProduct" module="Magento_Catalog"/>
   </scenario>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
index 05ae4f0a614e8f9f9104ebd8d3e63f3a32940f7d..261bb040f55b1284e9729a839061e66d5ba35735 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
@@ -28,6 +28,7 @@
             <field name="downloadable_links" xsi:type="array">
                 <item name="dataset" xsi:type="string">with_two_separately_links</item>
             </field>
+            <field name="product_has_weight" xsi:type="string">This item has no weight</field>
             <field name="website_ids" xsi:type="array">
                 <item name="0" xsi:type="string">Main Website</item>
             </field>
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
index 6756d4eaf737a058e2cbb803c474e1535917289e..b6ed37af715be90fc600aa5728744ccd3a160d68 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
@@ -39,6 +39,13 @@ abstract class AbstractFormContainers extends Form
      */
     protected $header = 'header.page-header';
 
+    /**
+     * Close button locator.
+     *
+     * @var string
+     */
+    protected $closeButton = 'aside[style]:not([style=""]) [data-role="closeBtn"]';
+
     /**
      * Initialize.
      *
@@ -188,12 +195,15 @@ abstract class AbstractFormContainers extends Form
             if ($this->openContainer($containerName)) {
                 $mapping = $container->dataMapping($this->unassignedFields);
                 foreach ($mapping as $fieldName => $data) {
-                    $element = $container->_rootElement->find($data['selector'], $data['strategy'], $data['input']);
+                    $element = $this->getElement($this->_rootElement, $data);
                     if ($element->isVisible()) {
                         $element->setValue($data['value']);
                         unset($this->unassignedFields[$fieldName]);
                     }
                 }
+                if ($this->browser->find($this->closeButton)->isVisible()) {
+                    $this->browser->find($this->closeButton)->click();
+                }
                 if (empty($this->unassignedFields)) {
                     break;
                 }
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
index 2bf428feff8ef6290accb174f7f4fd55c3c29d63..6a5919b8cb1cfcfc2c8a666009e977ab0baafe0b 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
@@ -44,6 +44,13 @@ class FormSections extends AbstractFormContainers
      */
     protected $opened = '._show';
 
+    /**
+     * Locator for error messages.
+     *
+     * @var string
+     */
+    protected $errorMessages = '[data-ui-id="messages-message-error"]';
+
     /**
      * Get Section class.
      *
@@ -120,24 +127,35 @@ class FormSections extends AbstractFormContainers
     }
 
     /**
-     * Get Require Notice Attributes.
+     * Get require notice fields.
      *
      * @param InjectableFixture $product
      * @return array
      */
-    public function getRequireNoticeAttributes(InjectableFixture $product)
+    public function getRequireNoticeFields(InjectableFixture $product)
     {
         $data = [];
-        $tabs = $this->getFixtureFieldsByContainers($product);
-        foreach (array_keys($tabs) as $tabName) {
-            $tab = $this->getSection($tabName);
-            $this->openSection($tabName);
-            $errors = $tab->getJsErrors();
+        $sections = $this->getFixtureFieldsByContainers($product);
+        foreach (array_keys($sections) as $sectionName) {
+            $section = $this->getSection($sectionName);
+            $this->openSection($sectionName);
+            $errors = $section->getValidationErrors();
             if (!empty($errors)) {
-                $data[$tabName] = $errors;
+                $data[$sectionName] = $errors;
             }
         }
 
         return $data;
     }
+
+    /**
+     * Check if section is visible.
+     *
+     * @param string $sectionName
+     * @return bool
+     */
+    public function isSectionVisible($sectionName)
+    {
+        return ($this->isCollapsible($sectionName) && !$this->isCollapsed($sectionName));
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Section.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Section.php
index ce746e53e4d92c9ded1337e72c9a4b771a478189..f0aafd5250fd4209bc524102ee2f50724fbeeec7 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Section.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Section.php
@@ -6,10 +6,68 @@
 
 namespace Magento\Ui\Test\Block\Adminhtml;
 
+use Magento\Mtf\Client\Locator;
+
 /**
  * Is used to represent any (collapsible) section on the page.
  */
 class Section extends AbstractContainer
 {
-    //
+    /**
+     * Field with error.
+     *
+     * @var string
+     */
+    protected $errorField = '//fieldset/*[contains(@class,"field ")][.//*[contains(@class,"error")]]';
+
+    /**
+     * Error label.
+     *
+     * @var string
+     */
+    protected $errorLabel = './/*[contains(@class,"label")]';
+
+    /**
+     * Error text.
+     *
+     * @var string
+     */
+    protected $errorText = './/label[contains(@class,"error")]';
+
+    /**
+     * Locator for section.
+     *
+     * @var string
+     */
+    protected $section = '[data-index="%s"]';
+
+    /**
+     * Get array of label => validation error text.
+     *
+     * @return array
+     */
+    public function getValidationErrors()
+    {
+        $data = [];
+        $elements = $this->_rootElement->getElements($this->errorField, Locator::SELECTOR_XPATH);
+        foreach ($elements as $element) {
+            $error = $element->find($this->errorText, Locator::SELECTOR_XPATH);
+            if ($error->isVisible()) {
+                $label = $element->find($this->errorLabel, Locator::SELECTOR_XPATH)->getText();
+                $data[$label] = $error->getText();
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Check whether section is visible.
+     *
+     * @param string $sectionName
+     * @return bool
+     */
+    public function isSectionVisible($sectionName)
+    {
+        return $this->_rootElement->find(sprintf($this->section, $sectionName))->isVisible();
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php
index 8146a04b34398a758c815c787feb9cfe047c786d..2ae37ed9b71946b9924064a3cd1fa0a30e6b3c88 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php
@@ -80,6 +80,11 @@ foreach ($prices as $price) {
         'simple-' . $productId
     )->setPrice(
         $price
+    )->setStockData(
+        [
+            'qty' => 100,
+            'is_in_stock' => 1,
+        ]
     )->setWeight(
         18
     )->setCategoryIds(
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php
index 4992805824538bc35ec803abea5056b6456bb134..7ec85f110a5b58bc9c721593e50e2c6fb4fbb682 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php
@@ -16,4 +16,9 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL)
     ->setTaxClassId(0)
     ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
     ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
-    ->save();
+    ->setStockData(
+        [
+            'qty' => 100,
+            'is_in_stock' => 1,
+        ]
+    )->save();
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
deleted file mode 100644
index 12aae4429203d85c9095ba607dfe25f620852353..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\CatalogInventory\Model\Config\Backend;
-
-use Magento\TestFramework\Helper\Bootstrap as Bootstrap;
-
-/**
- * Class ManagestockTest
- */
-class ManagestockTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Data provider for testSaveAndRebuildIndex
-     * @return array
-     */
-    public function saveAndRebuildIndexDataProvider()
-    {
-        return [
-            [1, 1],
-            [0, 0],
-        ];
-    }
-
-    /**
-     * Test rebuild stock indexer on stock status config save
-     *
-     * @dataProvider saveAndRebuildIndexDataProvider
-     *
-     * @magentoAppIsolation enabled
-     * @magentoDbIsolation enabled
-     * @magentoConfigFixture default/cataloginventory/item_options/manage_stock 0
-     *
-     * @param int $newStockValue new value for stock status
-     * @param int $callCount count matcher
-     */
-    public function testSaveAndRebuildIndex($newStockValue, $callCount)
-    {
-        /** @var \Magento\CatalogInventory\Model\StockIndex */
-        $stockManagement = $this->getMock(
-            '\Magento\CatalogInventory\Model\StockIndex',
-            ['rebuild'],
-            [],
-            '',
-            false
-        );
-
-        $stockManagement->expects($this->exactly($callCount))
-            ->method('rebuild');
-
-        $manageStock = new Managestock(
-            Bootstrap::getObjectManager()->get('Magento\Framework\Model\Context'),
-            Bootstrap::getObjectManager()->get('Magento\Framework\Registry'),
-            Bootstrap::getObjectManager()->get('Magento\Framework\App\Config\ScopeConfigInterface'),
-            Bootstrap::getObjectManager()->get('Magento\Framework\App\Cache\TypeListInterface'),
-            $stockManagement,
-            Bootstrap::getObjectManager()->get('Magento\CatalogInventory\Model\Indexer\Stock\Processor'),
-            Bootstrap::getObjectManager()->get('Magento\Config\Model\ResourceModel\Config')
-        );
-
-        $manageStock->setPath('cataloginventory/item_options/manage_stock');
-        $manageStock->setScope('default');
-        $manageStock->setScopeId(0);
-        $manageStock->setValue($newStockValue);
-
-        // assert
-        $manageStock->save();
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php
index 8fbcad5267cf774401910a63b7dcf7b2c8bcd427..02ddb8e23b9924bc2acd357831724196ae1fbcf8 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php
@@ -17,12 +17,19 @@ class DefaultStockTest extends \PHPUnit_Framework_TestCase
      */
     private $indexer;
 
+    /**
+     * @var \Magento\CatalogInventory\Api\StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
     protected function setUp()
     {
         $this->indexer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\DefaultStock::class
         );
-
+        $this->stockConfiguration = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            \Magento\CatalogInventory\Api\StockConfigurationInterface::class
+        );
     }
 
     /**
@@ -53,7 +60,7 @@ class DefaultStockTest extends \PHPUnit_Framework_TestCase
         );
         $criteria = $criteriaFactory->create();
         $criteria->setProductsFilter([$product->getId()]);
-        $criteria->addFilter('website', 'website_id', $testWebsite->getId());
+        $criteria->addFilter('website', 'website_id', $this->stockConfiguration->getDefaultScopeId());
         $items = $stockStatusRepository->getList($criteria)->getItems();
         $this->assertEquals($product->getId(), $items[$product->getId()]->getProductId());
     }
diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php
index 7ccfba9b3c1b7cf743cfeb30512ffc11902ddf80..4c15a2a9e08877c2b3516ad86f5458df7ed5acd3 100644
--- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php
+++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php
@@ -17,7 +17,13 @@ $product
     ->setPrice(10)
     ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
     ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
-    ->setLinksPurchasedSeparately(true);
+    ->setLinksPurchasedSeparately(true)
+    ->setStockData(
+        [
+            'qty' => 100,
+            'is_in_stock' => 1,
+        ]
+    );
 
 /**
  * @var \Magento\Downloadable\Api\Data\LinkInterfaceFactory $linkFactory
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php
index c94078c41d741682c467819a704610ec5cdad799..8fb3c96eae0b5993b4ec93b3eac13cfccb2de97e 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php
+++ b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php
@@ -28,7 +28,12 @@ $product->setTypeId('simple')
     ->setPrice(10)
     ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
     ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
-    ->save();
+    ->setStockData(
+        [
+            'qty' => 100,
+            'is_in_stock' => 1,
+        ]
+    )->save();
 $product->load(1);
 
 $billingData = [
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php
index 2304dcdc21399e3dbe7936c83fc880ab06b38139..95f387213d16ccb97ffb4d41321cd2aa941f8fef 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php
@@ -17,7 +17,12 @@ $product->setTypeId('simple')
     ->setMetaDescription('meta description')
     ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
     ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
-    ->save();
+    ->setStockData(
+        [
+            'qty' => 100,
+            'is_in_stock' => 1,
+        ]
+    )->save();
 
 $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
     ->create('Magento\Catalog\Api\ProductRepositoryInterface');
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index be9b65ed051d3e757c197feb845b14541ee8f4e3..bdcadc125b2ca3c0b47eb52ecc3dcc56eff30a24 100755
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -4220,5 +4220,5 @@ return [
     ['Magento\Braintree\Test\Unit\Model\VaultTest'],
     ['Magento\Braintree\Test\Unit\Observer\DeleteBraintreeCustomerTest'],
     ['Magento\Braintree\Test\Unit\Observer\ProcessBraintreeAddressTest'],
-    ['Magento\Braintree\Test\Unit\Observer\ProcessBraintreePaymentTest']
+    ['Magento\Braintree\Test\Unit\Observer\ProcessBraintreePaymentTest'],
 ];
diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
index 44eedd2c9fc40de783f778ccfa7568531db64907..90de5d2832b53cbaef102f2dd818032bba614aae 100644
--- a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
+++ b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
@@ -3,7 +3,6 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\Code\Minifier\Adapter\Css;
 
 use CSSmin as CssMinLibrary;
@@ -26,10 +25,24 @@ class CSSmin implements AdapterInterface
 
     /**
      * @param CssMinLibrary $cssMinifier
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(CssMinLibrary $cssMinifier)
     {
-        $this->cssMinifier = $cssMinifier;
+        // TODO: set $cssMinifier in constructor once MAGETWO-51176 is resolved.
+    }
+
+    /**
+     * Get CSS Minifier
+     *
+     * @return \CSSMin
+     */
+    private function getCssMin()
+    {
+        if (!($this->cssMinifier instanceof \CSSMin)) {
+            $this->cssMinifier = new \CSSmin(false);
+        }
+        return $this->cssMinifier;
     }
 
     /**
@@ -42,7 +55,7 @@ class CSSmin implements AdapterInterface
     {
         $pcreRecursionLimit = ini_get('pcre.recursion_limit');
         ini_set('pcre.recursion_limit', self::PCRE_RECURSION_LIMIT);
-        $result = $this->cssMinifier->run($content);
+        $result = $this->getCssMin()->run($content);
         ini_set('pcre.recursion_limit', $pcreRecursionLimit);
         return $result;
     }
diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6cc3c489206be68d5809017b01e6b727fa8462a
--- /dev/null
+++ b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Code\Test\Unit\Minifier\Adapter\Css;
+
+class CssMinTest extends \PHPUnit_Framework_TestCase
+{
+    public function testMinify()
+    {
+        $cssMinMock = $this->getMockBuilder(\CSSmin::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $cssMinAdapter = new \Magento\Framework\Code\Minifier\Adapter\Css\CSSmin($cssMinMock);
+        $property = new \ReflectionProperty(\Magento\Framework\Code\Minifier\Adapter\Css\CSSmin::class, 'cssMinifier');
+        $property->setAccessible(true);
+        $property->setValue($cssMinAdapter, $cssMinMock);
+
+        $expectedResult = 'minified content';
+        $cssMinMock->expects($this->once())->method('run')->willReturn($expectedResult);
+        $this->assertEquals($expectedResult, $cssMinAdapter->minify('not minified'));
+    }
+}
diff --git a/lib/internal/Magento/Framework/Console/Cli.php b/lib/internal/Magento/Framework/Console/Cli.php
index 6e9110de1ab75200dc859f39018b7010deeb8423..9742acbbd237cdce6f379f2fbb218526d3f60f62 100644
--- a/lib/internal/Magento/Framework/Console/Cli.php
+++ b/lib/internal/Magento/Framework/Console/Cli.php
@@ -3,22 +3,23 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\Console;
 
-use Magento\Framework\Filesystem\Driver\File;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Input\ArgvInput;
 use Symfony\Component\Console\Application as SymfonyApplication;
 use Magento\Framework\App\Bootstrap;
+use Magento\Framework\Filesystem\Driver\File;
 use Magento\Framework\Shell\ComplexParameter;
-use Symfony\Component\Console\Input\ArgvInput;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Magento\Framework\Setup\FilePermissions;
+use Magento\Setup\Console\CompilerPreparation;
 
 /**
- * Magento2 CLI Application. This is the hood for all command line tools supported by Magento.
+ * Magento 2 CLI Application. This is the hood for all command line tools supported by Magento
  *
  * {@inheritdoc}
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Cli extends SymfonyApplication
 {
@@ -27,7 +28,9 @@ class Cli extends SymfonyApplication
      */
     const INPUT_KEY_BOOTSTRAP = 'bootstrap';
 
-    /** @var \Zend\ServiceManager\ServiceManager */
+    /**
+     * @var \Zend\ServiceManager\ServiceManager
+     */
     private $serviceManager;
 
     /**
@@ -47,23 +50,6 @@ class Cli extends SymfonyApplication
      */
     public function doRun(InputInterface $input, OutputInterface $output)
     {
-        // Check to make sure var/generation/Magento folder dir have read/execute permission for the current user
-        /** @var \Magento\Setup\Model\ObjectManagerProvider $omProvider */
-        $omProvider = $this->serviceManager->get('Magento\Setup\Model\ObjectManagerProvider');
-        /** @var \Magento\Framework\ObjectManagerInterface $objectManager */
-        $objectManager = $omProvider->get();
-        /** @var \Magento\Framework\Setup\Filepermissions $filePermissions */
-        $filePermissions = $objectManager->get('Magento\Framework\Setup\FilePermissions');
-        if ($filePermissions->checkDirectoryPermissionForCLIUser() === false) {
-            $output->writeln(
-                "<error>Command line user ("
-                . get_current_user()
-                . ") may not have proper read+execute permissions for directories under \"var/generation/\" . "
-                . "Please address this issue before using Magento command line."
-            );
-            return 0;
-        }
-
         $exitCode = parent::doRun($input, $output);
         if ($this->initException) {
             $output->writeln(
@@ -76,21 +62,31 @@ class Cli extends SymfonyApplication
     }
 
     /**
-     * @param string $name    The name of the application
-     * @param string $version The version of the application
+     * @param string $name  application name
+     * @param string $version application version
+     * @SuppressWarnings(PHPMD.ExitExpression)
      */
     public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
     {
         $this->serviceManager = \Zend\Mvc\Application::init(require BP . '/setup/config/application.config.php')
             ->getServiceManager();
+        $generationDirectoryAccess = new GenerationDirectoryAccess($this->serviceManager);
+        if (!$generationDirectoryAccess->check()) {
+            $output = new ConsoleOutput();
+            $output->writeln(
+                '<error>Command line user does not have read and write permissions on var/generation directory.  Please'
+                . ' address this issue before using Magento command line.</error>'
+            );
+            exit(0);
+        }
         /**
-         * Temporary workaround until the compiler is able to clear the generation directory. (MAGETWO-44493)
+         * Temporary workaround until the compiler is able to clear the generation directory
+         * @todo remove after MAGETWO-44493 resolved
          */
-        if (class_exists('Magento\Setup\Console\CompilerPreparation')) {
-            (new \Magento\Setup\Console\CompilerPreparation($this->serviceManager, new ArgvInput(), new File()))
-                ->handleCompilerEnvironment();
+        if (class_exists(CompilerPreparation::class)) {
+            $compilerPreparation = new CompilerPreparation($this->serviceManager, new ArgvInput(), new File());
+            $compilerPreparation->handleCompilerEnvironment();
         }
-
         parent::__construct($name, $version);
     }
 
diff --git a/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php b/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php
new file mode 100644
index 0000000000000000000000000000000000000000..873669bcf8fff35aeac7874e922ad73943853953
--- /dev/null
+++ b/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Console;
+
+use Magento\Framework\App\Bootstrap;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem\DriverPool;
+use Magento\Framework\Filesystem\File\WriteFactory;
+use Magento\Framework\Filesystem\Directory\Write;
+use Zend\ServiceManager\ServiceManager;
+use Magento\Setup\Mvc\Bootstrap\InitParamListener;
+
+/**
+ * Check var/generation read and write access
+ */
+class GenerationDirectoryAccess
+{
+    /**
+     * @var ServiceManager
+     */
+    private $serviceManager;
+
+    /**
+     * @param ServiceManager $serviceManager
+     */
+    public function __construct(
+        ServiceManager $serviceManager
+    ) {
+        $this->serviceManager = $serviceManager;
+    }
+
+    /**
+     * Check var/generation read and write access
+     *
+     * @return bool
+     */
+    public function check()
+    {
+        $initParams = $this->serviceManager->get(InitParamListener::BOOTSTRAP_PARAM);
+        $filesystemDirPaths = isset($initParams[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS])
+            ? $initParams[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS]
+            : [];
+        $directoryList = new DirectoryList(BP, $filesystemDirPaths);
+        $generationDirectoryPath = $directoryList->getPath(DirectoryList::GENERATION);
+        $driverPool = new DriverPool();
+        $fileWriteFactory = new WriteFactory($driverPool);
+        /** @var \Magento\Framework\Filesystem\DriverInterface $driver */
+        $driver = $driverPool->getDriver(DriverPool::FILE);
+        $directoryWrite = new Write($fileWriteFactory, $driver, $generationDirectoryPath);
+        if ($directoryWrite->isExist()) {
+            if ($directoryWrite->isDirectory()
+                || $directoryWrite->isReadable()
+            ) {
+                try {
+                    $probeFilePath = $generationDirectoryPath . DIRECTORY_SEPARATOR . time();
+                    $fileWriteFactory->create($probeFilePath, DriverPool::FILE, 'w');
+                    $directoryWrite->delete($probeFilePath);
+                } catch (\Exception $e) {
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        } else {
+            try {
+                $directoryWrite->create();
+            } catch (\Exception $e) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php b/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..a00bf449718ab3f148d039e810c1a863cf89a7b2
--- /dev/null
+++ b/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Filesystem\Filter;
+
+/**
+ * Filters Iterator to exclude specified files
+ */
+class ExcludeFilter extends \FilterIterator
+{
+    /**
+     * Array that is used for filtering
+     *
+     * @var array
+     */
+    protected $_filters;
+
+    /**
+     * Constructor
+     *
+     * @param \Iterator $iterator
+     * @param array $filters list of files to skip
+     */
+    public function __construct(\Iterator $iterator, array $filters)
+    {
+        parent::__construct($iterator);
+        $this->_filters = $filters;
+    }
+
+    /**
+     * Check whether the current element of the iterator is acceptable
+     *
+     * @return bool
+     */
+    public function accept()
+    {
+        $current = str_replace('\\', '/', $this->current()->__toString());
+        $currentFilename = str_replace('\\', '/', $this->current()->getFilename());
+
+        if ($currentFilename == '.' || $currentFilename == '..') {
+            return false;
+        }
+
+        foreach ($this->_filters as $filter) {
+            $filter = str_replace('\\', '/', $filter);
+            if (false !== strpos($current, $filter)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php b/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bca9b5b66768591238324b4262fe8471374d47e3
--- /dev/null
+++ b/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Filesystem\Test\Unit\File;
+
+use \Magento\Framework\Filesystem\Filter\ExcludeFilter;
+
+/**
+ * Class ExcludeFilterTest
+ */
+class ExcludeFilterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Iterator
+     */
+    protected $iterator;
+
+    protected function setUp()
+    {
+        $this->iterator = $this->getFilesIterator();
+    }
+
+    public function testExclusion()
+    {
+        $iterator = new ExcludeFilter(
+            $this->iterator,
+            [
+                BP . '/var/session/'
+            ]
+        );
+
+        foreach ($iterator as $i) {
+            $result[] = $i;
+        }
+
+        $this->assertTrue(!in_array(BP . '/var/session/', $result), 'Filtered path should not be in array');
+    }
+
+    private function getFilesIterator ()
+    {
+        $files = [
+            BP . '/var/',
+            BP . '/var/session/',
+            BP . '/var/cache/'
+        ];
+
+        foreach ($files as $file) {
+            $item = $this->getMockBuilder('SplFileInfoClass')->setMethods(['__toString', 'getFilename'])->getMock();
+            $item->expects($this->any())->method('__toString')->willReturn($file);
+            $item->expects($this->any())->method('getFilename')->willReturn('notDots');
+            yield $item;
+        }
+    }
+}
diff --git a/lib/internal/Magento/Framework/Indexer/CacheContext.php b/lib/internal/Magento/Framework/Indexer/CacheContext.php
index cf4c4bc5ee2334b64bc668af495e9b083e5b87f4..230adc543d4371a203fcf330c5a8de403e2a2150 100644
--- a/lib/internal/Magento/Framework/Indexer/CacheContext.php
+++ b/lib/internal/Magento/Framework/Indexer/CacheContext.php
@@ -15,6 +15,11 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface
      */
     protected $entities = [];
 
+    /**
+     * @var array
+     */
+    private $tags = [];
+
     /**
      * Register entity Ids
      *
@@ -29,6 +34,18 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface
         return $this;
     }
 
+    /**
+     * Register entity tags
+     *
+     * @param string $cacheTag
+     * @return $this
+     */
+    public function registerTags($cacheTags)
+    {
+        $this->tags = array_merge($this->tags, $cacheTags);
+        return $this;
+    }
+
     /**
      * Returns registered entities
      *
@@ -57,6 +74,6 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface
                 $identities[] = $cacheTag . '_' . $id;
             }
         }
-        return $identities;
+        return array_merge($identities, array_unique($this->tags));
     }
 }
diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/AbstractResource.php b/lib/internal/Magento/Framework/Model/ResourceModel/AbstractResource.php
index d2b901d950555508b7f7edbb1b58cb3338af1a0d..451ec868bef316b3393b31912c4811530b0a8b25 100644
--- a/lib/internal/Magento/Framework/Model/ResourceModel/AbstractResource.php
+++ b/lib/internal/Magento/Framework/Model/ResourceModel/AbstractResource.php
@@ -56,7 +56,7 @@ abstract class AbstractResource
     /**
      * Subscribe some callback to transaction commit
      *
-     * @param array $callback
+     * @param callable|array $callback
      * @return $this
      * @api
      */
diff --git a/lib/internal/Magento/Framework/Module/DependencyChecker.php b/lib/internal/Magento/Framework/Module/DependencyChecker.php
index 1149d2f35bcdbbf723ca939bd93635ba81c31edc..92adbd6fbb7bfdff02ce8ace917c063e8010236d 100644
--- a/lib/internal/Magento/Framework/Module/DependencyChecker.php
+++ b/lib/internal/Magento/Framework/Module/DependencyChecker.php
@@ -50,7 +50,6 @@ class DependencyChecker
         $this->enabledModuleList = $list->getNames();
         $this->fullModuleList = $loader->load();
         $this->packageInfo = $packageInfoFactory->create();
-        $this->graph = $this->createGraph();
     }
 
     /**
@@ -93,6 +92,7 @@ class DependencyChecker
      */
     private function checkDependencyGraph($isEnable, $moduleNames, $enabledModules)
     {
+        $this->graph = $this->createGraph();
         $dependenciesMissingAll = [];
         $graphMode = $isEnable ? Graph::DIRECTIONAL : Graph::INVERSE;
         foreach ($moduleNames as $moduleName) {
diff --git a/lib/internal/Magento/Framework/Search/Search.php b/lib/internal/Magento/Framework/Search/Search.php
index 718357d4c29ca237ebaa0772f0dadc1dbbbe197a..d7d00b08f484df6cfe2a4bdbbf4f31f83c0a405e 100644
--- a/lib/internal/Magento/Framework/Search/Search.php
+++ b/lib/internal/Magento/Framework/Search/Search.php
@@ -57,7 +57,7 @@ class Search implements SearchInterface
     {
         $this->requestBuilder->setRequestName($searchCriteria->getRequestName());
 
-        $scope = $this->scopeResolver->getScope();
+        $scope = $this->scopeResolver->getScope()->getId();
         $this->requestBuilder->bindDimension('scope', $scope);
 
         foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
@@ -84,7 +84,7 @@ class Search implements SearchInterface
      */
     private function addFieldToFilter($field, $condition = null)
     {
-        if (!is_array($condition) || !in_array(key($condition), ['from', 'to'])) {
+        if (!is_array($condition) || !in_array(key($condition), ['from', 'to'], true)) {
             $this->requestBuilder->bind($field, $condition);
         } else {
             if (!empty($condition['from'])) {
diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php
index bb4f56445c862182dcc703e5e3258dc2b8abf6c9..89e83e7cc8bf1609419c76f79f387064a4b51ac5 100644
--- a/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php
+++ b/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php
@@ -65,26 +65,25 @@ class SearchTest extends \PHPUnit_Framework_TestCase
     public function testSearch()
     {
         $requestName = 'requestName';
-        $scope = 333;
-        $filterField = 'filterField';
-        $filterValue = 'filterValue';
-
-        $filter = $this->getMockBuilder('Magento\Framework\Api\Filter')
+        $scopeId = 333;
+        $filters = [
+            $this->createFilterMock('array_filter', ['arrayValue1', 'arrayValue2']),
+            $this->createFilterMock('simple_filter', 'filterValue'),
+            $this->createFilterMock('from_filter', ['from' => 30]),
+            $this->createFilterMock('to_filter', ['to' => 100]),
+            $this->createFilterMock('range_filter', ['from' => 60, 'to' => 82]),
+        ];
+
+        $scope = $this->getMockBuilder('Magento\Framework\App\ScopeInterface')
             ->disableOriginalConstructor()
-            ->getMock();
-        $filter->expects($this->once())
-            ->method('getField')
-            ->willReturn($filterField);
-        $filter->expects($this->once())
-            ->method('getValue')
-            ->willReturn($filterValue);
-
+            ->getMockForAbstractClass();
+        
         $filterGroup = $this->getMockBuilder('Magento\Framework\Api\Search\FilterGroup')
             ->disableOriginalConstructor()
             ->getMock();
         $filterGroup->expects($this->once())
             ->method('getFilters')
-            ->willReturn([$filter]);
+            ->willReturn($filters);
 
         $searchCriteria = $this->getMockBuilder('Magento\Framework\Api\Search\SearchCriteriaInterface')
             ->disableOriginalConstructor()
@@ -113,8 +112,8 @@ class SearchTest extends \PHPUnit_Framework_TestCase
             ->with($requestName);
         $this->requestBuilder->expects($this->once())
             ->method('bindDimension')
-            ->with('scope', $scope);
-        $this->requestBuilder->expects($this->any())
+            ->with('scope', $scopeId);
+        $this->requestBuilder->expects($this->exactly(6))
             ->method('bind');
         $this->requestBuilder->expects($this->once())
             ->method('create')
@@ -134,8 +133,31 @@ class SearchTest extends \PHPUnit_Framework_TestCase
             ->method('getScope')
             ->willReturn($scope);
 
+        $scope->expects($this->once())
+            ->method('getId')
+            ->willReturn($scopeId);
+
         $searchResult = $this->model->search($searchCriteria);
 
         $this->assertInstanceOf('Magento\Framework\Api\Search\SearchResultInterface', $searchResult);
     }
+
+    /**
+     * @param $field
+     * @param $value
+     * @return \Magento\Framework\Api\Filter|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private function createFilterMock($field, $value)
+    {
+        $filter = $this->getMockBuilder('Magento\Framework\Api\Filter')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filter->expects($this->once())
+            ->method('getField')
+            ->willReturn($field);
+        $filter->expects($this->once())
+            ->method('getValue')
+            ->willReturn($value);
+        return $filter;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php
index d4dce686583b060b6e98a8335bf96d9c04608598..1a23e2974f568d90c33d49067cc228f8666d6705 100644
--- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php
+++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php
@@ -5,9 +5,14 @@
  */
 namespace Magento\Framework\Session\SaveHandler\Redis;
 
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Store\Model\ScopeInterface as StoreScopeInterface;
 use Magento\Framework\App\DeploymentConfig;
 use Magento\Framework\App\State;
 
+/**
+ * Redis session save handler
+ */
 class Config implements \Cm\RedisSession\Handler\ConfigInterface
 {
     /**
@@ -95,6 +100,21 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface
      */
     const PARAM_BREAK_AFTER             = 'session/redis/break_after';
 
+    /**
+     * Cookie lifetime config path
+     */
+    const XML_PATH_COOKIE_LIFETIME = 'web/cookie/cookie_lifetime';
+
+    /**
+     * Admin session lifetime config path
+     */
+    const XML_PATH_ADMIN_SESSION_LIFETIME = 'admin/security/session_lifetime';
+
+    /**
+     * Session max lifetime
+     */
+    const SESSION_MAX_LIFETIME = 31536000;
+
     /**
      * Deployment config
      *
@@ -102,14 +122,24 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface
      */
     private $deploymentConfig;
 
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
     /**
      * @param DeploymentConfig $deploymentConfig
      * @param State $appState
+     * @param ScopeConfigInterface $scopeConfig
      */
-    public function __construct(DeploymentConfig $deploymentConfig, State $appState)
-    {
+    public function __construct(
+        DeploymentConfig $deploymentConfig,
+        State $appState,
+        ScopeConfigInterface $scopeConfig
+    ) {
         $this->deploymentConfig = $deploymentConfig;
         $this->appState = $appState;
+        $this->scopeConfig = $scopeConfig;
     }
 
     /**
@@ -197,7 +227,7 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface
      */
     public function getMaxLifetime()
     {
-        return $this->deploymentConfig->get(self::PARAM_MAX_LIFETIME);
+        return self::SESSION_MAX_LIFETIME;
     }
 
     /**
@@ -247,4 +277,15 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface
     {
         return $this->deploymentConfig->get(self::PARAM_BREAK_AFTER . '_' . $this->appState->getAreaCode());
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLifetime()
+    {
+        if ($this->appState->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
+            return (int)$this->scopeConfig->getValue(self::XML_PATH_ADMIN_SESSION_LIFETIME);
+        }
+        return (int)$this->scopeConfig->getValue(self::XML_PATH_COOKIE_LIFETIME, StoreScopeInterface::SCOPE_STORE);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php
index f34ef8b756d3343620ce736529a089032ca0a403..c66c31d2fcdff67dcf11b21f35cb3a26c45950db 100644
--- a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php
+++ b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php
@@ -5,35 +5,44 @@
  */
 namespace Magento\Framework\Session\Test\Unit\SaveHandler\Redis;
 
+use Magento\Store\Model\ScopeInterface;
 use Magento\Framework\Session\SaveHandler\Redis\Config;
 
 class ConfigTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\App\DeploymentConfig
+     * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $deploymentConfig;
+    private $deploymentConfigMock;
 
     /**
-     * @var \Magento\Framework\App\State
+     * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $appState;
+    private $appStateMock;
 
     /**
-     * @var \Magento\Framework\Session\SaveHandler\Redis\Config
+     * @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $config;
+    private $scopeConfigMock;
+
+    /**
+     * @var Config
+     */
+    private $config;
 
     public function setUp()
     {
-        $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
-        $this->appState = $this->getMock('Magento\Framework\App\State', [], [], '', false);
+        $this->deploymentConfigMock = $this->getMock(\Magento\Framework\App\DeploymentConfig::class, [], [], '', false);
+        $this->appStateMock = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false);
+        $this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config::class, [], [], '', false);
+
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->config = $objectManager->getObject(
-            'Magento\Framework\Session\SaveHandler\Redis\Config',
+            Config::class,
             [
-                'deploymentConfig' => $this->deploymentConfig,
-                'appState' => $this->appState
+                'deploymentConfig' => $this->deploymentConfigMock,
+                'appState' => $this->appStateMock,
+                'scopeConfig' => $this->scopeConfigMock
             ]
         );
     }
@@ -41,7 +50,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetLogLevel()
     {
         $expected = 2;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_LOG_LEVEL)
             ->willReturn($expected);
@@ -51,7 +60,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetHost()
     {
         $expected = '127.0.0.1';
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_HOST)
             ->willReturn($expected);
@@ -61,7 +70,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetPort()
     {
         $expected = 1234;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_PORT)
             ->willReturn($expected);
@@ -71,7 +80,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetDatabase()
     {
         $expected = 2;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_DATABASE)
             ->willReturn($expected);
@@ -81,7 +90,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetPassword()
     {
         $expected = 'password';
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_PASSWORD)
             ->willReturn($expected);
@@ -91,7 +100,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetTimeout()
     {
         $expected = 10;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_TIMEOUT)
             ->willReturn($expected);
@@ -101,7 +110,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetPersistentIdentifier()
     {
         $expected = 'sess01';
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_PERSISTENT_IDENTIFIER)
             ->willReturn($expected);
@@ -111,7 +120,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetCompressionThreshold()
     {
         $expected = 2;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_COMPRESSION_THRESHOLD)
             ->willReturn($expected);
@@ -121,7 +130,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetCompressionLibrary()
     {
         $expected = 'gzip';
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_COMPRESSION_LIBRARY)
             ->willReturn($expected);
@@ -131,7 +140,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetMaxConcurrency()
     {
         $expected = 6;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_MAX_CONCURRENCY)
             ->willReturn($expected);
@@ -140,18 +149,13 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testGetMaxLifetime()
     {
-        $expected = 30;
-        $this->deploymentConfig->expects($this->once())
-            ->method('get')
-            ->with(Config::PARAM_MAX_LIFETIME)
-            ->willReturn($expected);
-        $this->assertEquals($this->config->getMaxLifetime(), $expected);
+        $this->assertEquals($this->config->getMaxLifetime(), Config::SESSION_MAX_LIFETIME);
     }
 
     public function testGetMinLifetime()
     {
         $expected = 30;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_MIN_LIFETIME)
             ->willReturn($expected);
@@ -161,7 +165,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetDisableLocking()
     {
         $expected = false;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_DISABLE_LOCKING)
             ->willReturn($expected);
@@ -171,7 +175,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetBotLifetime()
     {
         $expected = 30;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_BOT_LIFETIME)
             ->willReturn($expected);
@@ -181,7 +185,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetBotFirstLifetime()
     {
         $expected = 30;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_BOT_FIRST_LIFETIME)
             ->willReturn($expected);
@@ -191,7 +195,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetFirstLifetime()
     {
         $expected = 30;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_FIRST_LIFETIME)
             ->willReturn($expected);
@@ -202,13 +206,44 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     {
         $areaCode = 'frontend';
         $breakAfter = 5;
-        $this->deploymentConfig->expects($this->once())
+        $this->deploymentConfigMock->expects($this->once())
             ->method('get')
             ->with(Config::PARAM_BREAK_AFTER . '_' . $areaCode)
             ->willReturn($breakAfter);
-        $this->appState->expects($this->once())
+        $this->appStateMock->expects($this->once())
             ->method('getAreaCode')
             ->willReturn($areaCode);
         $this->assertEquals($this->config->getBreakAfter(), $breakAfter);
     }
+
+    public function testGetLifetimeAdmin()
+    {
+        $areaCode = 'adminhtml';
+        $expectedLifetime = 123;
+        $this->appStateMock->expects($this->once())
+            ->method('getAreaCode')
+            ->willReturn($areaCode);
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(Config::XML_PATH_ADMIN_SESSION_LIFETIME)
+            ->willReturn($expectedLifetime);
+        $this->assertEquals($this->config->getLifetime(), $expectedLifetime);
+    }
+
+    public function testGetLifetimeFrontend()
+    {
+        $areaCode = 'frontend';
+        $expectedLifetime = 234;
+        $this->appStateMock->expects($this->once())
+            ->method('getAreaCode')
+            ->willReturn($areaCode);
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(
+                Config::XML_PATH_COOKIE_LIFETIME,
+                ScopeInterface::SCOPE_STORE
+            )
+            ->willReturn($expectedLifetime);
+        $this->assertEquals($this->config->getLifetime(), $expectedLifetime);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Setup/FilePermissions.php b/lib/internal/Magento/Framework/Setup/FilePermissions.php
index e70e583c27114c0071fe16d85b7cccb1f05324aa..4bb0816a34752969ae843d791e8823512f88610c 100644
--- a/lib/internal/Magento/Framework/Setup/FilePermissions.php
+++ b/lib/internal/Magento/Framework/Setup/FilePermissions.php
@@ -3,13 +3,12 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\Setup;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Backup\Filesystem\Iterator\Filter;
+use Magento\Framework\Filesystem\Filter\ExcludeFilter;
 use Magento\Framework\Filesystem;
-use Magento\Framework\Filesystem\Driver\File;
 
 class FilePermissions
 {
@@ -23,11 +22,6 @@ class FilePermissions
      */
     protected $directoryList;
 
-    /**
-     * @var File
-     */
-    protected $driverFile;
-
     /**
      * List of required writable directories for installation
      *
@@ -66,16 +60,13 @@ class FilePermissions
     /**
      * @param Filesystem $filesystem
      * @param DirectoryList $directoryList
-     * @param File $driverFile
      */
     public function __construct(
         Filesystem $filesystem,
-        DirectoryList $directoryList,
-        File $driverFile
+        DirectoryList $directoryList
     ) {
         $this->filesystem = $filesystem;
         $this->directoryList = $directoryList;
-        $this->driverFile = $driverFile;
     }
 
     /**
@@ -152,10 +143,18 @@ class FilePermissions
         );
         $noWritableFilesFolders = [
             $this->directoryList->getPath(DirectoryList::GENERATION) . '/',
-            $this->directoryList->getPath(DirectoryList::DI) .'/'
+            $this->directoryList->getPath(DirectoryList::DI) . '/',
         ];
 
         $directoryIterator = new Filter($directoryIterator, $noWritableFilesFolders);
+
+        $directoryIterator = new ExcludeFilter(
+            $directoryIterator,
+            [
+                $this->directoryList->getPath(DirectoryList::SESSION) . '/',
+            ]
+        );
+
         $foundNonWritable = false;
 
         try {
@@ -212,28 +211,6 @@ class FilePermissions
         return $this->isReadableDirectory($directory) && !$directory->isWritable();
     }
 
-    /**
-     * Checks if var/generation/* has read and execute permissions
-     *
-     * @return bool
-     */
-    public function checkDirectoryPermissionForCLIUser()
-    {
-        $varGenerationDir = $this->directoryList->getPath(DirectoryList::GENERATION);
-        $dirs = $this->driverFile->readDirectory($varGenerationDir);
-        array_unshift($dirs, $varGenerationDir);
-
-        foreach ($dirs as $dir) {
-            if (!is_dir($dir)
-                || !is_readable($dir)
-                || !is_executable($dir)
-            ) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     /**
      * Checks if directory exists and is readable
      *
diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php
index 29869b89be72a9f4b194fff100f18b8272b80e13..cff6323802083c6000f009833415562eee6c3957 100644
--- a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php
+++ b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php
@@ -3,12 +3,10 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\Setup\Test\Unit;
 
 use \Magento\Framework\Setup\FilePermissions;
 use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Filesystem\Driver\File;
 
 class FilePermissionsTest extends \PHPUnit_Framework_TestCase
 {
@@ -27,11 +25,6 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase
      */
     private $directoryListMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Filesystem\Driver\File
-     */
-    private $driverFileMock;
-
     /**
      * @var FilePermissions
      */
@@ -41,7 +34,6 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase
     {
         $this->directoryWriteMock = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
         $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
-        $this->driverFileMock = $this->getMock('Magento\Framework\Filesystem\Driver\File', [], [], '', false);
 
         $this->filesystemMock
             ->expects($this->any())
@@ -51,8 +43,7 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase
 
         $this->filePermissions = new FilePermissions(
             $this->filesystemMock,
-            $this->directoryListMock,
-            $this->driverFileMock
+            $this->directoryListMock
         );
     }
 
diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Filter/Date.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Filter/Date.php
index 3f0749c5b9573ed64557f0959682cc71ea1a70c4..43c05e99084b505d2b88a25f97fb80ff8d6bb0c8 100644
--- a/lib/internal/Magento/Framework/Stdlib/DateTime/Filter/Date.php
+++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Filter/Date.php
@@ -52,6 +52,11 @@ class Date implements \Zend_Filter_Interface
      */
     public function filter($value)
     {
-        return $this->_normalToLocalFilter->filter($this->_localToNormalFilter->filter($value));
+        $value = $this->_normalToLocalFilter->filter($this->_localToNormalFilter->filter($value));
+
+        /**
+         * @todo MAGETWO-51391
+         */
+        return str_replace("\xc2\xa0", '', $value);
     }
 }
diff --git a/lib/web/jquery/jstree/jquery.jstree.js b/lib/web/jquery/jstree/jquery.jstree.js
index c6ea72abecf32e2360e2b7afe30f46e6c80e7d1b..e2f6330ba45eb0ea6d74ed49a065d6745dac3c6c 100644
--- a/lib/web/jquery/jstree/jquery.jstree.js
+++ b/lib/web/jquery/jstree/jquery.jstree.js
@@ -31,11 +31,11 @@
 (function () { if(jQuery && jQuery.jstree) { return; }
 	var is_ie6 = false, is_ie7 = false, is_ff2 = false;
 
-/* 
+/*
  * jsTree core
  */
 (function ($) {
-	// Common functions not related to jsTree 
+	// Common functions not related to jsTree
 	// decided to move them to a `vakata` "namespace"
 	$.vakata = {};
 	// CSS related functions
@@ -63,8 +63,8 @@
 			if(sheet.insertRule) { sheet.insertRule(rule_name + ' { }', 0); } else { sheet.addRule(rule_name, null, 0); }
 			return $.vakata.css.get_css(rule_name);
 		},
-		remove_css : function(rule_name, sheet) { 
-			return $.vakata.css.get_css(rule_name, true, sheet); 
+		remove_css : function(rule_name, sheet) {
+			return $.vakata.css.get_css(rule_name, true, sheet);
 		},
 		add_sheet : function(opts) {
 			var tmp = false, is_new = true;
@@ -77,12 +77,12 @@
 					if(opts.title) { tmp.setAttribute("id", opts.title + "-stylesheet"); }
 				}
 				if(tmp.styleSheet) {
-					if(is_new) { 
-						document.getElementsByTagName("head")[0].appendChild(tmp); 
-						tmp.styleSheet.cssText = opts.str; 
+					if(is_new) {
+						document.getElementsByTagName("head")[0].appendChild(tmp);
+						tmp.styleSheet.cssText = opts.str;
 					}
 					else {
-						tmp.styleSheet.cssText = tmp.styleSheet.cssText + " " + opts.str; 
+						tmp.styleSheet.cssText = tmp.styleSheet.cssText + " " + opts.str;
 					}
 				}
 				else {
@@ -108,7 +108,7 @@
 		}
 	};
 
-	// private variables 
+	// private variables
 	var instances = [],			// instance array (used by $.jstree.reference/create/focused)
 		focused_instance = -1,	// the index in the instance array of the currently focused instance
 		plugins = {},			// list of included plugins
@@ -117,7 +117,7 @@
 	// jQuery plugin wrapper (thanks to jquery UI widget function)
 	$.fn.jstree = function (settings) {
 		var isMethodCall = (typeof settings == 'string'), // is this a method call like $().jstree("open_node")
-			args = Array.prototype.slice.call(arguments, 1), 
+			args = Array.prototype.slice.call(arguments, 1),
 			returnValue = this;
 
 		// if a method call execute the method on all selected instances
@@ -135,8 +135,8 @@
 				var instance_id = $.data(this, "jstree_instance_id"),
 					a = [],
 					b = settings ? $.extend({}, true, settings) : {},
-					c = $(this), 
-					s = false, 
+					c = $(this),
+					s = false,
 					t = [];
 				a = a.concat(args);
 				if(c.data("jstree")) { a.push(c.data("jstree")); }
@@ -157,14 +157,14 @@
 				// extend defaults with passed data
 				s = $.extend(true, {}, $.jstree.defaults, b);
 				s.plugins = b.plugins;
-				$.each(plugins, function (i, val) { 
-					if($.inArray(i, s.plugins) === -1) { s[i] = null; delete s[i]; } 
+				$.each(plugins, function (i, val) {
+					if($.inArray(i, s.plugins) === -1) { s[i] = null; delete s[i]; }
 					else { t.push(i); }
 				});
 				s.plugins = t;
 
 				// push the new object to the instances array (at the same time set the default classes to the container) and init
-				instances[instance_id] = new $.jstree._instance(instance_id, $(this).addClass("jstree jstree-" + instance_id), s); 
+				instances[instance_id] = new $.jstree._instance(instance_id, $(this).addClass("jstree jstree-" + instance_id), s);
 				// init all activated plugins for this instance
 				$.each(instances[instance_id]._get_settings().plugins, function (i, val) { instances[instance_id].data[val] = {}; });
 				$.each(instances[instance_id]._get_settings().plugins, function (i, val) { if(plugins[val]) { plugins[val].__init.apply(instances[instance_id]); } });
@@ -181,16 +181,16 @@
 			plugins : []
 		},
 		_focused : function () { return instances[focused_instance] || null; },
-		_reference : function (needle) { 
+		_reference : function (needle) {
 			// get by instance id
 			if(instances[needle]) { return instances[needle]; }
 			// get by DOM (if still no luck - return null
-			var o = $(needle); 
+			var o = $(needle);
 			if(!o.length && typeof needle === "string") { o = $("#" + needle); }
 			if(!o.length) { return null; }
-			return instances[o.closest(".jstree").data("jstree_instance_id")] || null; 
+			return instances[o.closest(".jstree").data("jstree_instance_id")] || null;
 		},
-		_instance : function (index, container, settings) { 
+		_instance : function (index, container, settings) {
 			// for plugins to store data in
 			this.data = { core : {} };
 			this.get_settings	= function () { return $.extend(true, {}, settings); };
@@ -198,14 +198,14 @@
 			this.get_index		= function () { return index; };
 			this.get_container	= function () { return container; };
 			this.get_container_ul = function () { return container.children("ul:eq(0)"); };
-			this._set_settings	= function (s) { 
+			this._set_settings	= function (s) {
 				settings = $.extend(true, {}, settings, s);
 			};
 		},
 		_fn : { },
 		plugin : function (pname, pdata) {
 			pdata = $.extend({}, {
-				__init		: $.noop, 
+				__init		: $.noop,
 				__destroy	: $.noop,
 				_fn			: {},
 				defaults	: false
@@ -242,11 +242,11 @@
 						if(typeof rslt !== "undefined") { args = rslt; }
 
 						rslt = func.apply(
-							$.extend({}, this, { 
-								__callback : function (data) { 
+							$.extend({}, this, {
+								__callback : function (data) {
 									this.get_container().triggerHandler( i + '.jstree', { "inst" : this, "args" : args, "rslt" : data, "rlbk" : rlbk });
 								},
-								__rollback : function () { 
+								__rollback : function () {
 									rlbk = this.get_rollback();
 									return rlbk;
 								},
@@ -280,22 +280,22 @@
 		// code is copied from jQuery ($.browser is deprecated + there is a bug in IE)
 		var u = navigator.userAgent.toLowerCase(),
 			v = (u.match( /.+?(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
-			css_string = '' + 
-				'.jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } ' + 
-				'.jstree li { display:block; min-height:18px; line-height:18px; white-space:nowrap; margin-left:18px; min-width:18px; } ' + 
-				'.jstree-rtl li { margin-left:0; margin-right:18px; } ' + 
-				'.jstree > ul > li { margin-left:0px; } ' + 
-				'.jstree-rtl > ul > li { margin-right:0px; } ' + 
-				'.jstree ins { display:inline-block; text-decoration:none; width:18px; height:18px; margin:0 0 0 0; padding:0; } ' + 
-				'.jstree a { display:inline-block; line-height:16px; height:16px; color:black; white-space:nowrap; text-decoration:none; padding:1px 2px; margin:0; } ' + 
-				'.jstree a:focus { outline: none; } ' + 
-				'.jstree a > ins { height:16px; width:16px; } ' + 
-				'.jstree a > .jstree-icon { margin-right:3px; } ' + 
-				'.jstree-rtl a > .jstree-icon { margin-left:3px; margin-right:0; } ' + 
-				'li.jstree-open > ul { display:block; } ' + 
+			css_string = '' +
+				'.jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } ' +
+				'.jstree li { display:block; min-height:18px; line-height:18px; white-space:nowrap; margin-left:18px; min-width:18px; } ' +
+				'.jstree-rtl li { margin-left:0; margin-right:18px; } ' +
+				'.jstree > ul > li { margin-left:0px; } ' +
+				'.jstree-rtl > ul > li { margin-right:0px; } ' +
+				'.jstree ins { display:inline-block; text-decoration:none; width:18px; height:18px; margin:0 0 0 0; padding:0; } ' +
+				'.jstree a { display:inline-block; line-height:16px; height:16px; color:black; white-space:nowrap; text-decoration:none; padding:1px 2px; margin:0; } ' +
+				'.jstree a:focus { outline: none; } ' +
+				'.jstree a > ins { height:16px; width:16px; } ' +
+				'.jstree a > .jstree-icon { margin-right:3px; } ' +
+				'.jstree-rtl a > .jstree-icon { margin-left:3px; margin-right:0; } ' +
+				'li.jstree-open > ul { display:block; } ' +
 				'li.jstree-closed > ul { display:none; } ';
 		// Correct IE 6 (does not support the > CSS selector)
-		if(/msie/.test(u) && parseInt(v, 10) == 6) { 
+		if(/msie/.test(u) && parseInt(v, 10) == 6) {
 			is_ie6 = true;
 
 			// fix image flicker and lack of caching
@@ -303,28 +303,28 @@
 				document.execCommand("BackgroundImageCache", false, true);
 			} catch (err) { }
 
-			css_string += '' + 
-				'.jstree li { height:18px; margin-left:0; margin-right:0; } ' + 
-				'.jstree li li { margin-left:18px; } ' + 
-				'.jstree-rtl li li { margin-left:0px; margin-right:18px; } ' + 
-				'li.jstree-open ul { display:block; } ' + 
-				'li.jstree-closed ul { display:none !important; } ' + 
-				'.jstree li a { display:inline; border-width:0 !important; padding:0px 2px !important; } ' + 
-				'.jstree li a ins { height:16px; width:16px; margin-right:3px; } ' + 
+			css_string += '' +
+				'.jstree li { height:18px; margin-left:0; margin-right:0; } ' +
+				'.jstree li li { margin-left:18px; } ' +
+				'.jstree-rtl li li { margin-left:0px; margin-right:18px; } ' +
+				'li.jstree-open ul { display:block; } ' +
+				'li.jstree-closed ul { display:none !important; } ' +
+				'.jstree li a { display:inline; border-width:0 !important; padding:0px 2px !important; } ' +
+				'.jstree li a ins { height:16px; width:16px; margin-right:3px; } ' +
 				'.jstree-rtl li a ins { margin-right:0px; margin-left:3px; } ';
 		}
 		// Correct IE 7 (shifts anchor nodes onhover)
-		if(/msie/.test(u) && parseInt(v, 10) == 7) { 
+		if(/msie/.test(u) && parseInt(v, 10) == 7) {
 			is_ie7 = true;
 			css_string += '.jstree li a { border-width:0 !important; padding:0px 2px !important; } ';
 		}
 		// correct ff2 lack of display:inline-block
 		if(!/compatible/.test(u) && /mozilla/.test(u) && parseFloat(v, 10) < 1.9) {
 			is_ff2 = true;
-			css_string += '' + 
-				'.jstree ins { display:-moz-inline-box; } ' + 
+			css_string += '' +
+				'.jstree ins { display:-moz-inline-box; } ' +
 				'.jstree li { line-height:12px; } ' + // WHY??
-				'.jstree a { display:-moz-inline-box; } ' + 
+				'.jstree a { display:-moz-inline-box; } ' +
 				'.jstree .jstree-no-icons .jstree-checkbox { display:-moz-inline-stack !important; } ';
 				/* this shouldn't be here as it is theme specific */
 		}
@@ -339,7 +339,7 @@
 			this.data.core.to_open = this.get_settings().core.initially_open;
 			this.data.core.to_load = this.get_settings().core.initially_load;
 		},
-		defaults : { 
+		defaults : {
 			html_titles	: false,
 			animation	: 500,
 			initially_open : [],
@@ -354,9 +354,9 @@
 				multiple_selection : "Multiple selection"
 			}
 		},
-		_fn : { 
-			init	: function () { 
-				this.set_focus(); 
+		_fn : {
+			init	: function () {
+				this.set_focus();
 				if(this._get_settings().core.rtl) {
 					this.get_container().addClass("jstree-rtl").css("direction", "rtl");
 				}
@@ -369,16 +369,16 @@
 							// if(trgt.is("ins") && event.pageY - trgt.offset().top < this.data.core.li_height) { this.toggle_node(trgt); }
 							this.toggle_node(trgt);
 						}, this))
-					.bind("mousedown.jstree", $.proxy(function () { 
+					.bind("mousedown.jstree", $.proxy(function () {
 							this.set_focus(); // This used to be setTimeout(set_focus,0) - why?
 						}, this))
-					.bind("dblclick.jstree", function (event) { 
+					.bind("dblclick.jstree", function (event) {
 						var sel;
 						if(document.selection && document.selection.empty) { document.selection.empty(); }
 						else {
 							if(window.getSelection) {
 								sel = window.getSelection();
-								try { 
+								try {
 									sel.removeAllRanges();
 									sel.collapse();
 								} catch (err) { }
@@ -387,7 +387,7 @@
 					});
 				if(this._get_settings().core.notify_plugins) {
 					this.get_container()
-						.bind("load_node.jstree", $.proxy(function (e, data) { 
+						.bind("load_node.jstree", $.proxy(function (e, data) {
 								var o = this._get_node(data.rslt.obj),
 									t = this;
 								if(o === -1) { o = this.get_container_ul(); }
@@ -406,7 +406,7 @@
 				}
 				if(this._get_settings().core.load_open) {
 					this.get_container()
-						.bind("load_node.jstree", $.proxy(function (e, data) { 
+						.bind("load_node.jstree", $.proxy(function (e, data) {
 								var o = this._get_node(data.rslt.obj),
 									t = this;
 								if(o === -1) { o = this.get_container_ul(); }
@@ -419,7 +419,7 @@
 				this.__callback();
 				this.load_node(-1, function () { this.loaded(); this.reload_nodes(); });
 			},
-			destroy	: function () { 
+			destroy	: function () {
 				var i,
 					n = this.get_index(),
 					s = this._get_settings(),
@@ -430,12 +430,12 @@
 				});
 				this.__callback();
 				// set focus to another instance if this one is focused
-				if(this.is_focused()) { 
-					for(i in instances) { 
-						if(instances.hasOwnProperty(i) && i != n) { 
-							instances[i].set_focus(); 
-							break; 
-						} 
+				if(this.is_focused()) {
+					for(i in instances) {
+						if(instances.hasOwnProperty(i) && i != n) {
+							instances[i].set_focus();
+							break;
+						}
 					}
 				}
 				// if no other instance found
@@ -476,7 +476,7 @@
 			save_opened : function () {
 				var _this = this;
 				this.data.core.to_open = [];
-				this.get_container_ul().find("li.jstree-open").each(function () { 
+				this.get_container_ul().find("li.jstree-open").each(function () {
 					if(this.id) { _this.data.core.to_open.push("#" + this.id.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:")); }
 				});
 				this.__callback(_this.data.core.to_open);
@@ -487,9 +487,9 @@
 					done = true,
 					current = [],
 					remaining = [];
-				if(!is_callback) { 
-					this.data.core.reopen = false; 
-					this.data.core.refreshing = true; 
+				if(!is_callback) {
+					this.data.core.reopen = false;
+					this.data.core.refreshing = true;
 					this.data.core.to_open = $.map($.makeArray(this.data.core.to_open), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
 					this.data.core.to_load = $.map($.makeArray(this.data.core.to_load), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
 					if(this.data.core.to_open.length) {
@@ -504,7 +504,7 @@
 					});
 					if(current.length) {
 						this.data.core.to_load = remaining;
-						$.each(current, function (i, val) { 
+						$.each(current, function (i, val) {
 							if(!_this._is_loaded(val)) {
 								_this.load_node(val, function () { _this.reload_nodes(true); }, function () { _this.reload_nodes(true); });
 								done = false;
@@ -514,10 +514,10 @@
 				}
 				if(this.data.core.to_open.length) {
 					$.each(this.data.core.to_open, function (i, val) {
-						_this.open_node(val, false, true); 
+						_this.open_node(val, false, true);
 					});
 				}
-				if(done) { 
+				if(done) {
 					// TODO: find a more elegant approach to syncronizing returning requests
 					if(this.data.core.reopen) { clearTimeout(this.data.core.reopen); }
 					this.data.core.reopen = setTimeout(function () { _this.__callback({}, _this); }, 50);
@@ -529,7 +529,7 @@
 				var _this = this;
 				if(this.data.core.to_open.length) {
 					$.each(this.data.core.to_open, function (i, val) {
-						_this.open_node(val, false, true); 
+						_this.open_node(val, false, true);
 					});
 				}
 				this.__callback({});
@@ -545,36 +545,36 @@
 				this.load_node(obj, function () { _this.__callback({ "obj" : obj}); _this.reload_nodes(); });
 			},
 			// Dummy function to fire after the first load (so that there is a jstree.loaded event)
-			loaded	: function () { 
-				this.__callback(); 
+			loaded	: function () {
+				this.__callback();
 			},
 			// deal with focus
-			set_focus	: function () { 
+			set_focus	: function () {
 				if(this.is_focused()) { return; }
 				var f = $.jstree._focused();
 				if(f) { f.unset_focus(); }
 
-				this.get_container().addClass("jstree-focused"); 
-				focused_instance = this.get_index(); 
+				this.get_container().addClass("jstree-focused");
+				focused_instance = this.get_index();
 				this.__callback();
 			},
-			is_focused	: function () { 
-				return focused_instance == this.get_index(); 
+			is_focused	: function () {
+				return focused_instance == this.get_index();
 			},
 			unset_focus	: function () {
 				if(this.is_focused()) {
-					this.get_container().removeClass("jstree-focused"); 
-					focused_instance = -1; 
+					this.get_container().removeClass("jstree-focused");
+					focused_instance = -1;
 				}
 				this.__callback();
 			},
 
 			// traverse
-			_get_node		: function (obj) { 
-				var $obj = $(obj, this.get_container()); 
-				if($obj.is(".jstree") || obj == -1) { return -1; } 
-				$obj = $obj.closest("li", this.get_container()); 
-				return $obj.length ? $obj : false; 
+			_get_node		: function (obj) {
+				var $obj = $(obj, this.get_container());
+				if($obj.is(".jstree") || obj == -1) { return -1; }
+				$obj = $obj.closest("li", this.get_container());
+				return $obj.length ? $obj : false;
 			},
 			_get_next		: function (obj, strict) {
 				obj = this._get_node(obj);
@@ -684,7 +684,7 @@
 			open_all	: function (obj, do_animation, original_obj) {
 				obj = obj ? this._get_node(obj) : -1;
 				if(!obj || obj === -1) { obj = this.get_container_ul(); }
-				if(original_obj) { 
+				if(original_obj) {
 					obj = obj.find("li.jstree-closed");
 				}
 				else {
@@ -693,8 +693,8 @@
 					else { obj = obj.find("li.jstree-closed"); }
 				}
 				var _this = this;
-				obj.each(function () { 
-					var __this = this; 
+				obj.each(function () {
+					var __this = this;
 					if(!_this._is_loaded(this)) { _this.open_node(this, function() { _this.open_all(__this, do_animation, original_obj); }, !do_animation); }
 					else { _this.open_node(this, false, !do_animation); }
 				});
@@ -719,9 +719,9 @@
 				this.__callback({ "obj" : obj });
 			},
 			// rollback
-			get_rollback : function () { 
+			get_rollback : function () {
 				this.__callback();
-				return { i : this.get_index(), h : this.get_container().children("ul").clone(true), d : this.data }; 
+				return { i : this.get_index(), h : this.get_container().children("ul").clone(true), d : this.data };
 			},
 			set_rollback : function (html, data) {
 				this.get_container().empty().append(html);
@@ -764,7 +764,7 @@
 					}
 					tmp.prepend("<ins class='jstree-icon'>&#160;</ins>");
 					if(!m.icon && js.icon) { m.icon = js.icon; }
-					if(m.icon) { 
+					if(m.icon) {
 						if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
 						else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); }
 					}
@@ -879,11 +879,11 @@
 						case "first":
 						case "before":
 						case "inside":
-							p.cp = 0; 
+							p.cp = 0;
 							break;
 						case "after":
 						case "last":
-							p.cp = p.rt.get_container().find(" > ul > li").length; 
+							p.cp = p.rt.get_container().find(" > ul > li").length;
 							break;
 						default:
 							p.cp = p.p;
@@ -909,10 +909,10 @@
 							p.cr = p.r;
 							break;
 						case "last":
-							p.cp = p.r.find(" > ul > li").length; 
+							p.cp = p.r.find(" > ul > li").length;
 							p.cr = p.r;
 							break;
-						default: 
+						default:
 							p.cp = p.p;
 							p.cr = p.r;
 							break;
@@ -933,18 +933,18 @@
 				var obj = prepared_move, ret = true, r = obj.r === -1 ? this.get_container() : obj.r;
 				if(!obj || !obj.o || obj.or[0] === obj.o[0]) { return false; }
 				if(obj.op && obj.np && obj.op[0] === obj.np[0] && obj.cp - 1 === obj.o.index()) { return false; }
-				obj.o.each(function () { 
+				obj.o.each(function () {
 					if(r.parentsUntil(".jstree", "li").addBack().index(this) !== -1) { ret = false; return false; }
 				});
 				return ret;
 			},
 			move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
-				if(!is_prepared) { 
+				if(!is_prepared) {
 					return this.prepare_move(obj, ref, position, function (p) {
 						this.move_node(p, false, false, is_copy, true, skip_check);
 					});
 				}
-				if(is_copy) { 
+				if(is_copy) {
 					prepared_move.cy = true;
 				}
 				if(!skip_check && !this.check_move()) { return false; }
@@ -960,12 +960,12 @@
 				else { o = obj.o; }
 
 				if(obj.or.length) { obj.or.before(o); }
-				else { 
+				else {
 					if(!obj.np.children("ul").length) { $("<ul />").appendTo(obj.np); }
-					obj.np.children("ul:eq(0)").append(o); 
+					obj.np.children("ul:eq(0)").append(o);
 				}
 
-				try { 
+				try {
 					obj.ot.clean_node(obj.op);
 					obj.rt.clean_node(obj.np);
 					if(!obj.op.find("> ul > li").length) {
@@ -973,9 +973,9 @@
 					}
 				} catch (e) { }
 
-				if(is_copy) { 
+				if(is_copy) {
 					prepared_move.cy = true;
-					prepared_move.oc = o; 
+					prepared_move.oc = o;
 				}
 				this.__callback(prepared_move);
 				return prepared_move;
@@ -986,7 +986,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree ui plugin
  * This plugins handles selecting/deselecting/hovering/dehovering nodes
  */
@@ -998,7 +998,7 @@
 			e2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>').css({ position: 'absolute', top: -1000, left: 0 }).appendTo('body');
 			scrollbar_width = e1.width() - e2.width();
 			e1.add(e2).remove();
-		} 
+		}
 		else {
 			e1 = $('<div />').css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: 0 })
 					.prependTo('body').append('<div />').find('div').css({ width: '100%', height: 200 });
@@ -1007,9 +1007,9 @@
 		}
 	});
 	$.jstree.plugin("ui", {
-		__init : function () { 
-			this.data.ui.selected = $(); 
-			this.data.ui.last_selected = false; 
+		__init : function () {
+			this.data.ui.selected = $();
+			this.data.ui.last_selected = false;
 			this.data.ui.hovered = null;
 			this.data.ui.to_select = this.get_settings().ui.initially_select;
 
@@ -1031,41 +1031,41 @@
 							this.dehover_node(event.target);
 						}
 					}, this))
-				.bind("reopen.jstree", $.proxy(function () { 
+				.bind("reopen.jstree", $.proxy(function () {
 						this.reselect();
 					}, this))
-				.bind("get_rollback.jstree", $.proxy(function () { 
+				.bind("get_rollback.jstree", $.proxy(function () {
 						this.dehover_node();
 						this.save_selected();
 					}, this))
-				.bind("set_rollback.jstree", $.proxy(function () { 
+				.bind("set_rollback.jstree", $.proxy(function () {
 						this.reselect();
 					}, this))
-				.bind("close_node.jstree", $.proxy(function (event, data) { 
+				.bind("close_node.jstree", $.proxy(function (event, data) {
 						var s = this._get_settings().ui,
 							obj = this._get_node(data.rslt.obj),
 							clk = (obj && obj.length) ? obj.children("ul").find("a.jstree-clicked") : $(),
 							_this = this;
 						if(s.selected_parent_close === false || !clk.length) { return; }
-						clk.each(function () { 
+						clk.each(function () {
 							_this.deselect_node(this);
 							if(s.selected_parent_close === "select_parent") { _this.select_node(obj); }
 						});
 					}, this))
-				.bind("delete_node.jstree", $.proxy(function (event, data) { 
+				.bind("delete_node.jstree", $.proxy(function (event, data) {
 						var s = this._get_settings().ui.select_prev_on_delete,
 							obj = this._get_node(data.rslt.obj),
 							clk = (obj && obj.length) ? obj.find("a.jstree-clicked") : [],
 							_this = this;
 						clk.each(function () { _this.deselect_node(this); });
-						if(s && clk.length) { 
-							data.rslt.prev.each(function () { 
+						if(s && clk.length) {
+							data.rslt.prev.each(function () {
 								if(this.parentNode) { _this.select_node(this); return false; /* if return false is removed all prev nodes will be selected */}
 							});
 						}
 					}, this))
-				.bind("move_node.jstree", $.proxy(function (event, data) { 
-						if(data.rslt.cy) { 
+				.bind("move_node.jstree", $.proxy(function (event, data) {
+						if(data.rslt.cy) {
 							data.rslt.oc.find("a.jstree-clicked").removeClass("jstree-clicked");
 						}
 					}, this));
@@ -1080,13 +1080,13 @@
 			disable_selecting_children : false,
 			initially_select : []
 		},
-		_fn : { 
+		_fn : {
 			_get_node : function (obj, allow_multiple) {
 				if(typeof obj === "undefined" || obj === null) { return allow_multiple ? this.data.ui.selected : this.data.ui.last_selected; }
-				var $obj = $(obj, this.get_container()); 
-				if($obj.is(".jstree") || obj == -1) { return -1; } 
-				$obj = $obj.closest("li", this.get_container()); 
-				return $obj.length ? $obj : false; 
+				var $obj = $(obj, this.get_container());
+				if($obj.is(".jstree") || obj == -1) { return -1; }
+				$obj = $obj.closest("li", this.get_container());
+				return $obj.length ? $obj : false;
 			},
 			_ui_notify : function (n, data) {
 				if(data.selected) {
@@ -1138,7 +1138,7 @@
 					proceed = true,
 					t = this;
 				if(check) {
-					if(s.disable_selecting_children && is_multiple && 
+					if(s.disable_selecting_children && is_multiple &&
 						(
 							(obj.parentsUntil(".jstree","li").children("a.jstree-clicked").length) ||
 							(obj.children("ul").find("a.jstree-clicked:eq(0)").length)
@@ -1163,22 +1163,22 @@
 								proceed = false;
 							}
 							break;
-						case (is_selected && !is_multiple): 
+						case (is_selected && !is_multiple):
 							this.deselect_all();
 							is_selected = false;
 							proceed = true;
 							break;
-						case (!is_selected && !is_multiple): 
+						case (!is_selected && !is_multiple):
 							if(s.select_limit == -1 || s.select_limit > 0) {
 								this.deselect_all();
 								proceed = true;
 							}
 							break;
-						case (is_selected && is_multiple): 
+						case (is_selected && is_multiple):
 							this.deselect_node(obj);
 							break;
-						case (!is_selected && is_multiple): 
-							if(s.select_limit == -1 || this.data.ui.selected.length + 1 <= s.select_limit) { 
+						case (!is_selected && is_multiple):
+							if(s.select_limit == -1 || this.data.ui.selected.length + 1 <= s.select_limit) {
 								proceed = true;
 							}
 							break;
@@ -1201,11 +1201,11 @@
 					obj = this._get_node(obj);
 					if(!obj || obj === -1 || !obj.length || !obj.is(":visible")) { return; }
 					t = obj.offset().top - this.get_container().offset().top;
-					if(t < 0) { 
-						c.scrollTop = c.scrollTop + t - 1; 
+					if(t < 0) {
+						c.scrollTop = c.scrollTop + t - 1;
 					}
-					if(t + this.data.core.li_height + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0) > c.offsetHeight) { 
-						c.scrollTop = c.scrollTop + (t - c.offsetHeight + this.data.core.li_height + 1 + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0)); 
+					if(t + this.data.core.li_height + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0) > c.offsetHeight) {
+						c.scrollTop = c.scrollTop + (t - c.offsetHeight + this.data.core.li_height + 1 + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0));
 					}
 				}
 			},
@@ -1226,8 +1226,8 @@
 				else { this.select_node(obj); }
 			},
 			is_selected : function (obj) { return this.data.ui.selected.index(this._get_node(obj)) >= 0; },
-			get_selected : function (context) { 
-				return context ? $(context).find("a.jstree-clicked").parent() : this.data.ui.selected; 
+			get_selected : function (context) {
+				return context ? $(context).find("a.jstree-clicked").parent() : this.data.ui.selected;
 			},
 			deselect_all : function (context) {
 				var ret = context ? $(context).find("a.jstree-clicked").parent() : this.get_container().find("a.jstree-clicked").parent();
@@ -1243,12 +1243,12 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree CRRM plugin
  * Handles creating/renaming/removing/moving nodes by user interaction.
  */
 (function ($) {
-	$.jstree.plugin("crrm", { 
+	$.jstree.plugin("crrm", {
 		__init : function () {
 			this.get_container()
 				.bind("move_node.jstree", $.proxy(function (e, data) {
@@ -1279,7 +1279,7 @@
 					t = this.get_text(obj),
 					h1 = $("<div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
 					h2 = obj.css("position","relative").append(
-					$("<input />", { 
+					$("<input />", {
 						"value" : t,
 						"class" : "jstree-rename-input",
 						// "size" : t.length,
@@ -1318,7 +1318,7 @@
 							if(key == 13) { return false; }
 						}
 					})
-				).children(".jstree-rename-input"); 
+				).children(".jstree-rename-input");
 				this.set_text(obj, "");
 				h1.css({
 						fontFamily		: h2.css('fontFamily')		|| '',
@@ -1336,7 +1336,7 @@
 				obj = this._get_node(obj);
 				this.__rollback();
 				var f = this.__callback;
-				this._show_input(obj, function (obj, new_name, old_name) { 
+				this._show_input(obj, function (obj, new_name, old_name) {
 					f.call(this, { "obj" : obj, "new_name" : new_name, "old_name" : old_name });
 				});
 			},
@@ -1350,8 +1350,8 @@
 						pos = $(t).index();
 					if(callback) { callback.call(this, t); }
 					if(p.length && p.hasClass("jstree-closed")) { this.open_node(p, false, true); }
-					if(!skip_rename) { 
-						this._show_input(t, function (obj, new_name, old_name) { 
+					if(!skip_rename) {
+						this._show_input(t, function (obj, new_name, old_name) {
 							_this.__callback({ "obj" : obj, "name" : new_name, "parent" : p, "position" : pos });
 						});
 					}
@@ -1374,7 +1374,7 @@
 			},
 			move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
 				var s = this._get_settings().crrm.move;
-				if(!is_prepared) { 
+				if(!is_prepared) {
 					if(typeof position === "undefined") { position = s.default_position; }
 					if(position === "inside" && !s.default_position.match(/^(before|after)$/)) { position = s.default_position; }
 					return this.__call_old(true, obj, ref, position, is_copy, false, skip_check);
@@ -1400,7 +1400,7 @@
 				this.data.crrm.cp_nodes = obj;
 				this.__callback({ "obj" : obj });
 			},
-			paste : function (obj) { 
+			paste : function (obj) {
 				obj = this._get_node(obj);
 				if(!obj || !obj.length) { return false; }
 				var nodes = this.data.crrm.ct_nodes ? this.data.crrm.ct_nodes : this.data.crrm.cp_nodes;
@@ -1416,7 +1416,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree themes plugin
  * Handles loading and setting themes, as well as detecting path to themes, etc.
  */
@@ -1425,12 +1425,12 @@
 	// this variable stores the path to the themes folder - if left as false - it will be autodetected
 	$.jstree._themes = false;
 	$.jstree.plugin("themes", {
-		__init : function () { 
+		__init : function () {
 			this.get_container()
 				.bind("init.jstree", $.proxy(function () {
 						var s = this._get_settings().themes;
-						this.data.themes.dots = s.dots; 
-						this.data.themes.icons = s.icons; 
+						this.data.themes.dots = s.dots;
+						this.data.themes.icons = s.icons;
 						this.set_theme(s.theme, s.url);
 					}, this))
 				.bind("loaded.jstree", $.proxy(function () {
@@ -1441,10 +1441,10 @@
 						else { this.show_icons(); }
 					}, this));
 		},
-		defaults : { 
-			theme : "default", 
+		defaults : {
+			theme : "default",
 			url : false,
-			dots : true,
+			dots : false,
 			icons : true
 		},
 		_fn : {
@@ -1452,7 +1452,7 @@
 				if(!theme_name) { return false; }
 				if(!theme_url) { theme_url = $.jstree._themes + theme_name + '/style.css'; }
 				if($.inArray(theme_url, themes_loaded) == -1) {
-					$.vakata.css.add_sheet({ "url" : theme_url });
+					// $.vakata.css.add_sheet({ "url" : theme_url });
 					themes_loaded.push(theme_url);
 				}
 				if(this.data.themes.theme != theme_name) {
@@ -1480,10 +1480,10 @@
 	// autodetect themes path
 	$(function () {
 		if($.jstree._themes === false) {
-			$("script").each(function () { 
-				if(this.src.toString().match(/jquery\.jstree[^\/]*?\.js(\?.*)?$/)) { 
-					$.jstree._themes = this.src.toString().replace(/jquery\.jstree[^\/]*?\.js(\?.*)?$/, "") + 'themes/'; 
-					return false; 
+			$("script").each(function () {
+				if(this.src.toString().match(/jquery\.jstree[^\/]*?\.js(\?.*)?$/)) {
+					$.jstree._themes = this.src.toString().replace(/jquery\.jstree[^\/]*?\.js(\?.*)?$/, "") + 'themes/';
+					return false;
 				}
 			});
 		}
@@ -1503,7 +1503,7 @@
 	var bound = [];
 	function exec(i, event) {
 		var f = $.jstree._focused(), tmp;
-		if(f && f.data && f.data.hotkeys && f.data.hotkeys.enabled) { 
+		if(f && f.data && f.data.hotkeys && f.data.hotkeys.enabled) {
 			tmp = f._get_settings().hotkeys[i];
 			if(tmp) { return tmp.call(f, event); }
 		}
@@ -1528,37 +1528,37 @@
 			this.enable_hotkeys();
 		},
 		defaults : {
-			"up" : function () { 
+			"up" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_prev(o));
-				return false; 
+				return false;
 			},
-			"ctrl+up" : function () { 
+			"ctrl+up" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_prev(o));
-				return false; 
+				return false;
 			},
-			"shift+up" : function () { 
+			"shift+up" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_prev(o));
-				return false; 
+				return false;
 			},
-			"down" : function () { 
+			"down" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_next(o));
 				return false;
 			},
-			"ctrl+down" : function () { 
+			"ctrl+down" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_next(o));
 				return false;
 			},
-			"shift+down" : function () { 
+			"shift+down" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
 				this.hover_node(this._get_next(o));
 				return false;
 			},
-			"left" : function () { 
+			"left" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o) {
 					if(o.hasClass("jstree-open")) { this.close_node(o); }
@@ -1566,7 +1566,7 @@
 				}
 				return false;
 			},
-			"ctrl+left" : function () { 
+			"ctrl+left" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o) {
 					if(o.hasClass("jstree-open")) { this.close_node(o); }
@@ -1574,7 +1574,7 @@
 				}
 				return false;
 			},
-			"shift+left" : function () { 
+			"shift+left" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o) {
 					if(o.hasClass("jstree-open")) { this.close_node(o); }
@@ -1582,7 +1582,7 @@
 				}
 				return false;
 			},
-			"right" : function () { 
+			"right" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o && o.length) {
 					if(o.hasClass("jstree-closed")) { this.open_node(o); }
@@ -1590,7 +1590,7 @@
 				}
 				return false;
 			},
-			"ctrl+right" : function () { 
+			"ctrl+right" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o && o.length) {
 					if(o.hasClass("jstree-closed")) { this.open_node(o); }
@@ -1598,7 +1598,7 @@
 				}
 				return false;
 			},
-			"shift+right" : function () { 
+			"shift+right" : function () {
 				var o = this.data.ui.hovered || this.data.ui.last_selected;
 				if(o && o.length) {
 					if(o.hasClass("jstree-closed")) { this.open_node(o); }
@@ -1606,19 +1606,19 @@
 				}
 				return false;
 			},
-			"space" : function () { 
-				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click(); } 
-				return false; 
+			"space" : function () {
+				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click(); }
+				return false;
 			},
-			"ctrl+space" : function (event) { 
+			"ctrl+space" : function (event) {
 				event.type = "click";
-				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); } 
-				return false; 
+				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
+				return false;
 			},
-			"shift+space" : function (event) { 
+			"shift+space" : function (event) {
 				event.type = "click";
-				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); } 
-				return false; 
+				if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
+				return false;
 			},
 			"f2" : function () { this.rename(this.data.ui.hovered || this.data.ui.last_selected); },
 			"del" : function () { this.remove(this.data.ui.hovered || this._get_node(null)); }
@@ -1635,7 +1635,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree JSON plugin
  * The JSON data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
  */
@@ -1649,11 +1649,11 @@
 				});
 			}
 		},
-		defaults : { 
+		defaults : {
 			// `data` can be a function:
 			//  * accepts two arguments - node being loaded and a callback to pass the result to
 			//  * will be executed in the current tree's scope & ajax won't be supported
-			data : false, 
+			data : false,
 			ajax : false,
 			correct_state : true,
 			progressive_render : false,
@@ -1661,9 +1661,9 @@
 		},
 		_fn : {
 			load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_json(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
-			_is_loaded : function (obj) { 
+			_is_loaded : function (obj) {
 				var s = this._get_settings().json_data;
-				obj = this._get_node(obj); 
+				obj = this._get_node(obj);
 				return obj == -1 || !obj || (!s.ajax && !s.progressive_render && !$.isFunction(s.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").length > 0;
 			},
 			refresh : function (obj) {
@@ -1701,7 +1701,7 @@
 					case ($.isFunction(s.data)):
 						s.data.call(this, obj, $.proxy(function (d) {
 							d = this._parse_json(d, obj);
-							if(!d) { 
+							if(!d) {
 								if(obj === -1 || !obj) {
 									if(s.correct_state) { this.get_container().children("ul").empty(); }
 								}
@@ -1727,7 +1727,7 @@
 								this.get_container().children("ul").empty().append(d.children());
 								this.clean_node();
 							}
-							else { 
+							else {
 								if(s.correct_state) { this.get_container().children("ul").empty(); }
 							}
 						}
@@ -1735,7 +1735,7 @@
 						break;
 					case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
 						error_func = function (x, t, e) {
-							var ef = this.get_settings().json_data.ajax.error; 
+							var ef = this.get_settings().json_data.ajax.error;
 							if(ef) { ef.call(this, x, t, e); }
 							if(obj != -1 && obj.length) {
 								obj.children("a.jstree-loading").removeClass("jstree-loading");
@@ -1748,7 +1748,7 @@
 							if(e_call) { e_call.call(this); }
 						};
 						success_func = function (d, t, x) {
-							var sf = this.get_settings().json_data.ajax.success; 
+							var sf = this.get_settings().json_data.ajax.success;
 							if(sf) { d = sf.call(this,d,t,x) || d; }
 							if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "") || (!$.isArray(d) && !$.isPlainObject(d))) {
 								return error_func.call(this, x, t, "");
@@ -1762,17 +1762,17 @@
 							}
 							else {
 								if(obj === -1 || !obj) {
-									if(s.correct_state) { 
-										this.get_container().children("ul").empty(); 
+									if(s.correct_state) {
+										this.get_container().children("ul").empty();
 										if(s_call) { s_call.call(this); }
 									}
 								}
 								else {
 									obj.children("a.jstree-loading").removeClass("jstree-loading");
 									obj.removeData("jstree_is_loading");
-									if(s.correct_state) { 
+									if(s.correct_state) {
 										this.correct_state(obj);
-										if(s_call) { s_call.call(this); } 
+										if(s_call) { s_call.call(this); }
 									}
 								}
 							}
@@ -1788,14 +1788,14 @@
 				}
 			},
 			_parse_json : function (js, obj, is_callback) {
-				var d = false, 
+				var d = false,
 					p = this._get_settings(),
 					s = p.json_data,
 					t = p.core.html_titles,
 					tmp, i, j, ul1, ul2;
 
 				if(!js) { return d; }
-				if(s.progressive_unload && obj && obj !== -1) { 
+				if(s.progressive_unload && obj && obj !== -1) {
 					obj.data("jstree_children", d);
 				}
 				if($.isArray(js)) {
@@ -1826,14 +1826,14 @@
 						}
 						tmp.prepend("<ins class='jstree-icon'>&#160;</ins>");
 						if(!m.icon && js.icon) { m.icon = js.icon; }
-						if(m.icon) { 
+						if(m.icon) {
 							if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
 							else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); }
 						}
 						d.append(tmp);
 					});
 					d.prepend("<ins class='jstree-icon'>&#160;</ins>");
-					if(js.children) { 
+					if(js.children) {
 						if(s.progressive_render && js.state !== "open") {
 							d.addClass("jstree-closed").data("jstree_children", js.children);
 						}
@@ -1858,8 +1858,8 @@
 				return d;
 			},
 			get_json : function (obj, li_attr, a_attr, is_callback) {
-				var result = [], 
-					s = this._get_settings(), 
+				var result = [],
+					s = this._get_settings(),
 					_this = this,
 					tmp1, tmp2, li, a, t, lang;
 				obj = this._get_node(obj);
@@ -1872,10 +1872,10 @@
 					li = $(this);
 					tmp1 = { data : [] };
 					if(li_attr.length) { tmp1.attr = { }; }
-					$.each(li_attr, function (i, v) { 
-						tmp2 = li.attr(v); 
+					$.each(li_attr, function (i, v) {
+						tmp2 = li.attr(v);
 						if(tmp2 && tmp2.length && tmp2.replace(/jstree[^ ]*/ig,'').length) {
-							tmp1.attr[v] = (" " + tmp2).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,""); 
+							tmp1.attr[v] = (" " + tmp2).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
 						}
 					});
 					if(li.hasClass("jstree-open")) { tmp1.state = "open"; }
@@ -1885,11 +1885,11 @@
 					a.each(function () {
 						t = $(this);
 						if(
-							a_attr.length || 
-							$.inArray("languages", s.plugins) !== -1 || 
-							t.children("ins").get(0).style.backgroundImage.length || 
+							a_attr.length ||
+							$.inArray("languages", s.plugins) !== -1 ||
+							t.children("ins").get(0).style.backgroundImage.length ||
 							(t.children("ins").get(0).className && t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').length)
-						) { 
+						) {
 							lang = false;
 							if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) {
 								$.each(s.languages, function (l, lv) {
@@ -1899,7 +1899,7 @@
 									}
 								});
 							}
-							tmp2 = { attr : { }, title : _this.get_text(t, lang) }; 
+							tmp2 = { attr : { }, title : _this.get_text(t, lang) };
 							$.each(a_attr, function (k, z) {
 								tmp2.attr[z] = (" " + (t.attr(z) || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
 							});
@@ -1932,7 +1932,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree languages plugin
  * Adds support for multiple language versions in one tree
  * This basically allows for many titles coexisting in one node, but only one of them being visible at any given time
@@ -1943,7 +1943,7 @@
 		__init : function () { this._load_css();  },
 		defaults : [],
 		_fn : {
-			set_lang : function (i) { 
+			set_lang : function (i) {
 				var langs = this._get_settings().languages,
 					st = false,
 					selector = ".jstree-" + this.get_index() + ' a';
@@ -2081,7 +2081,7 @@
 			this.get_container()
 				.one( ( this.data.ui ? "reselect" : "reopen" ) + ".jstree", $.proxy(function () {
 					this.get_container()
-						.bind("open_node.jstree close_node.jstree select_node.jstree deselect_node.jstree", $.proxy(function (e) { 
+						.bind("open_node.jstree close_node.jstree select_node.jstree deselect_node.jstree", $.proxy(function (e) {
 								if(this._get_settings().cookies.auto_save) { this.save_cookie((e.handleObj.namespace + e.handleObj.type).replace("jstree","")); }
 							}, this));
 				}, this));
@@ -2115,20 +2115,20 @@
 				switch(c) {
 					case "open_node":
 					case "close_node":
-						if(!!s.save_opened) { 
-							this.save_opened(); 
-							$.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options); 
+						if(!!s.save_opened) {
+							this.save_opened();
+							$.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options);
 						}
-						if(!!s.save_loaded) { 
-							this.save_loaded(); 
-							$.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options); 
+						if(!!s.save_loaded) {
+							this.save_loaded();
+							$.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options);
 						}
 						break;
 					case "select_node":
 					case "deselect_node":
-						if(!!s.save_selected && this.data.ui) { 
-							this.save_selected(); 
-							$.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options); 
+						if(!!s.save_selected && this.data.ui) {
+							this.save_selected();
+							$.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options);
 						}
 						break;
 				}
@@ -2201,7 +2201,7 @@
 		helper_top : 10,
 		user_data : {},
 
-		drag_start : function (e, data, html) { 
+		drag_start : function (e, data, html) {
 			if($.vakata.dnd.is_drag) { $.vakata.drag_stop({}); }
 			try {
 				e.currentTarget.unselectable = "on";
@@ -2217,10 +2217,10 @@
 			$(document).bind("mouseup", $.vakata.dnd.drag_stop);
 			return false;
 		},
-		drag : function (e) { 
+		drag : function (e) {
 			if(!$.vakata.dnd.is_down) { return; }
 			if(!$.vakata.dnd.is_drag) {
-				if(Math.abs(e.pageX - $.vakata.dnd.init_x) > 5 || Math.abs(e.pageY - $.vakata.dnd.init_y) > 5) { 
+				if(Math.abs(e.pageX - $.vakata.dnd.init_x) > 5 || Math.abs(e.pageY - $.vakata.dnd.init_y) > 5) {
 					$.vakata.dnd.helper.appendTo("body");
 					$.vakata.dnd.is_drag = true;
 					$(document).triggerHandler("drag_start.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
@@ -2231,18 +2231,18 @@
 			// maybe use a scrolling parent element instead of document?
 			if(e.type === "mousemove") { // thought of adding scroll in order to move the helper, but mouse poisition is n/a
 				var d = $(document), t = d.scrollTop(), l = d.scrollLeft();
-				if(e.pageY - t < 20) { 
+				if(e.pageY - t < 20) {
 					if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
 					if(!sti) { dir1 = "up"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() - $.vakata.dnd.scroll_spd); }, 150); }
 				}
-				else { 
+				else {
 					if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
 				}
 				if($(window).height() - (e.pageY - t) < 20) {
 					if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
 					if(!sti) { dir1 = "down"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() + $.vakata.dnd.scroll_spd); }, 150); }
 				}
-				else { 
+				else {
 					if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
 				}
 
@@ -2250,14 +2250,14 @@
 					if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
 					if(!sli) { dir2 = "left"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() - $.vakata.dnd.scroll_spd); }, 150); }
 				}
-				else { 
+				else {
 					if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
 				}
 				if($(window).width() - (e.pageX - l) < 20) {
 					if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
 					if(!sli) { dir2 = "right"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() + $.vakata.dnd.scroll_spd); }, 150); }
 				}
-				else { 
+				else {
 					if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
 				}
 			}
@@ -2307,7 +2307,7 @@
 				.bind("mouseenter.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							if(this.data.themes) {
-								m.attr("class", "jstree-" + this.data.themes.theme); 
+								m.attr("class", "jstree-" + this.data.themes.theme);
 								if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
 								$.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
 							}
@@ -2346,7 +2346,7 @@
 					}, this))
 				.bind("mouseleave.jstree", $.proxy(function (e) {
 						if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
-							return false; 
+							return false;
 						}
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
@@ -2390,24 +2390,24 @@
 
 						}
 					}, this))
-				.bind("scroll.jstree", $.proxy(function (e) { 
+				.bind("scroll.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && m && ml) {
 							m.hide();
 							ml.hide();
 						}
 					}, this))
-				.delegate("a", "mousedown.jstree", $.proxy(function (e) { 
+				.delegate("a", "mousedown.jstree", $.proxy(function (e) {
 						if(e.which === 1) {
 							this.start_drag(e.currentTarget, e);
 							return false;
 						}
 					}, this))
-				.delegate("a", "mouseenter.jstree", $.proxy(function (e) { 
+				.delegate("a", "mouseenter.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							this.dnd_enter(e.currentTarget);
 						}
 					}, this))
-				.delegate("a", "mousemove.jstree", $.proxy(function (e) { 
+				.delegate("a", "mousemove.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							if(!r || !r.length || r.children("a")[0] !== e.currentTarget) {
 								this.dnd_enter(e.currentTarget);
@@ -2418,27 +2418,27 @@
 							this.dnd_show();
 						}
 					}, this))
-				.delegate("a", "mouseleave.jstree", $.proxy(function (e) { 
+				.delegate("a", "mouseleave.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
-								return false; 
+								return false;
 							}
 								if(m) { m.hide(); }
 								if(ml) { ml.hide(); }
 							/*
-							var ec = $(e.currentTarget).closest("li"), 
+							var ec = $(e.currentTarget).closest("li"),
 								er = $(e.relatedTarget).closest("li");
 							if(er[0] !== ec.prev()[0] && er[0] !== ec.next()[0]) {
 								if(m) { m.hide(); }
 								if(ml) { ml.hide(); }
 							}
 							*/
-							this.data.dnd.mto = setTimeout( 
+							this.data.dnd.mto = setTimeout(
 								(function (t) { return function () { t.dnd_leave(e); }; })(this),
 							0);
 						}
 					}, this))
-				.delegate("a", "mouseup.jstree", $.proxy(function (e) { 
+				.delegate("a", "mouseup.jstree", $.proxy(function (e) {
 						if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
 							this.dnd_finish(e);
 						}
@@ -2466,7 +2466,7 @@
 						if(ml) { ml.css({ "top" : "-2000px" }); }
 					}, this))
 				.bind("drag_start.vakata", $.proxy(function (e, data) {
-						if(data.data.jstree) { 
+						if(data.data.jstree) {
 							var et = $(data.event.target);
 							if(et.closest(".jstree").hasClass("jstree-" + this.get_index())) {
 								this.dnd_enter(et);
@@ -2479,7 +2479,7 @@
 							var h = $.vakata.dnd.helper.children("ins");
 							if(e[this._get_settings().dnd.copy_modifier + "Key"] && h.hasClass("jstree-ok")) {
 								h.parent().html(h.parent().html().replace(/ \(Copy\)$/, "") + " (Copy)");
-							} 
+							}
 							else {
 								h.parent().html(h.parent().html().replace(/ \(Copy\)$/, ""));
 							}
@@ -2494,10 +2494,10 @@
 					.delegate(s.drag_target, "mousedown.jstree-" + this.get_index(), $.proxy(function (e) {
 						o = e.target;
 						$.vakata.dnd.drag_start(e, { jstree : true, obj : e.target }, "<ins class='jstree-icon'></ins>" + $(e.target).text() );
-						if(this.data.themes) { 
+						if(this.data.themes) {
 							if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
 							if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
-							$.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme); 
+							$.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
 						}
 						$.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
 						var cnt = this.get_container();
@@ -2578,7 +2578,7 @@
 					o = this.data.dnd.w < this.data.core.li_height/2 ? ["inside","before","after"] : ["inside","after","before"];
 				}
 				else { o = ["after","inside","before"]; }
-				$.each(o, $.proxy(function (i, val) { 
+				$.each(o, $.proxy(function (i, val) {
 					if(this.data.dnd[val]) {
 						$.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
 						r = val;
@@ -2586,7 +2586,7 @@
 					}
 				}, this));
 				if(r === false) { $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); }
-				
+
 				pos = rtl ? (this.data.dnd.off.right - 18) : (this.data.dnd.off.left + 10);
 				switch(r) {
 					case "before":
@@ -2629,30 +2629,30 @@
 				if(ml) { ml.hide(); }
 			},
 			dnd_enter : function (obj) {
-				if(this.data.dnd.mto) { 
+				if(this.data.dnd.mto) {
 					clearTimeout(this.data.dnd.mto);
 					this.data.dnd.mto = false;
 				}
 				var s = this._get_settings().dnd;
 				this.data.dnd.prepared = false;
 				r = this._get_node(obj);
-				if(s.check_timeout) { 
+				if(s.check_timeout) {
 					// do the calculations after a minimal timeout (users tend to drag quickly to the desired location)
 					if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
-					this.data.dnd.to1 = setTimeout($.proxy(this.dnd_prepare, this), s.check_timeout); 
+					this.data.dnd.to1 = setTimeout($.proxy(this.dnd_prepare, this), s.check_timeout);
 				}
-				else { 
-					this.dnd_prepare(); 
+				else {
+					this.dnd_prepare();
 				}
-				if(s.open_timeout) { 
+				if(s.open_timeout) {
 					if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
-					if(r && r.length && r.hasClass("jstree-closed")) { 
+					if(r && r.length && r.hasClass("jstree-closed")) {
 						// if the node is closed - open it, then recalculate
 						this.data.dnd.to2 = setTimeout($.proxy(this.dnd_open, this), s.open_timeout);
 					}
 				}
 				else {
-					if(r && r.length && r.hasClass("jstree-closed")) { 
+					if(r && r.length && r.hasClass("jstree-closed")) {
 						this.dnd_open();
 					}
 				}
@@ -2682,10 +2682,10 @@
 					cnt = this.get_container();
 				if(!this._get_settings().core.html_titles) { dt = dt.replace(/</ig,"&lt;").replace(/>/ig,"&gt;"); }
 				$.vakata.dnd.drag_start(e, { jstree : true, obj : o }, "<ins class='jstree-icon'></ins>" + dt );
-				if(this.data.themes) { 
+				if(this.data.themes) {
 					if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
 					if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
-					$.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme); 
+					$.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
 				}
 				this.data.dnd.cof = cnt.offset();
 				this.data.dnd.cw = parseInt(cnt.width(),10);
@@ -2695,47 +2695,47 @@
 		}
 	});
 	$(function() {
-		var css_string = '' + 
-			'#vakata-dragged ins { display:block; text-decoration:none; width:16px; height:16px; margin:0 0 0 0; padding:0; position:absolute; top:4px; left:4px; ' + 
+		var css_string = '' +
+			'#vakata-dragged ins { display:block; text-decoration:none; width:16px; height:16px; margin:0 0 0 0; padding:0; position:absolute; top:4px; left:4px; ' +
 			' -moz-border-radius:4px; border-radius:4px; -webkit-border-radius:4px; ' +
-			'} ' + 
-			'#vakata-dragged .jstree-ok { background:green; } ' + 
-			'#vakata-dragged .jstree-invalid { background:red; } ' + 
-			'#jstree-marker { padding:0; margin:0; font-size:12px; overflow:hidden; height:12px; width:8px; position:absolute; top:-30px; z-index:10001; background-repeat:no-repeat; display:none; background-color:transparent; text-shadow:1px 1px 1px white; color:black; line-height:10px; } ' + 
-			'#jstree-marker-line { padding:0; margin:0; line-height:0%; font-size:1px; overflow:hidden; height:1px; width:100px; position:absolute; top:-30px; z-index:10000; background-repeat:no-repeat; display:none; background-color:#456c43; ' + 
-			' cursor:pointer; border:1px solid #eeeeee; border-left:0; -moz-box-shadow: 0px 0px 2px #666; -webkit-box-shadow: 0px 0px 2px #666; box-shadow: 0px 0px 2px #666; ' + 
+			'} ' +
+			'#vakata-dragged .jstree-ok { background:green; } ' +
+			'#vakata-dragged .jstree-invalid { background:red; } ' +
+			'#jstree-marker { padding:0; margin:0; font-size:12px; overflow:hidden; height:12px; width:8px; position:absolute; top:-30px; z-index:10001; background-repeat:no-repeat; display:none; background-color:transparent; text-shadow:1px 1px 1px white; color:black; line-height:10px; } ' +
+			'#jstree-marker-line { padding:0; margin:0; line-height:0%; font-size:1px; overflow:hidden; height:1px; width:100px; position:absolute; top:-30px; z-index:10000; background-repeat:no-repeat; display:none; background-color:#456c43; ' +
+			' cursor:pointer; border:1px solid #eeeeee; border-left:0; -moz-box-shadow: 0px 0px 2px #666; -webkit-box-shadow: 0px 0px 2px #666; box-shadow: 0px 0px 2px #666; ' +
 			' -moz-border-radius:1px; border-radius:1px; -webkit-border-radius:1px; ' +
-			'}' + 
+			'}' +
 			'';
 		$.vakata.css.add_sheet({ str : css_string, title : "jstree" });
 		m = $("<div />").attr({ id : "jstree-marker" }).hide().html("&raquo;")
-			.bind("mouseleave mouseenter", function (e) { 
+			.bind("mouseleave mouseenter", function (e) {
 				m.hide();
 				ml.hide();
-				e.preventDefault(); 
-				e.stopImmediatePropagation(); 
-				return false; 
+				e.preventDefault();
+				e.stopImmediatePropagation();
+				return false;
 			})
 			.appendTo("body");
 		ml = $("<div />").attr({ id : "jstree-marker-line" }).hide()
-			.bind("mouseup", function (e) { 
-				if(r && r.length) { 
-					r.children("a").trigger(e); 
-					e.preventDefault(); 
-					e.stopImmediatePropagation(); 
-					return false; 
-				} 
+			.bind("mouseup", function (e) {
+				if(r && r.length) {
+					r.children("a").trigger(e);
+					e.preventDefault();
+					e.stopImmediatePropagation();
+					return false;
+				}
 			})
-			.bind("mouseleave", function (e) { 
+			.bind("mouseleave", function (e) {
 				var rt = $(e.relatedTarget);
 				if(rt.is(".jstree") || rt.closest(".jstree").length === 0) {
-					if(r && r.length) { 
-						r.children("a").trigger(e); 
+					if(r && r.length) {
+						r.children("a").trigger(e);
 						m.hide();
 						ml.hide();
-						e.preventDefault(); 
-						e.stopImmediatePropagation(); 
-						return false; 
+						e.preventDefault();
+						e.stopImmediatePropagation();
+						return false;
 					}
 				}
 			})
@@ -2766,7 +2766,7 @@
 			}
 
 			this.get_container()
-				.bind("open_node.jstree create_node.jstree clean_node.jstree refresh.jstree", $.proxy(function (e, data) { 
+				.bind("open_node.jstree create_node.jstree clean_node.jstree refresh.jstree", $.proxy(function (e, data) {
 						this._prepare_checkboxes(data.rslt.obj);
 					}, this))
 				.bind("loaded.jstree", $.proxy(function (e) {
@@ -2836,7 +2836,7 @@
 					});
 				});
 				if(!ts) {
-					obj.find(".jstree-checked").parent().parent().each(function () { _this._repair_state(this); }); 
+					obj.find(".jstree-checked").parent().parent().each(function () { _this._repair_state(this); });
 				}
 			},
 			change_state : function (obj, state) {
@@ -2845,26 +2845,26 @@
 				if(!obj || obj === -1) { return false; }
 				state = (state === false || state === true) ? state : obj.hasClass("jstree-checked");
 				if(this._get_settings().checkbox.two_state) {
-					if(state) { 
-						obj.removeClass("jstree-checked").addClass("jstree-unchecked"); 
+					if(state) {
+						obj.removeClass("jstree-checked").addClass("jstree-unchecked");
 						if(rc) { obj.children(":checkbox").prop("checked", false); }
 					}
-					else { 
-						obj.removeClass("jstree-unchecked").addClass("jstree-checked"); 
+					else {
+						obj.removeClass("jstree-unchecked").addClass("jstree-checked");
 						if(rc) { obj.children(":checkbox").prop("checked", true); }
 					}
 				}
 				else {
-					if(state) { 
+					if(state) {
 						coll = obj.find("li").addBack();
 						if(!coll.filter(".jstree-checked, .jstree-undetermined").length) { return false; }
-						coll.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked"); 
+						coll.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked");
 						if(rc) { coll.children(":checkbox").prop("checked", false); }
 					}
-					else { 
+					else {
 						coll = obj.find("li").addBack();
 						if(!coll.filter(".jstree-unchecked, .jstree-undetermined").length) { return false; }
-						coll.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked"); 
+						coll.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked");
 						if(rc) { coll.children(":checkbox").prop("checked", true); }
 						if(this.data.ui) { this.data.ui.last_selected = obj; }
 						this.data.checkbox.last_selected = obj;
@@ -2900,20 +2900,20 @@
 				return true;
 			},
 			check_node : function (obj) {
-				if(this.change_state(obj, false)) { 
+				if(this.change_state(obj, false)) {
 					obj = this._get_node(obj);
 					if(this._get_settings().checkbox.checked_parent_open) {
 						var t = this;
 						obj.parents(".jstree-closed").each(function () { t.open_node(this, false, true); });
 					}
-					this.__callback({ "obj" : obj }); 
+					this.__callback({ "obj" : obj });
 				}
 			},
 			uncheck_node : function (obj) {
 				if(this.change_state(obj, true)) { this.__callback({ "obj" : this._get_node(obj) }); }
 			},
 			check_all : function () {
-				var _this = this, 
+				var _this = this,
 					coll = this._get_settings().checkbox.two_state ? this.get_container_ul().find("li") : this.get_container_ul().children("li");
 				coll.each(function () {
 					_this.change_state(this, false);
@@ -2937,7 +2937,7 @@
 				obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
 				return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-checked") : obj.find("> ul > .jstree-checked, .jstree-undetermined > ul > .jstree-checked");
 			},
-			get_unchecked : function (obj, get_all) { 
+			get_unchecked : function (obj, get_all) {
 				obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
 				return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-unchecked") : obj.find("> ul > .jstree-unchecked, .jstree-undetermined > ul > .jstree-unchecked");
 			},
@@ -2959,13 +2959,13 @@
 				if(c === 0) { if(obj.hasClass("jstree-undetermined")) { this.change_state(obj, false); } }
 				else if(a === 0 && b === 0) { this.change_state(obj, true); }
 				else if(a === c) { this.change_state(obj, false); }
-				else { 
+				else {
 					obj.parentsUntil(".jstree","li").addBack().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
 					if(rc) { obj.parentsUntil(".jstree", "li").addBack().children(":checkbox").prop("checked", false); }
 				}
 			},
 			reselect : function () {
-				if(this.data.ui && this.data.checkbox.noui) { 
+				if(this.data.ui && this.data.checkbox.noui) {
 					var _this = this,
 						s = this.data.ui.to_select;
 					s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
@@ -2973,8 +2973,8 @@
 					$.each(s, function (i, val) { _this.check_node(val); });
 					this.__callback();
 				}
-				else { 
-					this.__call_old(); 
+				else {
+					this.__call_old();
 				}
 			},
 			save_loaded : function () {
@@ -2993,7 +2993,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree XML plugin
  * The XML data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
  */
@@ -3020,7 +3020,7 @@
 			xsl = new DOMParser().parseFromString(xsl, "text/xml");
 			// alert(xml.transformNode());
 			// callback.call(null, new XMLSerializer().serializeToString(rs));
-			
+
 		}
 		if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor !== "undefined") {
 			processor = new XSLTProcessor();
@@ -3044,137 +3044,137 @@
 		return false;
 	};
 	var xsl = {
-		'nest' : '<' + '?xml version="1.0" encoding="utf-8" ?>' + 
-			'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' + 
-			'<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/html" />' + 
-			'<xsl:template match="/">' + 
-			'	<xsl:call-template name="nodes">' + 
-			'		<xsl:with-param name="node" select="/root" />' + 
-			'	</xsl:call-template>' + 
-			'</xsl:template>' + 
-			'<xsl:template name="nodes">' + 
-			'	<xsl:param name="node" />' + 
-			'	<ul>' + 
-			'	<xsl:for-each select="$node/item">' + 
-			'		<xsl:variable name="children" select="count(./item) &gt; 0" />' + 
-			'		<li>' + 
-			'			<xsl:attribute name="class">' + 
-			'				<xsl:if test="position() = last()">jstree-last </xsl:if>' + 
-			'				<xsl:choose>' + 
-			'					<xsl:when test="@state = \'open\'">jstree-open </xsl:when>' + 
-			'					<xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' + 
-			'					<xsl:otherwise>jstree-leaf </xsl:otherwise>' + 
-			'				</xsl:choose>' + 
-			'				<xsl:value-of select="@class" />' + 
-			'			</xsl:attribute>' + 
-			'			<xsl:for-each select="@*">' + 
-			'				<xsl:if test="name() != \'class\' and name() != \'state\' and name() != \'hasChildren\'">' + 
-			'					<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 
-			'				</xsl:if>' + 
-			'			</xsl:for-each>' + 
-			'	<ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' + 
-			'			<xsl:for-each select="content/name">' + 
-			'				<a>' + 
-			'				<xsl:attribute name="href">' + 
-			'					<xsl:choose>' + 
-			'					<xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' + 
-			'					<xsl:otherwise>#</xsl:otherwise>' + 
-			'					</xsl:choose>' + 
-			'				</xsl:attribute>' + 
-			'				<xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' + 
-			'				<xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' + 
-			'				<xsl:for-each select="@*">' + 
-			'					<xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' + 
-			'						<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 
-			'					</xsl:if>' + 
-			'				</xsl:for-each>' + 
-			'					<ins>' + 
-			'						<xsl:attribute name="class">jstree-icon ' + 
-			'							<xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' + 
-			'						</xsl:attribute>' + 
-			'						<xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' + 
-			'						<xsl:text>&#xa0;</xsl:text>' + 
-			'					</ins>' + 
-			'					<xsl:copy-of select="./child::node()" />' + 
-			'				</a>' + 
-			'			</xsl:for-each>' + 
-			'			<xsl:if test="$children or @hasChildren"><xsl:call-template name="nodes"><xsl:with-param name="node" select="current()" /></xsl:call-template></xsl:if>' + 
-			'		</li>' + 
-			'	</xsl:for-each>' + 
-			'	</ul>' + 
-			'</xsl:template>' + 
+		'nest' : '<' + '?xml version="1.0" encoding="utf-8" ?>' +
+			'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' +
+			'<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/html" />' +
+			'<xsl:template match="/">' +
+			'	<xsl:call-template name="nodes">' +
+			'		<xsl:with-param name="node" select="/root" />' +
+			'	</xsl:call-template>' +
+			'</xsl:template>' +
+			'<xsl:template name="nodes">' +
+			'	<xsl:param name="node" />' +
+			'	<ul>' +
+			'	<xsl:for-each select="$node/item">' +
+			'		<xsl:variable name="children" select="count(./item) &gt; 0" />' +
+			'		<li>' +
+			'			<xsl:attribute name="class">' +
+			'				<xsl:if test="position() = last()">jstree-last </xsl:if>' +
+			'				<xsl:choose>' +
+			'					<xsl:when test="@state = \'open\'">jstree-open </xsl:when>' +
+			'					<xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' +
+			'					<xsl:otherwise>jstree-leaf </xsl:otherwise>' +
+			'				</xsl:choose>' +
+			'				<xsl:value-of select="@class" />' +
+			'			</xsl:attribute>' +
+			'			<xsl:for-each select="@*">' +
+			'				<xsl:if test="name() != \'class\' and name() != \'state\' and name() != \'hasChildren\'">' +
+			'					<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+			'				</xsl:if>' +
+			'			</xsl:for-each>' +
+			'	<ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' +
+			'			<xsl:for-each select="content/name">' +
+			'				<a>' +
+			'				<xsl:attribute name="href">' +
+			'					<xsl:choose>' +
+			'					<xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' +
+			'					<xsl:otherwise>#</xsl:otherwise>' +
+			'					</xsl:choose>' +
+			'				</xsl:attribute>' +
+			'				<xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' +
+			'				<xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' +
+			'				<xsl:for-each select="@*">' +
+			'					<xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' +
+			'						<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+			'					</xsl:if>' +
+			'				</xsl:for-each>' +
+			'					<ins>' +
+			'						<xsl:attribute name="class">jstree-icon ' +
+			'							<xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' +
+			'						</xsl:attribute>' +
+			'						<xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' +
+			'						<xsl:text>&#xa0;</xsl:text>' +
+			'					</ins>' +
+			'					<xsl:copy-of select="./child::node()" />' +
+			'				</a>' +
+			'			</xsl:for-each>' +
+			'			<xsl:if test="$children or @hasChildren"><xsl:call-template name="nodes"><xsl:with-param name="node" select="current()" /></xsl:call-template></xsl:if>' +
+			'		</li>' +
+			'	</xsl:for-each>' +
+			'	</ul>' +
+			'</xsl:template>' +
 			'</xsl:stylesheet>',
 
-		'flat' : '<' + '?xml version="1.0" encoding="utf-8" ?>' + 
-			'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' + 
-			'<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/xml" />' + 
-			'<xsl:template match="/">' + 
-			'	<ul>' + 
+		'flat' : '<' + '?xml version="1.0" encoding="utf-8" ?>' +
+			'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' +
+			'<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/xml" />' +
+			'<xsl:template match="/">' +
+			'	<ul>' +
 			'	<xsl:for-each select="//item[not(@parent_id) or @parent_id=0 or not(@parent_id = //item/@id)]">' + /* the last `or` may be removed */
-			'		<xsl:call-template name="nodes">' + 
-			'			<xsl:with-param name="node" select="." />' + 
-			'			<xsl:with-param name="is_last" select="number(position() = last())" />' + 
-			'		</xsl:call-template>' + 
-			'	</xsl:for-each>' + 
-			'	</ul>' + 
-			'</xsl:template>' + 
-			'<xsl:template name="nodes">' + 
-			'	<xsl:param name="node" />' + 
-			'	<xsl:param name="is_last" />' + 
-			'	<xsl:variable name="children" select="count(//item[@parent_id=$node/attribute::id]) &gt; 0" />' + 
-			'	<li>' + 
-			'	<xsl:attribute name="class">' + 
-			'		<xsl:if test="$is_last = true()">jstree-last </xsl:if>' + 
-			'		<xsl:choose>' + 
-			'			<xsl:when test="@state = \'open\'">jstree-open </xsl:when>' + 
-			'			<xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' + 
-			'			<xsl:otherwise>jstree-leaf </xsl:otherwise>' + 
-			'		</xsl:choose>' + 
-			'		<xsl:value-of select="@class" />' + 
-			'	</xsl:attribute>' + 
-			'	<xsl:for-each select="@*">' + 
-			'		<xsl:if test="name() != \'parent_id\' and name() != \'hasChildren\' and name() != \'class\' and name() != \'state\'">' + 
-			'		<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 
-			'		</xsl:if>' + 
-			'	</xsl:for-each>' + 
-			'	<ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' + 
-			'	<xsl:for-each select="content/name">' + 
-			'		<a>' + 
-			'		<xsl:attribute name="href">' + 
-			'			<xsl:choose>' + 
-			'			<xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' + 
-			'			<xsl:otherwise>#</xsl:otherwise>' + 
-			'			</xsl:choose>' + 
-			'		</xsl:attribute>' + 
-			'		<xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' + 
-			'		<xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' + 
-			'		<xsl:for-each select="@*">' + 
-			'			<xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' + 
-			'				<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 
-			'			</xsl:if>' + 
-			'		</xsl:for-each>' + 
-			'			<ins>' + 
-			'				<xsl:attribute name="class">jstree-icon ' + 
-			'					<xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' + 
-			'				</xsl:attribute>' + 
-			'				<xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' + 
-			'				<xsl:text>&#xa0;</xsl:text>' + 
-			'			</ins>' + 
-			'			<xsl:copy-of select="./child::node()" />' + 
-			'		</a>' + 
-			'	</xsl:for-each>' + 
-			'	<xsl:if test="$children">' + 
-			'		<ul>' + 
-			'		<xsl:for-each select="//item[@parent_id=$node/attribute::id]">' + 
-			'			<xsl:call-template name="nodes">' + 
-			'				<xsl:with-param name="node" select="." />' + 
-			'				<xsl:with-param name="is_last" select="number(position() = last())" />' + 
-			'			</xsl:call-template>' + 
-			'		</xsl:for-each>' + 
-			'		</ul>' + 
-			'	</xsl:if>' + 
-			'	</li>' + 
-			'</xsl:template>' + 
+			'		<xsl:call-template name="nodes">' +
+			'			<xsl:with-param name="node" select="." />' +
+			'			<xsl:with-param name="is_last" select="number(position() = last())" />' +
+			'		</xsl:call-template>' +
+			'	</xsl:for-each>' +
+			'	</ul>' +
+			'</xsl:template>' +
+			'<xsl:template name="nodes">' +
+			'	<xsl:param name="node" />' +
+			'	<xsl:param name="is_last" />' +
+			'	<xsl:variable name="children" select="count(//item[@parent_id=$node/attribute::id]) &gt; 0" />' +
+			'	<li>' +
+			'	<xsl:attribute name="class">' +
+			'		<xsl:if test="$is_last = true()">jstree-last </xsl:if>' +
+			'		<xsl:choose>' +
+			'			<xsl:when test="@state = \'open\'">jstree-open </xsl:when>' +
+			'			<xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' +
+			'			<xsl:otherwise>jstree-leaf </xsl:otherwise>' +
+			'		</xsl:choose>' +
+			'		<xsl:value-of select="@class" />' +
+			'	</xsl:attribute>' +
+			'	<xsl:for-each select="@*">' +
+			'		<xsl:if test="name() != \'parent_id\' and name() != \'hasChildren\' and name() != \'class\' and name() != \'state\'">' +
+			'		<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+			'		</xsl:if>' +
+			'	</xsl:for-each>' +
+			'	<ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' +
+			'	<xsl:for-each select="content/name">' +
+			'		<a>' +
+			'		<xsl:attribute name="href">' +
+			'			<xsl:choose>' +
+			'			<xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' +
+			'			<xsl:otherwise>#</xsl:otherwise>' +
+			'			</xsl:choose>' +
+			'		</xsl:attribute>' +
+			'		<xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' +
+			'		<xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' +
+			'		<xsl:for-each select="@*">' +
+			'			<xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' +
+			'				<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+			'			</xsl:if>' +
+			'		</xsl:for-each>' +
+			'			<ins>' +
+			'				<xsl:attribute name="class">jstree-icon ' +
+			'					<xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' +
+			'				</xsl:attribute>' +
+			'				<xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' +
+			'				<xsl:text>&#xa0;</xsl:text>' +
+			'			</ins>' +
+			'			<xsl:copy-of select="./child::node()" />' +
+			'		</a>' +
+			'	</xsl:for-each>' +
+			'	<xsl:if test="$children">' +
+			'		<ul>' +
+			'		<xsl:for-each select="//item[@parent_id=$node/attribute::id]">' +
+			'			<xsl:call-template name="nodes">' +
+			'				<xsl:with-param name="node" select="." />' +
+			'				<xsl:with-param name="is_last" select="number(position() = last())" />' +
+			'			</xsl:call-template>' +
+			'		</xsl:for-each>' +
+			'		</ul>' +
+			'	</xsl:if>' +
+			'	</li>' +
+			'</xsl:template>' +
 			'</xsl:stylesheet>'
 	},
 	escape_xml = function(string) {
@@ -3187,7 +3187,7 @@
 			.replace(/'/g, '&apos;');
 	};
 	$.jstree.plugin("xml_data", {
-		defaults : { 
+		defaults : {
 			data : false,
 			ajax : false,
 			xsl : "flat",
@@ -3198,7 +3198,7 @@
 		},
 		_fn : {
 			load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_xml(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
-			_is_loaded : function (obj) { 
+			_is_loaded : function (obj) {
 				var s = this._get_settings().xml_data;
 				obj = this._get_node(obj);
 				return obj == -1 || !obj || (!s.ajax && !$.isFunction(s.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0;
@@ -3228,18 +3228,18 @@
 										if(s_call) { s_call.call(this); }
 									}
 									else {
-										if(obj && obj !== -1) { 
+										if(obj && obj !== -1) {
 											obj.children("a.jstree-loading").removeClass("jstree-loading");
 											obj.removeData("jstree_is_loading");
-											if(s.correct_state) { 
+											if(s.correct_state) {
 												this.correct_state(obj);
-												if(s_call) { s_call.call(this); } 
+												if(s_call) { s_call.call(this); }
 											}
 										}
 										else {
-											if(s.correct_state) { 
+											if(s.correct_state) {
 												this.get_container().children("ul").empty();
-												if(s_call) { s_call.call(this); } 
+												if(s_call) { s_call.call(this); }
 											}
 										}
 									}
@@ -3259,9 +3259,9 @@
 										if(s_call) { s_call.call(this); }
 									}
 								}
-								else { 
-									if(s.correct_state) { 
-										this.get_container().children("ul").empty(); 
+								else {
+									if(s.correct_state) {
+										this.get_container().children("ul").empty();
 										if(s_call) { s_call.call(this); }
 									}
 								}
@@ -3270,7 +3270,7 @@
 						break;
 					case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
 						error_func = function (x, t, e) {
-							var ef = this.get_settings().xml_data.ajax.error; 
+							var ef = this.get_settings().xml_data.ajax.error;
 							if(ef) { ef.call(this, x, t, e); }
 							if(obj !== -1 && obj.length) {
 								obj.children("a.jstree-loading").removeClass("jstree-loading");
@@ -3284,7 +3284,7 @@
 						};
 						success_func = function (d, t, x) {
 							d = x.responseText;
-							var sf = this.get_settings().xml_data.ajax.success; 
+							var sf = this.get_settings().xml_data.ajax.success;
 							if(sf) { d = sf.call(this,d,t,x) || d; }
 							if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "")) {
 								return error_func.call(this, x, t, "");
@@ -3300,18 +3300,18 @@
 										if(s_call) { s_call.call(this); }
 									}
 									else {
-										if(obj && obj !== -1) { 
+										if(obj && obj !== -1) {
 											obj.children("a.jstree-loading").removeClass("jstree-loading");
 											obj.removeData("jstree_is_loading");
-											if(s.correct_state) { 
+											if(s.correct_state) {
 												this.correct_state(obj);
-												if(s_call) { s_call.call(this); } 
+												if(s_call) { s_call.call(this); }
 											}
 										}
 										else {
-											if(s.correct_state) { 
+											if(s.correct_state) {
 												this.get_container().children("ul").empty();
-												if(s_call) { s_call.call(this); } 
+												if(s_call) { s_call.call(this); }
 											}
 										}
 									}
@@ -3333,8 +3333,8 @@
 				$.vakata.xslt(xml, xsl[s.xsl], callback);
 			},
 			get_xml : function (tp, obj, li_attr, a_attr, is_callback) {
-				var result = "", 
-					s = this._get_settings(), 
+				var result = "",
+					s = this._get_settings(),
 					_this = this,
 					tmp1, tmp2, li, a, lang;
 				if(!tp) { tp = "flat"; }
@@ -3346,19 +3346,19 @@
 
 				a_attr = $.isArray(a_attr) ? a_attr : [ ];
 
-				if(!is_callback) { 
-					if(s.xml_data.get_include_preamble) { 
-						result += '<' + '?xml version="1.0" encoding="UTF-8"?' + '>'; 
+				if(!is_callback) {
+					if(s.xml_data.get_include_preamble) {
+						result += '<' + '?xml version="1.0" encoding="UTF-8"?' + '>';
 					}
-					result += "<root>"; 
+					result += "<root>";
 				}
 				obj.each(function () {
 					result += "<item";
 					li = $(this);
-					$.each(li_attr, function (i, v) { 
+					$.each(li_attr, function (i, v) {
 						var t = li.attr(v);
 						if(!s.xml_data.get_skip_empty || typeof t !== "undefined") {
-							result += " " + v + "=\"" + escape_xml((" " + (t || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"")) + "\""; 
+							result += " " + v + "=\"" + escape_xml((" " + (t || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"")) + "\"";
 						}
 					});
 					if(li.hasClass("jstree-open")) { result += " state=\"open\""; }
@@ -3376,7 +3376,7 @@
 								if(tmp1.hasClass(z)) { result += " lang=\"" + escape_xml(z) + "\""; lang = z; return false; }
 							});
 						}
-						if(a_attr.length) { 
+						if(a_attr.length) {
 							$.each(a_attr, function (k, z) {
 								var t = tmp1.attr(z);
 								if(!s.xml_data.get_skip_empty || typeof t !== "undefined") {
@@ -3447,7 +3447,7 @@
 		_fn : {
 			search : function (str, skip_async) {
 				if($.trim(str) === "") { this.clear_search(); return; }
-				var s = this.get_settings().search, 
+				var s = this.get_settings().search,
 					t = this,
 					error_func = function () { },
 					success_func = function () { };
@@ -3457,7 +3457,7 @@
 					this.search.supress_callback = true;
 					error_func = function () { };
 					success_func = function (d, t, x) {
-						var sf = this.get_settings().search.ajax.success; 
+						var sf = this.get_settings().search.ajax.success;
 						if(sf) { d = sf.call(this,d,t,x) || d; }
 						this.data.search.to_open = d;
 						this._search_open();
@@ -3497,8 +3497,8 @@
 					});
 					if(current.length) {
 						this.data.search.to_open = remaining;
-						$.each(current, function (i, val) { 
-							_this.open_node(val, function () { _this._search_open(true); }); 
+						$.each(current, function (i, val) {
+							_this.open_node(val, function () { _this._search_open(true); });
 						});
 						done = false;
 					}
@@ -3510,7 +3510,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree contextmenu plugin
  */
 (function ($) {
@@ -3543,27 +3543,27 @@
 
 			h = $.vakata.context.cnt.height();
 			w = $.vakata.context.cnt.width();
-			if(x + w > $(document).width()) { 
-				x = $(document).width() - (w + 5); 
-				$.vakata.context.cnt.find("li > ul").addClass("right"); 
+			if(x + w > $(document).width()) {
+				x = $(document).width() - (w + 5);
+				$.vakata.context.cnt.find("li > ul").addClass("right");
 			}
-			if(y + h > $(document).height()) { 
-				y = y - (h + t[0].offsetHeight); 
-				$.vakata.context.cnt.find("li > ul").addClass("bottom"); 
+			if(y + h > $(document).height()) {
+				y = y - (h + t[0].offsetHeight);
+				$.vakata.context.cnt.find("li > ul").addClass("bottom");
 			}
 
 			$.vakata.context.cnt
 				.css({ "left" : x, "top" : y })
 				.find("li:has(ul)")
-					.bind("mouseenter", function (e) { 
+					.bind("mouseenter", function (e) {
 						var w = $(document).width(),
 							h = $(document).height(),
-							ul = $(this).children("ul").show(); 
+							ul = $(this).children("ul").show();
 						if(w !== $(document).width()) { ul.toggleClass("right"); }
 						if(h !== $(document).height()) { ul.toggleClass("bottom"); }
 					})
-					.bind("mouseleave", function (e) { 
-						$(this).children("ul").hide(); 
+					.bind("mouseleave", function (e) {
+						$(this).children("ul").hide();
 					})
 					.end()
 				.css({ "visibility" : "visible" })
@@ -3622,17 +3622,17 @@
 		}
 	};
 	$(function () {
-		var css_string = '' + 
-			'#vakata-contextmenu { display:block; visibility:hidden; left:0; top:-200px; position:absolute; margin:0; padding:0; min-width:180px; background:#ebebeb; border:1px solid silver; z-index:10000; *width:180px; } ' + 
-			'#vakata-contextmenu ul { min-width:180px; *width:180px; } ' + 
-			'#vakata-contextmenu ul, #vakata-contextmenu li { margin:0; padding:0; list-style-type:none; display:block; } ' + 
-			'#vakata-contextmenu li { line-height:20px; min-height:20px; position:relative; padding:0px; } ' + 
-			'#vakata-contextmenu li a { padding:1px 6px; line-height:17px; display:block; text-decoration:none; margin:1px 1px 0 1px; } ' + 
-			'#vakata-contextmenu li ins { float:left; width:16px; height:16px; text-decoration:none; margin-right:2px; } ' + 
-			'#vakata-contextmenu li a:hover, #vakata-contextmenu li.vakata-hover > a { background:gray; color:white; } ' + 
-			'#vakata-contextmenu li ul { display:none; position:absolute; top:-2px; left:100%; background:#ebebeb; border:1px solid gray; } ' + 
-			'#vakata-contextmenu .right { right:100%; left:auto; } ' + 
-			'#vakata-contextmenu .bottom { bottom:-1px; top:auto; } ' + 
+		var css_string = '' +
+			'#vakata-contextmenu { display:block; visibility:hidden; left:0; top:-200px; position:absolute; margin:0; padding:0; min-width:180px; background:#ebebeb; border:1px solid silver; z-index:10000; *width:180px; } ' +
+			'#vakata-contextmenu ul { min-width:180px; *width:180px; } ' +
+			'#vakata-contextmenu ul, #vakata-contextmenu li { margin:0; padding:0; list-style-type:none; display:block; } ' +
+			'#vakata-contextmenu li { line-height:20px; min-height:20px; position:relative; padding:0px; } ' +
+			'#vakata-contextmenu li a { padding:1px 6px; line-height:17px; display:block; text-decoration:none; margin:1px 1px 0 1px; } ' +
+			'#vakata-contextmenu li ins { float:left; width:16px; height:16px; text-decoration:none; margin-right:2px; } ' +
+			'#vakata-contextmenu li a:hover, #vakata-contextmenu li.vakata-hover > a { background:gray; color:white; } ' +
+			'#vakata-contextmenu li ul { display:none; position:absolute; top:-2px; left:100%; background:#ebebeb; border:1px solid gray; } ' +
+			'#vakata-contextmenu .right { right:100%; left:auto; } ' +
+			'#vakata-contextmenu .bottom { bottom:-1px; top:auto; } ' +
 			'#vakata-contextmenu li.vakata-separator { min-height:0; height:1px; line-height:1px; font-size:1px; overflow:hidden; margin:0 2px; background:silver; /* border-top:1px solid #fefefe; */ padding:0; } ';
 		$.vakata.css.add_sheet({ str : css_string, title : "vakata" });
 		$.vakata.context.cnt
@@ -3650,43 +3650,43 @@
 		$(document).bind("mousedown", function (e) { if($.vakata.context.vis && !$.contains($.vakata.context.cnt[0], e.target)) { $.vakata.context.hide(); } });
 		if(typeof $.hotkeys !== "undefined") {
 			$(document)
-				.bind("keydown", "up", function (e) { 
-					if($.vakata.context.vis) { 
+				.bind("keydown", "up", function (e) {
+					if($.vakata.context.vis) {
 						var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").prevAll("li:not(.vakata-separator)").first();
 						if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").last(); }
 						o.addClass("vakata-hover");
-						e.stopImmediatePropagation(); 
+						e.stopImmediatePropagation();
 						e.preventDefault();
-					} 
+					}
 				})
-				.bind("keydown", "down", function (e) { 
-					if($.vakata.context.vis) { 
+				.bind("keydown", "down", function (e) {
+					if($.vakata.context.vis) {
 						var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").nextAll("li:not(.vakata-separator)").first();
 						if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").first(); }
 						o.addClass("vakata-hover");
-						e.stopImmediatePropagation(); 
+						e.stopImmediatePropagation();
 						e.preventDefault();
-					} 
+					}
 				})
-				.bind("keydown", "right", function (e) { 
-					if($.vakata.context.vis) { 
+				.bind("keydown", "right", function (e) {
+					if($.vakata.context.vis) {
 						$.vakata.context.cnt.find(".vakata-hover").children("ul").show().children("li:not(.vakata-separator)").removeClass("vakata-hover").first().addClass("vakata-hover");
-						e.stopImmediatePropagation(); 
+						e.stopImmediatePropagation();
 						e.preventDefault();
-					} 
+					}
 				})
-				.bind("keydown", "left", function (e) { 
-					if($.vakata.context.vis) { 
+				.bind("keydown", "left", function (e) {
+					if($.vakata.context.vis) {
 						$.vakata.context.cnt.find(".vakata-hover").children("ul").hide().children(".vakata-separator").removeClass("vakata-hover");
-						e.stopImmediatePropagation(); 
+						e.stopImmediatePropagation();
 						e.preventDefault();
-					} 
+					}
 				})
-				.bind("keydown", "esc", function (e) { 
-					$.vakata.context.hide(); 
+				.bind("keydown", "esc", function (e) {
+					$.vakata.context.hide();
 					e.preventDefault();
 				})
-				.bind("keydown", "space", function (e) { 
+				.bind("keydown", "space", function (e) {
 					$.vakata.context.cnt.find(".vakata-hover").last().children("a").click();
 					e.preventDefault();
 				});
@@ -3715,7 +3715,7 @@
 					}, this));
 			$(document).bind("context_hide.vakata", $.proxy(function () { this.data.contextmenu = false; }, this));
 		},
-		defaults : { 
+		defaults : {
 			select_node : false, // requires UI plugin
 			show_at_node : true,
 			items : { // Could be a function that should return an object like this one
@@ -3744,7 +3744,7 @@
 					"separator_after"	: false,
 					"label"				: "Edit",
 					"action"			: false,
-					"submenu" : { 
+					"submenu" : {
 						"cut" : {
 							"separator_before"	: false,
 							"separator_after"	: false,
@@ -3796,7 +3796,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree types plugin
  * Adds support types of nodes
  * You can set an attribute on each li node, that represents its type.
@@ -3808,14 +3808,14 @@
 			var s = this._get_settings().types;
 			this.data.types.attach_to = [];
 			this.get_container()
-				.bind("init.jstree", $.proxy(function () { 
-						var types = s.types, 
-							attr  = s.type_attr, 
-							icons_css = "", 
+				.bind("init.jstree", $.proxy(function () {
+						var types = s.types,
+							attr  = s.type_attr,
+							icons_css = "",
 							_this = this;
 
 						$.each(types, function (i, tp) {
-							$.each(tp, function (k, v) { 
+							$.each(tp, function (k, v) {
 								if(!/^(max_depth|max_children|icon|valid_children)$/.test(k)) { _this.data.types.attach_to.push(k); }
 							});
 							if(!tp.icon) { return true; }
@@ -3830,9 +3830,9 @@
 						});
 						if(icons_css !== "") { $.vakata.css.add_sheet({ 'str' : icons_css, title : "jstree-types" }); }
 					}, this))
-				.bind("before.jstree", $.proxy(function (e, data) { 
-						var s, t, 
-							o = this._get_settings().types.use_data ? this._get_node(data.args[0]) : false, 
+				.bind("before.jstree", $.proxy(function (e, data) {
+						var s, t,
+							o = this._get_settings().types.use_data ? this._get_node(data.args[0]) : false,
 							d = o && o !== -1 && o.length ? o.data("jstree") : false;
 						if(d && d.types && d.types[data.func] === false) { e.stopImmediatePropagation(); return false; }
 						if($.inArray(data.func, this.data.types.attach_to) !== -1) {
@@ -3840,9 +3840,9 @@
 							s = this._get_settings().types.types;
 							t = this._get_type(data.args[0]);
 							if(
-								( 
-									(s[t] && typeof s[t][data.func] !== "undefined") || 
-									(s["default"] && typeof s["default"][data.func] !== "undefined") 
+								(
+									(s[t] && typeof s[t][data.func] !== "undefined") ||
+									(s["default"] && typeof s["default"][data.func] !== "undefined")
 								) && this._check(data.func, data.args[0]) === false
 							) {
 								e.stopImmediatePropagation();
@@ -3875,7 +3875,7 @@
 			valid_children		: "all",
 
 			// whether to use $.data
-			use_data : false, 
+			use_data : false,
 			// where is the type stores (the rel attribute of the LI element)
 			type_attr : "rel",
 			// a list of types
@@ -3910,7 +3910,7 @@
 			_check : function (rule, obj, opts) {
 				obj = this._get_node(obj);
 				var v = false, t = this._get_type(obj), d = 0, _this = this, s = this._get_settings().types, data = false;
-				if(obj === -1) { 
+				if(obj === -1) {
 					if(!!s[rule]) { v = s[rule]; }
 					else { return; }
 				}
@@ -3947,7 +3947,7 @@
 					vc = m.rt._check("valid_children", m.cr),
 					ch = 0, d = 1, t;
 
-				if(vc === "none") { return false; } 
+				if(vc === "none") { return false; }
 				if($.isArray(vc) && m.ot && m.ot._get_type) {
 					m.o.each(function () {
 						if($.inArray(m.ot._get_type(this), vc) === -1) { d = false; return false; }
@@ -3984,11 +3984,11 @@
 						ch;
 					if(typeof js === "string") { js = { data : js }; }
 					if(!js) { js = {}; }
-					if(vc === "none") { return false; } 
+					if(vc === "none") { return false; }
 					if($.isArray(vc)) {
-						if(!js.attr || !js.attr[s.type_attr]) { 
+						if(!js.attr || !js.attr[s.type_attr]) {
 							if(!js.attr) { js.attr = {}; }
-							js.attr[s.type_attr] = vc[0]; 
+							js.attr[s.type_attr] = vc[0];
 						}
 						else {
 							if($.inArray(js.attr[s.type_attr], vc) === -1) { return false; }
@@ -4007,27 +4007,27 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree HTML plugin
  * The HTML data store. Datastores are build by replacing the `load_node` and `_is_loaded` functions.
  */
 (function ($) {
 	$.jstree.plugin("html_data", {
-		__init : function () { 
+		__init : function () {
 			// this used to use html() and clean the whitespace, but this way any attached data was lost
 			this.data.html_data.original_container_html = this.get_container().find(" > ul > li").clone(true);
 			// remove white space from LI node - otherwise nodes appear a bit to the right
 			this.data.html_data.original_container_html.find("li").addBack().contents().filter(function() { return this.nodeType == 3; }).remove();
 		},
-		defaults : { 
+		defaults : {
 			data : false,
 			ajax : false,
 			correct_state : true
 		},
 		_fn : {
 			load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_html(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
-			_is_loaded : function (obj) { 
-				obj = this._get_node(obj); 
+			_is_loaded : function (obj) {
+				obj = this._get_node(obj);
 				return obj == -1 || !obj || (!this._get_settings().html_data.ajax && !$.isFunction(this._get_settings().html_data.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0;
 			},
 			load_node_html : function (obj, s_call, e_call) {
@@ -4055,15 +4055,15 @@
 								if(obj && obj !== -1) {
 									obj.children("a.jstree-loading").removeClass("jstree-loading");
 									obj.removeData("jstree_is_loading");
-									if(s.correct_state) { 
+									if(s.correct_state) {
 										this.correct_state(obj);
-										if(s_call) { s_call.call(this); } 
+										if(s_call) { s_call.call(this); }
 									}
 								}
 								else {
-									if(s.correct_state) { 
+									if(s.correct_state) {
 										this.get_container().children("ul").empty();
-										if(s_call) { s_call.call(this); } 
+										if(s_call) { s_call.call(this); }
 									}
 								}
 							}
@@ -4095,7 +4095,7 @@
 					case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
 						obj = this._get_node(obj);
 						error_func = function (x, t, e) {
-							var ef = this.get_settings().html_data.ajax.error; 
+							var ef = this.get_settings().html_data.ajax.error;
 							if(ef) { ef.call(this, x, t, e); }
 							if(obj != -1 && obj.length) {
 								obj.children("a.jstree-loading").removeClass("jstree-loading");
@@ -4108,7 +4108,7 @@
 							if(e_call) { e_call.call(this); }
 						};
 						success_func = function (d, t, x) {
-							var sf = this.get_settings().html_data.ajax.success; 
+							var sf = this.get_settings().html_data.ajax.success;
 							if(sf) { d = sf.call(this,d,t,x) || d; }
 							if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "")) {
 								return error_func.call(this, x, t, "");
@@ -4125,15 +4125,15 @@
 								if(obj && obj !== -1) {
 									obj.children("a.jstree-loading").removeClass("jstree-loading");
 									obj.removeData("jstree_is_loading");
-									if(s.correct_state) { 
+									if(s.correct_state) {
 										this.correct_state(obj);
-										if(s_call) { s_call.call(this); } 
+										if(s_call) { s_call.call(this); }
 									}
 								}
 								else {
-									if(s.correct_state) { 
+									if(s.correct_state) {
 										this.get_container().children("ul").empty();
-										if(s_call) { s_call.call(this); } 
+										if(s_call) { s_call.call(this); }
 									}
 								}
 							}
@@ -4155,7 +4155,7 @@
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree themeroller plugin
  * Adds support for jQuery UI themes. Include this at the end of your plugins list, also make sure "themes" is not included.
  */
@@ -4174,11 +4174,11 @@
 				.delegate("a","mouseleave.jstree", function () {
 					$(this).removeClass(s.item_h);
 				})
-				.bind("init.jstree", $.proxy(function (e, data) { 
+				.bind("init.jstree", $.proxy(function (e, data) {
 						data.inst.get_container().find("> ul > li > .jstree-loading > ins").addClass("ui-icon-refresh");
 						this._themeroller(data.inst.get_container().find("> ul > li"));
 					}, this))
-				.bind("open_node.jstree create_node.jstree", $.proxy(function (e, data) { 
+				.bind("open_node.jstree create_node.jstree", $.proxy(function (e, data) {
 						this._themeroller(data.rslt.obj);
 					}, this))
 				.bind("loaded.jstree refresh.jstree", $.proxy(function (e) {
@@ -4194,10 +4194,10 @@
 						data.rslt.obj
 							.children("ins.jstree-icon").removeClass(s.opened + " " + s.closed + " ui-icon").end()
 							.find("> a > ins.ui-icon")
-								.filter(function() { 
+								.filter(function() {
 									return this.className.toString()
 										.replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
-										.indexOf("ui-icon-") === -1; 
+										.indexOf("ui-icon-") === -1;
 								}).removeClass(s.item_open + " " + s.item_clsd).addClass(s.item_leaf || "jstree-no-icon");
 					}, this))
 				.bind("select_node.jstree", $.proxy(function (e, data) {
@@ -4241,10 +4241,10 @@
 						.children("ins.jstree-icon").removeClass(s.opened).addClass("ui-icon " + s.closed).end()
 						.children("a").addClass(s.item)
 							.children("ins.jstree-icon").addClass("ui-icon")
-								.filter(function() { 
+								.filter(function() {
 									return this.className.toString()
 										.replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
-										.indexOf("ui-icon-") === -1; 
+										.indexOf("ui-icon-") === -1;
 								}).removeClass(s.item_leaf + " " + s.item_open).addClass(s.item_clsd || "jstree-no-icon")
 								.end()
 							.end()
@@ -4254,10 +4254,10 @@
 						.children("ins.jstree-icon").removeClass(s.closed).addClass("ui-icon " + s.opened).end()
 						.children("a").addClass(s.item)
 							.children("ins.jstree-icon").addClass("ui-icon")
-								.filter(function() { 
+								.filter(function() {
 									return this.className.toString()
 										.replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
-										.indexOf("ui-icon-") === -1; 
+										.indexOf("ui-icon-") === -1;
 								}).removeClass(s.item_leaf + " " + s.item_clsd).addClass(s.item_open || "jstree-no-icon")
 								.end()
 							.end()
@@ -4267,10 +4267,10 @@
 						.children("ins.jstree-icon").removeClass(s.closed + " ui-icon " + s.opened).end()
 						.children("a").addClass(s.item)
 							.children("ins.jstree-icon").addClass("ui-icon")
-								.filter(function() { 
+								.filter(function() {
 									return this.className.toString()
 										.replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
-										.indexOf("ui-icon-") === -1; 
+										.indexOf("ui-icon-") === -1;
 								}).removeClass(s.item_clsd + " " + s.item_open).addClass(s.item_leaf || "jstree-no-icon");
 			}
 		},
@@ -4286,16 +4286,16 @@
 		}
 	});
 	$(function() {
-		var css_string = '' + 
-			'.jstree-themeroller .ui-icon { overflow:visible; } ' + 
-			'.jstree-themeroller a { padding:0 2px; } ' + 
+		var css_string = '' +
+			'.jstree-themeroller .ui-icon { overflow:visible; } ' +
+			'.jstree-themeroller a { padding:0 2px; } ' +
 			'.jstree-themeroller .jstree-no-icon { display:none; }';
 		$.vakata.css.add_sheet({ str : css_string, title : "jstree" });
 	});
 })(jQuery);
 //*/
 
-/* 
+/*
  * jsTree unique plugin
  * Forces different names amongst siblings (still a bit experimental)
  * NOTE: does not check language versions (it will not be possible to have nodes with the same title, even in different languages)
@@ -4304,7 +4304,7 @@
 	$.jstree.plugin("unique", {
 		__init : function () {
 			this.get_container()
-				.bind("before.jstree", $.proxy(function (e, data) { 
+				.bind("before.jstree", $.proxy(function (e, data) {
 						var nms = [], res = true, p, t;
 						if(data.func == "move_node") {
 							// obj, ref, position, is_copy, is_prepared, skip_check
@@ -4343,10 +4343,10 @@
 						}
 					}, this));
 		},
-		defaults : { 
+		defaults : {
 			error_callback : $.noop
 		},
-		_fn : { 
+		_fn : {
 			_check_unique : function (nms, p, func) {
 				var cnms = [];
 				p.children("a").each(function () { cnms.push($(this).text().replace(/^\s+/g,"")); });
@@ -4384,27 +4384,27 @@
 			this.data.wholerow.html = false;
 			this.data.wholerow.to = false;
 			this.get_container()
-				.bind("init.jstree", $.proxy(function (e, data) { 
+				.bind("init.jstree", $.proxy(function (e, data) {
 						this._get_settings().core.animation = 0;
 					}, this))
-				.bind("open_node.jstree create_node.jstree clean_node.jstree loaded.jstree", $.proxy(function (e, data) { 
+				.bind("open_node.jstree create_node.jstree clean_node.jstree loaded.jstree", $.proxy(function (e, data) {
 						this._prepare_wholerow_span( data && data.rslt && data.rslt.obj ? data.rslt.obj : -1 );
 					}, this))
-				.bind("search.jstree clear_search.jstree reopen.jstree after_open.jstree after_close.jstree create_node.jstree delete_node.jstree clean_node.jstree", $.proxy(function (e, data) { 
+				.bind("search.jstree clear_search.jstree reopen.jstree after_open.jstree after_close.jstree create_node.jstree delete_node.jstree clean_node.jstree", $.proxy(function (e, data) {
 						if(this.data.to) { clearTimeout(this.data.to); }
 						this.data.to = setTimeout( (function (t, o) { return function() { t._prepare_wholerow_ul(o); }; })(this,  data && data.rslt && data.rslt.obj ? data.rslt.obj : -1), 0);
 					}, this))
-				.bind("deselect_all.jstree", $.proxy(function (e, data) { 
+				.bind("deselect_all.jstree", $.proxy(function (e, data) {
 						this.get_container().find(" > .jstree-wholerow .jstree-clicked").removeClass("jstree-clicked " + (this.data.themeroller ? this._get_settings().themeroller.item_a : "" ));
 					}, this))
-				.bind("select_node.jstree deselect_node.jstree ", $.proxy(function (e, data) { 
-						data.rslt.obj.each(function () { 
+				.bind("select_node.jstree deselect_node.jstree ", $.proxy(function (e, data) {
+						data.rslt.obj.each(function () {
 							var ref = data.inst.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt((($(this).offset().top - data.inst.get_container().offset().top + data.inst.get_container()[0].scrollTop) / data.inst.data.core.li_height),10)) + ")");
 							// ref.children("a")[e.type === "select_node" ? "addClass" : "removeClass"]("jstree-clicked");
 							ref.children("a").attr("class",data.rslt.obj.children("a").attr("class"));
 						});
 					}, this))
-				.bind("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) { 
+				.bind("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
 						this.get_container().find(" > .jstree-wholerow .jstree-hovered").removeClass("jstree-hovered " + (this.data.themeroller ? this._get_settings().themeroller.item_h : "" ));
 						if(e.type === "hover_node") {
 							var ref = this.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt(((data.rslt.obj.offset().top - this.get_container().offset().top + this.get_container()[0].scrollTop) / this.data.core.li_height),10)) + ")");
@@ -4468,25 +4468,25 @@
 		}
 	});
 	$(function() {
-		var css_string = '' + 
-			'.jstree .jstree-wholerow-real { position:relative; z-index:1; } ' + 
-			'.jstree .jstree-wholerow-real li { cursor:pointer; } ' + 
-			'.jstree .jstree-wholerow-real a { border-left-color:transparent !important; border-right-color:transparent !important; } ' + 
-			'.jstree .jstree-wholerow { position:relative; z-index:0; height:0; } ' + 
-			'.jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { width:100%; } ' + 
-			'.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li, .jstree .jstree-wholerow a { margin:0 !important; padding:0 !important; } ' + 
-			'.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { background:transparent !important; }' + 
-			'.jstree .jstree-wholerow ins, .jstree .jstree-wholerow span, .jstree .jstree-wholerow input { display:none !important; }' + 
-			'.jstree .jstree-wholerow a, .jstree .jstree-wholerow a:hover { text-indent:-9999px; !important; width:100%; padding:0 !important; border-right-width:0px !important; border-left-width:0px !important; } ' + 
+		var css_string = '' +
+			'.jstree .jstree-wholerow-real { position:relative; z-index:1; } ' +
+			'.jstree .jstree-wholerow-real li { cursor:pointer; } ' +
+			'.jstree .jstree-wholerow-real a { border-left-color:transparent !important; border-right-color:transparent !important; } ' +
+			'.jstree .jstree-wholerow { position:relative; z-index:0; height:0; } ' +
+			'.jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { width:100%; } ' +
+			'.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li, .jstree .jstree-wholerow a { margin:0 !important; padding:0 !important; } ' +
+			'.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { background:transparent !important; }' +
+			'.jstree .jstree-wholerow ins, .jstree .jstree-wholerow span, .jstree .jstree-wholerow input { display:none !important; }' +
+			'.jstree .jstree-wholerow a, .jstree .jstree-wholerow a:hover { text-indent:-9999px; !important; width:100%; padding:0 !important; border-right-width:0px !important; border-left-width:0px !important; } ' +
 			'.jstree .jstree-wholerow-span { position:absolute; left:0; margin:0px; padding:0; height:18px; border-width:0; padding:0; z-index:0; }';
 		if(is_ff2) {
-			css_string += '' + 
-				'.jstree .jstree-wholerow a { display:block; height:18px; margin:0; padding:0; border:0; } ' + 
+			css_string += '' +
+				'.jstree .jstree-wholerow a { display:block; height:18px; margin:0; padding:0; border:0; } ' +
 				'.jstree .jstree-wholerow-real a { border-color:transparent !important; } ';
 		}
 		if(is_ie7 || is_ie6) {
-			css_string += '' + 
-				'.jstree .jstree-wholerow, .jstree .jstree-wholerow li, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow a { margin:0; padding:0; line-height:18px; } ' + 
+			css_string += '' +
+				'.jstree .jstree-wholerow, .jstree .jstree-wholerow li, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow a { margin:0; padding:0; line-height:18px; } ' +
 				'.jstree .jstree-wholerow a { display:block; height:18px; line-height:18px; overflow:hidden; } ';
 		}
 		$.vakata.css.add_sheet({ str : css_string, title : "jstree" });
@@ -4532,7 +4532,7 @@
 		},
 		_fn : {
 			model_done : function (data, callback) {
-				var ret = [], 
+				var ret = [],
 					s = this._get_settings(),
 					_this = this;
 
diff --git a/lib/web/mage/backend/jstree-mixin.js b/lib/web/mage/backend/jstree-mixin.js
new file mode 100644
index 0000000000000000000000000000000000000000..78e02034fdf0f57ab9a2b698e0e43723cd09f9a7
--- /dev/null
+++ b/lib/web/mage/backend/jstree-mixin.js
@@ -0,0 +1,13 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'jquery'
+], function ($) {
+    'use strict';
+
+    return function () {
+        $.jstree._themes = require.s.contexts._.config.baseUrl + 'jquery/jstree/themes/';
+    };
+});
diff --git a/setup/src/Magento/Setup/Fixtures/FixtureModel.php b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
index edd7297db4b0c1126e8fc1ddf2b8ffd0581e3d04..0bbb4167854d124a3393414276b63623319c7faa 100644
--- a/setup/src/Magento/Setup/Fixtures/FixtureModel.php
+++ b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
@@ -110,12 +110,8 @@ class FixtureModel
         foreach ($files as $file) {
             $file = basename($file, '.php');
             /** @var \Magento\Setup\Fixtures\Fixture $fixture */
-            $fixture = $this->objectManager->create(
-                'Magento\Setup\Fixtures' . '\\' . $file,
-                [
-                    'fixtureModel' => $this
-                ]
-            );
+            $type = 'Magento\Setup\Fixtures' . '\\' . $file;
+            $fixture = new $type($this);
             $this->fixtures[$fixture->getPriority()] = $fixture;
         }
 
diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php
index d2c37704e42055d304f03f20c2462e0cc54a3da3..595f34a03d05396bd300be86d66b0b6a75aecf8f 100644
--- a/setup/src/Magento/Setup/Model/Installer.php
+++ b/setup/src/Magento/Setup/Model/Installer.php
@@ -825,7 +825,7 @@ class Installer
             $this->log->log("Module '{$moduleName}':");
             $modulePostUpdater = $this->getSchemaDataHandler($moduleName, $handlerType);
             if ($modulePostUpdater) {
-                $this->log->logInline('Running ' + str_replace('-', ' ', $handlerType) + '...');
+                $this->log->logInline('Running ' . str_replace('-', ' ', $handlerType) . '...');
                 $modulePostUpdater->install($setup, $moduleContextList[$moduleName]);
             }
             $this->logProgress();
diff --git a/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php
index bad169e114754ee24dd850c636b2f27b3e9e76d0..ee5a42069fb0cca56c7bac2065ec7f3ac6607182 100644
--- a/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php
+++ b/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php
@@ -6,7 +6,7 @@
 namespace Magento\Setup\Module\Di\Code\Reader;
 
 use Magento\Framework\Exception\FileSystemException;
-use Zend\Code\Scanner\FileScanner;
+use Magento\Setup\Module\Di\Code\Reader\FileScanner;
 
 class ClassesScanner implements ClassesScannerInterface
 {
diff --git a/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php
new file mode 100644
index 0000000000000000000000000000000000000000..5293b782064242a571cb7580835abb6586d2a454
--- /dev/null
+++ b/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php
@@ -0,0 +1,367 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\Setup\Module\Di\Code\Reader;
+
+/**
+ * @SuppressWarnings(PHPMD)
+ */
+class FileScanner extends \Zend\Code\Scanner\FileScanner
+{
+    /**
+     * @var int
+     */
+    private $tokenType;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function scan()
+    {
+        if ($this->isScanned) {
+            return;
+        }
+
+        if (!$this->tokens) {
+            throw new \Zend\Code\Exception\RuntimeException('No tokens were provided');
+        }
+
+        /**
+         * Define PHP 5.4 'trait' token constant.
+         */
+        if (!defined('T_TRAIT')) {
+            define('T_TRAIT', 42001);
+        }
+
+        /**
+         * Variables & Setup
+         */
+
+        $tokens = &$this->tokens; // localize
+        $infos = &$this->infos; // localize
+        $tokenIndex = null;
+        $token = null;
+        $this->tokenType = null;
+        $tokenContent = null;
+        $tokenLine = null;
+        $namespace = null;
+        $docCommentIndex = false;
+        $infoIndex = 0;
+
+        /*
+         * MACRO creation
+         */
+        $MACRO_TOKEN_ADVANCE = function () use (&$tokens, &$tokenIndex, &$token, &$tokenContent, &$tokenLine) {
+            $tokenIndex = ($tokenIndex === null) ? 0 : $tokenIndex + 1;
+            if (!isset($tokens[$tokenIndex])) {
+                $token = false;
+                $tokenContent = false;
+                $this->tokenType = false;
+                $tokenLine = false;
+
+                return false;
+            }
+            if (is_string($tokens[$tokenIndex]) && $tokens[$tokenIndex] === '"') {
+                do {
+                    $tokenIndex++;
+                } while (!(is_string($tokens[$tokenIndex]) && $tokens[$tokenIndex] === '"'));
+            }
+            $token = $tokens[$tokenIndex];
+            if (is_array($token)) {
+                list($this->tokenType, $tokenContent, $tokenLine) = $token;
+            } else {
+                $this->tokenType = null;
+                $tokenContent = $token;
+            }
+
+            return $tokenIndex;
+        };
+        $MACRO_TOKEN_LOGICAL_START_INDEX = function () use (&$tokenIndex, &$docCommentIndex) {
+            return ($docCommentIndex === false) ? $tokenIndex : $docCommentIndex;
+        };
+        $MACRO_DOC_COMMENT_START = function () use (&$tokenIndex, &$docCommentIndex) {
+            $docCommentIndex = $tokenIndex;
+
+            return $docCommentIndex;
+        };
+        $MACRO_DOC_COMMENT_VALIDATE = function () use (&$docCommentIndex) {
+            static $validTrailingTokens = null;
+            if ($validTrailingTokens === null) {
+                $validTrailingTokens = array(T_WHITESPACE, T_FINAL, T_ABSTRACT, T_INTERFACE, T_CLASS, T_FUNCTION);
+            }
+            if ($docCommentIndex !== false && !in_array($this->tokenType, $validTrailingTokens)) {
+                $docCommentIndex = false;
+            }
+
+            return $docCommentIndex;
+        };
+        $MACRO_INFO_ADVANCE = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) {
+            $infos[$infoIndex]['tokenEnd'] = $tokenIndex;
+            $infos[$infoIndex]['lineEnd'] = $tokenLine;
+            $infoIndex++;
+
+            return $infoIndex;
+        };
+
+        /**
+         * START FINITE STATE MACHINE FOR SCANNING TOKENS
+         */
+
+        // Initialize token
+        $MACRO_TOKEN_ADVANCE();
+
+        SCANNER_TOP:
+
+        if ($token === false) {
+            goto SCANNER_END;
+        }
+
+        // Validate current doc comment index
+        $MACRO_DOC_COMMENT_VALIDATE();
+
+        switch ($this->tokenType) {
+
+            case T_DOC_COMMENT:
+
+                $MACRO_DOC_COMMENT_START();
+                goto SCANNER_CONTINUE;
+            //goto no break needed
+
+            case T_NAMESPACE:
+
+                $infos[$infoIndex] = array(
+                    'type' => 'namespace',
+                    'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(),
+                    'tokenEnd' => null,
+                    'lineStart' => $token[2],
+                    'lineEnd' => null,
+                    'namespace' => null,
+                );
+
+                // start processing with next token
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+
+                SCANNER_NAMESPACE_TOP:
+
+                if ($this->tokenType === null && $tokenContent === ';' || $tokenContent === '{') {
+                    goto SCANNER_NAMESPACE_END;
+                }
+
+                if ($this->tokenType === T_WHITESPACE) {
+                    goto SCANNER_NAMESPACE_CONTINUE;
+                }
+
+                if ($this->tokenType === T_NS_SEPARATOR || $this->tokenType === T_STRING) {
+                    $infos[$infoIndex]['namespace'] .= $tokenContent;
+                }
+
+                SCANNER_NAMESPACE_CONTINUE:
+
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+                goto SCANNER_NAMESPACE_TOP;
+
+                SCANNER_NAMESPACE_END:
+
+                $namespace = $infos[$infoIndex]['namespace'];
+
+                $MACRO_INFO_ADVANCE();
+                goto SCANNER_CONTINUE;
+            //goto no break needed
+
+            case T_USE:
+
+                $infos[$infoIndex] = array(
+                    'type' => 'use',
+                    'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(),
+                    'tokenEnd' => null,
+                    'lineStart' => $tokens[$tokenIndex][2],
+                    'lineEnd' => null,
+                    'namespace' => $namespace,
+                    'statements' => array(0 => array('use' => null,
+                        'as' => null)),
+                );
+
+                $useStatementIndex = 0;
+                $useAsContext = false;
+
+                // start processing with next token
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+
+                SCANNER_USE_TOP:
+
+                if ($this->tokenType === null) {
+                    if ($tokenContent === ';') {
+                        goto SCANNER_USE_END;
+                    } elseif ($tokenContent === ',') {
+                        $useAsContext = false;
+                        $useStatementIndex++;
+                        $infos[$infoIndex]['statements'][$useStatementIndex] = array('use' => null,
+                            'as' => null);
+                    }
+                }
+
+                // ANALYZE
+                if ($this->tokenType !== null) {
+                    if ($this->tokenType == T_AS) {
+                        $useAsContext = true;
+                        goto SCANNER_USE_CONTINUE;
+                    }
+
+                    if ($this->tokenType == T_NS_SEPARATOR || $this->tokenType == T_STRING) {
+                        if ($useAsContext == false) {
+                            $infos[$infoIndex]['statements'][$useStatementIndex]['use'] .= $tokenContent;
+                        } else {
+                            $infos[$infoIndex]['statements'][$useStatementIndex]['as'] = $tokenContent;
+                        }
+                    }
+                }
+
+                SCANNER_USE_CONTINUE:
+
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+                goto SCANNER_USE_TOP;
+
+                SCANNER_USE_END:
+
+                $MACRO_INFO_ADVANCE();
+                goto SCANNER_CONTINUE;
+            //goto no break needed
+
+            case T_INCLUDE:
+            case T_INCLUDE_ONCE:
+            case T_REQUIRE:
+            case T_REQUIRE_ONCE:
+
+                // Static for performance
+                static $includeTypes = array(
+                    T_INCLUDE => 'include',
+                    T_INCLUDE_ONCE => 'include_once',
+                    T_REQUIRE => 'require',
+                    T_REQUIRE_ONCE => 'require_once'
+                );
+
+                $infos[$infoIndex] = array(
+                    'type' => 'include',
+                    'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(),
+                    'tokenEnd' => null,
+                    'lineStart' => $tokens[$tokenIndex][2],
+                    'lineEnd' => null,
+                    'includeType' => $includeTypes[$tokens[$tokenIndex][0]],
+                    'path' => '',
+                );
+
+                // start processing with next token
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+
+                SCANNER_INCLUDE_TOP:
+
+                if ($this->tokenType === null && $tokenContent === ';') {
+                    goto SCANNER_INCLUDE_END;
+                }
+
+                $infos[$infoIndex]['path'] .= $tokenContent;
+
+                SCANNER_INCLUDE_CONTINUE:
+
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+                goto SCANNER_INCLUDE_TOP;
+
+                SCANNER_INCLUDE_END:
+
+                $MACRO_INFO_ADVANCE();
+                goto SCANNER_CONTINUE;
+            //goto no break needed
+
+            case T_FUNCTION:
+            case T_FINAL:
+            case T_ABSTRACT:
+            case T_CLASS:
+            case T_INTERFACE:
+            case T_TRAIT:
+
+                $infos[$infoIndex] = array(
+                    'type' => ($this->tokenType === T_FUNCTION) ? 'function' : 'class',
+                    'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(),
+                    'tokenEnd' => null,
+                    'lineStart' => $tokens[$tokenIndex][2],
+                    'lineEnd' => null,
+                    'namespace' => $namespace,
+                    'uses' => $this->getUsesNoScan($namespace),
+                    'name' => null,
+                    'shortName' => null,
+                );
+
+                $classBraceCount = 0;
+
+                // start processing with current token
+
+                SCANNER_CLASS_TOP:
+
+                // process the name
+                if ($infos[$infoIndex]['shortName'] == ''
+                    && (($this->tokenType === T_CLASS || $this->tokenType === T_INTERFACE || $this->tokenType === T_TRAIT) && $infos[$infoIndex]['type'] === 'class'
+                        || ($this->tokenType === T_FUNCTION && $infos[$infoIndex]['type'] === 'function'))
+                ) {
+                    $infos[$infoIndex]['shortName'] = $tokens[$tokenIndex + 2][1];
+                    $infos[$infoIndex]['name'] = (($namespace !== null) ? $namespace . '\\' : '') . $infos[$infoIndex]['shortName'];
+                }
+
+                if ($this->tokenType === null) {
+                    if ($tokenContent == '{') {
+                        $classBraceCount++;
+                    }
+                    if ($tokenContent == '}') {
+                        $classBraceCount--;
+                        if ($classBraceCount === 0) {
+                            goto SCANNER_CLASS_END;
+                        }
+                    }
+                }
+
+                SCANNER_CLASS_CONTINUE:
+
+                if ($MACRO_TOKEN_ADVANCE() === false) {
+                    goto SCANNER_END;
+                }
+                goto SCANNER_CLASS_TOP;
+
+                SCANNER_CLASS_END:
+
+                $MACRO_INFO_ADVANCE();
+                goto SCANNER_CONTINUE;
+
+        }
+
+        SCANNER_CONTINUE:
+
+        if ($MACRO_TOKEN_ADVANCE() === false) {
+            goto SCANNER_END;
+        }
+        goto SCANNER_TOP;
+
+        SCANNER_END:
+
+        /**
+         * END FINITE STATE MACHINE FOR SCANNING TOKENS
+         */
+
+        $this->isScanned = true;
+    }
+}
\ No newline at end of file
diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
index 769b3b634d0215b53bfbe8f3df7a5c7171aafaae..2d98bc58f789ad4b8476fa057e615c27d7093253 100644
--- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
+++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
@@ -123,15 +123,20 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
                 /** @var \Magento\Framework\App\State $adminAppState */
                 $adminAppState = $objectManager->get('Magento\Framework\App\State');
                 $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMIN);
-                $objectManager->create(
-                    'Magento\Backend\Model\Auth\Session',
+                /** @var \Magento\Backend\Model\Session\AdminConfig $sessionConfig */
+                $sessionConfig = $objectManager->get(\Magento\Backend\Model\Session\AdminConfig::class);
+                $cookiePath = $this->getSetupCookiePath($objectManager);
+                $sessionConfig->setCookiePath($cookiePath);
+                /** @var \Magento\Backend\Model\Auth\Session $adminSession */
+                $adminSession = $objectManager->create(
+                    \Magento\Backend\Model\Auth\Session::class,
                     [
-                        'sessionConfig' => $objectManager->get('Magento\Backend\Model\Session\AdminConfig'),
+                        'sessionConfig' => $sessionConfig,
                         'appState' => $adminAppState
                     ]
                 );
-
-                if (!$objectManager->get('Magento\Backend\Model\Auth')->isLoggedIn()) {
+                if (!$objectManager->get(\Magento\Backend\Model\Auth::class)->isLoggedIn()) {
+                    $adminSession->destroy();
                     $response = $event->getResponse();
                     $response->getHeaders()->addHeaderLine('Location', 'index.php/session/unlogin');
                     $response->setStatusCode(302);
@@ -144,6 +149,25 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
         return false;
     }
 
+    /**
+     * Get cookie path
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @return string
+     */
+    private function getSetupCookiePath(\Magento\Framework\ObjectManagerInterface $objectManager)
+    {
+        /** @var \Magento\Backend\App\BackendAppList $backendAppList */
+        $backendAppList = $objectManager->get(\Magento\Backend\App\BackendAppList::class);
+        $backendApp = $backendAppList->getBackendApp('setup');
+        /** @var \Magento\Backend\Model\UrlFactory $backendUrlFactory */
+        $backendUrlFactory = $objectManager->get(\Magento\Backend\Model\UrlFactory::class);
+        $baseUrl = parse_url($backendUrlFactory->create()->getBaseUrl(), PHP_URL_PATH);
+        $baseUrl = \Magento\Framework\App\Request\Http::getUrlNoScript($baseUrl);
+        $cookiePath = $baseUrl . $backendApp->getCookiePath();
+        return $cookiePath;
+    }
+
     /**
      * {@inheritdoc}
      */