diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
index 8e93868dc7e51916a1c44997ad98045edbe1bd4f..8fdb867c9dbd84a2903a9a3372144d05c54922f4 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
@@ -417,6 +417,9 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
         if ($this->getAttributeCode() == 'price') {
             return false;
         }
+        if ($this->getAttributeCode() == 'visibility') {
+            return true;
+        }
 
         if (!$this->getIsFilterableInSearch() && !$this->getIsVisibleInAdvancedSearch() && !$this->getIsFilterable()) {
             return false;
diff --git a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
index a19eb9d1cc57344e6f2fcce5f94b81be113cc84f..cbe1aa3d066651a7d90f75b655da1ef79c95cf49 100644
--- a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
+++ b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
@@ -254,10 +254,10 @@ class InstallSchema implements InstallSchemaInterface
             ->addIndex(
                 $installer->getIdxName(
                     'cataloginventory_stock_item',
-                    ['product_id', 'website_id'],
+                    ['product_id', 'stock_id'],
                     \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
                 ),
-                ['product_id', 'website_id'],
+                ['product_id', 'stock_id'],
                 ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
             )
             ->addIndex(
diff --git a/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php b/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fd3d264ee67d6a5bef74cebb829f82b9a324e92
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Setup/UpgradeSchema.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Setup;
+
+use Magento\Framework\Setup\UpgradeSchemaInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\SchemaSetupInterface;
+use Magento\CatalogInventory\Model\Stock\Item as StockItem;
+
+class UpgradeSchema implements UpgradeSchemaInterface
+{
+    /**
+     * @var string
+     */
+    private $productCompositeKeyVersion = '2.2.0';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $setup->startSetup();
+
+        if (version_compare($context->getVersion(), $this->productCompositeKeyVersion, '<')) {
+            $this->upgradeProductCompositeKey($setup);
+        }
+
+        $setup->endSetup();
+    }
+
+    /**
+     * @param SchemaSetupInterface $setup
+     * @return void
+     */
+    private function upgradeProductCompositeKey(SchemaSetupInterface $setup)
+    {
+        $oldCompositeKeyColumns = ['product_id', 'website_id'];
+        $newCompositeKeyColumns = ['product_id', 'stock_id'];
+
+        $foreignKeys = $this->getForeignKeys($setup, $oldCompositeKeyColumns);
+        // drop foreign keys
+        $this->dropForeignKeys($setup, $foreignKeys);
+
+        $oldIndexName = $setup->getIdxName(
+            $setup->getTable(StockItem::ENTITY),
+            $oldCompositeKeyColumns,
+            \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
+        );
+
+        $newIndexName = $setup->getIdxName(
+            $setup->getTable(StockItem::ENTITY),
+            $newCompositeKeyColumns,
+            \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
+        );
+
+        // Drop a key based on the following columns: "product_id","website_id"
+        $setup->getConnection()->dropIndex($setup->getTable(StockItem::ENTITY), $oldIndexName);
+
+        // Create a key based on the following columns: "product_id","stock_id"
+        $setup->getConnection()
+            ->addIndex(
+                $setup->getTable(StockItem::ENTITY),
+                $newIndexName,
+                $newCompositeKeyColumns,
+                \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
+            );
+        // restore deleted foreign keys
+        $this->createForeignKeys($setup, $foreignKeys);
+    }
+
+    /**
+     * @param SchemaSetupInterface $setup
+     * @param array                $keys
+     * @return void
+     */
+    private function dropForeignKeys(SchemaSetupInterface $setup, array $keys)
+    {
+        foreach ($keys as $key) {
+            $setup->getConnection()->dropForeignKey($key['TABLE_NAME'], $key['FK_NAME']);
+        }
+    }
+
+    /**
+     * @param SchemaSetupInterface $setup
+     * @param array                $keys
+     * @return void
+     */
+    private function createForeignKeys(SchemaSetupInterface $setup, array $keys)
+    {
+        foreach ($keys as $key) {
+            $setup->getConnection()->addForeignKey(
+                $key['FK_NAME'],
+                $key['TABLE_NAME'],
+                $key['COLUMN_NAME'],
+                $key['REF_TABLE_NAME'],
+                $key['REF_COLUMN_NAME'],
+                $key['ON_DELETE']
+            );
+        }
+    }
+
+    /**
+     * @param SchemaSetupInterface $setup
+     * @param array                $compositeKeys
+     * @return array
+     */
+    private function getForeignKeys(SchemaSetupInterface $setup, array $compositeKeys)
+    {
+        $foreignKeys = [];
+        $allForeignKeys = $setup->getConnection()->getForeignKeys($setup->getTable(StockItem::ENTITY));
+        foreach ($allForeignKeys as $key) {
+            if (in_array($key['COLUMN_NAME'], $compositeKeys)) {
+                $foreignKeys[] = $key;
+            }
+        }
+
+        return $foreignKeys;
+    }
+}
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html
index da625c51d4b7734ccc4808fd9161502e15acf1a9..798be1f978f54e3cd7e4c51bfb0e3e20e8ae82e2 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html
@@ -15,7 +15,12 @@
     <!-- /ko --><br/>
     <!-- ko foreach: { data: currentBillingAddress().customAttributes, as: 'element' } -->
         <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } -->
