diff --git a/app/code/Magento/Cms/Block/Page.php b/app/code/Magento/Cms/Block/Page.php
index 3a63f5b4b941c80a6a1ecfe9f5afb94223e56935..adbb1251c2d4c42e83811155cfd441ddf1c781ed 100644
--- a/app/code/Magento/Cms/Block/Page.php
+++ b/app/code/Magento/Cms/Block/Page.php
@@ -126,16 +126,26 @@ class Page extends \Magento\Framework\View\Element\AbstractBlock implements
      */
     protected function _addBreadcrumbs(\Magento\Cms\Model\Page $page)
     {
+        $homePageIdentifier = $this->_scopeConfig->getValue(
+            'web/default/cms_home_page',
+            ScopeInterface::SCOPE_STORE
+        );
+        $homePageDelimiterPosition = strrpos($homePageIdentifier, '|');
+        if ($homePageDelimiterPosition) {
+            $homePageIdentifier = substr($homePageIdentifier, 0, $homePageDelimiterPosition);
+        }
+        $noRouteIdentifier = $this->_scopeConfig->getValue(
+            'web/default/cms_no_route',
+            ScopeInterface::SCOPE_STORE
+        );
+        $noRouteDelimiterPosition = strrpos($noRouteIdentifier, '|');
+        if ($noRouteDelimiterPosition) {
+            $noRouteIdentifier = substr($noRouteIdentifier, 0, $noRouteDelimiterPosition);
+        }
         if ($this->_scopeConfig->getValue('web/default/show_cms_breadcrumbs', ScopeInterface::SCOPE_STORE)
             && ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs'))
-            && $page->getIdentifier() !== $this->_scopeConfig->getValue(
-                'web/default/cms_home_page',
-                ScopeInterface::SCOPE_STORE
-            )
-            && $page->getIdentifier() !== $this->_scopeConfig->getValue(
-                'web/default/cms_no_route',
-                ScopeInterface::SCOPE_STORE
-            )
+            && $page->getIdentifier() !== $homePageIdentifier
+            && $page->getIdentifier() !== $noRouteIdentifier
         ) {
             $breadcrumbsBlock->addCrumb(
                 'home',
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
index 245e7fc8a41a47602df47911d871858e79a219e0..7ffec9083aec015e76ff86c4574515f5c52e6c07 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
@@ -344,7 +344,6 @@ define([
         _determineProductData: function () {
             // Check if product is in a list of products.
             var productId,
-                product,
                 isInProductView = false;
 
             productId = this.element.parents('.product-item-details')
@@ -352,8 +351,7 @@ define([
 
             if (!productId) {
                 // Check individual product.
-                product = document.getElementsByName('product')[0];
-                productId = product ? product.value : undefined;
+                productId = $('[name=product]').val();
                 isInProductView = productId > 0;
             }
 
diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php
index 92ae78f26d0919c1ea7340d667f0ca708ebdc69e..d8d09efb5d66fc8be254938d7d5113bda9746ca6 100644
--- a/lib/internal/Magento/Framework/Data/Collection.php
+++ b/lib/internal/Magento/Framework/Data/Collection.php
@@ -514,17 +514,29 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll
     }
 
     /**
-     * @param string|array $objMethod
+     * Call method or callback on each item in the collection.
+     * 
+     * @param string|array|\Closure $objMethod
      * @param array $args
      * @return void
      */
     public function each($objMethod, $args = [])
     {
-        foreach ($args->_items as $k => $item) {
-            $args->_items[$k] = call_user_func($objMethod, $item);
+        if ($objMethod instanceof \Closure) {
+            foreach ($this->getItems() as $item) {
+                $objMethod($item, ...$args);
+            }
+        } elseif (is_array($objMethod)) {
+            foreach ($this->getItems() as $item) {
+                call_user_func($objMethod, $item, ...$args);
+            }
+        } else {
+            foreach ($this->getItems() as $item) {
+                $item->$objMethod(...$args);
+            }
         }
     }
-
+    
     /**
      * Setting data for all collection items
      *
diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php
index 90f0ac2be6d0f15c4a6917875c5451e36514945d..b54374ad10a8380a2d47aa2af8ed2a3da8a72524 100644
--- a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php
+++ b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Framework\Data\Test\Unit;
 
+// @codingStandardsIgnoreFile
+
 class CollectionTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -173,4 +175,85 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $this->_model->removeAllItems();
         $this->assertEquals([], $this->_model->getItems());
     }
+
+    public function testEachCallsMethodOnEachItemWithNoArgs()
+    {
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
+            $item->expects($this->once())->method('testCallback')->with();
+            $this->_model->addItem($item);
+        }
+        $this->_model->each('testCallback');
+    }
+    
+    public function testEachCallsMethodOnEachItemWithArgs()
+    {
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
+            $item->expects($this->once())->method('testCallback')->with('a', 'b', 'c');
+            $this->_model->addItem($item);
+        }
+        $this->_model->each('testCallback', ['a', 'b', 'c']);
+    }
+
+    public function testCallsClosureWithEachItemAndNoArgs()
+    {
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
+            $item->expects($this->once())->method('testCallback')->with();
+            $this->_model->addItem($item);
+        }
+        $this->_model->each(function ($item) {
+            $item->testCallback();
+        });
+    }
+
+    public function testCallsClosureWithEachItemAndArgs()
+    {
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
+            $item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c');
+            $this->_model->addItem($item);
+        }
+        $this->_model->each(function ($item, ...$args) {
+            $item->testItemCallback(...$args);
+        }, ['a', 'b', 'c']);
+    }
+
+    public function testCallsCallableArrayWithEachItemNoArgs()
+    {
+        $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance')
+            ->setMethods(['testObjCallback'])
+            ->getMock();
+        $mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) {
+            $item->testItemCallback(...$args);
+        });
+
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
+            $item->expects($this->once())->method('testItemCallback')->with();
+            $this->_model->addItem($item);
+        }
+
+        $this->_model->each([$mockCallbackObject, 'testObjCallback']);
+    }
+
+    public function testCallsCallableArrayWithEachItemAndArgs()
+    {
+        $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance')
+            ->setMethods(['testObjCallback'])
+            ->getMock();
+        $mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) {
+            $item->testItemCallback(...$args);
+        });
+
+        for ($i = 0; $i < 3; $i++) {
+            $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
+            $item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c');
+            $this->_model->addItem($item);
+        }
+
+        $callback = [$mockCallbackObject, 'testObjCallback'];
+        $this->_model->each($callback, ['a', 'b', 'c']);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php b/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php
index a2d7e486e66ee29749b013535be5945d72152c33..0b3650c28fd720321733e278a3a226b700dd10e4 100644
--- a/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php
+++ b/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php
@@ -7,7 +7,7 @@
  */
 namespace Magento\Framework\Session;
 
-interface SaveHandlerInterface extends \Zend_Session_SaveHandler_Interface
+interface SaveHandlerInterface extends \SessionHandlerInterface
 {
     /**
      * Default session save handler