diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
index edd654a7393126c61b877d35b36de9077316ec4d..a4218e92b3486db76afc61254553b914610d99c3 100644
--- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
@@ -278,15 +278,19 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             ->method('getOptionsReadOnly')
             ->willReturn(false);
 
+        $firstExpectedCustomOption = clone $this->customOptionMock;
+        $firstExpectedCustomOption->setData($optionsData['option2']);
+        $secondExpectedCustomOption = clone $this->customOptionMock;
+        $secondExpectedCustomOption->setData($optionsData['option3']);
         $this->customOptionFactoryMock->expects($this->any())
             ->method('create')
             ->willReturnMap([
                 [
                     ['data' => $optionsData['option2']],
-                    (clone $this->customOptionMock)->setData($optionsData['option2'])
+                    $firstExpectedCustomOption
                 ], [
                     ['data' => $optionsData['option3']],
-                    (clone $this->customOptionMock)->setData($optionsData['option3'])
+                    $secondExpectedCustomOption
                 ]
             ]);
 
diff --git a/app/code/Magento/Indexer/Setup/RecurringData.php b/app/code/Magento/Indexer/Setup/RecurringData.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd6f8f0241dc81cf5a632a355f5193c82e180023
--- /dev/null
+++ b/app/code/Magento/Indexer/Setup/RecurringData.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Indexer\Setup;
+
+use Magento\Framework\Setup\InstallDataInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\ModuleDataSetupInterface;
+use Magento\Indexer\Model\IndexerFactory;
+use Magento\Framework\Indexer\ConfigInterface;
+
+/**
+ * Recurring data upgrade for indexer module
+ */
+class RecurringData implements InstallDataInterface
+{
+    /**
+     * @var IndexerFactory
+     */
+    private $indexerFactory;
+
+    /**
+     * @var ConfigInterface
+     */
+    private $configInterface;
+
+    /**
+     * RecurringData constructor.
+     *
+     * @param IndexerFactory $indexerFactory
+     * @param ConfigInterface $configInterface
+     */
+    public function __construct(
+        IndexerFactory $indexerFactory,
+        ConfigInterface $configInterface
+    ) {
+        $this->indexerFactory = $indexerFactory;
+        $this->configInterface = $configInterface;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
+    {
+        foreach (array_keys($this->configInterface->getIndexers()) as $indexerId) {
+            $indexer = $this->indexerFactory->create()->load($indexerId);
+            if ($indexer->isScheduled()) {
+                $indexer->getView()->unsubscribe()->subscribe();
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
index 1e1d217715d260e5f43c437b7a91431215d338f1..4b656ee299dddc04527d2be6145b49e3098c3578 100644
--- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
+++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
@@ -602,7 +602,9 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon
      */
     public function getMappedSqlField()
     {
-        if (!$this->isAttributeSetOrCategory()) {
+        if ($this->getAttribute() == 'sku') {
+            $mappedSqlField = 'e.sku';
+        } elseif (!$this->isAttributeSetOrCategory()) {
             $mappedSqlField = $this->getEavAttributeTableAlias() . '.value';
         } elseif ($this->getAttribute() == 'category_ids') {
             $mappedSqlField = 'e.entity_id';
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
index da44fd2eaf99e55e925d9c946b6d7e8ee8370408..58435b066261ed28cc7f33ff01fc250940b6eb17 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
@@ -110,7 +110,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductPage" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation6" summary="Create Configurable Product with Creating New Category and New Attribute (Required Fields Only)" ticketId="MAGETWO-13361">
-            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, stable:no</data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_searchable_options</data>
             <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">configurable_sku_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php
index 43c101176bdac80f4540c013f13b58d9b4a600d9..1314c1503b2f310db1ff80b461b05de986962935 100644
--- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php
+++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php
@@ -74,7 +74,7 @@ class UpgradeSystemTest extends Injectable
         );
         $version = $upgrade['upgradeVersion'];
 
-        $suffix = "( (CE|EE))$";
+        $suffix = "( (CE|EE|B2B))$";
         $normalVersion = '(0|[1-9]\d*)';
         $preReleaseVersion = "((0(?!\\d+(\\.|\\+|{$suffix}))|[1-9A-Za-z])[0-9A-Za-z-]*)";
         $buildVersion = '([0-9A-Za-z][0-9A-Za-z-]*)';
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
index 4029454ee523052fedcc9592b778fea9704b7abf..87bd329ef3b5611475c6ee9486cdc9f27c4ea5fe 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
@@ -22,6 +22,16 @@ class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase
      */
     protected static $changedFileList = '';
 
+    /**
+     * @var string Path for Magento's composer.json
+     */
+    protected static $composerFilePath = BP . '/composer.json';
+
+    /**
+     * @var bool Is tests executes on develop branch
+     */
+    protected static $isOnDevVersion = false;
+
     /**
      *  Set changed files paths and list for all projects
      */
@@ -30,6 +40,13 @@ class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase
         foreach (glob(self::$changedFilesPattern) as $changedFile) {
             self::$changedFileList .= file_get_contents($changedFile) . PHP_EOL;
         }
+
+        if (file_exists(self::$composerFilePath)) {
+            $jsonData = json_decode(file_get_contents(self::$composerFilePath));
+            if (substr((string) $jsonData->version, -4) == '-dev') {
+                self::$isOnDevVersion = true;
+            }
+        }
     }
 
     /**
@@ -37,6 +54,9 @@ class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase
      */
     public function testModuleXmlFiles()
     {
+        if (self::$isOnDevVersion) {
+            $this->markTestSkipped('This test isn\'t applicable to the developer version of Magento');
+        }
         preg_match_all('|etc/module\.xml$|mi', self::$changedFileList, $matches);
         $this->assertEmpty(
             reset($matches),
@@ -50,6 +70,9 @@ class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase
      */
     public function testModuleSetupFiles()
     {
+        if (self::$isOnDevVersion) {
+            $this->markTestSkipped('This test isn\'t applicable to the developer version of Magento');
+        }
         preg_match_all('|app/code/Magento/[^/]+/Setup/[^/]+$|mi', self::$changedFileList, $matches);
         $this->assertEmpty(
             reset($matches),
diff --git a/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php b/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
index 74a6cc7d2cd923e46b80f39c2645c5cef2ba421a..d714caa1724f07c3aab05de714048e8ec72a6a80 100644
--- a/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
+++ b/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
@@ -54,25 +54,70 @@ class ArrayType implements InterpreterInterface
      */
     private function sortItems($items)
     {
-        uasort(
-            $items,
-            function ($firstItem, $secondItem) {
-                $firstValue = 0;
-                $secondValue = 0;
-                if (isset($firstItem['sortOrder'])) {
-                    $firstValue = intval($firstItem['sortOrder']);
+        $sortOrderDefined = $this->isSortOrderDefined($items);
+        if ($sortOrderDefined) {
+            $indexedItems = [];
+            foreach ($items as $key => $item) {
+                $indexedItems[] = ['key' => $key, 'item' => $item];
+            }
+            uksort(
+                $indexedItems,
+                function ($firstItemKey, $secondItemKey) use ($indexedItems) {
+                    return $this->compareItems($firstItemKey, $secondItemKey, $indexedItems);
                 }
+            );
+            // Convert array of sorted items back to initial format
+            $items = [];
+            foreach ($indexedItems as $indexedItem) {
+                $items[$indexedItem['key']] = $indexedItem['item'];
+            }
+        }
+        return $items;
+    }
 
-                if (isset($secondItem['sortOrder'])) {
-                    $secondValue = intval($secondItem['sortOrder']);
-                }
+    /**
+     * Compare sortOrder of item
+     *
+     * @param mixed $firstItemKey
+     * @param mixed $secondItemKey
+     * @param array $indexedItems
+     * @return int
+     */
+    private function compareItems($firstItemKey, $secondItemKey, $indexedItems)
+    {
+        $firstItem = $indexedItems[$firstItemKey]['item'];
+        $secondItem = $indexedItems[$secondItemKey]['item'];
+        $firstValue = 0;
+        $secondValue = 0;
+        if (isset($firstItem['sortOrder'])) {
+            $firstValue = intval($firstItem['sortOrder']);
+        }
 
-                if ($firstValue == $secondValue) {
-                    return 0;
-                }
-                return $firstValue < $secondValue ? -1 : 1;
+        if (isset($secondItem['sortOrder'])) {
+            $secondValue = intval($secondItem['sortOrder']);
+        }
+
+        if ($firstValue == $secondValue) {
+            // These keys reflect initial relative position of items.
+            // Allows stable sort for items with equal 'sortOrder'
+            return $firstItemKey < $secondItemKey ? -1 : 1;
+        }
+        return $firstValue < $secondValue ? -1 : 1;
+    }
+
+    /**
+     * Determine if a sort order exists for any of the items.
+     *
+     * @param array $items
+     * @return bool
+     */
+    private function isSortOrderDefined($items)
+    {
+        foreach ($items as $itemData) {
+            if (isset($itemData['sortOrder'])) {
+                return true;
             }
-        );
-        return $items;
+        }
+        return false;
     }
 }
diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
index 7d3c21ba271cecf75a83d4bc9aa5923ce1920337..e1bc7528cbe1a00a0d5abebb2739cf9a83c7f43a 100644
--- a/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
+++ b/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
@@ -103,6 +103,40 @@ class ArrayTypeTest extends \PHPUnit_Framework_TestCase
                     'key1' => '-value 1-',
                 ],
             ],
+            'pre-sorted array items' => [
+                [
+                    'item' => [
+                        'key1' => ['value' => 'value 1'],
+                        'key4' => ['value' => 'value 4'],
+                        'key2' => ['value' => 'value 2', 'sortOrder' => 10],
+                        'key3' => ['value' => 'value 3'],
+                    ],
+                ],
+                [
+                    'key1' => '-value 1-',
+                    'key4' => '-value 4-',
+                    'key3' => '-value 3-',
+                    'key2' => '-value 2-',
+                ],
+            ],
+            'sort order edge case values' => [
+                [
+                    'item' => [
+                        'key1' => ['value' => 'value 1', 'sortOrder' => 101],
+                        'key4' => ['value' => 'value 4'],
+                        'key2' => ['value' => 'value 2', 'sortOrder' => -10],
+                        'key3' => ['value' => 'value 3'],
+                        'key5' => ['value' => 'value 5', 'sortOrder' => 20],
+                    ],
+                ],
+                [
+                    'key2' => '-value 2-',
+                    'key4' => '-value 4-',
+                    'key3' => '-value 3-',
+                    'key5' => '-value 5-',
+                    'key1' => '-value 1-',
+                ],
+            ],
         ];
     }
 }
diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
index cd7a236f723590ffe5138fa063dabfa5968c8c3b..2cbf5da0bfbbba3ab562942c068913f5d0f12069 100644
--- a/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
+++ b/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
@@ -40,13 +40,13 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->connectionMock = $this->getMock(\Magento\Framework\DB\Adapter\Pdo\Mysql::class, [], [], '', false);
-        $this->resourceMock = $this->getMock(
-            \Magento\Framework\App\ResourceConnection::class,
-            [],
-            [],
-            '',
-            false,
-            false
+        $this->resourceMock = $this->getMock(
+            \Magento\Framework\App\ResourceConnection::class,
+            [],
+            [],
+            '',
+            false,
+            false
         );
 
         $this->connectionMock->expects($this->any())
@@ -57,19 +57,19 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('getConnection')
             ->willReturn($this->connectionMock);
 
-        $this->triggerFactoryMock = $this->getMock(
+        $this->triggerFactoryMock = $this->getMock(
             \Magento\Framework\DB\Ddl\TriggerFactory::class, [], [], '', false, false
         );
-        $this->viewCollectionMock = $this->getMockForAbstractClass(
+        $this->viewCollectionMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\View\CollectionInterface::class, [], '', false, false, true, []
         );
-        $this->viewMock = $this->getMockForAbstractClass(
+        $this->viewMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\ViewInterface::class, [], '', false, false, true, []
         );
 
         $this->resourceMock->expects($this->any())
             ->method('getTableName')
-            ->willReturn($this->tableName);
+            ->will($this->returnArgument(0));
 
         $this->model = new Subscription(
             $this->resourceMock,
@@ -96,11 +96,15 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('columnName', $this->model->getColumnName());
     }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     public function testCreate()
     {
         $triggerName = 'trigger_name';
         $this->resourceMock->expects($this->atLeastOnce())->method('getTriggerName')->willReturn($triggerName);
         $triggerMock = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Trigger::class)
+            ->setMethods(['setName', 'getName', 'setTime', 'setEvent', 'setTable', 'addStatement'])
             ->disableOriginalConstructor()
             ->getMock();
         $triggerMock->expects($this->exactly(3))
@@ -121,11 +125,38 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('setTable')
             ->with($this->tableName)
             ->will($this->returnSelf());
-        $triggerMock->expects($this->exactly(6))
+
+        $triggerMock->expects($this->at(4))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(5))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(11))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(12))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(18))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (OLD.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(19))
             ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (OLD.columnName);")
             ->will($this->returnSelf());
 
-        $changelogMock = $this->getMockForAbstractClass(
+        $changelogMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\View\ChangelogInterface::class, [], '', false, false, true, []
         );
         $changelogMock->expects($this->exactly(3))
@@ -143,7 +174,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($triggerMock));
 
-        $otherChangelogMock = $this->getMockForAbstractClass(
+        $otherChangelogMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\View\ChangelogInterface::class, [], '', false, false, true, []
         );
         $otherChangelogMock->expects($this->exactly(3))
@@ -153,7 +184,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('getColumnName')
             ->will($this->returnValue('entity_id'));
 
-        $otherViewMock = $this->getMockForAbstractClass(
+        $otherViewMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\ViewInterface::class, [], '', false, false, true, []
         );
         $otherViewMock->expects($this->exactly(1))
@@ -216,7 +247,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($triggerMock));
 
-        $otherChangelogMock = $this->getMockForAbstractClass(
+        $otherChangelogMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\View\ChangelogInterface::class, [], '', false, false, true, []
         );
         $otherChangelogMock->expects($this->exactly(3))
@@ -226,7 +257,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('getColumnName')
             ->will($this->returnValue('entity_id'));
 
-        $otherViewMock = $this->getMockForAbstractClass(
+        $otherViewMock = $this->getMockForAbstractClass(
             \Magento\Framework\Mview\ViewInterface::class, [], '', false, false, true, []
         );
         $otherViewMock->expects($this->exactly(1))
diff --git a/lib/internal/Magento/Framework/Mview/etc/mview.xsd b/lib/internal/Magento/Framework/Mview/etc/mview.xsd
index d171699c3784a8437985b6d741b0bc5d8297373a..0521691e852368d1e157733ff31e71c3ea41a07f 100644
--- a/lib/internal/Magento/Framework/Mview/etc/mview.xsd
+++ b/lib/internal/Magento/Framework/Mview/etc/mview.xsd
@@ -106,7 +106,7 @@
     <xs:simpleType name="subscriptionModelType">
         <xs:annotation>
             <xs:documentation>
-                Subscription model must be a valid PHP class or interface name.
+                DEPRECATED. Subscription model must be a valid PHP class or interface name.
             </xs:documentation>
         </xs:annotation>
         <xs:restriction base="xs:string">