-            <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "object") -->
+                <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "string") -->
+                <!-- ko text: element[attribute] --><!-- /ko -->
+            <!-- /ko --><br/>
         <!-- /ko -->
     <!-- /ko -->
     <button type="button"
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html
index a2b83ead6b354451b99a4a1003a0f04df905dbbc..92469fdec3d7fcc8660d7d5a385cfa9c28c18252 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html
@@ -15,7 +15,12 @@
     <!-- /ko --><br/>
     <!-- ko foreach: { data: address().customAttributes, as: 'element' } -->
         <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } -->
-            <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "object") -->
+                <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "string") -->
+                <!-- ko text: element[attribute] --><!-- /ko -->
+            <!-- /ko --><br/>
         <!-- /ko -->
     <!-- /ko -->
     <!-- ko if: (address().isEditable()) -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html
index 440a2c7fc468fc493d10eb0cb57320c5593e1bf8..36ea556ae9ec95f09496094771a1340305ffdd43 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html
@@ -15,7 +15,12 @@
     <!-- /ko --><br/>
     <!-- ko foreach: { data: address().customAttributes, as: 'element' } -->
         <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } -->
-            <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "object") -->
+                <!-- ko text: element[attribute].value --><!-- /ko -->
+            <!-- /ko -->
+            <!-- ko if: (typeof element[attribute] === "string") -->
+                <!-- ko text: element[attribute] --><!-- /ko -->
+            <!-- /ko --><br/>
         <!-- /ko -->
     <!-- /ko -->
 <!-- /ko -->
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
index 02ff894df7c1fb1ed6ec7b6af07f019cece1b8cb..74a7e8112aa0ddb528b46168a16df15310fd227c 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -202,7 +202,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
             $collection = $this->getAssociatedProductCollection(
                 $product
             )->addAttributeToSelect(
-                ['name', 'price',  'special_price', 'special_from_date', 'special_to_date']
+                ['name', 'price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id']
             )->addFilterByRequiredOptions()->setPositionOrder()->addStoreFilter(
                 $this->getStoreFilter($product)
             )->addAttributeToFilter(
diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php
index 13840b120636773dd108adcdf4a9f590e629383d..f64f2fe84a8cd9a496c0c85f8135e3274cd75f2f 100644
--- a/app/code/Magento/Store/Model/StoreManager.php
+++ b/app/code/Magento/Store/Model/StoreManager.php
@@ -152,7 +152,7 @@ class StoreManager implements
     public function getStore($storeId = null)
     {
         if (!isset($storeId) || '' === $storeId || $storeId === true) {
-            if (!$this->currentStoreId) {
+            if (null === $this->currentStoreId) {
                 \Magento\Framework\Profiler::start('store.resolve');
                 $this->currentStoreId = $this->storeResolver->getCurrentStoreId();
                 \Magento\Framework\Profiler::stop('store.resolve');
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php
index 8a949c474bc847942f1bd5922d00514cd6133d08..43bd771f609cd86fddcfb99c21ac05687bfe06a9 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.php
@@ -65,4 +65,20 @@ class AddressModal extends Form
 
         return $result;
     }
+
+    /**
+     * Fixture mapping.
+     *
+     * @param array|null $fields
+     * @param string|null $parent
+     * @return array
+     */
+    protected function dataMapping(array $fields = null, $parent = null)
+    {
+        if (isset($fields['custom_attribute'])) {
+            $this->placeholders = ['attribute_code' => $fields['custom_attribute']['code']];
+            $this->applyPlaceholders();
+        }
+        return parent::dataMapping($fields, $parent);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml
index 13403b792684512c9741bca74a78f7c84036eb48..4a6160698839382c83809824913ebcf3770a0f7f 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/AddressModal.xml
@@ -22,5 +22,8 @@
         </country_id>
         <telephone />
         <postcode />
+        <custom_attribute>
+            <selector>[name="custom_attributes[%attribute_code%]"]</selector>
+        </custom_attribute>
     </fields>
 </mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php
index b9d5f3c3af01e10559e2c942e546f4eeda6576c3..78eaf403826bc054996c570c2167600ac4fac0ff 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php
@@ -61,4 +61,20 @@ class Edit extends Form
     {
         $this->_rootElement->find($this->saveAddress)->click();
     }
+
+    /**
+     * Fixture mapping.
+     *
+     * @param array|null $fields
+     * @param string|null $parent
+     * @return array
+     */
+    protected function dataMapping(array $fields = null, $parent = null)
+    {
+        if (isset($fields['custom_attribute'])) {
+            $this->placeholders = ['attribute_code' => $fields['custom_attribute']['code']];
+            $this->applyPlaceholders();
+        }
+        return parent::dataMapping($fields, $parent);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php
deleted file mode 100644
index 4946f0825870974337a3724fae591e58b8d861be..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Customer\Test\Page;
-
-use Magento\Mtf\Client\Locator;
-use Magento\Mtf\Factory\Factory;
-use Magento\Mtf\Page\Page;
-
-/**
- * Customer Address Edit page.
- */
-class CustomerAddressEdit extends Page
-{
-    /**
-     * URL for Customer Address Edit page.
-     */
-    const MCA = 'customer/address/edit';
-
-    /**
-     * Customer Address Edit form.
-     *
-     * @var string
-     */
-    protected $editForm = '#form-validate';
-
-    /**
-     * Init page. Set page url.
-     *
-     * @return void
-     */
-    protected function initUrl()
-    {
-        $this->url = $_ENV['app_frontend_url'] . self::MCA;
-    }
-
-    /**
-     * Get Customer Address Edit form.
-     *
-     * @return \Magento\Customer\Test\Block\Address\Edit
-     */
-    public function getEditForm()
-    {
-        return Factory::getBlockFactory()->getMagentoCustomerAddressEdit(
-            $this->browser->find($this->editForm, Locator::SELECTOR_CSS)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f3738d05e5e3d0439496b2df70532613b9144d8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAddressEdit.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="CustomerAddressEdit" mca="customer/address/edit" module="Magento_Customer">
+        <block name="editForm" class="Magento\Customer\Test\Block\Address\Edit" locator="#form-validate" strategy="css selector" />
+    </page>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php
index bd774f806053eb90b28ff70003cd703f315e1b2d..31ce18926b51ba89d70d8e5a73508562d405c9cf 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View.php
@@ -94,4 +94,19 @@ class View extends ParentView
     {
         $this->getGroupedProductBlock()->fill($product);
     }
+
+    /**
+     * Set quantity and click add to cart.
+     * @param FixtureInterface $product
+     * @param string|int $qty
+     */
+    public function setQtyAndClickAddToCartGrouped(FixtureInterface $product, $qty)
+    {
+        $associatedProducts = $product->getAssociated()['products'];
+        $groupedProductBlock = $this->getGroupedProductBlock();
+        foreach ($associatedProducts as $product) {
+            $groupedProductBlock->setQty($product->getId(), $qty);
+        }
+        $this->clickAddToCart();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php
index 42b3b0dfcf76047bcd3c23ed1fcf117e497dcbf2..7498c3c56587dd1bace2b00727c90428af19435d 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Catalog/Product/View/Type/Grouped.php
@@ -65,6 +65,18 @@ class Grouped extends Block
         return $this->_rootElement->find(sprintf($this->qtySubProductById, $subProductId))->getValue();
     }
 
+    /**
+     * Set qty to subproduct block
+     *
+     * @param int $subProductId
+     * @param string|int $qty
+     * @return void
+     */
+    public function setQty($subProductId, $qty)
+    {
+        $this->_rootElement->find(sprintf($this->qtySubProductById, $subProductId))->setValue($qty);
+    }
+
     /**
      * Fill product options on view page.
      *
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
index f843482eca1ca860869bb3a4413f71c632f05719..9db1477946df13464d6fabbb2a95cfed7a4046c6 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
@@ -8,6 +8,7 @@ namespace Magento\GroupedProduct\Test\Block\Checkout\Cart;
 
 use Magento\Checkout\Test\Block\Cart\AbstractCartItem;
 use Magento\Checkout\Test\Block\Cart\CartItem as CheckoutCartItem;
+use Magento\Mtf\Client\Locator;
 
 /**
  * Class CartItem
@@ -119,4 +120,57 @@ class CartItem extends AbstractCartItem
             $cartItem->removeItem();
         }
     }
+
+    /**
+     * Get product price including tax
+     *
+     * @return string|null
+     */
+    public function getPriceInclTax()
+    {
+        return $this->getPriceByType($this->priceInclTax, Locator::SELECTOR_XPATH);
+    }
+
+    /**
+     * Get product price excluding tax
+     *
+     * @return string|null
+     */
+    public function getPriceExclTax()
+    {
+        return $this->getPriceByType($this->priceExclTax, Locator::SELECTOR_XPATH);
+    }
+
+    /**
+     * Get sub-total excluding tax for the specified item in the cart
+     *
+     * @return string|null
+     */
+    public function getSubtotalPriceExclTax()
+    {
+        return $this->getPriceByType($this->subTotalPriceExclTax);
+    }
+
+    /**
+     * Get price for the specified item in the cart by the price type
+     *
+     * @return string|null
+     */
+    public function getSubtotalPriceInclTax()
+    {
+        return $this->getPriceByType($this->subTotalPriceInclTax);
+    }
+
+    /**
+     * @param string $priceType
+     * @param string $strategy
+     * @return mixed|null
+     */
+    private function getPriceByType($priceType, $strategy = Locator::SELECTOR_CSS)
+    {
+        $cartProductPrice = $this->_rootElement->find($priceType, $strategy);
+        return $cartProductPrice->isVisible()
+            ? str_replace(',', '', $this->escapeCurrency($cartProductPrice->getText()))
+            : null;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fd3ebe177b3a2f5b0cfb10141f4a3e64f41a8b9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GroupedProduct\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Tax\Test\Constraint\AbstractAssertTaxRuleIsAppliedToAllPrices;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\Fixture\InjectableFixture;
+
+/**
+ * Checks that prices excl tax on category, product and cart pages are equal to specified in dataset.
+ */
+abstract class AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage extends
+ AbstractAssertTaxRuleIsAppliedToAllPrices
+{
+
+    /**
+     * Get grouped product view prices.
+     *
+     * @param FixtureInterface $product
+     * @param array $actualPrices
+     * @return array
+     */
+    abstract protected function getGroupedProductPagePrices(FixtureInterface $product, array $actualPrices);
+
+    /**
+     * Assert that specified prices are actual on category, product and cart pages.
+     *
+     * @param InjectableFixture $product
+     * @param array $prices
+     * @param int $qty
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategoryView $catalogCategoryView
+     * @param CatalogProductView $catalogProductView
+     * @param CheckoutCart $checkoutCart
+     * @param FixtureFactory $fixtureFactory
+     * @return void
+     */
+    public function processAssert(
+        InjectableFixture $product,
+        array $prices,
+        $qty,
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $catalogCategoryView,
+        CatalogProductView $catalogProductView,
+        CheckoutCart $checkoutCart,
+        FixtureFactory $fixtureFactory
+    ) {
+        $this->cmsIndex = $cmsIndex;
+        $this->catalogCategoryView = $catalogCategoryView;
+        $this->catalogProductView = $catalogProductView;
+        $this->checkoutCart = $checkoutCart;
+        //Preconditions
+        $address = $fixtureFactory->createByCode('address', ['dataset' => 'US_address_NY']);
+        $shipping = ['shipping_service' => 'Flat Rate', 'shipping_method' => 'Fixed'];
+        $actualPrices = [];
+        //Assertion steps
+        $productCategory = $product->getCategoryIds()[0];
+        $this->openCategory($productCategory);
+        $actualPrices = $this->getCategoryPrices($product, $actualPrices);
+        $catalogCategoryView->getListProductBlock()->getProductItem($product)->open();
+        $catalogProductView->getGroupedProductViewBlock()->fillOptions($product);
+        $actualPrices = $this->getGroupedProductPagePrices($product, $actualPrices);
+        $catalogProductView->getGroupedProductViewBlock()->setQtyAndClickAddToCartGrouped($product, $qty);
+        $catalogProductView->getMessagesBlock()->waitSuccessMessage();
+        $this->checkoutCart->open();
+        $this->fillEstimateBlock($address, $shipping);
+        $actualPrices = $this->getCartPrices($product, $actualPrices);
+        $actualPrices = $this->getTotals($actualPrices);
+        //Prices verification
+        $message = 'Prices from dataset should be equal to prices on frontend.';
+        \PHPUnit_Framework_Assert::assertEquals($prices, $actualPrices, $message);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php
new file mode 100644
index 0000000000000000000000000000000000000000..57853d344672b0e09a2f6aa9a821146108295cb4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Constraint/AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GroupedProduct\Test\Constraint;
+
+use Magento\Mtf\Fixture\FixtureInterface;
+
+/**
+ * Checks that prices excl tax on category, product and cart pages are equal to specified in dataset.
+ */
+class AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax extends
+ AbstractAssertTaxRuleIsAppliedToAllPricesOnGroupedProductPage
+{
+    /**
+     * @inheritdoc
+     */
+    public function getCategoryPrices(FixtureInterface $product, $actualPrices)
+    {
+        $priceBlock = $this->catalogCategoryView->getListProductBlock()->getProductItem($product)->getPriceBlock();
+        $actualPrices['category_price_excl_tax'] = $priceBlock->getPriceExcludingTax();
+        $actualPrices['category_price_incl_tax'] = $priceBlock->getPriceIncludingTax();
+
+        return $actualPrices;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getGroupedProductPagePrices(FixtureInterface $product, array $actualPrices)
+    {
+        $associatedProducts = $product->getAssociated();
+        /** @var \Magento\GroupedProduct\Test\Block\Catalog\Product\View $groupedProductBlock */
+        $this->catalogProductView = $this->catalogProductView->getGroupedProductViewBlock();
+        foreach (array_keys($associatedProducts['products']) as $productIndex) {
+            //Process assertions
+            $this->catalogProductView ->itemPriceProductBlock(++$productIndex);
+            $actualPrices['sub_product_view_prices_' . $productIndex] =  $this->getProductPagePrices($actualPrices);
+        }
+        return $actualPrices;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getProductPagePrices($actualPrices)
+    {
+        $priceBlock = $this->catalogProductView ->getPriceBlock();
+        $productPrices['product_view_price_excl_tax'] = $priceBlock->getPriceExcludingTax();
+        $productPrices['product_view_price_incl_tax'] = $priceBlock->getPriceIncludingTax();
+
+        return $productPrices;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTotals($actualPrices)
+    {
+        $totalsBlock = $this->checkoutCart->getTotalsBlock();
+        $actualPrices['subtotal_excl_tax'] = $totalsBlock->getSubtotalExcludingTax();
+        $actualPrices['subtotal_incl_tax'] = $totalsBlock->getSubtotalIncludingTax();
+        $actualPrices['discount'] = $totalsBlock->getDiscount();
+        $actualPrices['shipping_excl_tax'] = $totalsBlock->getShippingPrice();
+        $actualPrices['shipping_incl_tax'] = $totalsBlock->getShippingPriceInclTax();
+        $actualPrices['tax'] = $totalsBlock->getTax();
+        $actualPrices['grand_total_excl_tax'] = $totalsBlock->getGrandTotalExcludingTax();
+        $actualPrices['grand_total_incl_tax'] = $totalsBlock->getGrandTotalIncludingTax();
+
+        return $actualPrices;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
index bbdbc011ae8c9c8859d16dcfbd6b2e7428d46246..7648899060f8f3314d1a33b26082724ae1495fa8 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
@@ -125,5 +125,33 @@
                 <item name="dataset" xsi:type="string">grouped_three_simple_products</item>
             </field>
         </dataset>
+
+        <dataset name="grouped_product_with_special_price">
+            <field name="name" xsi:type="string">Test grouped product with special price %isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_grouped_product_with_special_price_%isolation%</field>
+            <field name="category_ids" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="associated" xsi:type="array">
+                <item name="dataset" xsi:type="string">defaultSimpleProduct_with_specialPrice</item>
+            </field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">test-grouped-product-with-special-price-%isolation%</field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c57afc28b88683e3b08917ae2c1d8942a7c3b614
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/TaxCalculationTest.xml
@@ -0,0 +1,41 @@
+<?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\Tax\Test\TestCase\TaxCalculationTest" summary="Apply Taxes for grouped products" ticketId="MAGETWO-60576">
+        <variation name="TaxCalculationTestGroupedProduct">
+            <data name="product" xsi:type="string">groupedProduct::grouped_product_with_special_price</data>
+            <data name="taxRule" xsi:type="string">us_full_tax_rule</data>
+            <data name="shippingAddress/dataset" xsi:type="string">US_address_1</data>
+            <data name="customer/dataset" xsi:type="string">johndoe_unique</data>
+            <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data>
+            <data name="catalogRule" xsi:type="string">-</data>
+            <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data>
+            <data name="flushCache" xsi:type="boolean">true</data>
+            <data name="qty" xsi:type="string">3</data>
+            <data name="prices/category_price_excl_tax" xsi:type="string">9.00</data>
+            <data name="prices/category_price_incl_tax" xsi:type="string">9.90</data>
+            <data name="prices/sub_product_view_prices_1/product_view_price_excl_tax" xsi:type="string">9.00</data>
+            <data name="prices/sub_product_view_prices_1/product_view_price_incl_tax" xsi:type="string">9.90</data>
+            <data name="prices/sub_product_view_prices_2/product_view_price_excl_tax" xsi:type="string">9.00</data>
+            <data name="prices/sub_product_view_prices_2/product_view_price_incl_tax" xsi:type="string">9.90</data>
+            <data name="prices/cart_item_price_excl_tax" xsi:type="string">9.00</data>
+            <data name="prices/cart_item_price_incl_tax" xsi:type="string">9.90</data>
+            <data name="prices/cart_item_subtotal_excl_tax" xsi:type="string">27.00</data>
+            <data name="prices/cart_item_subtotal_incl_tax" xsi:type="string">29.70</data>
+            <data name="prices/subtotal_excl_tax" xsi:type="string">54.00</data>
+            <data name="prices/subtotal_incl_tax" xsi:type="string">59.40</data>
+            <data name="prices/shipping_excl_tax" xsi:type="string">30.00</data>
+            <data name="prices/shipping_incl_tax" xsi:type="string">30.00</data>
+            <data name="prices/discount" xsi:type="string">27.00</data>
+            <data name="prices/tax" xsi:type="string">2.70</data>
+            <data name="prices/grand_total_excl_tax" xsi:type="string">57.00</data>
+            <data name="prices/grand_total_incl_tax" xsi:type="string">59.70</data>
+            <constraint name="Magento\GroupedProduct\Test\Constraint\AssertTaxRuleIsAppliedToAllPricesGroupedExcludingIncludingTax" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
index fc2763aea017dee37b05216a1b881665a29dc551..c17553629ae59a3b0c8ef7c1643112743cd82bf8 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
@@ -45,6 +45,47 @@ class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendContr
         $this->assertTrue($isRedirectPresent);
     }
 
+    /**
+     * @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save::execute
+     *
+     * @dataProvider saveActionVisibilityAttrDataProvider
+     * @param array $attributes
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testSaveActionChangeVisibility($attributes)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Catalog\Model\ProductRepository::class
+        );
+        $product = $repository->get('simple');
+        $product->setOrigData();
+        $product->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE);
+        $product->save();
+
+        /** @var $session \Magento\Backend\Model\Session */
+        $session = $objectManager->get(\Magento\Backend\Model\Session::class);
+        $session->setProductIds([$product->getId()]);
+        $this->getRequest()->setParam('attributes', $attributes);
+
+        $this->dispatch('backend/catalog/product_action_attribute/save/store/0');
+        /** @var \Magento\Catalog\Model\Category $category */
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            \Magento\Catalog\Model\CategoryFactory::class
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            \Magento\Catalog\Block\Product\ListProduct::class
+        );
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productItem = $productCollection->getFirstItem();
+        $this->assertEquals($session->getProductIds(), [$productItem->getId()]);
+    }
+
     /**
      * @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Validate::execute
      *
@@ -97,4 +138,17 @@ class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendContr
             ]
         ];
     }
+
+    /**
+     * Data Provider for save with visibility attribute
+     *
+     * @return array
+     */
+    public function saveActionVisibilityAttrDataProvider()
+    {
+        return [
+            ['arguments' => ['visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH]],
+            ['arguments' => ['visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG]]
+        ];
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c42856d865649d5206df2c76de323fff521c5482
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Store/Model/StoreManagerTest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Store\Model;
+
+use Magento\Framework\ObjectManagerInterface as ObjectManager;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class StoreManagerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Class dependencies initialization
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+        $this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
+    }
+
+    /**
+     * Check that behavior of setting and getting store into StoreManager is correct
+     * Setting: Magento\Store\Model\StoreManagerInterface::setCurrentStore
+     * Getting: Magento\Store\Model\StoreManagerInterface::getStore
+     *
+     * @return void
+     */
+    public function testDefaultStoreIdIsSetCorrectly()
+    {
+        $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID);
+        $this->assertEquals(Store::DEFAULT_STORE_ID, $this->storeManager->getStore()->getId());
+    }
+}