diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php
index 5c3fd4730aaed4907cbf197f6a5298060ad12acf..0bb468b77ee6ea18df11e7fd349e8315c6f74318 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php
@@ -59,7 +59,7 @@ class Stock extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
         if (isset($stockData['qty']) && $stockData['qty'] === '') {
             $stockData['qty'] = null;
         }
-        if ($object->getStockData() !== null || $stockData !== null) {
+        if ($object->getStockData() !== null && $stockData !== null) {
             $object->setStockData(array_replace((array)$object->getStockData(), (array)$stockData));
         }
         $object->unsetData($this->getAttribute()->getAttributeCode());
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/BaseSelectProcessorInterface.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/BaseSelectProcessorInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6a995b654703402175f79ccc6e50b5172db5fd4
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/BaseSelectProcessorInterface.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\ResourceModel\Product;
+
+use Magento\Framework\DB\Select;
+
+/**
+ * Interface BaseSelectProcessorInterface
+ * @api
+ */
+interface BaseSelectProcessorInterface
+{
+    /**
+     * Product table alias
+     */
+    const PRODUCT_TABLE_ALIAS = 'child';
+
+    /**
+     * @param Select $select
+     * @return Select
+     */
+    public function process(Select $select);
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/CompositeBaseSelectProcessor.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/CompositeBaseSelectProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..86f5a23708400ef40a58677f07e57552a39bd6bd
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/CompositeBaseSelectProcessor.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\ResourceModel\Product;
+
+use Magento\Framework\DB\Select;
+use Magento\Framework\Exception\InputException;
+
+/**
+ * Class CompositeBaseSelectProcessor
+ */
+class CompositeBaseSelectProcessor implements BaseSelectProcessorInterface
+{
+    /**
+     * @var BaseSelectProcessorInterface[]
+     */
+    private $baseSelectProcessors;
+
+    /**
+     * @param BaseSelectProcessorInterface[] $baseSelectProcessors
+     * @throws InputException
+     */
+    public function __construct(
+        array $baseSelectProcessors
+    ) {
+        foreach ($baseSelectProcessors as $baseSelectProcessor) {
+            if (!$baseSelectProcessor instanceof BaseSelectProcessorInterface) {
+                throw new InputException(
+                    __('Processor %1 doesn\'t implement BaseSelectProcessorInterface', get_class($baseSelectProcessor))
+                );
+            }
+        }
+        $this->baseSelectProcessors = $baseSelectProcessors;
+    }
+
+    /**
+     * @param Select $select
+     * @return Select
+     */
+    public function process(Select $select)
+    {
+        foreach ($this->baseSelectProcessors as $baseSelectProcessor) {
+            $select = $baseSelectProcessor->process($select);
+        }
+        return $select;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php
index ea72691ea003939fc277299bee214da316f4f757..3aa6642c82d845eb6ca1143f9c82484c53c659f9 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php
@@ -6,7 +6,8 @@
 namespace Magento\Catalog\Model\ResourceModel\Product\Indexer;
 
 use Magento\Catalog\Api\Data\ProductInterface;
-use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Select;
 use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface;
 
@@ -32,22 +33,31 @@ class LinkedProductSelectBuilderByIndexPrice implements LinkedProductSelectBuild
      */
     private $metadataPool;
 
+    /**
+     * @var BaseSelectProcessorInterface
+     */
+    private $baseSelectProcessor;
+
     /**
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resourceConnection
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
+     * @param BaseSelectProcessorInterface $baseSelectProcessor
      */
     public function __construct(
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\App\ResourceConnection $resourceConnection,
         \Magento\Customer\Model\Session $customerSession,
-        \Magento\Framework\EntityManager\MetadataPool $metadataPool
+        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
+        BaseSelectProcessorInterface $baseSelectProcessor = null
     ) {
         $this->storeManager = $storeManager;
         $this->resource = $resourceConnection;
         $this->customerSession = $customerSession;
         $this->metadataPool = $metadataPool;
+        $this->baseSelectProcessor = (null !== $baseSelectProcessor)
+            ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
     }
 
     /**
@@ -58,24 +68,27 @@ class LinkedProductSelectBuilderByIndexPrice implements LinkedProductSelectBuild
         $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
         $productTable = $this->resource->getTableName('catalog_product_entity');
 
-        return [$this->resource->getConnection()->select()
+        $priceSelect = $this->resource->getConnection()->select()
             ->from(['parent' => $productTable], '')
             ->joinInner(
                 ['link' => $this->resource->getTableName('catalog_product_relation')],
                 "link.parent_id = parent.$linkField",
                 []
             )->joinInner(
-                ['child' => $productTable],
-                "child.entity_id = link.child_id",
+                [BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS => $productTable],
+                sprintf('%s.entity_id = link.child_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 ['entity_id']
             )->joinInner(
                 ['t' => $this->resource->getTableName('catalog_product_index_price')],
-                't.entity_id = child.entity_id',
+                sprintf('t.entity_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 []
-            )->where('parent.entity_id = ? ', $productId)
+            )->where('parent.entity_id = ?', $productId)
             ->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId())
             ->where('t.customer_group_id = ?', $this->customerSession->getCustomerGroupId())
             ->order('t.min_price ' . Select::SQL_ASC)
-            ->limit(1)];
+            ->limit(1);
+        $priceSelect = $this->baseSelectProcessor->process($priceSelect);
+
+        return [$priceSelect];
     }
 }
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php
index d325ab1a9a08d1175c0fedb2a94c10ac5d7dc3c2..7caa72b367979bc4ecbded5641490a59f7835928 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php
@@ -7,6 +7,7 @@ namespace Magento\Catalog\Model\ResourceModel\Product;
 
 use Magento\Catalog\Api\Data\ProductInterface;
 use Magento\Catalog\Model\Product;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Select;
 use Magento\Store\Model\Store;
 
@@ -37,25 +38,34 @@ class LinkedProductSelectBuilderByBasePrice implements LinkedProductSelectBuilde
      */
     private $metadataPool;
 
+    /**
+     * @var BaseSelectProcessorInterface
+     */
+    private $baseSelectProcessor;
+
     /**
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resourceConnection
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Catalog\Helper\Data $catalogHelper
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
+     * @param BaseSelectProcessorInterface $baseSelectProcessor
      */
     public function __construct(
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\App\ResourceConnection $resourceConnection,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Catalog\Helper\Data $catalogHelper,
-        \Magento\Framework\EntityManager\MetadataPool $metadataPool
+        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
+        BaseSelectProcessorInterface $baseSelectProcessor = null
     ) {
         $this->storeManager = $storeManager;
         $this->resource = $resourceConnection;
         $this->eavConfig = $eavConfig;
         $this->catalogHelper = $catalogHelper;
         $this->metadataPool = $metadataPool;
+        $this->baseSelectProcessor = (null !== $baseSelectProcessor)
+            ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
     }
 
     /**
@@ -74,18 +84,19 @@ class LinkedProductSelectBuilderByBasePrice implements LinkedProductSelectBuilde
                 "link.parent_id = parent.$linkField",
                 []
             )->joinInner(
-                ['child' => $productTable],
-                "child.entity_id = link.child_id",
+                [BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS => $productTable],
+                sprintf('%s.entity_id = link.child_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS, $linkField),
                 ['entity_id']
             )->joinInner(
                 ['t' => $priceAttribute->getBackendTable()],
-                "t.$linkField = child.$linkField",
+                sprintf('t.%s = %s.%1$s', $linkField, BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 []
-            )->where('parent.entity_id = ? ', $productId)
+            )->where('parent.entity_id = ?', $productId)
             ->where('t.attribute_id = ?', $priceAttribute->getAttributeId())
             ->where('t.value IS NOT NULL')
             ->order('t.value ' . Select::SQL_ASC)
             ->limit(1);
+        $priceSelect = $this->baseSelectProcessor->process($priceSelect);
 
         $priceSelectDefault = clone $priceSelect;
         $priceSelectDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php
index 792a8f5b86d102204a93491c0413ae2839b16a73..68eaf206e293fea3e90c04e9dfb7bc0329704162 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php
@@ -7,9 +7,13 @@ namespace Magento\Catalog\Model\ResourceModel\Product;
 
 use Magento\Catalog\Api\Data\ProductInterface;
 use Magento\Catalog\Model\Product;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Select;
 use Magento\Store\Model\Store;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBuilderInterface
 {
     /**
@@ -47,6 +51,11 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
      */
     private $metadataPool;
 
+    /**
+     * @var BaseSelectProcessorInterface
+     */
+    private $baseSelectProcessor;
+
     /**
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resourceConnection
@@ -55,6 +64,7 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
+     * @param BaseSelectProcessorInterface $baseSelectProcessor
      */
     public function __construct(
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -63,7 +73,8 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
         \Magento\Catalog\Helper\Data $catalogHelper,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\EntityManager\MetadataPool $metadataPool
+        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
+        BaseSelectProcessorInterface $baseSelectProcessor = null
     ) {
         $this->storeManager = $storeManager;
         $this->resource = $resourceConnection;
@@ -72,6 +83,8 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
         $this->dateTime = $dateTime;
         $this->localeDate = $localeDate;
         $this->metadataPool = $metadataPool;
+        $this->baseSelectProcessor = (null !== $baseSelectProcessor)
+            ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
     }
 
     /**
@@ -95,12 +108,12 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
                 "link.parent_id = parent.$linkField",
                 []
             )->joinInner(
-                ['child' => $productTable],
-                "child.entity_id = link.child_id",
+                [BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS => $productTable],
+                sprintf('%s.entity_id = link.child_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 ['entity_id']
             )->joinInner(
                 ['t' => $specialPriceAttribute->getBackendTable()],
-                "t.$linkField = child.$linkField",
+                sprintf('t.%s = %s.%1$s', $linkField, BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 []
             )->joinLeft(
                 ['special_from' => $specialPriceFromDate->getBackendTable()],
@@ -116,7 +129,7 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
                     $specialPriceToDate->getAttributeId()
                 ),
                 ''
-            )->where('parent.entity_id = ? ', $productId)
+            )->where('parent.entity_id = ?', $productId)
             ->where('t.attribute_id = ?', $specialPriceAttribute->getAttributeId())
             ->where('t.value IS NOT NULL')
             ->where(
@@ -127,6 +140,7 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui
                 $currentDate
             )->order('t.value ' . Select::SQL_ASC)
             ->limit(1);
+        $specialPrice = $this->baseSelectProcessor->process($specialPrice);
 
         $specialPriceDefault = clone $specialPrice;
         $specialPriceDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php
index d2d6d89c0a2a5828290e1191147451e4f6d20b7b..25bf83f837de72cec501379378e6960084d6b1fd 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php
@@ -6,7 +6,7 @@
 namespace Magento\Catalog\Model\ResourceModel\Product;
 
 use Magento\Catalog\Api\Data\ProductInterface;
-use Magento\Catalog\Model\Product;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Select;
 
 class LinkedProductSelectBuilderByTierPrice implements LinkedProductSelectBuilderInterface
@@ -41,25 +41,34 @@ class LinkedProductSelectBuilderByTierPrice implements LinkedProductSelectBuilde
      */
     private $metadataPool;
 
+    /**
+     * @var BaseSelectProcessorInterface
+     */
+    private $baseSelectProcessor;
+
     /**
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resourceConnection
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Catalog\Helper\Data $catalogHelper
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
+     * @param BaseSelectProcessorInterface $baseSelectProcessor
      */
     public function __construct(
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\App\ResourceConnection $resourceConnection,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Catalog\Helper\Data $catalogHelper,
-        \Magento\Framework\EntityManager\MetadataPool $metadataPool
+        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
+        BaseSelectProcessorInterface $baseSelectProcessor = null
     ) {
         $this->storeManager = $storeManager;
         $this->resource = $resourceConnection;
         $this->customerSession = $customerSession;
         $this->catalogHelper = $catalogHelper;
         $this->metadataPool = $metadataPool;
+        $this->baseSelectProcessor = (null !== $baseSelectProcessor)
+            ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
     }
 
     /**
@@ -77,18 +86,19 @@ class LinkedProductSelectBuilderByTierPrice implements LinkedProductSelectBuilde
                 "link.parent_id = parent.$linkField",
                 []
             )->joinInner(
-                ['child' => $productTable],
-                "child.entity_id = link.child_id",
+                [BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS => $productTable],
+                sprintf('%s.entity_id = link.child_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 ['entity_id']
             )->joinInner(
                 ['t' => $this->resource->getTableName('catalog_product_entity_tier_price')],
-                "t.$linkField = child.$linkField",
+                sprintf('t.%s = %s.%1$s', $linkField, BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
                 []
-            )->where('parent.entity_id = ? ', $productId)
+            )->where('parent.entity_id = ?', $productId)
             ->where('t.all_groups = 1 OR customer_group_id = ?', $this->customerSession->getCustomerGroupId())
             ->where('t.qty = ?', 1)
             ->order('t.value ' . Select::SQL_ASC)
             ->limit(1);
+        $priceSelect = $this->baseSelectProcessor->process($priceSelect);
 
         $priceSelectDefault = clone $priceSelect;
         $priceSelectDefault->where('t.website_id = ?', self::DEFAULT_WEBSITE_ID);
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/StatusBaseSelectProcessor.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/StatusBaseSelectProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..656998113fdb92e50e5177db4876651cfcd2023a
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/StatusBaseSelectProcessor.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\ResourceModel\Product;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Eav\Model\Config;
+use Magento\Framework\DB\Select;
+use Magento\Framework\EntityManager\MetadataPool;
+
+/**
+ * Class StatusBaseSelectProcessor
+ */
+class StatusBaseSelectProcessor implements BaseSelectProcessorInterface
+{
+    /**
+     * @var Config
+     */
+    private $eavConfig;
+
+    /**
+     * @var MetadataPool
+     */
+    private $metadataPool;
+
+    /**
+     * @param Config $eavConfig
+     * @param MetadataPool $metadataPool
+     */
+    public function __construct(
+        Config $eavConfig,
+        MetadataPool $metadataPool
+    ) {
+        $this->eavConfig = $eavConfig;
+        $this->metadataPool = $metadataPool;
+    }
+
+    /**
+     * @param Select $select
+     * @return Select
+     */
+    public function process(Select $select)
+    {
+        $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
+        $statusAttribute = $this->eavConfig->getAttribute(Product::ENTITY, ProductInterface::STATUS);
+
+        $select->join(
+            ['status_attr' => $statusAttribute->getBackendTable()],
+            sprintf('status_attr.%s = %s.%1$s', $linkField, self::PRODUCT_TABLE_ALIAS),
+            []
+        )
+            ->where('status_attr.attribute_id = ?', $statusAttribute->getAttributeId())
+            ->where('status_attr.value = ?', Status::STATUS_ENABLED);
+
+        return $select;
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Backend/StockTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Backend/StockTest.php
index ec9cb624db79af510c2625ffee2680ede7653a19..32d62fd7a998e7bf820b7b0c26b6a7202350c26a 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Backend/StockTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Backend/StockTest.php
@@ -125,4 +125,17 @@ class StockTest extends \PHPUnit_Framework_TestCase
         $stockData = $object->getStockData();
         $this->assertEquals(0, $stockData['qty']);
     }
+
+    public function testBeforeSaveNoStockData()
+    {
+        $object = new \Magento\Framework\DataObject(
+            [
+                self::ATTRIBUTE_NAME => ['is_in_stock' => 1, 'qty' => 0]
+            ]
+        );
+
+        $this->model->beforeSave($object);
+        $this->assertNull($object->getStockData());
+        $this->assertNull($object->getData(self::ATTRIBUTE_NAME));
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CompositeBaseSelectProcessorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CompositeBaseSelectProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d296474c202f091b4c1435453ec7941007e10885
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CompositeBaseSelectProcessorTest.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product;
+
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor;
+use Magento\Framework\DB\Select;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class CompositeBaseSelectProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager =  new ObjectManager($this);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testInitializeWithWrongProcessorInstance()
+    {
+        $processorValid = $this->getMock(BaseSelectProcessorInterface::class);
+        $processorInvalid = $this->getMock(\stdClass::class);
+
+        $this->objectManager->getObject(CompositeBaseSelectProcessor::class, [
+            'baseSelectProcessors' => [$processorValid, $processorInvalid],
+        ]);
+    }
+
+    public function testProcess()
+    {
+        $select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
+
+        $processorFirst = $this->getMock(BaseSelectProcessorInterface::class);
+        $processorFirst->expects($this->once())->method('process')->with($select)->willReturn($select);
+
+        $processorSecond = $this->getMock(BaseSelectProcessorInterface::class);
+        $processorSecond->expects($this->once())->method('process')->with($select)->willReturn($select);
+
+        /** @var CompositeBaseSelectProcessor $baseSelectProcessors */
+        $baseSelectProcessors = $this->objectManager->getObject(CompositeBaseSelectProcessor::class, [
+            'baseSelectProcessors' => [$processorFirst, $processorSecond],
+        ]);
+        $this->assertEquals($select, $baseSelectProcessors->process($select));
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/StatusBaseSelectProcessorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/StatusBaseSelectProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0909f754a01c2c937e8c3692c52b1a256a27b0c3
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/StatusBaseSelectProcessorTest.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\Catalog\Model\ResourceModel\Product\StatusBaseSelectProcessor;
+use Magento\Eav\Model\Config;
+use Magento\Eav\Model\Entity\Attribute\AttributeInterface;
+use Magento\Framework\DB\Select;
+use Magento\Framework\EntityManager\EntityMetadataInterface;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class StatusBaseSelectProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eavConfig;
+
+    /**
+     * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $metadataPool;
+
+    /**
+     * @var Select|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $select;
+
+    /**
+     * @var StatusBaseSelectProcessor
+     */
+    private $statusBaseSelectProcessor;
+
+    protected function setUp()
+    {
+        $this->eavConfig = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
+        $this->metadataPool = $this->getMockBuilder(MetadataPool::class)->disableOriginalConstructor()->getMock();
+        $this->select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
+
+        $this->statusBaseSelectProcessor =  (new ObjectManager($this))->getObject(StatusBaseSelectProcessor::class, [
+            'eavConfig' => $this->eavConfig,
+            'metadataPool' => $this->metadataPool,
+        ]);
+    }
+
+    public function testProcess()
+    {
+        $linkField = 'link_field';
+        $backendTable = 'backend_table';
+        $attributeId = 'attribute_id';
+
+        $metadata = $this->getMock(EntityMetadataInterface::class);
+        $metadata->expects($this->once())
+            ->method('getLinkField')
+            ->willReturn($linkField);
+        $this->metadataPool->expects($this->once())
+            ->method('getMetadata')
+            ->with(ProductInterface::class)
+            ->willReturn($metadata);
+
+        $statusAttribute = $this->getMockBuilder(AttributeInterface::class)
+            ->setMethods(['getBackendTable', 'getAttributeId'])
+            ->getMock();
+        $statusAttribute->expects($this->once())
+            ->method('getBackendTable')
+            ->willReturn($backendTable);
+        $statusAttribute->expects($this->once())
+            ->method('getAttributeId')
+            ->willReturn($attributeId);
+        $this->eavConfig->expects($this->once())
+            ->method('getAttribute')
+            ->with(Product::ENTITY, ProductInterface::STATUS)
+            ->willReturn($statusAttribute);
+
+        $this->select->expects($this->once())
+            ->method('join')
+            ->with(
+                ['status_attr' => $backendTable],
+                sprintf('status_attr.%s = %s.%1$s', $linkField, BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
+                []
+            )
+            ->willReturnSelf();
+        $this->select->expects($this->at(1))
+            ->method('where')
+            ->with('status_attr.attribute_id = ?', $attributeId)
+            ->willReturnSelf();
+        $this->select->expects($this->at(2))
+            ->method('where')
+            ->with('status_attr.value = ?', Status::STATUS_ENABLED)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->select, $this->statusBaseSelectProcessor->process($this->select));
+    }
+}
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index d191f0332f5f28d28f22e981f8ebc74f0c0c8b98..6b39520ae021e9eb3bfafa20bda03e42c7db907a 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -837,4 +837,12 @@
     <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
         <plugin name="copy_quote_files_to_order" type="Magento\Catalog\Model\Plugin\QuoteItemProductOption"/>
     </type>
+    <preference for="Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface" type="Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor" />
+    <type name="Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor">
+        <arguments>
+            <argument name="baseSelectProcessors" xsi:type="array">
+                <item name="status" xsi:type="object">Magento\Catalog\Model\ResourceModel\Product\StatusBaseSelectProcessor</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..829fa8decda7d74b554810ba17118faba2ca970c
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Model\ResourceModel\Product;
+
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\CatalogInventory\Model\Stock;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Select;
+
+/**
+ * Class StockStatusBaseSelectProcessor
+ */
+class StockStatusBaseSelectProcessor implements BaseSelectProcessorInterface
+{
+    /**
+     * @var ResourceConnection
+     */
+    private $resource;
+
+    /**
+     * @param ResourceConnection $resource
+     */
+    public function __construct(ResourceConnection $resource)
+    {
+        $this->resource = $resource;
+    }
+
+    /**
+     * Add stock item filter to selects
+     *
+     * @param Select $select
+     * @return Select
+     */
+    public function process(Select $select)
+    {
+        $stockStatusTable = $this->resource->getTableName('cataloginventory_stock_status');
+
+        /** @var Select $select */
+        $select->join(
+            ['stock' => $stockStatusTable],
+            sprintf('stock.product_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
+            []
+        )
+            ->where('stock.stock_status = ?', Stock::STOCK_IN_STOCK);
+        return $select;
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4756e42ffe602bfc3b258656e0f2abe490a3acc1
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Test\Unit\Model\ResourceModel\Product;
+
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\CatalogInventory\Model\ResourceModel\Product\StockStatusBaseSelectProcessor;
+use Magento\CatalogInventory\Model\Stock;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Select;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class StockStatusBaseSelectProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resource;
+
+    /**
+     * @var Select|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $select;
+
+    /**
+     * @var StockStatusBaseSelectProcessor
+     */
+    private $stockStatusBaseSelectProcessor;
+
+    protected function setUp()
+    {
+        $this->resource = $this->getMockBuilder(ResourceConnection::class)->disableOriginalConstructor()->getMock();
+        $this->select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
+
+        $this->stockStatusBaseSelectProcessor =  (new ObjectManager($this))->getObject(
+            StockStatusBaseSelectProcessor::class,
+            [
+                'resource' => $this->resource,
+            ]
+        );
+    }
+
+    public function testProcess()
+    {
+        $tableName = 'table_name';
+
+        $this->resource->expects($this->once())
+            ->method('getTableName')
+            ->with('cataloginventory_stock_status')
+            ->willReturn($tableName);
+
+        $this->select->expects($this->once())
+            ->method('join')
+            ->with(
+                ['stock' => $tableName],
+                sprintf('stock.product_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
+                []
+            )
+            ->willReturnSelf();
+        $this->select->expects($this->once())
+            ->method('where')
+            ->with('stock.stock_status = ?', Stock::STOCK_IN_STOCK)
+            ->willReturnSelf();
+
+        $this->stockStatusBaseSelectProcessor->process($this->select);
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index 71b42ef89f73ce981f25393179fbbd05f59a4d08..e3ca5c01cedab6b5041a16248308208b3cccbcf5 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -79,4 +79,11 @@
             <argument name="indexerProcessor" xsi:type="object">Magento\CatalogInventory\Model\Indexer\Stock\Processor</argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Model\ResourceModel\Product\CompositeBaseSelectProcessor">
+        <arguments>
+            <argument name="baseSelectProcessors" xsi:type="array">
+                <item name="stock_status" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Product\StockStatusBaseSelectProcessor</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php
index 7d8d44dcbb68ad2539f0556fb7aec8eebe0caa2e..55b76eb225028a1a3d96d115066a4abc4b78fd60 100644
--- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php
+++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php
@@ -6,7 +6,8 @@
 namespace Magento\CatalogRule\Model\ResourceModel\Product;
 
 use Magento\Catalog\Api\Data\ProductInterface;
-use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Select;
 use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface;
 
@@ -42,6 +43,11 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
      */
     private $metadataPool;
 
+    /**
+     * @var BaseSelectProcessorInterface
+     */
+    private $baseSelectProcessor;
+
     /**
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resourceConnection
@@ -49,6 +55,7 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
+     * @param BaseSelectProcessorInterface $baseSelectProcessor
      */
     public function __construct(
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -56,7 +63,8 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\EntityManager\MetadataPool $metadataPool
+        \Magento\Framework\EntityManager\MetadataPool $metadataPool,
+        BaseSelectProcessorInterface $baseSelectProcessor = null
     ) {
         $this->storeManager = $storeManager;
         $this->resource = $resourceConnection;
@@ -64,6 +72,8 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
         $this->dateTime = $dateTime;
         $this->localeDate = $localeDate;
         $this->metadataPool = $metadataPool;
+        $this->baseSelectProcessor = (null !== $baseSelectProcessor)
+            ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
     }
 
     /**
@@ -76,25 +86,28 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
         $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
         $productTable = $this->resource->getTableName('catalog_product_entity');
 
-        return [$this->resource->getConnection()->select()
-                ->from(['parent' => $productTable], '')
-                ->joinInner(
-                    ['link' => $this->resource->getTableName('catalog_product_relation')],
-                    "link.parent_id = parent.$linkField",
-                    []
-                )->joinInner(
-                    ['child' => $productTable],
-                    "child.entity_id = link.child_id",
-                    ['entity_id']
-                )->joinInner(
-                    ['t' => $this->resource->getTableName('catalogrule_product_price')],
-                    't.product_id = child.entity_id',
-                    []
-                )->where('parent.entity_id = ? ', $productId)
+        $priceSelect = $this->resource->getConnection()->select()
+            ->from(['parent' => $productTable], '')
+            ->joinInner(
+                ['link' => $this->resource->getTableName('catalog_product_relation')],
+                "link.parent_id = parent.$linkField",
+                []
+            )->joinInner(
+                [BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS => $productTable],
+                sprintf('%s.entity_id = link.child_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
+                ['entity_id']
+            )->joinInner(
+                ['t' => $this->resource->getTableName('catalogrule_product_price')],
+                sprintf('t.product_id = %s.%s', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS, $linkField),
+                []
+            )->where('parent.entity_id = ?', $productId)
             ->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId())
             ->where('t.customer_group_id = ?', $this->customerSession->getCustomerGroupId())
             ->where('t.rule_date = ?', $currentDate)
             ->order('t.rule_price ' . Select::SQL_ASC)
-            ->limit(1)];
+            ->limit(1);
+        $priceSelect = $this->baseSelectProcessor->process($priceSelect);
+
+        return [$priceSelect];
     }
 }
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 2d6fa460ef66d26d106ad9417ffdf8d3548a3d00..3ec34cd96574bc90e5b0f8bd3bf552a877444ab0 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
@@ -44,6 +44,13 @@ define(
                         addressData.region.region_code = region['code'];
                         addressData.region.region = region['name'];
                     }
+                } else if (
+                    !addressData.region_id
+                    && countryData()[addressData.country_id]
+                    && countryData()[addressData.country_id]['regions']
+                ) {
+                    addressData.region.region_code = '';
+                    addressData.region.region = '';
                 }
                 delete addressData.region_id;
 
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
index bee4480b0dfb1c9db669d53f5091bb1d3564237a..9a3685b212b435e8c03adb7be2cd7a182e591b87 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
@@ -22,7 +22,7 @@ define([], function () {
         return {
             email: addressData.email,
             countryId: addressData['country_id'] || addressData.countryId || window.checkoutConfig.defaultCountryId,
-            regionId: regionId,
+            regionId: regionId || addressData.regionId,
             regionCode: (addressData.region) ? addressData.region.region_code : null,
             region: (addressData.region) ? addressData.region.region : null,
             customerId: addressData.customer_id,
@@ -30,7 +30,7 @@ define([], function () {
             company: addressData.company,
             telephone: addressData.telephone,
             fax: addressData.fax,
-            postcode: addressData.postcode ? addressData.postcode : window.checkoutConfig.defaultPostcode,
+            postcode: addressData.postcode ? addressData.postcode : window.checkoutConfig.defaultPostcode || undefined,
             city: addressData.city,
             firstname: addressData.firstname,
             lastname: addressData.lastname,
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
index 420d50b83478a91ab38b6a333a681f119b6db49e..c49960ecfb91dec735239c8bc1cc88f7ffebfab0 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
@@ -176,7 +176,7 @@ define(
                     address;
 
                 if (this.validateAddressData(addressFlat)) {
-                    addressFlat = $.extend(true, {}, quote.shippingAddress(), addressFlat);
+                    addressFlat = uiRegistry.get('checkoutProvider').shippingAddress;
                     address = addressConverter.formAddressDataToQuoteAddress(addressFlat);
                     selectShippingAddress(address);
                 }
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProvider.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProvider.php
index dcb75fe725dc20d74aa245831e8046dbd9665949..872538d9babab02aec00763ee317298f9c93697e 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProvider.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProvider.php
@@ -18,26 +18,6 @@ class ConfigurableOptionsProvider implements ConfigurableOptionsProviderInterfac
     /** @var Configurable */
     private $configurable;
 
-    /**
-     * @var RequestSafetyInterface
-     */
-    private $requestSafety;
-
-    /**
-     * @var ResourceConnection
-     */
-    private $resource;
-
-    /**
-     * @var LinkedProductSelectBuilderInterface
-     */
-    private $linkedProductSelectBuilder;
-
-    /**
-     * @var CollectionFactory
-     */
-    private $collectionFactory;
-
     /**
      * @var ProductInterface[]
      */
@@ -49,6 +29,7 @@ class ConfigurableOptionsProvider implements ConfigurableOptionsProviderInterfac
      * @param LinkedProductSelectBuilderInterface $linkedProductSelectBuilder
      * @param CollectionFactory $collectionFactory
      * @param RequestSafetyInterface $requestSafety
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(
         Configurable $configurable,
@@ -58,10 +39,6 @@ class ConfigurableOptionsProvider implements ConfigurableOptionsProviderInterfac
         RequestSafetyInterface $requestSafety
     ) {
         $this->configurable = $configurable;
-        $this->resource = $resourceConnection;
-        $this->linkedProductSelectBuilder = $linkedProductSelectBuilder;
-        $this->collectionFactory = $collectionFactory;
-        $this->requestSafety = $requestSafety;
     }
 
     /**
@@ -70,17 +47,7 @@ class ConfigurableOptionsProvider implements ConfigurableOptionsProviderInterfac
     public function getProducts(ProductInterface $product)
     {
         if (!isset($this->products[$product->getId()])) {
-            if ($this->requestSafety->isSafeMethod()) {
-                $productIds = $this->resource->getConnection()->fetchCol(
-                    '(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')'
-                );
-
-                $this->products[$product->getId()] = $this->collectionFactory->create()
-                    ->addAttributeToSelect(['price', 'special_price'])
-                    ->addIdFilter($productIds);
-            } else {
-                $this->products[$product->getId()] = $this->configurable->getUsedProducts($product);
-            }
+            $this->products[$product->getId()] = $this->configurable->getUsedProducts($product);
         }
         return $this->products[$product->getId()];
     }
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProviderInterface.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProviderInterface.php
index c7ac9446f42e306b78badec5f4b0825ce8c6f6c1..c0f2c218cc77c80a8e6785aba97431baea793975 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProviderInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableOptionsProviderInterface.php
@@ -10,6 +10,7 @@ use Magento\Catalog\Api\Data\ProductInterface;
 
 /**
  * Provide configurable sub-products for price calculation
+ * @api
  */
 interface ConfigurableOptionsProviderInterface
 {
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
index 75d08b5aa419bdec6d9db0c3112f2aa1b7e836a6..68e82ed76a23fbdda404c32eb7406d3117b3cd0e 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
@@ -6,7 +6,6 @@
 
 namespace Magento\ConfigurableProduct\Pricing\Price;
 
-use Magento\Catalog\Model\Product;
 use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
 use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
@@ -29,23 +28,27 @@ class ConfigurablePriceResolver implements PriceResolverInterface
     protected $configurable;
 
     /**
-     * @var ConfigurableOptionsProviderInterface
+     * @var LowestPriceOptionsProviderInterface
      */
-    private $configurableOptionsProvider;
+    private $lowestPriceOptionsProvider;
 
     /**
      * @param PriceResolverInterface $priceResolver
      * @param Configurable $configurable
      * @param PriceCurrencyInterface $priceCurrency
+     * @param LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider
      */
     public function __construct(
         PriceResolverInterface $priceResolver,
         Configurable $configurable,
-        PriceCurrencyInterface $priceCurrency
+        PriceCurrencyInterface $priceCurrency,
+        LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null
     ) {
         $this->priceResolver = $priceResolver;
         $this->configurable = $configurable;
         $this->priceCurrency = $priceCurrency;
+        $this->lowestPriceOptionsProvider = $lowestPriceOptionsProvider ?:
+            ObjectManager::getInstance()->get(LowestPriceOptionsProviderInterface::class);
     }
 
     /**
@@ -57,7 +60,7 @@ class ConfigurablePriceResolver implements PriceResolverInterface
     {
         $price = null;
 
-        foreach ($this->getConfigurableOptionsProvider()->getProducts($product) as $subProduct) {
+        foreach ($this->lowestPriceOptionsProvider->getProducts($product) as $subProduct) {
             $productPrice = $this->priceResolver->resolvePrice($subProduct);
             $price = $price ? min($price, $productPrice) : $productPrice;
         }
@@ -69,17 +72,4 @@ class ConfigurablePriceResolver implements PriceResolverInterface
 
         return (float)$price;
     }
-
-    /**
-     * @return \Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface
-     * @deprecated
-     */
-    private function getConfigurableOptionsProvider()
-    {
-        if (null === $this->configurableOptionsProvider) {
-            $this->configurableOptionsProvider = ObjectManager::getInstance()
-                ->get(ConfigurableOptionsProviderInterface::class);
-        }
-        return $this->configurableOptionsProvider;
-    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
index 14b788258ab75502183aaf0b3f842b1943fcec2d..7a710e2caacc96f0a20eae124d973de9fa6a4c49 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
@@ -44,22 +44,31 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
      */
     private $configurableOptionsProvider;
 
+    /**
+     * @var LowestPriceOptionsProviderInterface
+     */
+    private $lowestPriceOptionsProvider;
+
     /**
      * @param \Magento\Framework\Pricing\SaleableInterface $saleableItem
      * @param float $quantity
      * @param \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator
      * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
      * @param PriceResolverInterface $priceResolver
+     * @param LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider
      */
     public function __construct(
         \Magento\Framework\Pricing\SaleableInterface $saleableItem,
         $quantity,
         \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator,
         \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
-        PriceResolverInterface $priceResolver
+        PriceResolverInterface $priceResolver,
+        LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null
     ) {
         parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
         $this->priceResolver = $priceResolver;
+        $this->lowestPriceOptionsProvider = $lowestPriceOptionsProvider ?:
+            ObjectManager::getInstance()->get(LowestPriceOptionsProviderInterface::class);
     }
 
     /**
@@ -88,7 +97,6 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
     public function getMaxRegularAmount()
     {
         if (null === $this->maxRegularAmount) {
-            $this->maxRegularAmount = $this->doGetMaxRegularAmount();
             $this->maxRegularAmount = $this->doGetMaxRegularAmount() ?: false;
         }
         return $this->maxRegularAmount;
@@ -96,7 +104,7 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
     }
 
     /**
-     * Get max regular amount. Template method
+     * Get max regular amount
      *
      * @return \Magento\Framework\Pricing\Amount\AmountInterface
      */
@@ -124,14 +132,14 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
     }
 
     /**
-     * Get min regular amount. Template method
+     * Get min regular amount
      *
      * @return \Magento\Framework\Pricing\Amount\AmountInterface
      */
     protected function doGetMinRegularAmount()
     {
         $minAmount = null;
-        foreach ($this->getUsedProducts() as $product) {
+        foreach ($this->lowestPriceOptionsProvider->getProducts($this->product) as $product) {
             $childPriceAmount = $product->getPriceInfo()->getPrice(self::PRICE_CODE)->getAmount();
             if (!$minAmount || ($childPriceAmount->getValue() < $minAmount->getValue())) {
                 $minAmount = $childPriceAmount;
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b758866100eb8f52faa371e4bc1695ce385703f
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
+
+/**
+ * Retrieve list of products where each product contains lower price than others at least for one possible price type
+ */
+class LowestPriceOptionsProvider implements LowestPriceOptionsProviderInterface
+{
+    /**
+     * @var ResourceConnection
+     */
+    private $resource;
+
+    /**
+     * @var LinkedProductSelectBuilderInterface
+     */
+    private $linkedProductSelectBuilder;
+
+    /**
+     * @var CollectionFactory
+     */
+    private $collectionFactory;
+
+    /**
+     * @param ResourceConnection $resourceConnection
+     * @param LinkedProductSelectBuilderInterface $linkedProductSelectBuilder
+     * @param CollectionFactory $collectionFactory
+     */
+    public function __construct(
+        ResourceConnection $resourceConnection,
+        LinkedProductSelectBuilderInterface $linkedProductSelectBuilder,
+        CollectionFactory $collectionFactory
+    ) {
+        $this->resource = $resourceConnection;
+        $this->linkedProductSelectBuilder = $linkedProductSelectBuilder;
+        $this->collectionFactory = $collectionFactory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProducts(ProductInterface $product)
+    {
+        $productIds = $this->resource->getConnection()->fetchCol(
+            '(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')'
+        );
+
+        $lowestPriceChildProducts = $this->collectionFactory->create()
+            ->addAttributeToSelect(['price', 'special_price'])
+            ->addIdFilter($productIds)
+            ->getItems();
+        return $lowestPriceChildProducts;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProviderInterface.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProviderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0989a929be55ce46bdaa3451ba88a8a3ae8272a
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProviderInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+
+/**
+ * Retrieve list of products where each product contains lower price than others at least for one possible price type
+ * @api
+ */
+interface LowestPriceOptionsProviderInterface
+{
+    /**
+     * @param ProductInterface $product
+     * @return \Magento\Catalog\Api\Data\ProductInterface[]
+     */
+    public function getProducts(\Magento\Catalog\Api\Data\ProductInterface $product);
+}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php
index 16a296a3554548d31f1692f397cd0124e272a1af..19bf0eee888f181902824505a2808f8ae5106c15 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php
@@ -8,6 +8,8 @@ namespace Magento\ConfigurableProduct\Pricing\Render;
 use Magento\Catalog\Pricing\Price\FinalPrice;
 use Magento\Catalog\Pricing\Price\RegularPrice;
 use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
+use Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Pricing\Price\PriceInterface;
 use Magento\Framework\Pricing\Render\RendererPool;
 use Magento\Framework\Pricing\SaleableInterface;
@@ -16,9 +18,9 @@ use Magento\Framework\View\Element\Template\Context;
 class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
 {
     /**
-     * @var ConfigurableOptionsProviderInterface
+     * @var LowestPriceOptionsProviderInterface
      */
-    private $configurableOptionsProvider;
+    private $lowestPriceOptionsProvider;
 
     /**
      * @param Context $context
@@ -27,6 +29,8 @@ class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
      * @param RendererPool $rendererPool
      * @param ConfigurableOptionsProviderInterface $configurableOptionsProvider
      * @param array $data
+     * @param LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(
         Context $context,
@@ -34,10 +38,12 @@ class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
         PriceInterface $price,
         RendererPool $rendererPool,
         ConfigurableOptionsProviderInterface $configurableOptionsProvider,
-        array $data = []
+        array $data = [],
+        LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null
     ) {
-        $this->configurableOptionsProvider = $configurableOptionsProvider;
         parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
+        $this->lowestPriceOptionsProvider = $lowestPriceOptionsProvider ?:
+            ObjectManager::getInstance()->get(LowestPriceOptionsProviderInterface::class);
     }
 
     /**
@@ -48,7 +54,7 @@ class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
     public function hasSpecialPrice()
     {
         $product = $this->getSaleableItem();
-        foreach ($this->configurableOptionsProvider->getProducts($product) as $subProduct) {
+        foreach ($this->lowestPriceOptionsProvider->getProducts($product) as $subProduct) {
             $regularPrice = $subProduct->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getValue();
             $finalPrice = $subProduct->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
             if ($finalPrice < $regularPrice) {
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
index 0e2cfc0630226d500db55db0fd0fb0b60bb4d121..8db61bb5e0a4322ff3d614348616dfc0e2f34e27 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
@@ -5,13 +5,15 @@
  */
 namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Price;
 
-use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
+use Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var  ConfigurableOptionsProviderInterface */
-    private $cofigurableOptionProvider;
+    /**
+     * @var LowestPriceOptionsProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $lowestPriceOptionsProvider;
 
     /**
      * @var \Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver
@@ -19,12 +21,12 @@ class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
     protected $resolver;
 
     /**
-     * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Model\Product\Type\Configurable
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Model\Product\Type\Configurable
      */
     protected $configurable;
 
     /**
-     * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface
      */
     protected $priceResolver;
 
@@ -36,8 +38,7 @@ class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
         $className = \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface::class;
         $this->priceResolver = $this->getMockForAbstractClass($className, [], '', false, true, true, ['resolvePrice']);
 
-        $this->cofigurableOptionProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class)
-            ->disableOriginalConstructor()->getMock();
+        $this->lowestPriceOptionsProvider = $this->getMock(LowestPriceOptionsProviderInterface::class);
 
         $objectManager = new ObjectManager($this);
         $this->resolver = $objectManager->getObject(
@@ -45,7 +46,7 @@ class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
             [
                 'priceResolver' => $this->priceResolver,
                 'configurable' => $this->configurable,
-                'configurableOptionsProvider' => $this->cofigurableOptionProvider,
+                'lowestPriceOptionsProvider' => $this->lowestPriceOptionsProvider,
             ]
         );
     }
@@ -63,7 +64,7 @@ class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
 
         $product->expects($this->once())->method('getSku')->willReturn('Kiwi');
 
-        $this->cofigurableOptionProvider->expects($this->once())->method('getProducts')->willReturn([]);
+        $this->lowestPriceOptionsProvider->expects($this->once())->method('getProducts')->willReturn([]);
 
         $this->resolver->resolvePrice($product);
     }
@@ -83,8 +84,11 @@ class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase
 
         $product->expects($this->never())->method('getSku');
 
-        $this->cofigurableOptionProvider->expects($this->once())->method('getProducts')->willReturn([$product]);
-        $this->priceResolver->expects($this->atLeastOnce())->method('resolvePrice')->willReturn($price);
+        $this->lowestPriceOptionsProvider->expects($this->once())->method('getProducts')->willReturn([$product]);
+        $this->priceResolver->expects($this->once())
+            ->method('resolvePrice')
+            ->with($product)
+            ->willReturn($price);
 
         $this->assertEquals($expectedValue, $this->resolver->resolvePrice($product));
     }
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
index 4dbcfed5315252c62494b6ede30d4d14f9a598b2..b102e1d81f48ea421ce29a7cd914a758e94ccb68 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
@@ -7,8 +7,9 @@ namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Render;
 
 use Magento\Catalog\Pricing\Price\FinalPrice;
 use Magento\Catalog\Pricing\Price\RegularPrice;
-use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
+use Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface;
 use Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
 {
@@ -33,9 +34,9 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
     private $rendererPool;
 
     /**
-     * @var ConfigurableOptionsProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var LowestPriceOptionsProviderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $configurableOptionsProvider;
+    private $lowestPriceOptionsProvider;
 
     /**
      * @var FinalPriceBox
@@ -59,15 +60,18 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->configurableOptionsProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class)
+        $this->lowestPriceOptionsProvider = $this->getMockBuilder(LowestPriceOptionsProviderInterface::class)
             ->getMockForAbstractClass();
 
-        $this->model = new FinalPriceBox(
-            $this->context,
-            $this->saleableItem,
-            $this->price,
-            $this->rendererPool,
-            $this->configurableOptionsProvider
+        $this->model = (new ObjectManager($this))->getObject(
+            FinalPriceBox::class,
+            [
+                'context' => $this->context,
+                'saleableItem' => $this->saleableItem,
+                'price' => $this->price,
+                'rendererPool' => $this->rendererPool,
+                'lowestPriceOptionsProvider' => $this->lowestPriceOptionsProvider,
+            ]
         );
     }
 
@@ -115,7 +119,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
             ->method('getPriceInfo')
             ->willReturn($priceInfoMock);
 
-        $this->configurableOptionsProvider->expects($this->once())
+        $this->lowestPriceOptionsProvider->expects($this->once())
             ->method('getProducts')
             ->with($this->saleableItem)
             ->willReturn([$productMock]);
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index 89b271de838f992e9acd93ecdd27bc321f59d54e..b4d63d9d0245f84b3ecbae128e5254e8f9bf213a 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -13,6 +13,7 @@
     <preference for="Magento\ConfigurableProduct\Api\Data\OptionValueInterface" type="Magento\ConfigurableProduct\Model\Product\Type\Configurable\OptionValue" />
     <preference for="Magento\ConfigurableProduct\Api\Data\ConfigurableItemOptionValueInterface" type="Magento\ConfigurableProduct\Model\Quote\Item\ConfigurableItemOptionValue" />
     <preference for="Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface" type="Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProvider" />
+    <preference for="Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface" type="Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProvider" />
 
     <type name="Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option">
         <plugin name="configurable_product" type="Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct" sortOrder="50" />
diff --git a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/FrontendCompilation.php b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/FrontendCompilation.php
index 4573f15b016fa47bab5cc0fa7c7010644c4ada6e..8cd04f7d1e4c54804ba32c3c8b5235f9da3dd1db 100644
--- a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/FrontendCompilation.php
+++ b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/FrontendCompilation.php
@@ -74,10 +74,6 @@ class FrontendCompilation implements PreProcessorInterface
      */
     public function process(PreProcessor\Chain $chain)
     {
-        $content = $chain->getContent();
-        if (trim($content) !== '') {
-            return;
-        }
 
         try {
             $this->lockerProcess->lockProcess($this->lockName);
@@ -88,7 +84,7 @@ class FrontendCompilation implements PreProcessorInterface
             /** @var FallbackContext $context */
             $context = $chain->getAsset()->getContext();
 
-            $result = $this->processContent($path, $content, $module, $context);
+            $result = $this->processContent($path, $chain->getContent(), $module, $context);
             $chain->setContent($result['content']);
             $chain->setContentType($result['sourceType']);
         } finally {
@@ -107,14 +103,14 @@ class FrontendCompilation implements PreProcessorInterface
      */
     private function processContent($path, $content, $module, FallbackContext $context)
     {
-        $sourceType = '#\.' . preg_quote(pathinfo($path, PATHINFO_EXTENSION), '#') . '$#';
+        $sourceTypePattern = '#\.' . preg_quote(pathinfo($path, PATHINFO_EXTENSION), '#') . '$#';
 
         foreach ($this->alternativeSource->getAlternativesExtensionsNames() as $name) {
             $asset = $this->assetBuilder->setArea($context->getAreaCode())
                 ->setTheme($context->getThemePath())
                 ->setLocale($context->getLocale())
                 ->setModule($module)
-                ->setPath(preg_replace($sourceType, '.' . $name, $path))
+                ->setPath(preg_replace($sourceTypePattern, '.' . $name, $path))
                 ->build();
 
             $processedContent = $this->assetSource->getContent($asset);
@@ -129,7 +125,7 @@ class FrontendCompilation implements PreProcessorInterface
 
         return [
             'content' => $content,
-            'sourceType' => $sourceType
+            'sourceType' => pathinfo($path, PATHINFO_EXTENSION)
         ];
     }
 }
diff --git a/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/FrontendCompilationTest.php b/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/FrontendCompilationTest.php
index 97f0b1d5a6bdb081a47f22884f6dac93b3a743f1..b43d91c5e4dc6bc7768c47b1f8599c73b5855932 100644
--- a/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/FrontendCompilationTest.php
+++ b/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/FrontendCompilationTest.php
@@ -189,38 +189,6 @@ class FrontendCompilationTest extends \PHPUnit_Framework_TestCase
         $frontendCompilation->process($this->getChainMockExpects('', 1, 1, $newContentType));
     }
 
-    /**
-     * Run test for process method (content not empty)
-     */
-    public function testProcessContentNotEmpty()
-    {
-        $chainMock = $this->getChainMock();
-        $assetMock = $this->getAssetMock();
-
-        $chainMock->expects(self::once())
-            ->method('getContent')
-            ->willReturn('test-content');
-
-        $chainMock->expects(self::never())
-            ->method('getAsset')
-            ->willReturn($assetMock);
-
-        $this->lockerProcessMock->expects(self::never())
-            ->method('lockProcess');
-        $this->lockerProcessMock->expects(self::never())
-            ->method('unlockProcess');
-
-        $frontendCompilation = new FrontendCompilation(
-            $this->assetSourceMock,
-            $this->assetBuilderMock,
-            $this->alternativeSourceMock,
-            $this->lockerProcessMock,
-            'lock'
-        );
-
-        $frontendCompilation->process($chainMock);
-    }
-
     /**
      * @return Chain|\PHPUnit_Framework_MockObject_MockObject
      */
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 3cdcf70cf24266ae7613e7e6f790c4b6777ff23b..f84ca33b436f91e4afca6cae6f52c8b975cf4289 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -2157,6 +2157,12 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     {
         if (!$this->getReservedOrderId()) {
             $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this));
+        } else {
+            //checking if reserved order id was already used for some order
+            //if yes reserving new one if not using old one
+            if ($this->_getResource()->isOrderIncrementIdUsed($this->getReservedOrderId())) {
+                $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this));
+            }
         }
         return $this;
     }
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..7d8946661476cb851f2488405708847530e99673 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
@@ -59,10 +59,8 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
 
         $addressWeight = $address->getWeight();
         $freeMethodWeight = $address->getFreeMethodWeight();
+        $addressFreeShipping = $address->getFreeShipping();
 
-        $address->setFreeShipping(
-            $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems())
-        );
         $total->setTotalAmount($this->getCode(), 0);
         $total->setBaseTotalAmount($this->getCode(), 0);
 
@@ -98,7 +96,7 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
                         $itemQty = $child->getTotalQty();
                         $rowWeight = $itemWeight * $itemQty;
                         $addressWeight += $rowWeight;
-                        if ($address->getFreeShipping() || $child->getFreeShipping() === true) {
+                        if ($addressFreeShipping || $child->getFreeShipping() === true) {
                             $rowWeight = 0;
                         } elseif (is_numeric($child->getFreeShipping())) {
                             $freeQty = $child->getFreeShipping();
@@ -116,7 +114,7 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
                     $itemWeight = $item->getWeight();
                     $rowWeight = $itemWeight * $item->getQty();
                     $addressWeight += $rowWeight;
-                    if ($address->getFreeShipping() || $item->getFreeShipping() === true) {
+                    if ($addressFreeShipping || $item->getFreeShipping() === true) {
                         $rowWeight = 0;
                     } elseif (is_numeric($item->getFreeShipping())) {
                         $freeQty = $item->getFreeShipping();
@@ -136,7 +134,7 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
                 $itemWeight = $item->getWeight();
                 $rowWeight = $itemWeight * $item->getQty();
                 $addressWeight += $rowWeight;
-                if ($address->getFreeShipping() || $item->getFreeShipping() === true) {
+                if ($addressFreeShipping || $item->getFreeShipping() === true) {
                     $rowWeight = 0;
                 } elseif (is_numeric($item->getFreeShipping())) {
                     $freeQty = $item->getFreeShipping();
@@ -157,6 +155,10 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
 
         $address->setWeight($addressWeight);
         $address->setFreeMethodWeight($freeMethodWeight);
+        $address->setFreeShipping(
+            $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems())
+        );
+
         $address->collectShippingRates();
 
         if ($method) {
diff --git a/app/code/Magento/Quote/Model/ResourceModel/Quote.php b/app/code/Magento/Quote/Model/ResourceModel/Quote.php
index 241f0d6b272fc33f6b29ff4e2c069ca088c5073b..6113a1ba56ac184d59a6d0e37bd696455dce31cd 100644
--- a/app/code/Magento/Quote/Model/ResourceModel/Quote.php
+++ b/app/code/Magento/Quote/Model/ResourceModel/Quote.php
@@ -172,6 +172,29 @@ class Quote extends AbstractDb
         ->getNextValue();
     }
 
+    /**
+     * Check if order increment ID is already used.
+     * Method can be used to avoid collisions of order IDs.
+     *
+     * @param int $orderIncrementId
+     * @return bool
+     */
+    public function isOrderIncrementIdUsed($orderIncrementId)
+    {
+        /** @var  \Magento\Framework\DB\Adapter\AdapterInterface $adapter */
+        $adapter = $this->getConnection();
+        $bind = [':increment_id' => $orderIncrementId];
+        /** @var \Magento\Framework\DB\Select $select */
+        $select = $adapter->select();
+        $select->from($this->getTable('sales_order'), 'entity_id')->where('increment_id = :increment_id');
+        $entity_id = $adapter->fetchOne($select, $bind);
+        if ($entity_id > 0) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Mark quotes - that depend on catalog price rules - to be recollected on demand
      *
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
index 5165f299d45a96b7aa9b130a03747fad38955084..b54ce84fe1ac45fbee2d1b2c89a99c8546a11cab 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
@@ -314,7 +314,10 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
                     'customerRepository' => $this->customerRepositoryMock,
                     'objectCopyService' => $this->objectCopyServiceMock,
                     'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock,
-                    'customerDataFactory' => $this->customerDataFactoryMock
+                    'customerDataFactory' => $this->customerDataFactoryMock,
+                    'data' => [
+                        'reserved_order_id' => 1000001
+                    ]
                 ]
             );
     }
@@ -1237,4 +1240,30 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($itemResult, $this->quote->getAllItems());
     }
+
+    /**
+     * Test to verify if existing reserved_order_id in use
+     *
+     * @param bool $isReservedOrderIdExist
+     * @param int $reservedOrderId
+     * @dataProvider reservedOrderIdDataProvider
+     */
+    public function testReserveOrderId($isReservedOrderIdExist, $reservedOrderId)
+    {
+        $this->resourceMock
+            ->expects($this->once())
+            ->method('isOrderIncrementIdUsed')
+            ->with(1000001)->willReturn($isReservedOrderIdExist);
+        $this->resourceMock->expects($this->any())->method('getReservedOrderId')->willReturn($reservedOrderId);
+        $this->quote->reserveOrderId();
+        $this->assertEquals($reservedOrderId, $this->quote->getReservedOrderId());
+    }
+
+    public function reservedOrderIdDataProvider()
+    {
+        return [
+            'id_already_in_use' => [true, 100002],
+            'id_not_in_use' => [false, 1000001]
+        ];
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..15c58073c2e26a4921f771e6c4097fafc9275c91
--- /dev/null
+++ b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Test\Unit\Model\ResourceModel;
+
+class QuoteTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Quote\Model\ResourceModel\Quote
+     */
+    private $model;
+
+    /**
+     * @var \Magento\Framework\App\ResourceConnection
+     */
+    private $resourceMock;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql
+     */
+    private $adapterMock;
+
+    /**
+     * @var \Magento\Framework\DB\Select
+     */
+    private $selectMock;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->selectMock->expects($this->any())->method('from')->will($this->returnSelf());
+        $this->selectMock->expects($this->any())->method('where');
+
+        $this->adapterMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\Pdo\Mysql::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->adapterMock->expects($this->any())->method('select')->will($this->returnValue($this->selectMock));
+
+        $this->resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock->expects(
+            $this->any()
+        )->method(
+            'getConnection'
+        )->will(
+            $this->returnValue($this->adapterMock)
+        );
+
+        $this->model = $objectManagerHelper->getObject(
+            \Magento\Quote\Model\ResourceModel\Quote::class,
+            [
+                'resource' => $this->resourceMock
+            ]
+        );
+    }
+
+    /**
+     * Unit test to verify if isOrderIncrementIdUsed method works with different types increment ids
+     *
+     * @param array $value
+     * @dataProvider isOrderIncrementIdUsedDataProvider
+     */
+    public function testIsOrderIncrementIdUsed($value)
+    {
+        $expectedBind = [':increment_id' => $value];
+        $this->adapterMock->expects($this->once())->method('fetchOne')->with($this->selectMock, $expectedBind);
+        $this->model->isOrderIncrementIdUsed($value);
+    }
+
+    /**
+     * @return array
+     */
+    public function isOrderIncrementIdUsedDataProvider()
+    {
+        return [[100000001], ['10000000001'], ['M10000000001']];
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Cart.php b/app/code/Magento/Wishlist/Controller/Index/Cart.php
index f15e89d16c9b4f9bba2adbe2a23621417e255f1a..a907abcd1c56c829dedaddbd065fff3cc1fede08 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Cart.php
@@ -113,6 +113,7 @@ class Cart extends \Magento\Wishlist\Controller\AbstractIndex
      * @return \Magento\Framework\Controller\ResultInterface
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
     public function execute()
     {
@@ -137,6 +138,10 @@ class Cart extends \Magento\Wishlist\Controller\AbstractIndex
 
         // Set qty
         $qty = $this->getRequest()->getParam('qty');
+        $postQty = $this->getRequest()->getPostValue('qty');
+        if ($postQty !== null && $qty !== $postQty) {
+            $qty = $postQty;
+        }
         if (is_array($qty)) {
             if (isset($qty[$itemId])) {
                 $qty = $qty[$itemId];
diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
index e1a7cd448569f05060d9995ee5d02de41630f680..743fc39e4b43d7819af97fc97c84efb9f3f38013 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/CartTest.php
@@ -159,7 +159,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
 
         $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
             ->disableOriginalConstructor()
-            ->setMethods(['getParams', 'getParam', 'isAjax'])
+            ->setMethods(['getParams', 'getParam', 'isAjax', 'getPostValue'])
             ->getMockForAbstractClass();
 
         $this->redirectMock = $this->getMockBuilder(\Magento\Framework\App\Response\RedirectInterface::class)
@@ -916,4 +916,176 @@ class CartTest extends \PHPUnit_Framework_TestCase
 
         $this->assertSame($this->resultRedirectMock, $this->model->execute());
     }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testExecuteWithEditQuantity()
+    {
+        $itemId = 2;
+        $wishlistId = 1;
+        $qty = 1;
+        $postQty = 2;
+        $productId = 4;
+        $indexUrl = 'index_url';
+        $configureUrl = 'configure_url';
+        $options = [5 => 'option'];
+        $params = ['item' => $itemId, 'qty' => $qty];
+
+        $this->formKeyValidator->expects($this->once())
+            ->method('validate')
+            ->with($this->requestMock)
+            ->willReturn(true);
+
+        $itemMock = $this->getMockBuilder(\Magento\Wishlist\Model\Item::class)
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'load',
+                    'getId',
+                    'getWishlistId',
+                    'setQty',
+                    'setOptions',
+                    'getBuyRequest',
+                    'mergeBuyRequest',
+                    'addToCart',
+                    'getProduct',
+                    'getProductId',
+                ]
+            )
+            ->getMock();
+
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->once())
+            ->method('getWishlistId')
+            ->willReturn($wishlistId);
+
+        $wishlistMock = $this->getMockBuilder(\Magento\Wishlist\Model\Wishlist::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->with($wishlistId)
+            ->willReturn($wishlistMock);
+
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('qty', null)
+            ->willReturn($qty);
+
+        $this->requestMock->expects($this->once())
+            ->method('getPostValue')
+            ->with('qty')
+            ->willReturn($postQty);
+
+        $this->quantityProcessorMock->expects($this->once())
+            ->method('process')
+            ->with($postQty)
+            ->willReturnArgument(0);
+
+        $itemMock->expects($this->once())
+            ->method('setQty')
+            ->with($postQty)
+            ->willReturnSelf();
+
+        $this->urlMock->expects($this->at(0))
+            ->method('getUrl')
+            ->with('*/*', null)
+            ->willReturn($indexUrl);
+
+        $itemMock->expects($this->once())
+            ->method('getProductId')
+            ->willReturn($productId);
+
+        $this->urlMock->expects($this->at(1))
+            ->method('getUrl')
+            ->with('*/*/configure/', ['id' => $itemId, 'product_id' => $productId])
+            ->willReturn($configureUrl);
+
+        $optionMock = $this->getMockBuilder(\Magento\Wishlist\Model\Item\Option::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->optionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($optionMock);
+
+        $optionsMock = $this->getMockBuilder(\Magento\Wishlist\Model\ResourceModel\Item\Option\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionMock->expects($this->once())
+            ->method('getCollection')
+            ->willReturn($optionsMock);
+
+        $optionsMock->expects($this->once())
+            ->method('addItemFilter')
+            ->with([$itemId])
+            ->willReturnSelf();
+        $optionsMock->expects($this->once())
+            ->method('getOptionsByItem')
+            ->with($itemId)
+            ->willReturn($options);
+
+        $itemMock->expects($this->once())
+            ->method('setOptions')
+            ->with($options)
+            ->willReturnSelf();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+
+        $buyRequestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $itemMock->expects($this->once())
+            ->method('getBuyRequest')
+            ->willReturn($buyRequestMock);
+
+        $this->productHelperMock->expects($this->once())
+            ->method('addParamsToBuyRequest')
+            ->with($params, ['current_config' => $buyRequestMock])
+            ->willReturn($buyRequestMock);
+
+        $itemMock->expects($this->once())
+            ->method('mergeBuyRequest')
+            ->with($buyRequestMock)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('addToCart')
+            ->with($this->checkoutCartMock, true)
+            ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('message')));
+
+        $this->messageManagerMock->expects($this->once())
+            ->method('addNotice')
+            ->with('message', null)
+            ->willReturnSelf();
+
+        $this->helperMock->expects($this->once())
+            ->method('calculate')
+            ->willReturnSelf();
+
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setUrl')
+            ->with($configureUrl)
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultRedirectMock, $this->model->execute());
+    }
 }
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
index dbb680f8f25806508e44ef31724899149ca2b6ce..b08816a6728eb54b79ec806084f4a4e684702a29 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
@@ -22,7 +22,7 @@
                        template="Magento_Catalog::product/view/addto.phtml" cacheable="false">
                     <block class="Magento\Wishlist\Block\Item\Configure" name="view.addto.wishlist.bundle" after="view.addto.requisition"
                            template="item/configure/addto/wishlist.phtml" />
-                    <block class="Magento\Catalog\Block\Product\View\Addto\Compare" name="view.addto.compare.bundle" after="view.addto.wishlist"
+                    <block class="Magento\Catalog\Block\Product\View\AddTo\Compare" name="view.addto.compare.bundle" after="view.addto.wishlist"
                            template="Magento_Catalog::product/view/addto/compare.phtml" />
                 </block>
             </block>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
index 678e9306cbadb3bc22dafd9bca089a8b7f304ba7..211e09861995f27e22a446b93e465a7197936965 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml
@@ -195,8 +195,8 @@
             <data name="product/data/price_type" xsi:type="string">Yes</data>
             <data name="product/data/price/dataset" xsi:type="string">dynamic-8</data>
             <data name="product/data/special_price" xsi:type="string">20</data>
-            <data name="product/data/special_from_date/pattern" xsi:type="string">M j, Y -1 day</data>
-            <data name="product/data/special_to_date/pattern" xsi:type="string">M j, Y +3 days</data>
+            <data name="product/data/special_from_date/pattern" xsi:type="string">m/d/y -1 day</data>
+            <data name="product/data/special_to_date/pattern" xsi:type="string">m/d/y +3 days</data>
             <data name="product/data/bundle_selections/dataset" xsi:type="string">default_dynamic</data>
             <data name="product/data/bundle_selections/products" xsi:type="string">catalogProductSimple::product_100_dollar,catalogProductSimple::product_40_dollar</data>
             <data name="product/data/checkout_data/dataset" xsi:type="string">bundle_default</data>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
index ecd68593b08cc252e67a144ccd2a9610ac88f22d..e1cbc1a1d8ba2dba7f3be971b3f1b456f6e7d02a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
@@ -1233,5 +1233,35 @@
             <field name="url_key" xsi:type="string">overnight-duffle</field>
         </dataset>
 
+        <dataset name="simple_with_weight_10_for_salesrule">
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="name" xsi:type="string">Simple Product %isolation%</field>
+            <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field>
+            <field name="product_has_weight" xsi:type="string">This item has weight</field>
+            <field name="weight" xsi:type="string">10</field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="qty" xsi:type="string">25</item>
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">560</item>
+            </field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="url_key" xsi:type="string">simple-product-%isolation%</field>
+            <field name="checkout_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">simple_order_default</item>
+            </field>
+        </dataset>
+
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
index 697733fd3c33d8856f5d775452aca8ad977e77e9..fac0f811be2616675e85e3f34927731f13ea16b1 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
@@ -99,6 +99,13 @@ class Cart extends Block
      */
     protected $preloaderSpinner = '#preloaderSpinner';
 
+    /**
+     * Cart item class name.
+     *
+     * @var string
+     */
+    protected $cartItemClass = \Magento\Checkout\Test\Block\Cart\CartItem::class;
+
     /**
      * Wait for PayPal page is loaded.
      *
@@ -129,7 +136,7 @@ class Cart extends Block
                 Locator::SELECTOR_XPATH
             );
             $cartItem = $this->blockFactory->create(
-                '\\' . get_class($this) . '\CartItem',
+                $this->cartItemClass,
                 ['element' => $cartItemBlock]
             );
         }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php
index a3eda5ea1b3c5a3d6b5be217df906ca69b67f742..d29bad980faca881468ae1cf3a58523e13f7ad83 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php
@@ -13,5 +13,13 @@ use Magento\Mtf\Block\Form;
  */
 class Shipping extends Form
 {
-    //
+    /**
+     * Returns form's required elements
+     *
+     * @return \Magento\Mtf\Client\ElementInterface[]
+     */
+    public function getRequiredFields()
+    {
+        return $this->_rootElement->getElements("div .field._required");
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertShippingAddressJsValidationMessagesIsAbsent.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertShippingAddressJsValidationMessagesIsAbsent.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4f46a1c2b7c2577a0f61882f9d707397b1c1a20
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertShippingAddressJsValidationMessagesIsAbsent.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Test\Constraint;
+
+use Magento\Checkout\Test\Page\CheckoutOnepage;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertShippingAddressJsValidationMessagesIsAbsent
+ * Assert js validation messages are absent for required fields.
+ */
+class AssertShippingAddressJsValidationMessagesIsAbsent extends AbstractConstraint
+{
+    /**
+     * Assert js validation messages are absent for required fields.
+     *
+     * @param CheckoutOnepage $checkoutOnepage
+     * @return void
+     */
+    public function processAssert(CheckoutOnepage $checkoutOnepage)
+    {
+        $requiredFields = $checkoutOnepage->getShippingBlock()->getRequiredFields();
+
+        /** @var \Magento\Mtf\Client\ElementInterface $field */
+        foreach ($requiredFields as $field) {
+            $errorContainer = $field->find("div .field-error");
+            \PHPUnit_Framework_Assert::assertFalse(
+                $errorContainer->isVisible(),
+                'Js validation error messages must be absent for required fields after checkout start.'
+            );
+        }
+    }
+
+    /**
+     * Returns string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Js validation messages are absent for required fields.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5361ee6e3c127bafc03e53cd717ac067688f826a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Test\TestCase;
+
+use Magento\Mtf\TestCase\Scenario;
+
+/**
+ * Steps:
+ * 1. Go to Frontend as guest.
+ * 2. Add simple product to shopping cart
+ * 3. Go to shopping cart page
+ * 4. Proceed to checkout
+ * 5. Perform assertions.
+ *
+ * @group One_Page_Checkout
+ * @ZephyrId MAGETWO-59697
+ */
+class OnePageCheckoutJsValidationTest extends Scenario
+{
+    /**
+     * Runs one page checkout js validation test.
+     *
+     * @return void
+     */
+    public function test()
+    {
+        $this->executeScenario();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e930ff29882ceed4e8f99947a6a6ef4b4acc1c7a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutJsValidationTest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutJsValidationTest" summary="JS validation verification for Checkout flow" ticketId="MAGETWO-59697">
+        <variation name="OnePageCheckoutJsValidationTestVariation1" summary="JS validation is not applied for empty required checkout fields if customer did not fill them">
+            <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
+            <data name="checkoutMethod" xsi:type="string">guest</data>
+            <constraint name="Magento\Checkout\Test\Constraint\AssertShippingAddressJsValidationMessagesIsAbsent" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml
index a26a2cead49b07a094e550db1207e36d53269b15..24eb96c0a9347741384ffd6718bf349eeb452c85 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml
@@ -22,4 +22,10 @@
         <step name="placeOrder" module="Magento_Checkout" next="createCustomerAccount" />
         <step name="createCustomerAccount" module="Magento_Checkout" />
     </scenario>
+    <scenario name="OnePageCheckoutJsValidationTest" firstStep="setupConfiguration">
+        <step name="setupConfiguration" module="Magento_Config" next="createProducts" />
+        <step name="createProducts" module="Magento_Catalog" next="addProductsToTheCart" />
+        <step name="addProductsToTheCart" module="Magento_Checkout" next="ProceedToCheckout" />
+        <step name="ProceedToCheckout" module="Magento_Checkout" />
+    </scenario>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
index 5ab10a0e26f79fcded0b42c77562b077cf0b5412..310f52f75e2cf124e07ab1d7d4bf431e48759e8d 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Handler/SalesRule/Curl.php
@@ -70,6 +70,10 @@ class Curl extends Conditions implements SalesRuleInterface
             'type' => \Magento\SalesRule\Model\Rule\Condition\Address::class,
             'attribute' => 'postcode',
         ],
+        'Total Weight' => [
+            'type' => \Magento\SalesRule\Model\Rule\Condition\Address::class,
+            'attribute' => 'weight',
+        ],
         'Category' => [
             'type' => \Magento\SalesRule\Model\Rule\Condition\Product::class,
             'attribute' => 'category_ids',
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
index 010b9d3233d163f6ec35ed4291bebbe352bbe9c4..13b68aca6c6eb7867286019b3a9609b3b93db2a8 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml
@@ -279,5 +279,24 @@
             <field name="stop_rules_processing" xsi:type="string">No</field>
             <field name="simple_free_shipping" xsi:type="string">No</field>
         </dataset>
+        <dataset name="rule_with_freeshipping_by_weight">
+            <field name="name" xsi:type="string">Cart price rule with free shipping by weight</field>
+            <field name="is_active" xsi:type="string">Yes</field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="string">Main Website</item>
+            </field>
+            <field name="customer_group_ids" xsi:type="array">
+                <item name="0" xsi:type="string">NOT LOGGED IN</item>
+            </field>
+            <field name="coupon_type" xsi:type="string">No Coupon</field>
+            <field name="sort_order" xsi:type="string">1</field>
+            <field name="is_rss" xsi:type="string">Yes</field>
+            <field name="conditions_serialized" xsi:type="string">[Total Weight|is|1]</field>
+            <field name="simple_action" xsi:type="string">Percent of product price discount</field>
+            <field name="discount_amount" xsi:type="string">0</field>
+            <field name="apply_to_shipping" xsi:type="string">No</field>
+            <field name="stop_rules_processing" xsi:type="string">No</field>
+            <field name="simple_free_shipping" xsi:type="string">For matching items only</field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..11e510759fdcc5aa4c9368e61c3f5373d32dd9bb
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\SalesRule\Test\TestCase;
+
+/**
+ * Precondition:
+ * 1. Cart Price Rule was created.
+ *
+ * Steps:
+ * 1. Go to storefront
+ * 2. Add product to shopping cart
+ * 3. Go to shopping cart page
+ * 4. Perform asserts.
+ *
+ * @group Shopping_Cart_Price_Rules
+ * @ZephyrId MAGETWO-59665
+ */
+class ShoppingCartWithFreeShippingTest extends \Magento\Mtf\TestCase\Injectable
+{
+    /**
+     * @var \Magento\Mtf\TestStep\TestStepFactory
+     */
+    private $testStepFactory;
+
+    /**
+     * Inject data
+     *
+     * @param \Magento\Mtf\TestStep\TestStepFactory $testStepFactory
+     * @return void
+     */
+    public function __inject(
+        \Magento\Mtf\TestStep\TestStepFactory $testStepFactory
+    ) {
+        $this->testStepFactory = $testStepFactory;
+    }
+
+    /**
+     * Test sales rule with free shipping applied by product weight
+     *
+     * @param \Magento\SalesRule\Test\Fixture\SalesRule $salesRule
+     * @param \Magento\Catalog\Test\Fixture\CatalogProductSimple $product
+     * @param \Magento\Checkout\Test\Fixture\Cart $cart
+     * @return void
+     */
+    public function testRuleWithFreeShippingByWeight(
+        \Magento\SalesRule\Test\Fixture\SalesRule $salesRule,
+        \Magento\Catalog\Test\Fixture\CatalogProductSimple $product,
+        \Magento\Checkout\Test\Fixture\Cart $cart
+    ) {
+        $salesRule->persist();
+        $product->persist();
+
+        $this->testStepFactory->create(
+            \Magento\Checkout\Test\TestStep\AddProductsToTheCartStep::class,
+            ['products' => [$product]]
+        )->run();
+
+        $this->testStepFactory->create(
+            \Magento\Checkout\Test\TestStep\EstimateShippingAndTaxStep::class,
+            ['products' => [$product], 'cart' => $cart]
+        )->run();
+    }
+
+    /**
+     * Clear data after test.
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->testStepFactory->create(\Magento\SalesRule\Test\TestStep\DeleteAllSalesRuleStep::class)->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7391d2281f8094b059cfaf9d26115c371d9498b0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ShoppingCartWithFreeShippingTest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\SalesRule\Test\TestCase\ShoppingCartWithFreeShippingTest" summary="Shopping Cart With Freeshipping" ticketId="MAGETWO-59665">
+        <variation name="ShoppingCartWithFreeShippingTestVariation1">
+            <data name="salesRule/dataset" xsi:type="string">rule_with_freeshipping_by_weight</data>
+            <data name="product/dataset" xsi:type="string">default</data>
+            <data name="cart/data/subtotal" xsi:type="string">560.00</data>
+            <data name="cart/data/shipping_amount" xsi:type="string">0.00</data>
+            <data name="cart/data/grand_total" xsi:type="string">560.00</data>
+        </variation>
+        <variation name="ShoppingCartWithFreeShippingTestVariation2">
+            <data name="salesRule/dataset" xsi:type="string">rule_with_freeshipping_by_weight</data>
+            <data name="product/dataset" xsi:type="string">simple_with_weight_10_for_salesrule</data>
+            <data name="cart/data/subtotal" xsi:type="string">560.00</data>
+            <data name="cart/data/shipping_amount" xsi:type="string">5.00</data>
+            <data name="cart/data/grand_total" xsi:type="string">565.00</data>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist.php
index 47f787da38b04264372015a52449f984820490e5..bda0780f553006bddc3f0ce164cb4f6f824ee75d 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist.php
@@ -99,6 +99,7 @@ class Wishlist extends Block
     public function clickUpdateWishlist()
     {
         $this->waitFormToLoad();
+        $this->_rootElement->hover();
         $this->_rootElement->find($this->updateButton)->click();
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Api/StockItemSaveTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Api/StockItemSaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0dc5c3ef620c3c307d4b35b6b7b0e61091128775
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Api/StockItemSaveTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Api;
+
+use Magento\Catalog\Api\Data\ProductExtensionInterface;
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Api\ProductRepositoryInterface;
+
+class StockItemSaveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testSave()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var ProductRepositoryInterface $productRepository */
+        $productRepository = $objectManager->get(ProductRepositoryInterface::class);
+        /** @var ProductInterface $product */
+        $product = $productRepository->get('simple', false, null, true);
+
+        /** @var ProductExtensionInterface $ea */
+        $ea = $product->getExtensionAttributes();
+        $ea->getStockItem()->setQty(555);
+        $productRepository->save($product);
+
+        $product = $productRepository->get('simple', false, null, true);
+        $this->assertEquals(555, $product->getExtensionAttributes()->getStockItem()->getQty());
+
+        $stockItem = $product->getExtensionAttributes()->getStockItem();
+        $stockItem->setQty(200);
+        /** @var StockItemRepositoryInterface $stockItemRepository */
+        $stockItemRepository = $objectManager->get(StockItemRepositoryInterface::class);
+        $stockItemRepository->save($stockItem);
+        $this->assertEquals(200, $product->getExtensionAttributes()->getStockItem()->getQty());
+
+        $product = $productRepository->get('simple', false, null, true);
+        $this->assertEquals(200, $product->getExtensionAttributes()->getStockItem()->getQty());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionProviderTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..50787c7962412b0611edf093825563061da67119
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionProviderTest.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class LowestPriceOptionProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var LowestPriceOptionsProviderInterface
+     */
+    private $lowestPriceOptionsProvider;
+
+    /**
+     * @var ProductRepositoryInterface
+     */
+    private $productRepository;
+
+    protected function setUp()
+    {
+        $this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
+        $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+        $this->lowestPriceOptionsProvider = Bootstrap::getObjectManager()->get(
+            LowestPriceOptionsProviderInterface::class
+        );
+    }
+
+    /**
+     * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGetProductsIfOneOfChildIsDisabled()
+    {
+        $configurableProduct = $this->productRepository->getById(1, false, null, true);
+        $lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
+        $this->assertCount(1, $lowestPriceChildrenProducts);
+        $lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
+        $this->assertEquals(10, $lowestPriceChildrenProduct->getPrice());
+
+        // load full aggregation root
+        $lowestPriceChildProduct = $this->productRepository->get(
+            $lowestPriceChildrenProduct->getSku(),
+            false,
+            null,
+            true
+        );
+        $lowestPriceChildProduct->setStatus(Status::STATUS_DISABLED);
+        // update in global scope
+        $currentStoreId = $this->storeManager->getStore()->getId();
+        $this->storeManager->setCurrentStore(Store::ADMIN_CODE);
+        $this->productRepository->save($lowestPriceChildProduct);
+        $this->storeManager->setCurrentStore($currentStoreId);
+
+        $lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
+        $this->assertCount(1, $lowestPriceChildrenProducts);
+        $lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
+        $this->assertEquals(20, $lowestPriceChildrenProduct->getPrice());
+    }
+
+    /**
+     * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGetProductsIfOneOfChildIsOutOfStock()
+    {
+        $configurableProduct = $this->productRepository->getById(1, false, null, true);
+        $lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
+        $this->assertCount(1, $lowestPriceChildrenProducts);
+        $lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
+        $this->assertEquals(10, $lowestPriceChildrenProduct->getPrice());
+
+        // load full aggregation root
+        $lowestPriceChildProduct = $this->productRepository->get(
+            $lowestPriceChildrenProduct->getSku(),
+            false,
+            null,
+            true
+        );
+        $stockItem = $lowestPriceChildProduct->getExtensionAttributes()->getStockItem();
+        $stockItem->setIsInStock(0);
+        $this->productRepository->save($lowestPriceChildProduct);
+
+        $lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
+        $this->assertCount(1, $lowestPriceChildrenProducts);
+        $lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
+        $this->assertEquals(20, $lowestPriceChildrenProduct->getPrice());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/LayoutDirectivesTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/LayoutDirectivesTest.php
index 7a20762bbe9d4493131bb0f2acb8e432a0a9ddbf..607ee4c919a62437cdfaf0d2219248dfc77f7a27 100755
--- a/dev/tests/integration/testsuite/Magento/Framework/View/LayoutDirectivesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/LayoutDirectivesTest.php
@@ -198,6 +198,18 @@ class LayoutDirectivesTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($layout->isBlock('child_block2'));
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testRemoveCancellation()
+    {
+        $layout = $this->_getLayoutModel('remove_cancellation.xml');
+        $this->assertTrue($layout->isContainer('container1'));
+        $this->assertTrue($layout->isBlock('child_block1'));
+        $this->assertTrue($layout->isBlock('no_name2'));
+        $this->assertFalse($layout->getBlock('not_exist'));
+    }
+
     /**
      * @magentoAppIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout_directives_test/remove_cancellation.xml b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout_directives_test/remove_cancellation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff086b19fd1b02d80ffc849d9563bdb9419ae75e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout_directives_test/remove_cancellation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block class="Magento\Framework\View\Element\Text" name="no_name2"/>
+    </container>
+    <referenceContainer name="container1" remove="true"/>
+    <referenceBlock name="child_block1" remove="true"/>
+    <block class="Magento\Framework\View\Element\Text" name="block_container" as="block.container">
+        <block class="Magento\Framework\View\Element\Text" name="child_block1"/>
+        <block class="Magento\Framework\View\Element\Text" name="child_block2"/>
+    </block>
+    <referenceContainer name="not_exist" remove="false"/>
+    <referenceContainer name="container1" remove="false"/>
+    <referenceBlock name="child_block1" remove="false"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php
index da035c8eec78f8a547defd548f5cc93b10d474a6..8f295077afe330076e265c555cae280294cdd9f6 100644
--- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php
@@ -404,4 +404,23 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             \Magento\Customer\Model\Data\Customer::WEBSITE_ID => 1
         ];
     }
+
+    /**
+     * Test to verify that reserved_order_id will be changed if it already in used
+     *
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoDataFixture Magento/Quote/_files/empty_quote.php
+     */
+    public function testReserveOrderId()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var \Magento\Quote\Model\Quote  $quote */
+        $quote = $objectManager->create(\Magento\Quote\Model\Quote::class);
+        $quote->load('reserved_order_id', 'reserved_order_id');
+        $quote->reserveOrderId();
+        $this->assertEquals('reserved_order_id', $quote->getReservedOrderId());
+        $quote->setReservedOrderId('100000001');
+        $quote->reserveOrderId();
+        $this->assertNotEquals('100000001', $quote->getReservedOrderId());
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..43ee0893b75f9cc93bdca626d87d5592eefd62aa
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Quote/Model/ResourceModel/QuoteTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Model\ResourceModel;
+
+/**
+ * Class QuoteTest to verify isOrderIncrementIdUsed method behaviour
+ */
+class QuoteTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Quote\Model\ResourceModel\Quote
+     */
+    private $_resourceModel;
+
+    protected function setUp()
+    {
+        $this->_resourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Quote\Model\ResourceModel\Quote::class
+        );
+    }
+
+    /**
+     * Test to verify if isOrderIncrementIdUsed method works with numeric increment ids
+     *
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     */
+    public function testIsOrderIncrementIdUsedNumericIncrementId()
+    {
+        $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('100000001'));
+    }
+
+    /**
+     * Test to verify if isOrderIncrementIdUsed method works with alphanumeric increment ids
+     *
+     * @magentoDataFixture Magento/Sales/_files/order_alphanumeric_id.php
+     */
+    public function testIsOrderIncrementIdUsedAlphanumericIncrementId()
+    {
+        $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('M00000001'));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Quote/Address/Total/ShippingTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Quote/Address/Total/ShippingTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..543d02e42067483a56ee1b31d084a7e02c18952f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Quote/Address/Total/ShippingTest.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\SalesRule\Model\Quote\Address\Total;
+
+class ShippingTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Quote\Api\GuestCartManagementInterface
+     */
+    private $cartManagement;
+
+    /**
+     * @var \Magento\Quote\Api\GuestCartItemRepositoryInterface
+     */
+    private $itemRepository;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    private $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->cartManagement = $this->objectManager->get(\Magento\Quote\Api\GuestCartManagementInterface::class);
+        $this->itemRepository = $this->objectManager->get(\Magento\Quote\Api\GuestCartItemRepositoryInterface::class);
+    }
+
+    /**
+     * @magentoDataFixture Magento/SalesRule/_files/rule_free_shipping_by_product_weight.php
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testRuleByProductWeightWithFreeShipping()
+    {
+        $cartId = $this->prepareQuote(1);
+        $methods = $this->estimateShipping($cartId);
+
+        $this->assertTrue(count($methods) > 0);
+        $this->assertEquals('flatrate', $methods[0]->getMethodCode());
+        $this->assertEquals(0, $methods[0]->getAmount());
+
+    }
+
+    /**
+     * @magentoDataFixture Magento/SalesRule/_files/rule_free_shipping_by_product_weight.php
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testRuleByProductWeightWithoutFreeShipping()
+    {
+        $cartId = $this->prepareQuote(5);
+        $methods = $this->estimateShipping($cartId);
+
+        $this->assertTrue(count($methods) > 0);
+        $this->assertEquals('flatrate', $methods[0]->getMethodCode());
+        $this->assertEquals(25, $methods[0]->getAmount());
+
+    }
+
+    /**
+     * Estimate shipment for guest cart
+     *
+     * @param int $cartId
+     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[]
+     */
+    private function estimateShipping($cartId)
+    {
+        $addressFactory = $this->objectManager->get(\Magento\Quote\Api\Data\AddressInterfaceFactory::class);
+        /** @var \Magento\Quote\Api\Data\AddressInterface $address */
+        $address = $addressFactory->create();
+        $address->setCountryId('US');
+        $address->setRegionId(2);
+
+        /** @var \Magento\Quote\Api\GuestShipmentEstimationInterface $estimation */
+        $estimation = $this->objectManager->get(\Magento\Quote\Api\GuestShipmentEstimationInterface::class);
+        return $estimation->estimateByExtendedAddress($cartId, $address);
+    }
+
+    /**
+     * Create guest quote with products
+     *
+     * @param int $itemQty
+     * @return int
+     */
+    private function prepareQuote($itemQty)
+    {
+        $cartId = $this->cartManagement->createEmptyCart();
+
+        /** @var \Magento\Quote\Api\Data\CartItemInterfaceFactory $cartItemFactory */
+        $cartItemFactory = $this->objectManager->get(\Magento\Quote\Api\Data\CartItemInterfaceFactory::class);
+
+        /** @var \Magento\Quote\Api\Data\CartItemInterface $cartItem */
+        $cartItem = $cartItemFactory->create();
+        $cartItem->setQuoteId($cartId);
+        $cartItem->setQty($itemQty);
+        $cartItem->setSku('simple');
+        $cartItem->setProductType(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE);
+
+        $this->itemRepository->save($cartItem);
+
+        return $cartId;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rule_free_shipping_by_product_weight.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rule_free_shipping_by_product_weight.php
new file mode 100644
index 0000000000000000000000000000000000000000..d59f63d2f313601b06bafdac7287501980e20b37
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rule_free_shipping_by_product_weight.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+require 'cart_rule_free_shipping.php';
+$row =
+    [
+        'name' => 'Free shipping if item weight <= 1',
+        'conditions' => [
+            1 =>
+                [
+                    'type' => \Magento\SalesRule\Model\Rule\Condition\Combine::class,
+                    'attribute' => null,
+                    'operator' => null,
+                    'value' => '1',
+                    'is_value_processed' => null,
+                    'aggregator' => 'all',
+                    'conditions' => [
+                        [
+                            'type' => Magento\SalesRule\Model\Rule\Condition\Address::class,
+                            'attribute' => 'weight',
+                            'operator' => '<=',
+                            'value' => '1',
+                            'is_value_processed' => false,
+                        ]
+                    ]
+                ]
+
+        ],
+        'actions' => [],
+    ];
+$salesRule->loadPost($row);
+$salesRule->save();
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
index 836a928dc5a72cf6a517dc1ae7f1bbc61e62a763..e4078a959c7a89284e508a884229f69d80e2e25a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
@@ -115,3 +115,4 @@ DoubleColon
 \Magento\TestModuleMessageQueueConfiguration\AsyncHandler
 \Magento\TestModuleMessageQueueConfiguration\SyncHandler
 \Magento\TestModuleAsyncAmqp\Model\AsyncTestData
+\Magento\Mtf\Client\ElementInterface
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index bc49ab15a7d54151759f7e183fb36a8a7b6571c6..2ce1bf02bf3896da26a633c158b77697876c4d02 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2155,7 +2155,6 @@ return [
     ['addOrderedQty', 'Magento\Reports\Model\ResourceModel\Product\Collection'],
     ['prepareForProductsInCarts', 'Magento\Reports\Model\ResourceModel\Quote\Collection'],
     ['getOrdersSubSelect', 'Magento\Reports\Model\ResourceModel\Quote\Collection'],
-    ['isOrderIncrementIdUsed', 'Magento\Quote\Model\ResourceModel\Quote'],
     ['isStateProtected', 'Magento\Sales\Model\Order'],
     ['_getBundleOptions', 'Magento\Bundle\Block\Checkout\Cart\Item\Renderer'],
     ['_getSelectionFinalPrice', 'Magento\Bundle\Block\Checkout\Cart\Item\Renderer'],
diff --git a/lib/internal/Magento/Framework/View/Layout/Reader/Block.php b/lib/internal/Magento/Framework/View/Layout/Reader/Block.php
index 9831c52a4656310e99c424ce7cc7dd8cd17f68fe..ff5ade125521acff54a182cea51e7f34985292d0 100755
--- a/lib/internal/Magento/Framework/View/Layout/Reader/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Reader/Block.php
@@ -207,13 +207,15 @@ class Block implements Layout\ReaderInterface
         $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
         if ($elementRemove) {
             $scheduledStructure->setElementToRemoveList($elementName);
-        } else {
-            $data = $scheduledStructure->getStructureElementData($elementName, []);
-            $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
-            $this->updateScheduledData($currentElement, $data);
-            $this->evaluateArguments($currentElement, $data);
-            $scheduledStructure->setStructureElementData($elementName, $data);
+            return;
+        } elseif ($currentElement->getAttribute('remove')) {
+            $scheduledStructure->unsetElementFromListToRemove($elementName);
         }
+        $data = $scheduledStructure->getStructureElementData($elementName, []);
+        $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
+        $this->updateScheduledData($currentElement, $data);
+        $this->evaluateArguments($currentElement, $data);
+        $scheduledStructure->setStructureElementData($elementName, $data);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Layout/Reader/Container.php b/lib/internal/Magento/Framework/View/Layout/Reader/Container.php
index c4111a13c33b37fe7e5fcc202ec0773928a1844d..cd4956447a3b14a305e0ca90614633def896a6c7 100755
--- a/lib/internal/Magento/Framework/View/Layout/Reader/Container.php
+++ b/lib/internal/Magento/Framework/View/Layout/Reader/Container.php
@@ -141,11 +141,12 @@ class Container implements Layout\ReaderInterface
     ) {
         $containerName = $currentElement->getAttribute('name');
         $containerRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
-
         if ($containerRemove) {
             $scheduledStructure->setElementToRemoveList($containerName);
-        } else {
-            $this->mergeContainerAttributes($scheduledStructure, $currentElement);
+            return;
+        } elseif ($currentElement->getAttribute('remove')) {
+            $scheduledStructure->unsetElementFromListToRemove($containerName);
         }
+        $this->mergeContainerAttributes($scheduledStructure, $currentElement);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/BlockTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/BlockTest.php
index 24bbd9391807463226bbe5c276df9aca4c31fd59..8cf049f56f1743484f0d559e4f8abf0caaa6b5f3 100755
--- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/BlockTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/BlockTest.php
@@ -188,6 +188,12 @@ class BlockTest extends \PHPUnit_Framework_TestCase
         $setCondition,
         $setRemoveCondition
     ) {
+        if ($literal == 'referenceBlock' && $remove == 'false') {
+            $this->scheduledStructure->expects($this->once())
+                ->method('unsetElementFromListToRemove')
+                ->with($literal);
+        }
+
         $this->context->expects($this->once())->method('getScheduledStructure')
             ->will($this->returnValue($this->scheduledStructure));
 
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/ContainerTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/ContainerTest.php
index 4e10a5a6a08415ca9d06cb95f5e10fa3a9361c2e..198a70d2121f16962471d3e5f5587a1e89130c3f 100755
--- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/ContainerTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/Reader/ContainerTest.php
@@ -102,6 +102,12 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
             ->with($contextMock, $elementCurrent)
             ->willReturnSelf();
 
+        if ($elementCurrent->getAttribute('remove') == 'false') {
+            $scheduledStructureMock->expects($this->once())
+                ->method('unsetElementFromListToRemove')
+                ->with($elementCurrent->getAttribute('name'));
+        }
+        
         $this->container->interpret($contextMock, $elementCurrent);
     }
 
diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
index 167903f62c760ca8ce495efe0dc42c98546d161f..7b5100215200473f0610afaf27c922e4662cce8f 100755
--- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
+++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
@@ -53,6 +53,10 @@ define([
                 });
             }
 
+            if (jQuery.isReady) {
+                tinyMCE.dom.Event.domLoaded = true;
+            }
+
             tinyMCE.init(this.getSettings(mode));
         },