diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg/Content.php
index d5488ecc5d085ee4a5d4b535ccf24040dbaee2a6..ac8cb91222fba47c7c686c10b45d6b81e87db2eb 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg/Content.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg/Content.php
@@ -14,6 +14,12 @@ namespace Magento\Catalog\Block\Adminhtml\Helper\Form\Wysiwyg;
 use Magento\Backend\Block\Widget\Form;
 use Magento\Backend\Block\Widget\Form\Generic;
 
+/**
+ * Class Content
+ *
+ * @deprecated
+ * @see \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav
+ */
 class Content extends Generic
 {
     /**
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php
index 6dae249865157d1c5960c8be6cefa9bdf27b3126..43114cb83ad149ff07a2310ec1924dcd6f9faa25 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php
@@ -84,6 +84,11 @@ class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product
         $productIds = $collection->getAllIds();
         $storeId = (int) $this->getRequest()->getParam('store', 0);
         $status = (int) $this->getRequest()->getParam('status');
+        $filters = (array)$this->getRequest()->getParam('filters', []);
+
+        if (isset($filters['store_id'])) {
+            $storeId = (int)$filters['store_id'];
+        }
 
         try {
             $this->_validateMassStatus($productIds, $status);
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php
index c984840e2067daa0f43f06319e9c3a68b1287012..6e432447263ee9d4d6240a6c104b6c599db1e81c 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php
@@ -101,6 +101,9 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Set
             }
             $model->save();
             $this->messageManager->addSuccess(__('You saved the attribute set.'));
+        } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
+            $this->messageManager->addErrorMessage($e->getMessage());
+            $hasError = true;
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
             $this->messageManager->addError($e->getMessage());
             $hasError = true;
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php
index 327729cf83695931a8c378dc91f41ab66a9e7d69..290770bd296c3bf9ef8854de86008674776ae2b7 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php
@@ -73,9 +73,12 @@ class Sku extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
     {
         $attribute = $this->getAttribute();
         $entity = $attribute->getEntity();
-        $increment = $this->_getLastSimilarAttributeValueIncrement($attribute, $object);
         $attributeValue = $object->getData($attribute->getAttributeCode());
+        $increment = null;
         while (!$entity->checkAttributeUniqueValue($attribute, $object)) {
+            if ($increment === null) {
+                $increment = $this->_getLastSimilarAttributeValueIncrement($attribute, $object);
+            }
             $sku = trim($attributeValue);
             if (strlen($sku . '-' . ++$increment) > self::SKU_MAX_LENGTH) {
                 $sku = substr($sku, 0, -strlen($increment) - 1);
diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
index f17760237034041764539e533d5f1440b8dad3e4..cbf0464ca366158d4d3e4d75f65e4435f0834502 100644
--- a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
+++ b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
@@ -58,6 +58,11 @@ class CreateHandler implements ExtensionInterface
      */
     protected $fileStorageDb;
 
+    /**
+     * @var array
+     */
+    private $mediaAttributeCodes;
+
     /**
      * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
      * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
@@ -145,9 +150,11 @@ class CreateHandler implements ExtensionInterface
         }
 
         /* @var $mediaAttribute \Magento\Catalog\Api\Data\ProductAttributeInterface */
-        foreach ($this->mediaConfig->getMediaAttributeCodes() as $mediaAttrCode) {
+        foreach ($this->getMediaAttributeCodes() as $mediaAttrCode) {
             $attrData = $product->getData($mediaAttrCode);
-
+            if (empty($attrData) && empty($clearImages) && empty($newImages) && empty($existImages)) {
+                continue;
+            }
             if (in_array($attrData, $clearImages)) {
                 $product->setData($mediaAttrCode, 'no_selection');
             }
@@ -394,4 +401,17 @@ class CreateHandler implements ExtensionInterface
             );
         }
     }
+
+    /**
+     * Get Media Attribute Codes cached value
+     *
+     * @return array
+     */
+    private function getMediaAttributeCodes()
+    {
+        if ($this->mediaAttributeCodes === null) {
+            $this->mediaAttributeCodes = $this->mediaConfig->getMediaAttributeCodes();
+        }
+        return $this->mediaAttributeCodes;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php b/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php
index 3df4d9813a668b6fc81d7706412e1cf4e671c5e5..167dc2be15b292c4fabd9983911cd54cba89e62c 100644
--- a/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php
+++ b/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php
@@ -40,7 +40,6 @@ class SaveHandler
         Link $linkResource,
         ProductLinkRepositoryInterface $productLinkRepository
     ) {
-
         $this->metadataPool = $metadataPool;
         $this->linkResource = $linkResource;
         $this->productLinkRepository = $productLinkRepository;
@@ -54,12 +53,18 @@ class SaveHandler
      */
     public function execute($entityType, $entity)
     {
-        /** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
-        foreach ($this->productLinkRepository->getList($entity) as $link) {
-            $this->productLinkRepository->delete($link);
+        $link = $entity->getData($this->metadataPool->getMetadata($entityType)->getLinkField());
+        if ($this->linkResource->hasProductLinks($link)) {
+            /** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
+            foreach ($this->productLinkRepository->getList($entity) as $link) {
+                $this->productLinkRepository->delete($link);
+            }
         }
-        foreach ($entity->getProductLinks() as $link) {
-            $this->productLinkRepository->save($link);
+        $productLinks = $entity->getProductLinks();
+        if (count($productLinks) > 0) {
+            foreach ($entity->getProductLinks() as $link) {
+                $this->productLinkRepository->save($link);
+            }
         }
         return $entity;
     }
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
index 407c2027923de4c683272773d519cf1adc7b1917..e743c5d384bdd539a15c4f666b36ce0f43f7f4d0 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
@@ -238,7 +238,9 @@ class Category extends AbstractResource
         if (!$object->getChildrenCount()) {
             $object->setChildrenCount(0);
         }
-
+        $object->setAttributeSetId(
+            $object->getAttributeSetId() ?: $this->getEntityType()->getDefaultAttributeSetId()
+        );
         if ($object->isObjectNew()) {
             if ($object->getPosition() === null) {
                 $object->setPosition($this->_getMaxPosition($object->getPath()) + 1);
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
index 99c4316d20740edc4d3d6415bbfb06a344e7e5c7..8e93868dc7e51916a1c44997ad98045edbe1bd4f 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php
@@ -351,14 +351,11 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
      */
     public function getApplyTo()
     {
-        if ($this->getData(self::APPLY_TO)) {
-            if (is_array($this->getData(self::APPLY_TO))) {
-                return $this->getData(self::APPLY_TO);
-            }
-            return explode(',', $this->getData(self::APPLY_TO));
-        } else {
-            return [];
+        $applyTo = $this->_getData(self::APPLY_TO) ?: [];
+        if (!is_array($applyTo)) {
+            $applyTo = explode(',', $applyTo);
         }
+        return $applyTo;
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php
index bbccabe5a61c969f74294398ad484e1b0d3c64f9..17bfa90e8842d4dc511d8d78f2dc23151a3934b3 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php
@@ -96,6 +96,30 @@ class Link extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         return $connection->fetchOne($select, $bind);
     }
 
+    /**
+     * Check if product has links.
+     *
+     * @param int $parentId ID of product
+     * @return bool
+     */
+    public function hasProductLinks($parentId)
+    {
+        $connection = $this->getConnection();
+        $select = $connection->select()->from(
+            $this->getMainTable(),
+            ['count' => new \Zend_Db_Expr('COUNT(*)')]
+        )->where(
+            'product_id = :product_id'
+        ) ;
+
+        return $connection->fetchOne(
+            $select,
+            [
+                'product_id' => $parentId
+            ]
+        ) > 0;
+    }
+
     /**
      * Save Product Links process
      *
diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/MassStatusTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/MassStatusTest.php
index 0fff613c56e2e4edc5a6765826730ffefac89f10..6f7809d89e5bda52429f5c365f1fdd8519996189 100644
--- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/MassStatusTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/MassStatusTest.php
@@ -6,32 +6,74 @@
  */
 namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product;
 
+use Magento\Ui\Component\MassAction\Filter;
+use Magento\Backend\Model\View\Result\Redirect;
+use Magento\Catalog\Model\Indexer\Product\Price\Processor;
+use Magento\Catalog\Controller\Adminhtml\Product\Builder;
+use Magento\Framework\Data\Collection\AbstractDb;
+use Magento\Catalog\Model\Product\Action;
+
+/**
+ * Class MassStatusTest
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class MassStatusTest extends \Magento\Catalog\Test\Unit\Controller\Adminhtml\ProductTest
 {
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var Processor|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $priceProcessor;
+    private $priceProcessorMock;
 
-    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Backend\Model\View\Result\Redirect */
-    protected $resultRedirect;
+    /**
+     * @var Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resultRedirectMock;
+
+    /**
+     * @var Filter|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filterMock;
+
+    /**
+     * @var Builder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $productBuilderMock;
+
+    /**
+     * @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $abstractDbMock;
+
+    /**
+     * @var Action|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $actionMock;
 
     protected function setUp()
     {
-        $this->priceProcessor = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Price\Processor::class)
+        $this->priceProcessorMock = $this->getMockBuilder(Processor::class)
             ->disableOriginalConstructor()->getMock();
+        $this->productBuilderMock = $this->getMockBuilder(Builder::class)
+            ->setMethods(['build'])
+            ->disableOriginalConstructor()
+            ->getMock();
 
-        $productBuilder = $this->getMockBuilder(
-            \Magento\Catalog\Controller\Adminhtml\Product\Builder::class
-        )->setMethods(['build'])->disableOriginalConstructor()->getMock();
-
-        $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)->disableOriginalConstructor()
-            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])->getMock();
-        $product->expects($this->any())->method('getTypeId')->will($this->returnValue('simple'));
-        $product->expects($this->any())->method('getStoreId')->will($this->returnValue('1'));
-        $productBuilder->expects($this->any())->method('build')->will($this->returnValue($product));
+        $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])
+            ->getMock();
+        $productMock->expects($this->any())
+            ->method('getTypeId')
+            ->willReturn('simple');
+        $productMock->expects($this->any())
+            ->method('getStoreId')
+            ->willReturn('1');
+        $this->productBuilderMock->expects($this->any())
+            ->method('build')
+            ->willReturn($productMock);
 
-        $this->resultRedirect = $this->getMockBuilder(\Magento\Backend\Model\View\Result\Redirect::class)
+        $this->resultRedirectMock = $this->getMockBuilder(\Magento\Backend\Model\View\Result\Redirect::class)
             ->disableOriginalConstructor()
             ->getMock();
         $resultFactory = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class)
@@ -41,47 +83,71 @@ class MassStatusTest extends \Magento\Catalog\Test\Unit\Controller\Adminhtml\Pro
         $resultFactory->expects($this->atLeastOnce())
             ->method('create')
             ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT)
-            ->willReturn($this->resultRedirect);
+            ->willReturn($this->resultRedirectMock);
 
-        $abstractDbMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\AbstractDb::class)
+        $this->abstractDbMock = $this->getMockBuilder(AbstractDb::class)
             ->disableOriginalConstructor()
             ->setMethods(['getAllIds', 'getResource'])
             ->getMock();
-        $abstractDbMock->expects($this->any())
-            ->method('getAllIds')
-            ->willReturn([]);
-
-        $filterMock = $this->getMockBuilder(\Magento\Ui\Component\MassAction\Filter::class)
+        $this->filterMock = $this->getMockBuilder(\Magento\Ui\Component\MassAction\Filter::class)
             ->disableOriginalConstructor()
             ->setMethods(['getCollection'])
             ->getMock();
-        $filterMock->expects($this->any())
-            ->method('getCollection')
-            ->willReturn($abstractDbMock);
-        
-        $collectionFactoryMock = $this->getMockBuilder(
-            \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class
-        )
+        $this->actionMock = $this->getMockBuilder(Action::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $collectionFactoryMock =
+            $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class)
             ->disableOriginalConstructor()
             ->setMethods(['create'])
             ->getMock();
         $collectionFactoryMock->expects($this->any())
             ->method('create')
-            ->willReturn($abstractDbMock);
+            ->willReturn($this->abstractDbMock);
+
+        $additionalParams = [
+            'resultFactory' => $resultFactory
+        ];
+        /** @var \Magento\Backend\App\Action\Context $context */
+        $context = $this->initContext($additionalParams, [[Action::class, $this->actionMock]]);
 
-        $additionalParams = ['resultFactory' => $resultFactory];
         $this->action = new \Magento\Catalog\Controller\Adminhtml\Product\MassStatus(
-            $this->initContext($additionalParams),
-            $productBuilder,
-            $this->priceProcessor,
-            $filterMock,
+            $context,
+            $this->productBuilderMock,
+            $this->priceProcessorMock,
+            $this->filterMock,
             $collectionFactoryMock
         );
     }
 
     public function testMassStatusAction()
     {
-        $this->priceProcessor->expects($this->once())->method('reindexList');
+        $storeId = 1;
+        $status = \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED;
+        $filters = [
+            'store_id' => 2,
+        ];
+
+        $this->filterMock->expects($this->once())
+            ->method('getCollection')
+            ->willReturn($this->abstractDbMock);
+        $this->abstractDbMock->expects($this->once())
+            ->method('getAllIds')
+            ->willReturn([3]);
+        $this->request->expects($this->exactly(3))
+            ->method('getParam')
+            ->willReturnMap([
+                ['store', 0, $storeId],
+                ['status', null, $status],
+                ['filters', [], $filters]
+            ]);
+        $this->actionMock->expects($this->once())
+            ->method('updateAttributes')
+            ->with([3], ['status' => $status], 2);
+        $this->priceProcessorMock->expects($this->once())
+            ->method('reindexList');
+
         $this->action->execute();
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/ProductTest.php
index 9a21de70b4f114fceb5950ea716c580068584669..524bdceae10e03cfc9678f10d19b881588ff8de8 100644
--- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/ProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/ProductTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Test\Unit\Controller\Adminhtml;
 
+use Magento\Catalog\Api\Data\ProductInterface;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -25,17 +27,33 @@ abstract class ProductTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject */
     protected $request;
 
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $objectManagerMock;
+
     /**
      * Init context object
      *
      * @param array $additionalParams
+     * @param array $objectManagerMap Object Manager mappings
      * @return \PHPUnit_Framework_MockObject_MockObject
      */
-    protected function initContext(array $additionalParams = [])
+    protected function initContext(array $additionalParams = [], array $objectManagerMap = [])
     {
         $productActionMock = $this->getMock(\Magento\Catalog\Model\Product\Action::class, [], [], '', false);
-        $objectManagerMock = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class);
-        $objectManagerMock->expects($this->any())->method('get')->will($this->returnValue($productActionMock));
+
+        $this->objectManagerMock = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class);
+
+        if ($objectManagerMap) {
+            $this->objectManagerMock->expects($this->any())
+                ->method('get')
+                ->willReturnMap($objectManagerMap);
+        }
+
+        $this->objectManagerMock->expects($this->any())
+            ->method('get')
+            ->willReturn($productActionMock);
 
         $block = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class)
             ->disableOriginalConstructor()->getMockForAbstractClass();
@@ -93,7 +111,7 @@ abstract class ProductTest extends \PHPUnit_Framework_TestCase
         $this->context->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager));
         $this->context->expects($this->any())->method('getRequest')->will($this->returnValue($requestInterfaceMock));
         $this->context->expects($this->any())->method('getResponse')->will($this->returnValue($responseInterfaceMock));
-        $this->context->expects($this->any())->method('getObjectManager')->will($this->returnValue($objectManagerMock));
+        $this->context->expects($this->any())->method('getObjectManager')->willReturn($this->objectManagerMock);
 
         $this->context->expects($this->any())->method('getMessageManager')
             ->will($this->returnValue($managerInterfaceMock));
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
index 1419c17e11b298d1fcdc554a3131d7b8c9b8ffe8..e1680ab5a4081946b73b375a85c0b53cf916afd4 100755
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
@@ -754,7 +754,10 @@ class Eav extends AbstractModifier
         $meta['arguments']['data']['config']['wysiwyg'] = true;
         $meta['arguments']['data']['config']['wysiwygConfigData'] = [
             'add_variables' => false,
-            'add_widgets' => false
+            'add_widgets' => false,
+            'add_directives' => true,
+            'use_container' => true,
+            'container_class' => 'hor-scroll',
         ];
 
         return $meta;
diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
index 86b150062d3c057afe500a6d76aac3665690ba87..fa704272962162d43edd1d129c1229275614015a 100644
--- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\CatalogImportExport\Model\Export;
 
-use Magento\Framework\DB\Ddl\Table;
 use Magento\ImportExport\Model\Import;
 use \Magento\Store\Model\Store;
 use \Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
@@ -850,6 +849,24 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
         return $writer->getContents();
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    protected function _prepareEntityCollection(\Magento\Eav\Model\Entity\Collection\AbstractCollection $collection)
+    {
+        $exportFilter = !empty($this->_parameters[\Magento\ImportExport\Model\Export::FILTER_ELEMENT_GROUP]) ?
+            $this->_parameters[\Magento\ImportExport\Model\Export::FILTER_ELEMENT_GROUP] : [];
+
+        if (isset($exportFilter['category_ids'])
+            && trim($exportFilter['category_ids'])
+            && $collection instanceof \Magento\Catalog\Model\ResourceModel\Product\Collection
+        ) {
+            $collection->addCategoriesFilter(['in' => explode(',', $exportFilter['category_ids'])]);
+        }
+
+        return parent::_prepareEntityCollection($collection);
+    }
+
     /**
      * Get export data for collection
      *
@@ -953,7 +970,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                         if (is_scalar($attrValue)) {
                             if (!in_array($fieldName, $this->_getExportMainAttrCodes())) {
                                 $additionalAttributes[$fieldName] = $fieldName .
-                                    ImportProduct::PAIR_NAME_VALUE_SEPARATOR . $attrValue;
+                                    ImportProduct::PAIR_NAME_VALUE_SEPARATOR . $this->wrapValue($attrValue);
                             }
                             $data[$itemId][$storeId][$fieldName] = htmlspecialchars_decode($attrValue);
                         }
@@ -963,7 +980,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                             $additionalAttributes[$code] = $fieldName .
                                 ImportProduct::PAIR_NAME_VALUE_SEPARATOR . implode(
                                     ImportProduct::PSEUDO_MULTI_LINE_SEPARATOR,
-                                    $this->collectedMultiselectsData[$storeId][$productLinkId][$code]
+                                    $this->wrapValue($this->collectedMultiselectsData[$storeId][$productLinkId][$code])
                                 );
                         }
                     }
@@ -994,6 +1011,25 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
         return $data;
     }
 
+    /**
+     * Wrap values with double quotes if "Fields Enclosure" option is enabled
+     *
+     * @param string|array $value
+     * @return string|array
+     */
+    private function wrapValue($value)
+    {
+        if (!empty($this->_parameters[\Magento\ImportExport\Model\Export::FIELDS_ENCLOSURE])) {
+            $wrap = function ($value) {
+                return sprintf('"%s"', str_replace('"', '""', $value));
+            };
+
+            $value = is_array($value) ? array_map($wrap, $value) : $wrap($value);
+        }
+
+        return $value;
+    }
+
     /**
      * @return array
      */
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 16df0866135a7f07760134c7aff9a0b15bc6fb01..afb2e86b6248a79523405c78acd1cf27953b90c2 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -644,6 +644,13 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      */
     private $productEntityIdentifierField;
 
+    /**
+     * Escaped separator value for regular expression.
+     * The value is based on PSEUDO_MULTI_LINE_SEPARATOR constant.
+     * @var string
+     */
+    private $multiLineSeparatorForRegexp;
+
     /**
      * @param \Magento\Framework\Json\Helper\Data $jsonHelper
      * @param \Magento\ImportExport\Helper\Data $importExportData
@@ -2438,14 +2445,40 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
     }
 
     /**
-     * Retrieves additional attributes as array code=>value.
+     * Retrieves additional attributes in format:
+     * [
+     *      code1 => value1,
+     *      code2 => value2,
+     *      ...
+     *      codeN => valueN
+     * ]
      *
-     * @param string $additionalAttributes
+     * @param string $additionalAttributes Attributes data that will be parsed
      * @return array
      */
     private function parseAdditionalAttributes($additionalAttributes)
     {
-        $attributeNameValuePairs = explode($this->getMultipleValueSeparator(), $additionalAttributes);
+        return empty($this->_parameters[Import::FIELDS_ENCLOSURE])
+            ? $this->parseAttributesWithoutWrappedValues($additionalAttributes)
+            : $this->parseAttributesWithWrappedValues($additionalAttributes);
+    }
+
+    /**
+     * Parses data and returns attributes in format:
+     * [
+     *      code1 => value1,
+     *      code2 => value2,
+     *      ...
+     *      codeN => valueN
+     * ]
+     *
+     * @param string $attributesData Attributes data that will be parsed. It keeps data in format:
+     *      code=value,code2=value2...,codeN=valueN
+     * @return array
+     */
+    private function parseAttributesWithoutWrappedValues($attributesData)
+    {
+        $attributeNameValuePairs = explode($this->getMultipleValueSeparator(), $attributesData);
         $preparedAttributes = [];
         $code = '';
         foreach ($attributeNameValuePairs as $attributeData) {
@@ -2463,6 +2496,75 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         return $preparedAttributes;
     }
 
+    /**
+     * Parses data and returns attributes in format:
+     * [
+     *      code1 => value1,
+     *      code2 => value2,
+     *      ...
+     *      codeN => valueN
+     * ]
+     * All values have unescaped data except mupliselect attributes,
+     * they should be parsed in additional method - parseMultiselectValues()
+     *
+     * @param string $attributesData Attributes data that will be parsed. It keeps data in format:
+     *      code="value",code2="value2"...,codeN="valueN"
+     *  where every value is wrapped in double quotes. Double quotes as part of value should be duplicated.
+     *  E.g. attribute with code 'attr_code' has value 'my"value'. This data should be stored as attr_code="my""value"
+     *
+     * @return array
+     */
+    private function parseAttributesWithWrappedValues($attributesData)
+    {
+        $attributes = [];
+        preg_match_all('~((?:[a-z0-9_])+)="((?:[^"]|""|"' . $this->getMultiLineSeparatorForRegexp() . '")+)"+~',
+            $attributesData,
+            $matches
+        );
+        foreach ($matches[1] as $i => $attributeCode) {
+            $attribute = $this->retrieveAttributeByCode($attributeCode);
+            $value = 'multiselect' != $attribute->getFrontendInput()
+                ? str_replace('""', '"', $matches[2][$i])
+                : '"' . $matches[2][$i] . '"';
+            $attributes[$attributeCode] = $value;
+        }
+        return $attributes;
+    }
+
+    /**
+     * Parse values of multiselect attributes depends on "Fields Enclosure" parameter
+     *
+     * @param string $values
+     * @return array
+     */
+    public function parseMultiselectValues($values)
+    {
+        if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
+            return explode(self::PSEUDO_MULTI_LINE_SEPARATOR, $values);
+        }
+        if (preg_match_all('~"((?:[^"]|"")*)"~', $values, $matches)) {
+            return $values = array_map(function ($value) {
+                return str_replace('""', '"', $value);
+            }, $matches[1]);
+        }
+        return [$values];
+    }
+
+    /**
+     * Retrieves escaped PSEUDO_MULTI_LINE_SEPARATOR if it is metacharacter for regular expression
+     *
+     * @return string
+     */
+    private function getMultiLineSeparatorForRegexp()
+    {
+        if (!$this->multiLineSeparatorForRegexp) {
+            $this->multiLineSeparatorForRegexp = in_array(self::PSEUDO_MULTI_LINE_SEPARATOR, str_split('[\^$.|?*+(){}'))
+                ? '\\' . self::PSEUDO_MULTI_LINE_SEPARATOR
+                : self::PSEUDO_MULTI_LINE_SEPARATOR;
+        }
+        return $this->multiLineSeparatorForRegexp;
+    }
+
     /**
      * Set values in use_config_ fields.
      *
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
index 8461e617431d64fe3529162d54841d7da4740cdf..0d19b9fcbedc85e4df47ab745759282f4824b060 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
@@ -490,23 +490,25 @@ abstract class AbstractType
         $resultAttrs = [];
 
         foreach ($this->_getProductAttributes($rowData) as $attrCode => $attrParams) {
-            if (!$attrParams['is_static']) {
-                if (isset($rowData[$attrCode]) && strlen($rowData[$attrCode])) {
-                    $resultAttrs[$attrCode] = in_array($attrParams['type'], ['select', 'boolean'])
-                        ? $attrParams['options'][strtolower($rowData[$attrCode])]
-                        : $rowData[$attrCode];
-                    if ('multiselect' == $attrParams['type']) {
-                        $resultAttrs[$attrCode] = [];
-                        foreach (explode(Product::PSEUDO_MULTI_LINE_SEPARATOR, $rowData[$attrCode]) as $value) {
-                            $resultAttrs[$attrCode][] = $attrParams['options'][strtolower($value)];
-                        }
-                        $resultAttrs[$attrCode] = implode(',', $resultAttrs[$attrCode]);
+            if ($attrParams['is_static']) {
+                continue;
+            }
+            if (isset($rowData[$attrCode]) && strlen($rowData[$attrCode])) {
+                if (in_array($attrParams['type'], ['select', 'boolean'])) {
+                    $resultAttrs[$attrCode] = $attrParams['options'][strtolower($rowData[$attrCode])];
+                } elseif ('multiselect' == $attrParams['type']) {
+                    $resultAttrs[$attrCode] = [];
+                    foreach ($this->_entityModel->parseMultiselectValues($rowData[$attrCode]) as $value) {
+                        $resultAttrs[$attrCode][] = $attrParams['options'][strtolower($value)];
                     }
-                } elseif (array_key_exists($attrCode, $rowData)) {
+                    $resultAttrs[$attrCode] = implode(',', $resultAttrs[$attrCode]);
+                } else {
                     $resultAttrs[$attrCode] = $rowData[$attrCode];
-                } elseif ($withDefaultValue && null !== $attrParams['default_value']) {
-                    $resultAttrs[$attrCode] = $attrParams['default_value'];
                 }
+            } elseif (array_key_exists($attrCode, $rowData)) {
+                $resultAttrs[$attrCode] = $rowData[$attrCode];
+            } elseif ($withDefaultValue && null !== $attrParams['default_value']) {
+                $resultAttrs[$attrCode] = $attrParams['default_value'];
             }
         }
 
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php
index e57983796f695fcac97325123d102cbe5a9854b7..0ca40e916c85b0fe50886f36fe502538a370ae50 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php
@@ -71,6 +71,32 @@ class Validator extends AbstractValidator implements RowValidatorInterface
         return $valid;
     }
 
+    /**
+     * Check if value is valid attribute option
+     *
+     * @param string $attrCode
+     * @param array $possibleOptions
+     * @param string $value
+     * @return bool
+     */
+    private function validateOption($attrCode, $possibleOptions, $value)
+    {
+        if (!isset($possibleOptions[strtolower($value)])) {
+            $this->_addMessages(
+                [
+                    sprintf(
+                        $this->context->retrieveMessageTemplate(
+                            RowValidatorInterface::ERROR_INVALID_ATTRIBUTE_OPTION
+                        ),
+                        $attrCode
+                    )
+                ]
+            );
+            return false;
+        }
+        return true;
+    }
+
     /**
      * @param mixed $attrCode
      * @param string $type
@@ -166,23 +192,15 @@ class Validator extends AbstractValidator implements RowValidatorInterface
                 break;
             case 'select':
             case 'boolean':
+                $valid = $this->validateOption($attrCode, $attrParams['options'], $rowData[$attrCode]);
+                break;
             case 'multiselect':
-                $values = explode(Product::PSEUDO_MULTI_LINE_SEPARATOR, $rowData[$attrCode]);
-                $valid = true;
+                $values = $this->context->parseMultiselectValues($rowData[$attrCode]);
                 foreach ($values as $value) {
-                    $valid = $valid && isset($attrParams['options'][strtolower($value)]);
-                }
-                if (!$valid) {
-                    $this->_addMessages(
-                        [
-                            sprintf(
-                                $this->context->retrieveMessageTemplate(
-                                    RowValidatorInterface::ERROR_INVALID_ATTRIBUTE_OPTION
-                                ),
-                                $attrCode
-                            )
-                        ]
-                    );
+                    $valid = $this->validateOption($attrCode, $attrParams['options'], $value);
+                    if (!$valid) {
+                        break;
+                    }
                 }
                 break;
             case 'datetime':
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php b/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
index c5cdd1950cc3803a238bdd77caa1ee5fa2f8b88e..58e364920bb6ad4919212ba329e2d8294cd36027 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
@@ -15,13 +15,14 @@ use Magento\CatalogInventory\Model\Indexer\Stock\Processor;
 use Magento\CatalogInventory\Model\ResourceModel\Stock\Item as StockItemResource;
 use Magento\CatalogInventory\Model\Spi\StockStateProviderInterface;
 use Magento\CatalogInventory\Model\StockRegistryStorage;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\MapperFactory;
 use Magento\Framework\DB\QueryBuilderFactory;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
 use Magento\Framework\Stdlib\DateTime\DateTime;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
 
 /**
  * Class StockItemRepository
@@ -89,6 +90,9 @@ class StockItemRepository implements StockItemRepositoryInterface
      */
     protected $stockRegistryStorage;
 
+    /** @var  \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory */
+    protected $productCollectionFactory;
+
     /**
      * @param StockConfigurationInterface $stockConfiguration
      * @param StockStateProviderInterface $stockStateProvider
@@ -129,6 +133,21 @@ class StockItemRepository implements StockItemRepositoryInterface
         $this->dateTime = $dateTime;
     }
 
+    /**
+     * @deprecated
+     * @return  \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
+     */
+    private function getProductCollectionFactory()
+    {
+        if ($this->productCollectionFactory === null) {
+            $this->productCollectionFactory = ObjectManager::getInstance()->get(
+                \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class
+            );
+        }
+
+        return $this->productCollectionFactory;
+    }
+
     /**
      * @inheritdoc
      */
@@ -136,8 +155,12 @@ class StockItemRepository implements StockItemRepositoryInterface
     {
         try {
             /** @var \Magento\Catalog\Model\Product $product */
-            $product = $this->productFactory->create();
-            $product->load($stockItem->getProductId());
+            $product = $this->getProductCollectionFactory()->create()
+                ->setFlag('has_stock_status_filter')
+                ->addIdFilter($stockItem->getProductId())
+                ->addFieldToSelect('type_id')
+                ->getFirstItem();
+
             if (!$product->getId()) {
                 return $stockItem;
             }
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
index 769e2db4cc84553a3a10e081e6785a02a72b5d15..23b7805e622e32938a3403e58af7f30d8a8d80e8 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\CatalogInventory\Test\Unit\Model\Stock;
 
+use Magento\Catalog\Model\ResourceModel\Product\Collection;
+use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
 use Magento\CatalogInventory\Model\Stock\StockItemRepository;
 use Magento\CatalogInventory\Api\Data as InventoryApiData;
 use Magento\CatalogInventory\Model\StockRegistryStorage;
@@ -153,9 +155,8 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods(['load', 'getId', 'getTypeId', '__wakeup'])
             ->getMock();
-        $this->productFactoryMock->expects($this->any())
-            ->method('create')
-            ->willReturn($this->productMock);
+
+        $this->productFactoryMock->expects($this->any())->method('create')->willReturn($this->productMock);
 
         $this->queryBuilderFactoryMock = $this->getMockBuilder(\Magento\Framework\DB\QueryBuilderFactory::class)
             ->setMethods(['create'])
@@ -185,6 +186,22 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
+        $productCollection = $this->getMockBuilder(
+            \Magento\Catalog\Model\ResourceModel\Product\Collection::class
+        )->disableOriginalConstructor()->getMock();
+
+        $productCollection->expects($this->any())->method('setFlag')->willReturnSelf();
+        $productCollection->expects($this->any())->method('addIdFilter')->willReturnSelf();
+        $productCollection->expects($this->any())->method('addFieldToSelect')->willReturnSelf();
+        $productCollection->expects($this->any())->method('getFirstItem')->willReturn($this->productMock);
+
+        $productCollectionFactory = $this->getMockBuilder(CollectionFactory::class)
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $productCollectionFactory->expects($this->any())->method('create')->willReturn($productCollection);
+
         $this->model = (new ObjectManager($this))->getObject(
             StockItemRepository::class,
             [
@@ -200,6 +217,7 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
                 'indexProcessor' => $this->indexProcessorMock,
                 'dateTime' => $this->dateTime,
                 'stockRegistryStorage' => $this->stockRegistryStorage,
+                'productCollectionFactory' => $productCollectionFactory,
             ]
         );
     }
@@ -263,7 +281,6 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
         $productId = 1;
 
         $this->stockItemMock->expects($this->any())->method('getProductId')->willReturn($productId);
-        $this->productMock->expects($this->once())->method('load')->with($productId)->willReturnSelf();
         $this->productMock->expects($this->once())->method('getId')->willReturn($productId);
         $this->productMock->expects($this->once())->method('getTypeId')->willReturn('typeId');
         $this->stockConfigurationMock->expects($this->once())->method('isQty')->with('typeId')->willReturn(true);
@@ -309,7 +326,6 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
         $productId = 1;
 
         $this->stockItemMock->expects($this->any())->method('getProductId')->willReturn($productId);
-        $this->productMock->expects($this->once())->method('load')->with($productId)->willReturnSelf();
         $this->productMock->expects($this->once())->method('getId')->willReturn(null);
         $this->stockRegistryStorage->expects($this->never())->method('removeStockItem');
         $this->stockRegistryStorage->expects($this->never())->method('removeStockStatus');
@@ -325,7 +341,6 @@ class StockItemRepositoryTest extends \PHPUnit_Framework_TestCase
         $productId = 1;
 
         $this->stockItemMock->expects($this->any())->method('getProductId')->willReturn($productId);
-        $this->productMock->expects($this->once())->method('load')->with($productId)->willReturnSelf();
         $this->productMock->expects($this->once())->method('getId')->willReturn($productId);
         $this->productMock->expects($this->once())->method('getTypeId')->willReturn('typeId');
         $this->stockConfigurationMock->expects($this->once())->method('isQty')->with('typeId')->willReturn(false);
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php
index ea24235b0fe2ef694e2087f7a8bdbf4c8ece3399..cb9a6b534609f7205f2c8a569b022389e13436b7 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php
@@ -32,7 +32,7 @@ class UpdateConfigurations
         'swatch_image',
         'small_image',
         'thumbnail',
-        'image'
+        'image',
     ];
 
     /**
@@ -65,13 +65,15 @@ class UpdateConfigurations
     ) {
         $configurations = $this->getConfigurations();
         $configurations = $this->variationHandler->duplicateImagesForVariations($configurations);
-        foreach ($configurations as $productId => $productData) {
-            /** @var \Magento\Catalog\Model\Product $product */
-            $product = $this->productRepository->getById($productId, false, $this->request->getParam('store', 0));
-            $productData = $this->variationHandler->processMediaGallery($product, $productData);
-            $product->addData($productData);
-            if ($product->hasDataChanges()) {
-                $product->save();
+        if (count($configurations)) {
+            foreach ($configurations as $productId => $productData) {
+                /** @var \Magento\Catalog\Model\Product $product */
+                $product = $this->productRepository->getById($productId, false, $this->request->getParam('store', 0));
+                $productData = $this->variationHandler->processMediaGallery($product, $productData);
+                $product->addData($productData);
+                if ($product->hasDataChanges()) {
+                    $product->save();
+                }
             }
         }
         return $configurableProduct;
@@ -91,6 +93,12 @@ class UpdateConfigurations
         }
 
         foreach ($configurableMatrix as $item) {
+            if (empty($item['was_changed'])) {
+                continue;
+            } else {
+                unset($item['was_changed']);
+            }
+
             if (!$item['newProduct']) {
                 $result[$item['id']] = $this->mapData($item);
 
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
index 321870b96d32abf13c48fdc0975efc9ba5248f17..0d0bba60a7777c75deef4bc9e0a41720b9597163 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
@@ -29,6 +29,9 @@ class VariationHandler
     /** @var \Magento\Catalog\Model\ProductFactory */
     protected $productFactory;
 
+    /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[] */
+    private $attributes;
+
     /**
      * @var \Magento\CatalogInventory\Api\StockConfigurationInterface
      * @deprecated
@@ -70,6 +73,7 @@ class VariationHandler
     public function generateSimpleProducts($parentProduct, $productsData)
     {
         $generatedProductIds = [];
+        $this->attributes = null;
         $productsData = $this->duplicateImagesForVariations($productsData);
         foreach ($productsData as $simpleProductData) {
             $newSimpleProduct = $this->productFactory->create();
@@ -160,7 +164,10 @@ class VariationHandler
             $parentProduct->getNewVariationsAttributeSetId()
         );
 
-        foreach ($product->getTypeInstance()->getSetAttributes($product) as $attribute) {
+        if ($this->attributes === null) {
+            $this->attributes = $product->getTypeInstance()->getSetAttributes($product);
+        }
+        foreach ($this->attributes as $attribute) {
             if ($attribute->getIsUnique() ||
                 $attribute->getAttributeCode() == 'url_key' ||
                 $attribute->getFrontend()->getInputType() == 'gallery' ||
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php
index bed5c96b5216eb76344e9ce593ea56056be9a35b..def49f42fa960b738fe952be4a2d18bada61ffd2 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php
@@ -90,13 +90,24 @@ class UpdateConfigurationsTest extends \PHPUnit_Framework_TestCase
                 'swatch_image' => 'simple2_swatch_image',
                 'small_image' => 'simple2_small_image',
                 'thumbnail' => 'simple2_thumbnail',
-                'image' => 'simple2_image'
+                'image' => 'simple2_image',
+                'was_changed' => true,
             ],
             [
                 'newProduct' => false,
                 'id' => 'product3',
-                'qty' => '3'
-            ]
+                'qty' => '3',
+                'was_changed' => true,
+            ],
+            [
+                'newProduct' => false,
+                'id' => 'product4',
+                'status' => 'simple4_status',
+                'sku' => 'simple2_sku',
+                'name' => 'simple2_name',
+                'price' => '3.33',
+                'weight' => '5.55',
+            ],
         ];
         $configurations = [
             'product2' => [
@@ -118,8 +129,8 @@ class UpdateConfigurationsTest extends \PHPUnit_Framework_TestCase
         ];
         /** @var Product[]|\PHPUnit_Framework_MockObject_MockObject[] $productMocks */
         $productMocks = [
-            'product2' => $this->getProductMock($configurations['product2'], true),
-            'product3' => $this->getProductMock($configurations['product3'])
+            'product2' => $this->getProductMock($configurations['product2'], true, true),
+            'product3' => $this->getProductMock($configurations['product3'], false, true),
         ];
 
         $this->requestMock->expects(static::any())
@@ -161,26 +172,27 @@ class UpdateConfigurationsTest extends \PHPUnit_Framework_TestCase
      * @param bool $hasDataChanges
      * @return Product|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected function getProductMock(array $expectedData = null, $hasDataChanges = false)
+    protected function getProductMock(array $expectedData = null, $hasDataChanges = false, $wasChanged = false)
     {
         $productMock = $this->getMockBuilder(Product::class)
             ->disableOriginalConstructor()
             ->getMock();
 
-        if ($expectedData !== null) {
-            $productMock->expects(static::once())
-                ->method('addData')
-                ->with($expectedData)
+        if ($wasChanged !== false) {
+            if ($expectedData !== null) {
+                $productMock->expects(static::once())
+                    ->method('addData')
+                    ->with($expectedData)
+                    ->willReturnSelf();
+            }
+
+            $productMock->expects(static::any())
+                ->method('hasDataChanges')
+                ->willReturn($hasDataChanges);
+            $productMock->expects($hasDataChanges ? static::once() : static::never())
+                ->method('save')
                 ->willReturnSelf();
         }
-
-        $productMock->expects(static::any())
-            ->method('hasDataChanges')
-            ->willReturn($hasDataChanges);
-        $productMock->expects($hasDataChanges ? static::once() : static::never())
-            ->method('save')
-            ->willReturnSelf();
-
         return $productMock;
     }
 }
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
index ffabd9a8627dfca82da9b87ebd84c799086d9edf..c182d9f8216c09a42868eb487dfa06b0e718b5c7 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js
@@ -391,11 +391,11 @@ define([
                     'small_image': row['small_image'],
                     image: row.image,
                     'thumbnail': row.thumbnail,
-                    'attributes': attributesText
+                    'attributes': attributesText,
+                    'was_changed': true
                 };
                 product[this.canEditField] = row.editable;
                 product[this.newProductField] = row.newProduct;
-
                 tmpArray.push(product);
             }, this);
 
diff --git a/app/code/Magento/Deploy/Console/Command/DeployStaticContentCommand.php b/app/code/Magento/Deploy/Console/Command/DeployStaticContentCommand.php
index 51345c2b7609cb8e39cf25fb9a4f4f202cba6f65..8a006c8154b4b97eb6d39c1d41f8363b3e4df761 100644
--- a/app/code/Magento/Deploy/Console/Command/DeployStaticContentCommand.php
+++ b/app/code/Magento/Deploy/Console/Command/DeployStaticContentCommand.php
@@ -3,7 +3,6 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Deploy\Console\Command;
 
 use Magento\Framework\App\Utility\Files;
@@ -19,6 +18,8 @@ use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\App\State;
 use Magento\Deploy\Console\Command\DeployStaticOptionsInterface as Options;
 use Magento\Deploy\Model\DeployManager;
+use Magento\Framework\App\Cache;
+use Magento\Framework\App\Cache\Type\Dummy as DummyCache;
 
 /**
  * Deploy static content command
@@ -29,7 +30,7 @@ class DeployStaticContentCommand extends Command
     /**
      * Key for dry-run option
      * @deprecated
-     * @see Magento\Deploy\Console\Command\DeployStaticOptionsInterface::DRY_RUN
+     * @see \Magento\Deploy\Console\Command\DeployStaticOptionsInterface::DRY_RUN
      */
     const DRY_RUN_OPTION = 'dry-run';
 
@@ -87,6 +88,7 @@ class DeployStaticContentCommand extends Command
      * @param ObjectManagerFactory $objectManagerFactory
      * @param Locale $validator
      * @param ObjectManagerInterface $objectManager
+     * @throws \LogicException When the command name is empty
      */
     public function __construct(
         ObjectManagerFactory $objectManagerFactory,
@@ -96,6 +98,7 @@ class DeployStaticContentCommand extends Command
         $this->objectManagerFactory = $objectManagerFactory;
         $this->validator = $validator;
         $this->objectManager = $objectManager;
+
         parent::__construct();
     }
 
@@ -373,6 +376,7 @@ class DeployStaticContentCommand extends Command
     /**
      * {@inheritdoc}
      * @throws \InvalidArgumentException
+     * @throws LocalizedException
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
@@ -394,9 +398,9 @@ class DeployStaticContentCommand extends Command
         list ($deployableLanguages, $deployableAreaThemeMap, $requestedThemes)
             = $this->prepareDeployableEntities($filesUtil);
 
-        $output->writeln("Requested languages: " . implode(', ', $deployableLanguages));
-        $output->writeln("Requested areas: " . implode(', ', array_keys($deployableAreaThemeMap)));
-        $output->writeln("Requested themes: " . implode(', ', $requestedThemes));
+        $output->writeln('Requested languages: ' . implode(', ', $deployableLanguages));
+        $output->writeln('Requested areas: ' . implode(', ', array_keys($deployableAreaThemeMap)));
+        $output->writeln('Requested themes: ' . implode(', ', $requestedThemes));
 
         /** @var $deployManager DeployManager */
         $deployManager = $this->objectManager->create(
@@ -415,11 +419,13 @@ class DeployStaticContentCommand extends Command
             }
         }
 
+        $this->mockCache();
         return $deployManager->deploy();
     }
 
     /**
      * @param Files $filesUtil
+     * @throws \InvalidArgumentException
      * @return array
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
@@ -476,4 +482,18 @@ class DeployStaticContentCommand extends Command
 
         return [$deployableLanguages, $deployableAreaThemeMap, $requestedThemes];
     }
+
+    /**
+     * Mock Cache class with dummy implementation
+     *
+     * @return void
+     */
+    private function mockCache()
+    {
+        $this->objectManager->configure([
+            'preferences' => [
+                Cache::class => DummyCache::class
+            ]
+        ]);
+    }
 }
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index 878ddf812028825267297aac958c22c14070f7b9..5a88c601e17e3c033040b082f8dfe47b83fd6a03 100644
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -13,7 +13,8 @@ use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend;
 use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
 use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
 use Magento\Framework\App\Config\Element;
-use Magento\Framework\App\ResourceConnection\Config;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\Exception\AlreadyExistsException;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Model\AbstractModel;
 use Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor;
@@ -1108,6 +1109,7 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
      * @param  \Magento\Framework\Model\AbstractModel $object
      * @return $this
      * @throws \Exception
+     * @throws AlreadyExistsException
      */
     public function save(\Magento\Framework\Model\AbstractModel $object)
     {
@@ -1147,6 +1149,10 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
             }
             $this->addCommitCallback([$object, 'afterCommitCallback'])->commit();
             $object->setHasDataChanges(false);
+        } catch (DuplicateException $e) {
+            $this->rollBack();
+            $object->setHasDataChanges(true);
+            throw new AlreadyExistsException(__('Unique constraint violation found'), $e);
         } catch (\Exception $e) {
             $this->rollBack();
             $object->setHasDataChanges(true);
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
index 4f13ee75bfe32c29ae544c19e950691ead763323..0d8d18df223767b2812f58356de3b7904090d8f7 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
@@ -6,8 +6,8 @@
 
 namespace Magento\Eav\Model\Entity\Attribute;
 
-use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Api\AttributeValueFactory;
+use Magento\Framework\Exception\LocalizedException;
 
 /**
  * Entity/Attribute/Model - attribute abstract
@@ -595,11 +595,10 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractExtens
     {
         /** @var array $emptyStringTypes list of attribute types that treat empty string as a possible value */
         $emptyStringTypes = ['int', 'decimal', 'datetime', 'varchar', 'text', 'static'];
-        $attributeType = $this->getBackend()->getType();
         return (is_array($value) && count($value) == 0)
             || $value === null
-            || ($value === false && $attributeType != 'int')
-            || ($value === '' && in_array($attributeType, $emptyStringTypes));
+            || ($value === false && $this->getBackend()->getType() != 'int')
+            || ($value === '' && in_array($this->getBackend()->getType(), $emptyStringTypes));
     }
 
     /**
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AttributeGroupAlreadyExistsException.php b/app/code/Magento/Eav/Model/Entity/Attribute/AttributeGroupAlreadyExistsException.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca80ca089a2ea4cc3b297b4dc933b53049ed31f1
--- /dev/null
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/AttributeGroupAlreadyExistsException.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Eav\Model\Entity\Attribute;
+
+use Magento\Framework\Exception\AlreadyExistsException;
+
+/**
+ * Class AttributeGroupAlreadyExistsException
+ */
+class AttributeGroupAlreadyExistsException extends AlreadyExistsException
+{
+}
diff --git a/app/code/Magento/Eav/Model/ResourceModel/AttributeLoader.php b/app/code/Magento/Eav/Model/ResourceModel/AttributeLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..439f550a2bf020fadd8ae18abfb2348f4b18cf6b
--- /dev/null
+++ b/app/code/Magento/Eav/Model/ResourceModel/AttributeLoader.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Eav\Model\ResourceModel;
+
+use Magento\Eav\Api\AttributeRepositoryInterface as AttributeRepository;
+use Magento\Eav\Model\Entity\AttributeCache;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\EntityManager\MetadataPool;
+
+/**
+ * Сlass responsible for loading and caching of attributes related to the given attribute set.
+ *
+ * Can be used to improve performance of services that mostly read attribute data.
+ */
+class AttributeLoader
+{
+    /** Name of ATTRIBUTE_SET_ID field */
+    const ATTRIBUTE_SET_ID = 'attribute_set_id';
+
+    /**
+     * @var AttributeRepository
+     */
+    private $attributeRepository;
+
+    /**
+     * @var MetadataPool
+     */
+    private $metadataPool;
+
+    /**
+     * @var SearchCriteriaBuilder
+     */
+    private $searchCriteriaBuilder;
+
+    /**
+     * @var AttributeCache
+     */
+    private $attributeCache;
+
+    /**
+     * AttributeLoader constructor.
+     * @param AttributeRepository $attributeRepository
+     * @param MetadataPool $metadataPool
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param AttributeCache $attributeCache
+     */
+    public function __construct(
+        AttributeRepository $attributeRepository,
+        MetadataPool $metadataPool,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        AttributeCache $attributeCache
+    ) {
+        $this->attributeRepository = $attributeRepository;
+        $this->metadataPool = $metadataPool;
+        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+        $this->attributeCache = $attributeCache;
+    }
+
+    /**
+     * Get attributes list from attribute set
+     *
+     * @param string $entityType
+     * @param int $attributeSetId
+     * @return \Magento\Eav\Api\Data\AttributeInterface[]|\object[]
+     */
+    public function getAttributes($entityType, $attributeSetId = null)
+    {
+        $suffix =  self::ATTRIBUTE_SET_ID . '-' . ($attributeSetId ?: 'all');
+        if ($attributes = $this->attributeCache->getAttributes($entityType, $suffix)) {
+            return $attributes;
+        }
+
+        $metadata = $this->metadataPool->getMetadata($entityType);
+
+        if ($attributeSetId === null) {
+            $criteria = $this->searchCriteriaBuilder->addFilter(self::ATTRIBUTE_SET_ID, null, 'neq')->create();
+        } else {
+            $criteria = $this->searchCriteriaBuilder->addFilter(self::ATTRIBUTE_SET_ID, $attributeSetId)->create();
+        }
+
+        $searchResult = $this->attributeRepository->getList(
+            $metadata->getEavEntityType(),
+            $criteria
+        );
+        $attributes = $searchResult->getItems();
+
+        $this->attributeCache->saveAttributes(
+            $entityType,
+            $attributes,
+            $suffix
+        );
+        return $attributes;
+    }
+}
diff --git a/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php b/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php
index 74373cb593c4086c06378050e1fa89b944d78be6..5e340595df9867b1cb02fd795c6fc9be7e34fc02 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php
@@ -113,13 +113,14 @@ class AttributePersistor
             return;
         }
         $metadata = $this->metadataPool->getMetadata($entityType);
+        $linkField = $metadata->getLinkField();
         foreach ($this->delete[$entityType] as $link => $data) {
             $attributeCodes = array_keys($data);
             foreach ($attributeCodes as $attributeCode) {
                 /** @var AbstractAttribute $attribute */
                 $attribute = $this->attributeRepository->get($metadata->getEavEntityType(), $attributeCode);
                 $conditions = [
-                    $metadata->getLinkField() . ' = ?' => $link,
+                    $linkField . ' = ?' => $link,
                     'attribute_id = ?' => $attribute->getAttributeId()
                 ];
                 foreach ($context as $scope) {
@@ -147,6 +148,7 @@ class AttributePersistor
             return;
         }
         $metadata = $this->metadataPool->getMetadata($entityType);
+        $linkField = $metadata->getLinkField();
         foreach ($this->insert[$entityType] as $link => $data) {
             foreach ($data as $attributeCode => $attributeValue) {
                 /** @var AbstractAttribute $attribute */
@@ -155,7 +157,7 @@ class AttributePersistor
                     $attributeCode
                 );
                 $data = [
-                    $metadata->getLinkField() => $link,
+                    $linkField => $link,
                     'attribute_id' => $attribute->getAttributeId(),
                     'value' => $this->prepareValue($entityType, $attributeValue, $attribute)
                 ];
@@ -180,6 +182,7 @@ class AttributePersistor
             return;
         }
         $metadata = $this->metadataPool->getMetadata($entityType);
+        $linkField = $metadata->getLinkField();
         foreach ($this->update[$entityType] as $link => $data) {
             foreach ($data as $attributeCode => $attributeValue) {
                 /** @var AbstractAttribute $attribute */
@@ -188,7 +191,7 @@ class AttributePersistor
                     $attributeCode
                 );
                 $conditions = [
-                    $metadata->getLinkField() . ' = ?' => $link,
+                    $linkField . ' = ?' => $link,
                     'attribute_id = ?' => $attribute->getAttributeId(),
                 ];
                 foreach ($context as $scope) {
diff --git a/app/code/Magento/Eav/Model/ResourceModel/CreateHandler.php b/app/code/Magento/Eav/Model/ResourceModel/CreateHandler.php
index 1a8aaaf027f561966101e360020fb3a2441e27d6..df411b6a21698033c60839c0d855c3b0ed4e96e5 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/CreateHandler.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/CreateHandler.php
@@ -6,9 +6,10 @@
 namespace Magento\Eav\Model\ResourceModel;
 
 use Magento\Eav\Api\AttributeRepositoryInterface as AttributeRepository;
-use Magento\Framework\EntityManager\Operation\AttributeInterface;
-use Magento\Framework\EntityManager\MetadataPool;
 use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\EntityManager\Operation\AttributeInterface;
 use Magento\Framework\Model\Entity\ScopeResolver;
 
 /**
@@ -42,40 +43,43 @@ class CreateHandler implements AttributeInterface
      */
     private $scopeResolver;
 
+    /**
+     * @var AttributeLoader
+     */
+    private $attributeLoader;
+
     /**
      * @param AttributeRepository $attributeRepository
      * @param MetadataPool $metadataPool
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
      * @param AttributePersistor $attributePersistor
      * @param ScopeResolver $scopeResolver
+     * @param AttributeLoader $attributeLoader
      */
     public function __construct(
         AttributeRepository $attributeRepository,
         MetadataPool $metadataPool,
         SearchCriteriaBuilder $searchCriteriaBuilder,
         AttributePersistor $attributePersistor,
-        ScopeResolver $scopeResolver
+        ScopeResolver $scopeResolver,
+        AttributeLoader $attributeLoader = null
     ) {
         $this->attributeRepository = $attributeRepository;
         $this->metadataPool = $metadataPool;
         $this->searchCriteriaBuilder = $searchCriteriaBuilder;
         $this->attributePersistor = $attributePersistor;
         $this->scopeResolver = $scopeResolver;
+        $this->attributeLoader = $attributeLoader ?: ObjectManager::getInstance()->get(AttributeLoader::class);
     }
 
     /**
      * @param string $entityType
+     * @param int $attributeSetId
      * @return \Magento\Eav\Api\Data\AttributeInterface[]
-     * @throws \Exception
      */
-    protected function getAttributes($entityType)
+    protected function getAttributes($entityType, $attributeSetId = null)
     {
-        $metadata = $this->metadataPool->getMetadata($entityType);
-        $searchResult = $this->attributeRepository->getList(
-            $metadata->getEavEntityType(),
-            $this->searchCriteriaBuilder->addFilter('attribute_set_id', null, 'neq')->create()
-        );
-        return $searchResult->getItems();
+        return $this->attributeLoader->getAttributes($entityType, $attributeSetId);
     }
 
     /**
@@ -92,23 +96,28 @@ class CreateHandler implements AttributeInterface
         $metadata = $this->metadataPool->getMetadata($entityType);
         if ($metadata->getEavEntityType()) {
             $processed = [];
+            $entityLinkField = $metadata->getLinkField();
+            $attributeSetId = isset($entityData[AttributeLoader::ATTRIBUTE_SET_ID])
+                ? $entityData[AttributeLoader::ATTRIBUTE_SET_ID]
+                : null; // @todo verify is it normal to not have attributer_set_id
             /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
-            foreach ($this->getAttributes($entityType) as $attribute) {
+            foreach ($this->getAttributes($entityType, $attributeSetId) as $attribute) {
                 if ($attribute->isStatic()) {
                     continue;
                 }
-                if (isset($entityData[$attribute->getAttributeCode()])
-                    && !is_array($entityData[$attribute->getAttributeCode()])
-                    && !$attribute->isValueEmpty($entityData[$attribute->getAttributeCode()])
+
+                $attributeCode = $attribute->getAttributeCode();
+                if (isset($entityData[$attributeCode])
+                    && !is_array($entityData[$attributeCode])
+                    && !$attribute->isValueEmpty($entityData[$attributeCode])
                 ) {
-                    $entityLinkField = $metadata->getLinkField();
                     $this->attributePersistor->registerInsert(
                         $entityType,
                         $entityData[$entityLinkField],
-                        $attribute->getAttributeCode(),
-                        $entityData[$attribute->getAttributeCode()]
+                        $attributeCode,
+                        $entityData[$attributeCode]
                     );
-                    $processed[$attribute->getAttributeCode()] = $entityData[$attribute->getAttributeCode()];
+                    $processed[$attributeCode] = $entityData[$attributeCode];
                 }
             }
             $context = $this->scopeResolver->getEntityContext($entityType, $entityData);
diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Group.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Group.php
index 796f4d19f2eb8d90c4625542a33257e3a065a5af..9515bbc66437859d984f126b4d49f483c72f8194 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Group.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Group.php
@@ -5,6 +5,10 @@
  */
 namespace Magento\Eav\Model\ResourceModel\Entity\Attribute;
 
+use Magento\Eav\Model\Entity\Attribute\AttributeGroupAlreadyExistsException;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\Model\AbstractModel;
+
 /**
  * Eav Resource Entity Attribute Group
  *
@@ -50,10 +54,10 @@ class Group extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     /**
      * Perform actions before object save
      *
-     * @param \Magento\Framework\Model\AbstractModel $object
+     * @param AbstractModel $object
      * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
-    protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
+    protected function _beforeSave(AbstractModel $object)
     {
         if (!$object->getSortOrder()) {
             $object->setSortOrder($this->_getMaxSortOrder($object) + 1);
@@ -64,10 +68,10 @@ class Group extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     /**
      * Perform actions after object save
      *
-     * @param \Magento\Framework\Model\AbstractModel $object
+     * @param AbstractModel $object
      * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
-    protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
+    protected function _afterSave(AbstractModel $object)
     {
         if ($object->getAttributes()) {
             foreach ($object->getAttributes() as $attribute) {
@@ -82,7 +86,7 @@ class Group extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     /**
      * Retrieve max sort order
      *
-     * @param \Magento\Framework\Model\AbstractModel $object
+     * @param AbstractModel $object
      * @return int
      */
     protected function _getMaxSortOrder($object)
@@ -130,4 +134,38 @@ class Group extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
 
         return $this;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function saveNewObject(AbstractModel $object)
+    {
+        try {
+            return parent::saveNewObject($object);
+        } catch (DuplicateException $e) {
+            throw new AttributeGroupAlreadyExistsException(
+                __(
+                    'Attribute group with same code already exist. Please rename "%1" group',
+                    $object->getAttributeGroupName()
+                )
+            );
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function updateObject(AbstractModel $object)
+    {
+        try {
+            return parent::updateObject($object);
+        } catch (DuplicateException $e) {
+            throw new AttributeGroupAlreadyExistsException(
+                __(
+                    'Attribute group with same code already exist. Please rename "%1" group',
+                    $object->getAttributeGroupName()
+                )
+            );
+        }
+    }
 }
diff --git a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
index 0f892a272fa1a209ca7b2e632abc98db5afb5d3d..c775a24a03c465dad45640a7f634823cb8b43ef8 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
@@ -54,6 +54,11 @@ class UpdateHandler implements AttributeInterface
      */
     private $readHandler;
 
+    /**
+     * @var AttributeLoader
+     */
+    private $attributeLoader;
+
     /**
      * UpdateHandler constructor.
      * @param AttributeRepository $attributeRepository
@@ -62,6 +67,7 @@ class UpdateHandler implements AttributeInterface
      * @param AttributePersistor $attributePersistor
      * @param ReadSnapshot $readSnapshot
      * @param ScopeResolver $scopeResolver
+     * @param AttributeLoader $attributeLoader
      */
     public function __construct(
         AttributeRepository $attributeRepository,
@@ -69,7 +75,8 @@ class UpdateHandler implements AttributeInterface
         SearchCriteriaBuilder $searchCriteriaBuilder,
         AttributePersistor $attributePersistor,
         ReadSnapshot $readSnapshot,
-        ScopeResolver $scopeResolver
+        ScopeResolver $scopeResolver,
+        AttributeLoader $attributeLoader = null
     ) {
         $this->attributeRepository = $attributeRepository;
         $this->metadataPool = $metadataPool;
@@ -77,22 +84,17 @@ class UpdateHandler implements AttributeInterface
         $this->attributePersistor = $attributePersistor;
         $this->readSnapshot = $readSnapshot;
         $this->scopeResolver = $scopeResolver;
+        $this->attributeLoader = $attributeLoader ?: ObjectManager::getInstance()->get(AttributeLoader::class);
     }
 
     /**
      * @param string $entityType
+     * @param int $attributeSetId
      * @return \Magento\Eav\Api\Data\AttributeInterface[]
-     * @throws \Exception
      */
-    protected function getAttributes($entityType)
+    protected function getAttributes($entityType, $attributeSetId = null)
     {
-        $metadata = $this->metadataPool->getMetadata($entityType);
-
-        $searchResult = $this->attributeRepository->getList(
-            $metadata->getEavEntityType(),
-            $this->searchCriteriaBuilder->addFilter('attribute_set_id', null, 'neq')->create()
-        );
-        return $searchResult->getItems();
+        return $this->attributeLoader->getAttributes($entityType, $attributeSetId);
     }
 
     /**
@@ -118,8 +120,11 @@ class UpdateHandler implements AttributeInterface
                     $entityDataForSnapshot[$scope->getIdentifier()] = $entityData[$scope->getIdentifier()];
                 }
             }
+            $attributeSetId = isset($entityData[AttributeLoader::ATTRIBUTE_SET_ID])
+                ? $entityData[AttributeLoader::ATTRIBUTE_SET_ID]
+                : null; // @todo verify is it normal to not have attributer_set_id
             $snapshot = $this->readSnapshot->execute($entityType, $entityDataForSnapshot);
-            foreach ($this->getAttributes($entityType) as $attribute) {
+            foreach ($this->getAttributes($entityType, $attributeSetId) as $attribute) {
                 if ($attribute->isStatic()) {
                     continue;
                 }
diff --git a/app/code/Magento/Eav/Setup/UpgradeSchema.php b/app/code/Magento/Eav/Setup/UpgradeSchema.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b52bba7c2efbd379851ddf16a0cafbc077dcaf2
--- /dev/null
+++ b/app/code/Magento/Eav/Setup/UpgradeSchema.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Eav\Setup;
+
+use Magento\Framework\Setup\UpgradeSchemaInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\SchemaSetupInterface;
+
+/**
+ * Upgrade the Eav module DB scheme
+ */
+class UpgradeSchema implements UpgradeSchemaInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $setup->startSetup();
+
+        if (version_compare($context->getVersion(), '2.1.0', '<')) {
+            $this->addUniqueKeyToEavAttributeGroupTable($setup);
+        }
+        $setup->endSetup();
+    }
+
+    /**
+     * @param SchemaSetupInterface $setup
+     * @return void
+     */
+    private function addUniqueKeyToEavAttributeGroupTable(SchemaSetupInterface $setup)
+    {
+        $setup->getConnection()->addIndex(
+            $setup->getTable('eav_attribute_group'),
+            $setup->getIdxName(
+                'catalog_category_product',
+                ['attribute_set_id', 'attribute_group_code'],
+                \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
+            ),
+            ['attribute_set_id', 'attribute_group_code'],
+            \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
+        );
+    }
+}
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/AbstractEntityTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/AbstractEntityTest.php
index f39eeb892757645df9fc3157894249e18d8c4803..7628207e25a52c2ea7cd595bd47f65fb0d18ef81 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Entity/AbstractEntityTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/AbstractEntityTest.php
@@ -5,13 +5,17 @@
  */
 namespace Magento\Eav\Test\Unit\Model\Entity;
 
+use Magento\Eav\Model\Entity\AbstractEntity;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\Model\AbstractModel;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class AbstractEntityTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * Entity model to be tested
-     * @var \Magento\Eav\Model\Entity\AbstractEntity|\PHPUnit_Framework_MockObject_MockObject
+     * @var AbstractEntity|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $_model;
 
@@ -23,11 +27,11 @@ class AbstractEntityTest extends \PHPUnit_Framework_TestCase
         $objectManager = new ObjectManager($this);
         $this->eavConfig = $this->getMock(\Magento\Eav\Model\Config::class, [], [], '', false);
         $arguments =  $objectManager->getConstructArguments(
-            \Magento\Eav\Model\Entity\AbstractEntity::class,
+            AbstractEntity::class,
             ['eavConfig' => $this->eavConfig]
         );
         $this->_model = $this->getMockForAbstractClass(
-            \Magento\Eav\Model\Entity\AbstractEntity::class,
+            AbstractEntity::class,
             $arguments
         );
     }
@@ -113,7 +117,7 @@ class AbstractEntityTest extends \PHPUnit_Framework_TestCase
     /**
      * Get adapter mock
      *
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Adapter\Pdo\Mysql
      */
     protected function _getConnectionMock()
     {
@@ -300,7 +304,7 @@ class AbstractEntityTest extends \PHPUnit_Framework_TestCase
         $objectManager = new ObjectManager($this);
         $this->eavConfig = $this->getMock(\Magento\Eav\Model\Config::class, [], [], '', false);
         $arguments =  $objectManager->getConstructArguments(
-            \Magento\Eav\Model\Entity\AbstractEntity::class,
+            AbstractEntity::class,
             [
                 'eavConfig' => $eavConfig,
                 'data' => [
@@ -310,8 +314,8 @@ class AbstractEntityTest extends \PHPUnit_Framework_TestCase
                 ]
             ]
         );
-        /** @var $model \Magento\Framework\Model\AbstractModel|\PHPUnit_Framework_MockObject_MockObject */
-        $model = $this->getMockBuilder(\Magento\Eav\Model\Entity\AbstractEntity::class)
+        /** @var $model AbstractEntity|\PHPUnit_Framework_MockObject_MockObject */
+        $model = $this->getMockBuilder(AbstractEntity::class)
             ->setConstructorArgs($arguments)
             ->setMethods(['_getValue', 'beginTransaction', 'commit', 'rollback', 'getConnection'])
             ->getMock();
@@ -353,4 +357,30 @@ class AbstractEntityTest extends \PHPUnit_Framework_TestCase
             ]
         ];
     }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\AlreadyExistsException
+     */
+    public function testDuplicateExceptionProcessingOnSave()
+    {
+        $connection = $this->getMock(AdapterInterface::class);
+        $connection->expects($this->once())->method('rollback');
+
+        /** @var AbstractEntity|\PHPUnit_Framework_MockObject_MockObject $model */
+        $model = $this->getMockBuilder(AbstractEntity::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getConnection'])
+            ->getMockForAbstractClass();
+        $model->expects($this->any())->method('getConnection')->willReturn($connection);
+
+        /** @var AbstractModel|\PHPUnit_Framework_MockObject_MockObject $object */
+        $object = $this->getMockBuilder(AbstractModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $object->expects($this->once())->method('hasDataChanges')->willReturn(true);
+        $object->expects($this->once())->method('beforeSave')->willThrowException(new DuplicateException());
+        $object->expects($this->once())->method('setHasDataChanges')->with(true);
+
+        $model->save($object);
+    }
 }
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/AbstractAttributeTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/AbstractAttributeTest.php
index d6b88e0ac56915c3b116ac740b18cfd31ae9f876..a10bafacda42dc2b72fcc285307a0250cae3074b 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/AbstractAttributeTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/AbstractAttributeTest.php
@@ -207,7 +207,7 @@ class AbstractAttributeTest extends \PHPUnit_Framework_TestCase
             ]
         );
         $backendModelMock->expects($this->any())->method('getType')->willReturn($attributeType);
-        $model->expects($this->once())->method('getBackend')->willReturn($backendModelMock);
+        $model->expects($this->any())->method('getBackend')->willReturn($backendModelMock);
         $this->assertEquals($isEmpty, $model->isValueEmpty($value));
     }
 
diff --git a/app/code/Magento/Eav/etc/module.xml b/app/code/Magento/Eav/etc/module.xml
index c1c313d91501989578f03b404ae91acc2d0ccbb1..d03606d1eeb900a1dfec428c172cba0b47a01fc0 100644
--- a/app/code/Magento/Eav/etc/module.xml
+++ b/app/code/Magento/Eav/etc/module.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
-    <module name="Magento_Eav" setup_version="2.0.0">
+    <module name="Magento_Eav" setup_version="2.1.0">
         <sequence>
             <module name="Magento_Store"/>
         </sequence>
diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Edit/Form.php
index a56642d1dda33952bdb8d238dc074428a170b54b..fec1684f39f36ca7e259863bba817119cc896054 100644
--- a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Edit/Form.php
+++ b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Edit/Form.php
@@ -86,6 +86,16 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'values' => $this->_formatFactory->create()->toOptionArray()
             ]
         );
+        $fieldset->addField(
+            \Magento\ImportExport\Model\Export::FIELDS_ENCLOSURE,
+            'checkbox',
+            [
+                'name' => \Magento\ImportExport\Model\Export::FIELDS_ENCLOSURE,
+                'label' => __('Fields Enclosure'),
+                'title' => __('Fields Enclosure'),
+                'value' => 1,
+            ]
+        );
 
         $form->setUseContainer(true);
         $this->setForm($form);
diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php
index 1511f58d4b039c5376ef293b8c011d4e2b0e7396..435a663923306da40741c2c9a43a6a234944a98a 100644
--- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php
+++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php
@@ -174,6 +174,16 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                     'value' => Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
                 ]
             );
+            $fieldsets[$behaviorCode]->addField(
+                $behaviorCode . \Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE,
+                'checkbox',
+                [
+                    'name' => \Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE,
+                    'label' => __('Fields enclosure'),
+                    'title' => __('Fields enclosure'),
+                    'value' => 1,
+                ]
+            );
         }
 
         // fieldset for file uploading
diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php
index 2785327326e89359c6aabbbedb4e38cb136c1dfa..3b833cd4ab8834fc07a86ef9a52b51d66140ea3a 100644
--- a/app/code/Magento/ImportExport/Model/Export.php
+++ b/app/code/Magento/ImportExport/Model/Export.php
@@ -20,6 +20,11 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
 
     const FILTER_ELEMENT_SKIP = 'skip_attr';
 
+    /**
+     * Allow multiple values wrapping in double quotes for additional attributes.
+     */
+    const FIELDS_ENCLOSURE = 'fields_enclosure';
+
     /**
      * Filter fields types.
      */
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index 157887ec62c526458377d5d0103a992fab60a63d..89b5f88f0e9c2d4e071cdc0ec46d97bf731e64e8 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -78,6 +78,11 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
      */
     const FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR = '_import_multiple_value_separator';
 
+    /**
+     * Allow multiple values wrapping in double quotes for additional attributes.
+     */
+    const FIELDS_ENCLOSURE = 'fields_enclosure';
+
     /**#@-*/
 
     /**
diff --git a/app/code/Magento/ImportExport/view/adminhtml/templates/export/form/before.phtml b/app/code/Magento/ImportExport/view/adminhtml/templates/export/form/before.phtml
index b8acac6a1ab64dbec581785293c16ad18c5218f2..ce4f61cef4febc90a3e802c7dacc9b2e09fb28c3 100644
--- a/app/code/Magento/ImportExport/view/adminhtml/templates/export/form/before.phtml
+++ b/app/code/Magento/ImportExport/view/adminhtml/templates/export/form/before.phtml
@@ -80,6 +80,9 @@ require([
             var oldAction = form.action;
             var url = oldAction + ((oldAction.slice(-1) != '/') ? '/' : '') + 'entity/' + $F('entity')
                 + '/file_format/' + $F('file_format');
+            if ($F('fields_enclosure')) {
+                url += '/fields_enclosure/' + $F('fields_enclosure');
+            }
             form.action = url;
             form.submit();
             form.action   = oldAction;
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js b/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js
index d87b6b6b665ca0d070287474edb41eb5ced41c33..dca12f832cd15e1cdc197ec909df92557c45da60 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js
@@ -79,6 +79,10 @@ define([
         getData: function (params, options) {
             var cachedRequest = this.getRequest(params);
 
+            if (params && params.filters && params.filters['store_id']) {
+                cachedRequest = false;
+            }
+
             options = options || {};
 
             return !options.refresh && cachedRequest ?
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
index 5eeb7ddb61fa05657b08dda4711e82938e8778ce..0ad53eeeb90d9dab3a8877624429efefe314aefd 100644
--- a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
@@ -51,6 +51,7 @@ class ApiDataFixture
      */
     public function startTest(\PHPUnit_Framework_TestCase $test)
     {
+        \Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
         /** Apply method level fixtures if thy are available, apply class level fixtures otherwise */
         $this->_applyFixtures($this->_getFixtures('method', $test) ?: $this->_getFixtures('class', $test));
     }
@@ -61,6 +62,9 @@ class ApiDataFixture
     public function endTest()
     {
         $this->_revertFixtures();
+        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $objectManager->get(\Magento\Eav\Model\Entity\AttributeCache::class)->clear();
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml
index c949d827b4879599685bca266e12edfd2eb3a384..d4cf5dab742aa37684e8b5ee884bd6164c88426f 100644
--- a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml
@@ -6,12 +6,12 @@
  */
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
-    <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest" summary="One page check out with Authorize.Net payment method.">
-        <variation name="OnePageCheckoutAuthorizenetTestVariation1" summary="Check Out as a Guest with Authorize.Net and Offline Shipping method" ticketId="MAGETWO-12832">
+    <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest" summary="One page check out with Authorize.Net Direct Post payment method.">
+        <variation name="OnePageCheckoutAuthorizenetTestVariation1" summary="CheckOut with Authorize.Net Direct Post" ticketId="MAGETWO-59170">
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="customer/dataset" xsi:type="string">default</data>
-            <data name="shippingAddress/dataset" xsi:type="string">US_address_1</data>
-            <data name="checkoutMethod" xsi:type="string">guest</data>
+            <data name="checkoutMethod" xsi:type="string">login</data>
+            <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
             <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
             <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
             <data name="prices" xsi:type="array">
@@ -26,7 +26,7 @@
                 <item name="isClosed" xsi:type="string">No</item>
                 <item name="transactionType" xsi:type="string">Authorization</item>
             </data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php
index 6601bd44892c93e30573c5342e483eb232573e70..dda155f7fd66bd33a5532ab4a36c937a1d10178b 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php
@@ -38,6 +38,7 @@ class BraintreeSettlementReportTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.xml
index 183dc6ac906074fb6dc918e765d648ea437fd05b..e80f6071ae5d1d33b37bb7c26c7389ed08aa8962 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.xml
@@ -22,7 +22,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php
index a0bf482705f552318a7cdd09951aaff14eaf1cb2..c9d0904c85d675d7a4aa360ac6a2f8c00c6b0862 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php
@@ -33,6 +33,7 @@ class CheckoutWithBraintreePaypalCartTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.xml
index 09b33bfa79958668ceef14a20e48cf0ecce2646e..9e1090d6a22f91102be14f0f4319921651f01841 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.xml
@@ -20,7 +20,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
@@ -42,7 +42,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_sale, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php
index f0f0291b33e20428765c110dbb23600ba463bdde..9ee6bfb7c4e29b84043fd3b116a09153bfab4233 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php
@@ -33,6 +33,7 @@ class CheckoutWithBraintreePaypalMinicartTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.xml
index b426e7578729dd3b0ba514440b7b425b373ae20b..b41ea91e4598255a67e3e44180895873358a9b1a 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.xml
@@ -20,7 +20,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
@@ -42,7 +42,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_sale, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php
index 6554845d5ff81af96b887a9dbcb8e05761b21463..9e6cf0991db4e5fb2c3dd2c45de7d365e67395f6 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php
@@ -25,6 +25,7 @@ class CreateOnlineCreditMemoBraintreePaypalTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.xml
index 56c33af7a82b986b23372c9cbf0f2e8e915876a3..53847e55fd9f91e29fbeeb6c71a0402a1fb6a6f6 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.xml
@@ -22,9 +22,8 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_sale, braintree_paypal_skip_order_review</data>
             <data name="paymentAction" xsi:type="string">sale</data>
-            <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Credit Memo, Hold, Ship, Reorder</data>
             <data name="data/items_data/0/qty" xsi:type="string">-</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCreditMemoTab" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCommentsHistory" />
@@ -42,12 +41,11 @@
             <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_skip_order_review</data>
-            <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Credit Memo, Hold, Ship, Reorder</data>
             <data name="data/items_data/0/qty" xsi:type="string">2</data>
             <data name="refundData/items_data/0/qty" xsi:type="string">1</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="isCreditMemoPartial" xsi:type="string">Yes</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCreditMemoTab" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineInvoiceEntityTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineInvoiceEntityTest.xml
index 702a732e937eabedff8f6525e651fe4c16de942c..d9f382e4b650e5ce48955e264c67b36c893dbb84 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineInvoiceEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineInvoiceEntityTest.xml
@@ -29,7 +29,7 @@
             <data name="data/items_data/0/qty" xsi:type="string">-</data>
             <data name="data/form_data/do_shipment" xsi:type="string">No</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCaptureInCommentsHistory" />
@@ -58,7 +58,7 @@
             <data name="data/items_data/0/qty" xsi:type="string">1</data>
             <data name="data/form_data/do_shipment" xsi:type="string">No</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCaptureInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml
index 80596fb577b970d41e01e8e98d26c86a28262b70..9614923691c6c097702c3a222bfc52edfcd2489a 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\CreateOrderBackendTest" summary="Checkout with Braintree Credit Card from Admin">
         <variation name="CreateOrderBackendTestBraintreeVariation1" summary="Checkout with Braintree Credit Card from Admin (Payment Action = Authorize Only)" ticketId="MAGETWO-46294">
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="products/1" xsi:type="string">configurableProduct::with_one_option</data>
             <data name="products/2" xsi:type="string">bundleProduct::bundle_fixed_100_dollar_product</data>
@@ -32,11 +32,10 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertAuthorizationInCommentsHistory" />
-            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
         </variation>
         <variation name="CreateOrderBackendTestBraintreeVariation2" summary="Checkout with Braintree Credit Card from Admin (Payment Action = Authorize and Capture)" ticketId="MAGETWO-38316">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test, severity:S0</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="products/1" xsi:type="string">configurableProduct::with_one_option</data>
             <data name="products/2" xsi:type="string">bundleProduct::bundle_fixed_100_dollar_product</data>
@@ -63,7 +62,6 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCaptureInCommentsHistory" />
-            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateVaultOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateVaultOrderBackendTest.xml
index 4f05723609c2a8305f68a6893787684ae2e3d9df..db6cd3572eaa2acec5ded94997b1951c744e6652 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateVaultOrderBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateVaultOrderBackendTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Vault\Test\TestCase\CreateVaultOrderBackendTest" summary="Create Order from Admin via Braintree with saving Credit Cards">
         <variation name="CreateVaultOrderBackendTestBraintreeVariation1" summary="Checkout with Braintree Credit Card from Admin (Payment Action = Authorize Only)" ticketId="MAGETWO-47137, MAGETWO-47139">
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php
index 7048984886582f7e74ffaa6d5d0597ee4ae5b018..062de338d8921e15b786de0fd4b656e824354d80 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php
@@ -29,6 +29,7 @@ class InvoicePayPalBraintreeTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePaypalBraintreeTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePaypalBraintreeTest.xml
index bae626a427818b115d897d06dd33b4a894da1cba..352e0ed684919a43df66b429d5b8250d90cae351 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePaypalBraintreeTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePaypalBraintreeTest.xml
@@ -26,7 +26,7 @@
             <data name="data/items_data/0/qty" xsi:type="string">-</data>
             <data name="data/form_data/do_shipment" xsi:type="string">No</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceItems" />
@@ -51,7 +51,7 @@
             <data name="data/items_data/0/qty" xsi:type="string">1</data>
             <data name="data/form_data/do_shipment" xsi:type="string">No</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceItems" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.php
index 41f637d52941d463223e1706e1175939e8c817ee..68d36f3c754cf6ff5bca786cb314fd89e51f9c5d 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.php
@@ -8,17 +8,25 @@ namespace Magento\Braintree\Test\TestCase;
 use Magento\Mtf\TestCase\Scenario;
 
 /**
- * Class OnePageCheckoutAcceptPaymentTest
+ * Preconditions:
+ * 1. Order is placed with Braintree Credit Card from Storefront with Advanced Fraud Protection.
  *
- * This scenario places order via Braintree payment with
- * enabled Advanced Fraud protection and accept payment for placed order
- * to future processing
+ * Steps:
+ * 1. Log in to Admin.
+ * 2. Go to Sales > Orders page.
+ * 3. Open the placed order.
+ * 4. Click Accept button.
+ * 5. Perform assertions.
+ *
+ * @group Braintree
+ * @ZephyrId MAGETWO-56023
  */
 class OnePageCheckoutAcceptPaymentTest extends Scenario
 {
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'acceptance_test, 3rd_party_test';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.xml
index f42054b4a07325512db19b497627d0099dbc7a3a..841145d7a5fdfaa92f1a82ac00c9bf51f0601643 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutAcceptPaymentTest.xml
@@ -21,7 +21,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree,braintree_fraudprotection</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S2</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertAcceptPaymentSuccessMessagePresent" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertAcceptPaymentMessageInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.php
index 69fd4a8323eca15728d9c6f5b65c91a4929dc562..143ecb5a65d7d4a6af6a9b00d4b15175230cd0f4 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.php
@@ -8,16 +8,25 @@ namespace Magento\Braintree\Test\TestCase;
 use Magento\Mtf\TestCase\Scenario;
 
 /**
- * Class OnePageCheckoutDenyPaymentTest
+ * Preconditions:
+ * 1. Order is placed with Braintree Credit Card from Storefront with Advanced Fraud Protection.
  *
- * This scenario places order via Braintree payment with
- * enabled Advanced Fraud protection and deny payment for placed order
+ * Steps:
+ * 1. Log in to Admin.
+ * 2. Go to Sales > Orders page.
+ * 3. Open the placed order.
+ * 4. Click Deny button.
+ * 5. Perform assertions.
+ *
+ * @group Braintree
+ * @ZephyrId MAGETWO-56024
  */
 class OnePageCheckoutDenyPaymentTest extends Scenario
 {
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'acceptance_test, 3rd_party_test';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.xml
index 45476abfdfd12c18dc8a7b36782bc0b8f30ed3c0..95d07079ef36c9ae66672ec8cc465325273ecda4 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutDenyPaymentTest.xml
@@ -21,7 +21,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree,braintree_fraudprotection</data>
             <data name="status" xsi:type="string">Canceled</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S2</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertDenyPaymentSuccessMessagePresent" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertDenyPaymentMessageInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutTest.xml
index a1ceaa53da045345a1e4a7a5a51089a5623a85b8..1e9c539c8c0d379d6e5b69929e9270b21a8cc593 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutTest.xml
@@ -25,7 +25,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree_3dsecure</data>
             <data name="configData" xsi:type="string">braintree, braintree_3d_secure_not_triggered_due_threshold</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
@@ -48,7 +48,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree_3dsecure</data>
             <data name="configData" xsi:type="string">braintree, braintree_3d_secure_uk</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
@@ -71,13 +71,13 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertAuthorizationInCommentsHistory" />
         </variation>
-        <variation name="OnePageCheckoutBraintreeTestVariation4" summary="Checkout with Braintree for payment action Authorize and Capture" ticketId="MAGETWO-38420">
+        <variation name="OnePageCheckoutBraintreeTestVariation4" summary="Checkout with Braintree for payment action Authorize and Capture" ticketId="MAGETWO-59403">
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="products/1" xsi:type="string">configurableProduct::with_one_option</data>
             <data name="products/2" xsi:type="string">bundleProduct::bundle_fixed_100_dollar_product</data>
@@ -98,7 +98,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree, braintree_sale</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php
index 32599aa090651c76f7d9d2663309ea3a219f79f6..e4b7d82094db5a615b3df3000f18fbd9a1f41b6d 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php
@@ -39,6 +39,7 @@ class OnePageCheckoutWith3dSecureTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.xml
index 4cb5b1702dd3baac27c41b3c7367456299e8ef8e..295a9dcd5c5332dce7d6e5fad9dfcdc6f5352596 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.xml
@@ -31,7 +31,7 @@
             <data name="secure3d/dataset" xsi:type="string">secure3d_braintree</data>
             <data name="configData" xsi:type="string">braintree, braintree_3d_secure</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php
index 9cf0e9c90c1215649e50e0a708bcae5db371d9fd..a984f666c435680c68b97d0481b8b86a3f487b0e 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php
@@ -37,6 +37,7 @@ class OnePageCheckoutWithBraintreePaypalTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.xml
index 8f2177209f37b7f83d2b5ad97e2599ed7f7ff67c..7e38e6f0303b64e55ce6e126a2653f0ce7420df7 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.xml
@@ -21,7 +21,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
@@ -44,7 +44,7 @@
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_sale, braintree_paypal_skip_order_review</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
index 89d67936ab0c610cd67054d428c39cd8da341b53..23fc729edb99f9645f7587d8e350464c81083fcd 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml
@@ -25,12 +25,10 @@
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, braintree_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
-            <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Ship, Reorder, Edit</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
-            <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" />
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/ReorderUsingVaultTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/ReorderUsingVaultTest.xml
index 88ab2ef65c9a0e75d2eafff8c53fe898d9504efe..5a99c4a89a313392cdd596891712b1d2d4bbaec3 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/ReorderUsingVaultTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/ReorderUsingVaultTest.xml
@@ -23,7 +23,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="configData" xsi:type="string">braintree, braintree_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertAuthorizationInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php
index f6813b74e40d7b09edf48369f6dc79ca28fefa7d..8845f2a78629da6d2c3994b1e691cce117efa8bc 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php
@@ -43,6 +43,7 @@ class SaveUseDeleteVaultForPaypalBraintreeTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
index 6e214d4c205aacc72fa8b93cbd4c082d2d02fa96..c7a5182a1dfb3d693dc03eb5c77d9d2c26622a58 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
@@ -23,7 +23,7 @@
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Vault\Test\Constraint\AssertStoredPaymentDeletedMessage" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
index 00eb9c4802db6216bd1dbc0202231612166b306c..35d55784b676236d808cf0f54fc969fc65193b0b 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -22,7 +22,7 @@
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, braintree_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Ship, Reorder, Edit</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php
index 13b8240d4c49ebe4b047e59f6bfdb63102fbcf47..d2723a300285df0b560ece526e463b495f201d8f 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php
@@ -43,6 +43,7 @@ class UseVaultWith3dSecureOnCheckoutTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
index 0f00ff93612b8b1ef7792971b38846efbe3d2b43..a5aa7645148e158ad62a174bc26d08abfd037192 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
@@ -27,7 +27,7 @@
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, braintree_use_vault, braintree_3d_secure</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Ship</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/etc/di.xml
index be2d771e47f5bfaf9c93ac9ac909d87ef723bff1..7bdfca2f713f20a9f41b4c19d9bb1e36f55a59c1 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/etc/di.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/etc/di.xml
@@ -8,12 +8,12 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
     <type name="Magento\Braintree\Test\Constraint\Assert3dSecureInfoIsPresent">
         <arguments>
-            <argument name="severity" xsi:type="string">high</argument>
+            <argument name="severity" xsi:type="string">S1</argument>
         </arguments>
     </type>
     <type name="Magento\Braintree\Test\Constraint\AssertTransactionIsPresentInSettlementReport">
         <arguments>
-            <argument name="severity" xsi:type="string">high</argument>
+            <argument name="severity" xsi:type="string">S1</argument>
         </arguments>
     </type>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Dhl/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Dhl/Test/TestCase/OnePageCheckoutTest.xml
index 7d4a961b7686733323d2683ef335c72223f6b460..9bec14fd9575d945218bffd258cde0d06b766d92 100644
--- a/dev/tests/functional/tests/app/Magento/Dhl/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Dhl/Test/TestCase/OnePageCheckoutTest.xml
@@ -20,7 +20,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">Express easy</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, dhl_eu, shipping_origin_CH, config_base_currency_ch</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Fedex/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Fedex/Test/TestCase/OnePageCheckoutTest.xml
index 9d6b7d119e09ce6f65529c028b24e190d0f8d42f..fcf8331d18ba7fd02427602013b1674aadfb11fd 100644
--- a/dev/tests/functional/tests/app/Magento/Fedex/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Fedex/Test/TestCase/OnePageCheckoutTest.xml
@@ -20,7 +20,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">International Economy</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, fedex, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
@@ -39,7 +39,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">Ground</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, fedex, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.php b/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.php
index b1c2d71a43bdd7d77cabb00d010261245b599d00..37d85bd91b1d68ddea5ae0c1fd250547810d6d19 100644
--- a/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.php
+++ b/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.php
@@ -16,6 +16,7 @@ class ConflictResolutionTest extends Scenario
     /* tags */
     const MVP = 'no';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.xml b/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.xml
index dc2ba760025fb71427e2ea50a7e3cce4e1c305e5..163c33f7306bac0f8d859ea9cddbf98e6e2eb2a3 100644
--- a/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Payment/Test/TestCase/ConflictResolutionTest.xml
@@ -40,7 +40,7 @@
                     <item name="Authorize.net Direct Post" xsi:type="string"/>
                 </item>
             </data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S2</data>
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Payment/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Payment/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fc6a35a7c52c1b91792252cf08d13ff20d50a88f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Payment/Test/etc/di.xml
@@ -0,0 +1,34 @@
+<?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="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Payment\Test\Constraint\AssertCardRequiredFields">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Payment\Test\Constraint\AssertFieldsAreActive">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Payment\Test\Constraint\AssertFieldsAreDisabled">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Payment\Test\Constraint\AssertFieldsAreEnabled">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Payment\Test\Constraint\AssertFieldsArePresent">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php
index d4ec11acd51bf53c38de3be6e927b8a24037c1d8..3e510ab12ec3219a10ccabf6d20c0e2e8e70e0ba 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php
@@ -35,6 +35,7 @@ class CreatePayFlowOrderBackendNegativeTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml
index 04b34813e59ceacd332657d66366d2789f469e71..4ad751de68a71f0330aa547bf74481c3e306f379 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Paypal\Test\TestCase\CreatePayFlowOrderBackendNegativeTest" summary="Verify required fields validation for PayPal Payflow Pro credit card on admin order creation" ticketId="MAGETWO-58934">
         <variation name="CreatePayFlowOrderBackendNegativeTestPayflowProVariation1" summary="Verify required fields validation for credit card on admin order creation" ticketId="MAGETWO-58934">
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S2</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreateVaultOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreateVaultOrderBackendTest.xml
index 64a191040b8a451aede65fe73dc9785747509c4f..38666c36a2ba4e53641f45616060353ca5e5e22c 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreateVaultOrderBackendTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreateVaultOrderBackendTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Vault\Test\TestCase\CreateVaultOrderBackendTest" summary="Use saved for PayPal Payflow Pro credit card on admin order creation" ticketId="MAGETWO-47350">
         <variation name="CreateVaultOrderBackendTestPayflowProVariation1" summary="Use saved for PayPal Payflow Pro credit card on admin order creation" ticketId="MAGETWO-47350">
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php
index c8fb3e4f30f19834d1587cf1a1290aeeace7b958..8a10d08e0f6c3e6cdfddc7ec1a52d8796d54fca3 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php
@@ -31,6 +31,7 @@ class ExpressCheckoutFromProductPageTest extends Scenario
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
     const TO_MAINTAIN = 'yes';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.xml
index 4373523471cffc5e8e13b6bc01dffc9902516cd0..1d92fa149efbc336eb0910a451a1740f2eda6c14 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.xml
@@ -27,7 +27,7 @@
             </data>
             <data name="payment/method" xsi:type="string">paypal_express</data>
             <data name="configData" xsi:type="string">paypal_express, freeshipping</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php
index 7fc35ff1eb6fd83e929886bcdeac741de868fe68..6ecf356e27ff8c61a04329cb3211f0f6e1e9c05f 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php
@@ -31,6 +31,7 @@ class ExpressCheckoutFromShoppingCartTest extends Scenario
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
     const TO_MAINTAIN = 'yes';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.xml
index e4a4cd484a45a3b0ed0d8e015d791c207563b96a..38c876719bc3d82c772ff6f86cd507229ec5cf2b 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.xml
@@ -28,7 +28,7 @@
                 <item name="grandTotal" xsi:type="string">145.98</item>
             </data>
             <data name="configData" xsi:type="string">payflowpro</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php
index b40adf986dbe9a7311fec484411bb8a7ed50810d..5d7056d32703dbe6b79c6b099ab9a11fa2b9d41f 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php
@@ -35,6 +35,7 @@ class ExpressCheckoutOnePageTest extends Scenario
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
     const TO_MAINTAIN = 'yes';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.xml
index df02c3293b50c5ed1bb2394bdeb6fc378f677874..e52ed631ae46f983dc8860e7bf628f95a5a6a7fb 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.xml
@@ -26,7 +26,7 @@
             </data>
             <data name="payment/method" xsi:type="string">paypal_express</data>
             <data name="configData" xsi:type="string">paypal_express</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
@@ -51,7 +51,7 @@
             </data>
             <data name="payment/method" xsi:type="string">paypal_express</data>
             <data name="configData" xsi:type="string">payflowlink</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" />
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php
index 07f03b1c931cfc0c547f781451630fa828101294..66ca21d8d0f3eae424d9b3f926bf0003ff3dd9d6 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php
@@ -32,6 +32,7 @@ class InContextExpressCheckoutFromShoppingCartTest extends Scenario
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
     const TO_MAINTAIN = 'yes';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.xml
index 979a8c2f32db3fd9333adbfe6fd8b52263edf462..bbc566d1e31ec620746316d2e3ebcfe76c6883ae 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.xml
@@ -10,7 +10,7 @@
         <variation name="InContextExpressCheckoutFromShoppingCartTestVariation1" summary="In-Context Checkout with PayPal Express Checkout (API Credentials) from shopping cart " ticketId="MAGETWO-47213">
             <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
             <data name="configData" xsi:type="string">paypal_express, paypal_express_in_context</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Paypal\Test\Constraint\AssertExpressCancelledMessage" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php
index ff06e6b10266ef4b723811bf143b648aa59853e9..b96f6a3e4a70a4ce320b0bf7b424675a0eee8fc4 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php
@@ -32,6 +32,7 @@ class InContextExpressOnePageCheckoutTest extends Scenario
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
     const TO_MAINTAIN = 'yes';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.xml
index cbdd9c3b6d6d31d13acac40ef5c8420b51054f85..5fa8e6e8b775dfb4e0bae646d431196823312f98 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.xml
@@ -18,7 +18,7 @@
             </data>
             <data name="payment/method" xsi:type="string">paypal_express</data>
             <data name="configData" xsi:type="string">paypal_express_in_context, paypal_express, freeshipping</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Paypal\Test\Constraint\AssertExpressCancelledMessage" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/NavigateMenuTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..379e90eb72c0d15c28b4de340f019ed21e9978c5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/NavigateMenuTest.xml
@@ -0,0 +1,23 @@
+<?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\Backend\Test\TestCase\NavigateMenuTest" summary="Navigate through admin menu" ticketId="MAGETWO-34874">
+        <variation name="NavigateMenuTest50">
+            <data name="tag" xsi:type="string">severity:S0</data>
+            <data name="menuItem" xsi:type="string">Reports > PayPal Settlement</data>
+            <data name="pageTitle" xsi:type="string">PayPal Settlement Reports</data>
+            <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
+        </variation>
+        <variation name="NavigateMenuTest51">
+            <data name="tag" xsi:type="string">severity:S0</data>
+            <data name="menuItem" xsi:type="string">Sales > Billing Agreements</data>
+            <data name="pageTitle" xsi:type="string">Billing Agreements</data>
+            <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ReorderUsingVaultTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ReorderUsingVaultTest.xml
index bc3ee3cef1c68ba1668891cce3e6f2eb45a4d86d..c33abb1dbdd2263fded6dbbfb0f683848a3bdd3f 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ReorderUsingVaultTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ReorderUsingVaultTest.xml
@@ -23,7 +23,7 @@
             <data name="creditCard/dataset" xsi:type="string">visa_default</data>
             <data name="configData" xsi:type="string">payflowpro, payflowpro_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" />
             <constraint name="Magento\Sales\Test\Constraint\AssertAuthorizationInCommentsHistory" />
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
index bde3837d71fda02bad93ac1ced7c3c08835deafe..92b4be03b5937ffa318f9d3cd05f6e6d2290f6bc 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -21,7 +21,7 @@
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">payflowpro, payflowpro_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <data name="status" xsi:type="string">Processing</data>
             <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Ship, Reorder, Edit</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e56386d5e0eacc346bfb5ddaf84319a1d1d16313
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/di.xml
@@ -0,0 +1,19 @@
+<?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="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Paypal\Test\Constraint\Sandbox\AssertTotalPaypalReview">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Paypal\Test\Constraint\AssertExpressCancelledMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Ups/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Ups/Test/TestCase/OnePageCheckoutTest.xml
index b27bc81d2866045de5c9e1d18fa4689a09a360d1..45076e90aab202b1cae7fbc5abcefbfc6c11e317 100644
--- a/dev/tests/functional/tests/app/Magento/Ups/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Ups/Test/TestCase/OnePageCheckoutTest.xml
@@ -20,7 +20,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">UPS Ground</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, ups, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid"/>
@@ -39,7 +39,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">UPS Worldwide Expedited</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, ups, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid"/>
diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
index 28c2b0f16239c735c927a8d3f7ef8eb0ebc1b01b..0bd219bab3bfff2103ea9f7a1ff2934ca8e1ad59 100644
--- a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
@@ -20,7 +20,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">Priority Mail 1-Day</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid"/>
@@ -37,7 +37,7 @@
             <data name="cart/data/shipping_method" xsi:type="string">Priority Mail Express International Flat Rate Envelope</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
             <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid"/>
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php
index 3c306280215ea1a2ee460db6f7838fd7c33caf7c..a5194b3915191e7c5ef893bcb5958d610544ddf7 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php
@@ -38,6 +38,7 @@ class CreateVaultOrderBackendTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'acceptance_test, extended_acceptance_test, 3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
index 17db35df1b44e6d2be519426ba962f6696fee23d..e6462e4697aa612c1239b92b3c7b7e847bd252ba 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
@@ -32,6 +32,7 @@ class DeleteSavedCreditCardTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
index ae303b695277c53272efedc40231bf305b66fea5..ac69bfb9f47e4550e6ab4592cccbdf56cf682da3 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
@@ -52,7 +52,7 @@
             </data>
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, payflowpro, braintree_use_vault, payflowpro_use_vault</data>
-            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data>
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php
index c3b82af6949c4a0ea114324abae90aa7ccab3a24..e426662d30e5447599f0b2f4bc47b67902aeb7c9 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php
@@ -36,6 +36,8 @@ class ReorderUsingVaultTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'extended_acceptance_test, 3rd_party_test';
+    const SEVERITY = 'S1';
+
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php
index 902ccc62af7f57c23db399bc22d5d3530b0a7515..fb8b3575ee72e463254038446ce55561123e3103 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php
@@ -39,6 +39,7 @@ class UseVaultOnCheckoutTest extends Scenario
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = '3rd_party_test';
+    const SEVERITY = 'S0';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Vault/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aba54057312ea3491655b5ea6e75c9fef4dfc2ae
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/etc/di.xml
@@ -0,0 +1,19 @@
+<?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="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Vault\Test\Constraint\AssertCreditCardNotPresentOnCheckout">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Vault\Test\Constraint\AssertStoredPaymentDeletedMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic.xml
index 4b4ab839d3463cbef4c766161e41874d0d65e446..6836259eb671ac908ad017138bde36a86e764766 100644
--- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic.xml
+++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic.xml
@@ -7,11 +7,6 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd">
-    <rule scope="testcase">
-        <deny>
-            <tag group="test_type" value="3rd_party_test_deprecated" />
-        </deny>
-    </rule>
     <rule scope="variation">
         <deny>
             <tag group="test_type" value="3rd_party_test" />
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4738e1886be3e6d9ab64f65cd7f241b63453a741
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+use Magento\Eav\Api\AttributeSetRepositoryInterface;
+use Magento\Eav\Api\Data\AttributeSetInterface;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class SaveTest extends \Magento\TestFramework\TestCase\AbstractBackendController
+{
+    /**
+     * @magentoDataFixture Magento/Catalog/_files/attribute_set_with_renamed_group.php
+     */
+    public function testAlreadyExistsExceptionProcessingWhenGroupCodeIsDuplicated()
+    {
+        $attributeSet = $this->getAttributeSetByName('attribute_set_test');
+        $this->assertNotEmpty($attributeSet, 'Attribute set with name "attribute_set_test" is missed');
+
+        $this->getRequest()->setPostValue('data', json_encode([
+            'attribute_set_name' => 'attribute_set_test',
+            'groups' => [
+                ['ynode-418', 'attribute-group-name', 1],
+            ],
+            'attributes' => [
+                ['9999', 'ynode-418', 1, null]
+            ],
+            'not_attributes' => [],
+            'removeGroups' => [],
+        ]));
+        $this->dispatch('backend/catalog/product_set/save/id/' . $attributeSet->getAttributeSetId());
+
+        $jsonResponse = json_decode($this->getResponse()->getBody());
+        $this->assertNotNull($jsonResponse);
+        $this->assertEquals(1, $jsonResponse->error);
+        $this->assertContains(
+            'Attribute group with same code already exist. Please rename &quot;attribute-group-name&quot; group',
+            $jsonResponse->message
+        );
+    }
+
+    /**
+     * @param string $attributeSetName
+     * @return AttributeSetInterface|null
+     */
+    protected function getAttributeSetByName($attributeSetName)
+    {
+        $objectManager = Bootstrap::getObjectManager();
+
+        /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
+        $searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class);
+        $searchCriteriaBuilder->addFilter('attribute_set_name', $attributeSetName);
+
+        /** @var AttributeSetRepositoryInterface $attributeSetRepository */
+        $attributeSetRepository = $objectManager->get(AttributeSetRepositoryInterface::class);
+        $result = $attributeSetRepository->getList($searchCriteriaBuilder->create());
+
+        $items = $result->getItems();
+        return $result->getTotalCount() ? array_pop($items) : null;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_renamed_group.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_renamed_group.php
new file mode 100644
index 0000000000000000000000000000000000000000..d73baa9e70e023d55e0a3306a03f8b7a56666b86
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_renamed_group.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+use Magento\Catalog\Api\AttributeSetRepositoryInterface;
+use Magento\Eav\Api\AttributeGroupRepositoryInterface;
+use Magento\Eav\Api\Data\AttributeGroupInterface;
+use Magento\Eav\Api\Data\AttributeGroupInterfaceFactory;
+use Magento\Eav\Api\Data\AttributeSetInterface;
+use Magento\Eav\Api\Data\AttributeSetInterfaceFactory;
+use Magento\Eav\Model\Entity\Type;
+use Magento\Framework\Api\DataObjectHelper;
+use Magento\TestFramework\Helper\Bootstrap;
+
+$objectManager = Bootstrap::getObjectManager();
+$attributeSetFactory = $objectManager->get(AttributeSetInterfaceFactory::class);
+$attributeGroupFactory = $objectManager->get(AttributeGroupInterfaceFactory::class);
+/** @var DataObjectHelper $dataObjectHelper */
+$dataObjectHelper = $objectManager->get(DataObjectHelper::class);
+/** @var AttributeGroupRepositoryInterface $attributeGroupRepository */
+$attributeGroupRepository = $objectManager->get(AttributeGroupRepositoryInterface::class);
+/** @var AttributeSetRepositoryInterface $attributeSetRepository */
+$attributeSetRepository = $objectManager->get(AttributeSetRepositoryInterface::class);
+
+/** @var AttributeSetInterface $attributeSet */
+$attributeSet = $attributeSetFactory->create();
+$entityTypeId = $objectManager->create(Type::class)->loadByCode('catalog_product')->getId();
+$dataObjectHelper->populateWithArray(
+    $attributeSet,
+    [
+        'attribute_set_name' => 'attribute_set_test',
+        'entity_type_id' => $entityTypeId,
+    ],
+    AttributeSetInterface::class
+);
+$attributeSetRepository->save($attributeSet);
+
+/** @var AttributeGroupInterface $attributeGroup */
+$attributeGroup = $attributeGroupFactory->create();
+$dataObjectHelper->populateWithArray(
+    $attributeGroup,
+    [
+        'attribute_set_id' => $attributeSet->getAttributeSetId(),
+        'attribute_group_name' => 'attribute-group-name',
+        'default_id' => 1,
+    ],
+    AttributeGroupInterface::class
+);
+$attributeGroupRepository->save($attributeGroup);
+
+// during renaming group code is not changed
+$attributeGroup->setAttributeGroupName('attribute-group-renamed');
+$attributeGroupRepository->save($attributeGroup);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute.php
index 2c9d6ca91e9f9cd2487067389fc119b24ca4a3bc..963de3e46fea69c821902b8d4266681adc0d5ea8 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute.php
@@ -40,7 +40,7 @@ $attribute->setData(
                 'option_1' => ['Option 1'],
                 'option_2' => ['Option 2'],
                 'option_3' => ['Option 3'],
-                'option_4' => ['Option 4 "!@#$%^&*'],
+                'option_4' => ['Option 4 "!@#$%^&*']
             ],
             'order' => [
                 'option_1' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_incorrect_values.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_incorrect_values.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ab2f9ef65bffca50886f8c7ef4764c550da0aa5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_incorrect_values.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/* Create attribute */
+/** @var $installer \Magento\Catalog\Setup\CategorySetup */
+$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+    \Magento\Catalog\Setup\CategorySetup::class
+);
+/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
+$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+    \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
+);
+$attribute->setData(
+    [
+        'attribute_code' => 'multiselect_attribute',
+        'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
+        'is_global' => 1,
+        'is_user_defined' => 1,
+        'frontend_input' => 'multiselect',
+        'is_unique' => 0,
+        'is_required' => 0,
+        'is_searchable' => 0,
+        'is_visible_in_advanced_search' => 0,
+        'is_comparable' => 0,
+        'is_filterable' => 0,
+        'is_filterable_in_search' => 0,
+        'is_used_for_promo_rules' => 0,
+        'is_html_allowed_on_front' => 1,
+        'is_visible_on_front' => 0,
+        'used_in_product_listing' => 0,
+        'used_for_sort_by' => 0,
+        'frontend_label' => ['Multiselect Attribute'],
+        'backend_type' => 'varchar',
+        'backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class,
+        'option' => [
+            'value' => [
+                'option_1' => ['Opt|,=ion 1'],
+                'option_2' => ['Opt||,ion 2'],
+                'option_3' => ['Option 3 "!@#$%^&*, "|"']
+            ],
+            'order' => [
+                'option_1' => 1,
+                'option_2' => 2,
+                'option_3' => 3,
+            ],
+        ],
+    ]
+);
+$attribute->save();
+
+/* Assign attribute to attribute set */
+$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
index 9b06764ce264cfe9aaa6be03a6e61f2f01210631..dc9e440b045f86ad2e85de45124ac01881d3892c 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
@@ -206,4 +206,55 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $data = $model->setWriter($exportAdapter)->export();
         $this->assertEmpty($data);
     }
+
+    /**
+     * Verify if fields wrapping works correct when "Fields Enclosure" option enabled
+     *
+     * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php
+     */
+    public function testExportWithFieldsEnclosure()
+    {
+        $this->model->setParameters([
+            \Magento\ImportExport\Model\Export::FIELDS_ENCLOSURE => 1
+        ]);
+
+        $this->model->setWriter(
+            $this->objectManager->create(
+                \Magento\ImportExport\Model\Export\Adapter\Csv::class
+            )
+        );
+        $exportData = $this->model->export();
+
+        $this->assertContains('""Option 2""', $exportData);
+        $this->assertContains('""Option 3""', $exportData);
+        $this->assertContains('""Option 4 """"!@#$%^&*""', $exportData);
+        $this->assertContains('text_attribute=""!@#$%^&*()_+1234567890-=|\:;""""\'<,>.?/', $exportData);
+    }
+
+    /**
+     * Verify that "category ids" filter correctly applies to export result
+     *
+     * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_with_categories.php
+     */
+    public function testCategoryIdsFilter()
+    {
+        $this->model->setWriter(
+            $this->objectManager->create(
+                \Magento\ImportExport\Model\Export\Adapter\Csv::class
+            )
+        );
+
+        $this->model->setParameters([
+            \Magento\ImportExport\Model\Export::FILTER_ELEMENT_GROUP => [
+                'category_ids' => '2,13'
+            ]
+        ]);
+
+        $exportData = $this->model->export();
+
+        $this->assertContains('Simple Product', $exportData);
+        $this->assertContains('Simple Product Three', $exportData);
+        $this->assertNotContains('Simple Product Two', $exportData);
+        $this->assertNotContains('Simple Product Not Visible On Storefront', $exportData);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index a5c1f07c164156a0941b0f8da05c43bdff644b5e..9ab7db147d811d370a4c2609d5baf5ea35225680 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -1380,4 +1380,55 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
             array_values($actualProductSkus)
         );
     }
+
+    /**
+     * @magentoDataFixture Magento/Catalog/_files/multiselect_attribute_with_incorrect_values.php
+     * @magentoDataFixture Magento/Catalog/_files/product_text_attribute.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     */
+    public function testProductWithWrappedAdditionalAttributes()
+    {
+        $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
+        $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+        $source = $this->objectManager->create(
+            \Magento\ImportExport\Model\Import\Source\Csv::class,
+            [
+                'file' => __DIR__ . '/_files/products_to_import_with_additional_attributes.csv',
+                'directory' => $directory
+            ]
+        );
+        $errors = $this->_model->setParameters(
+            [
+                'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND,
+                'entity' => 'catalog_product',
+                \Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE => 1
+            ]
+        )->setSource(
+            $source
+        )->validateData();
+
+        $this->assertTrue($errors->getErrorsCount() == 0);
+
+        $this->_model->importData();
+
+        /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+        $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Catalog\Api\ProductRepositoryInterface::class
+        );
+
+        /** @var \Magento\Eav\Api\AttributeOptionManagementInterface $multiselectOptions */
+        $multiselectOptions = $this->objectManager->get(\Magento\Eav\Api\AttributeOptionManagementInterface::class)
+            ->getItems(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_attribute');
+
+        $product1 = $productRepository->get('simple1');
+        $this->assertEquals('\'", =|', $product1->getData('text_attribute'));
+        $this->assertEquals(implode(',', [$multiselectOptions[3]->getValue(), $multiselectOptions[2]->getValue()]),
+            $product1->getData('multiselect_attribute'));
+
+        $product2 = $productRepository->get('simple2');
+        $this->assertEquals('', $product2->getData('text_attribute'));
+        $this->assertEquals(implode(',', [$multiselectOptions[1]->getValue(), $multiselectOptions[2]->getValue()]),
+            $product2->getData('multiselect_attribute'));
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_additional_attributes.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_additional_attributes.csv
new file mode 100644
index 0000000000000000000000000000000000000000..eb882be4c6bb1dcb804cd284e1ce376c31feec37
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_additional_attributes.csv
@@ -0,0 +1,3 @@
+sku,product_type,name,price,attribute_set_code,categories,additional_attributes
+simple1,simple,"simple 1",25,Default,"Default Category/Category 1","text_attribute=""'"""", =|"",multiselect_attribute=""Option 3 """"!@#$%^&*, """"|""""""|""Opt||,ion 2"""
+simple2,simple,"simple 2",34,Default,"Default Category/Category 1","multiselect_attribute=""Opt|,=ion 1""|""Opt||,ion 2"",text_attribute="""""
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_categories.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_categories.php
new file mode 100644
index 0000000000000000000000000000000000000000..e65ff00bcffcabd1e2fdeae3810876178e0d06aa
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_categories.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
+
+require dirname(dirname(__DIR__)) . '/Catalog/_files/categories.php';
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_shipping_method_and_items_categories.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_shipping_method_and_items_categories.php
index 7fb35a4412bf8bbbda969b646a23eee84aac61ac..ec230f3c5126185e21d27226c65f6e09e7f125e5 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_shipping_method_and_items_categories.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_shipping_method_and_items_categories.php
@@ -56,7 +56,7 @@ $product->setTypeId(
 )->setId(
     444
 )->setAttributeSetId(
-    5
+    4
 )->setStoreId(
     1
 )->setWebsiteIds(
diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Block/Adminhtml/Export/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Block/Adminhtml/Export/Edit/FormTest.php
index 52fbe5ed7b6afbbd85f65aa864c453e46810facb..a463a426dd647cde6d352be51f63bd82a59db5d1 100644
--- a/dev/tests/integration/testsuite/Magento/ImportExport/Block/Adminhtml/Export/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/ImportExport/Block/Adminhtml/Export/Edit/FormTest.php
@@ -30,7 +30,11 @@ class FormTest extends \PHPUnit_Framework_TestCase
      *
      * @var array
      */
-    protected $_expectedFields = ['base_fieldset' => ['entity' => 'entity', 'file_format' => 'file_format']];
+    protected $_expectedFields = ['base_fieldset' => [
+        'entity' => 'entity',
+        'file_format' => 'file_format',
+        'fields_enclosure' => 'fields_enclosure'
+    ]];
 
     protected function setUp()
     {
diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/ExportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/ExportTest.php
index 9decf617d50ae1ca0b8c895b3d45e5c255d846cd..de9379d1494d3925590f228ea52c69934fd9bd8b 100644
--- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/ExportTest.php
+++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/ExportTest.php
@@ -84,6 +84,6 @@ class ExportTest extends \Magento\TestFramework\TestCase\AbstractBackendControll
 
         $body = $this->getResponse()->getBody();
         $this->assertSelectCount('fieldset#base_fieldset', 1, $body);
-        $this->assertSelectCount('fieldset#base_fieldset div.field', 2, $body);
+        $this->assertSelectCount('fieldset#base_fieldset div.field', 3, $body);
     }
 }
diff --git a/dev/tests/static/get_github_changes.php b/dev/tests/static/get_github_changes.php
index c142aae18d8ecd5a4ab3fa895e32e5510b71683b..f332208cd17d0861dd1b28bd7096a0b3fe0066a5 100644
--- a/dev/tests/static/get_github_changes.php
+++ b/dev/tests/static/get_github_changes.php
@@ -12,9 +12,9 @@
 // @codingStandardsIgnoreFile
 
 define(
-'USAGE',
-<<<USAGE
-    php -f get_github_changes.php --
+    'USAGE',
+    <<<USAGE
+        php -f get_github_changes.php --
     --output-file="<output_file>"
     --base-path="<base_path>"
     --repo="<main_repo>"
@@ -36,6 +36,8 @@ $fileExtensions = explode(',', isset($options['file-extensions']) ? $options['fi
 
 $mainline = 'mainline_' . (string)rand(0, 9999);
 $repo = getRepo($options, $mainline);
+$branches = $repo->getBranches('--remotes');
+generateBranchesList($options['output-file'], $branches, $options['branch']);
 $changes = retrieveChangesAcrossForks($mainline, $repo, $options['branch']);
 $changedFiles = getChangedFiles($changes, $fileExtensions);
 generateChangedFilesList($options['output-file'], $changedFiles);
@@ -57,6 +59,25 @@ function generateChangedFilesList($outputFile, $changedFiles)
     fclose($changedFilesList);
 }
 
+/**
+ * Generates a file containing origin branches
+ *
+ * @param string $outputFile
+ * @param array $branches
+ * @param string $branchName
+ * @return void
+ */
+function generateBranchesList($outputFile, $branches, $branchName)
+{
+    $branchOutputFile = str_replace('changed_files', 'branches', $outputFile);
+    $branchesList = fopen($branchOutputFile, 'w');
+    fwrite($branchesList, $branchName . PHP_EOL);
+    foreach ($branches as $branch) {
+        fwrite($branchesList, substr(strrchr($branch, '/'), 1) . PHP_EOL);
+    }
+    fclose($branchesList);
+}
+
 /**
  * Gets list of changed files
  *
@@ -84,7 +105,7 @@ function getChangedFiles(array $changes, array $fileExtensions)
  *
  * @param array $options
  * @param string $mainline
- * @return array
+ * @return GitRepo
  * @throws Exception
  */
 function getRepo($options, $mainline)
@@ -203,6 +224,19 @@ class GitRepo
         $this->call(sprintf('fetch %s', $remoteAlias));
     }
 
+    /**
+     * Returns branches
+     *
+     * @param string $source
+     * @return array|mixed
+     */
+    public function getBranches($source = '--all')
+    {
+        $result = $this->call(sprintf('branch ' . $source));
+
+        return is_array($result) ? $result : [];
+    }
+
     /**
      * Returns files changes between branch and HEAD
      *
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/exception_hierarchy.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/exception_hierarchy.txt
index 9ae1f7fc1452d3156aa7308ee3f81d194e99bbce..a50845d3884adf110ff8c36831e6ef8ac63670ca 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/exception_hierarchy.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/exception_hierarchy.txt
@@ -6,3 +6,4 @@
 \Magento\Framework\DB\Adapter\ConnectionException
 \Magento\Framework\DB\Adapter\DeadlockException
 \Magento\Framework\DB\Adapter\LockWaitException
+\Magento\Framework\DB\Adapter\DuplicateException
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
index 87bd329ef3b5611475c6ee9486cdc9f27c4ea5fe..2f3d312fb41ffba1287bafd324a64ac751316d5c 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php
@@ -15,38 +15,49 @@ class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase
     /**
      * @var string
      */
-    protected static $changedFilesPattern = __DIR__ . '/../_files/changed_files*';
+    private static $branchesFilesPattern = __DIR__ . '/../_files/branches*';
 
     /**
      * @var string
      */
-    protected static $changedFileList = '';
+    private static $changedFilesPattern = __DIR__ . '/../_files/changed_files*';
 
     /**
-     * @var string Path for Magento's composer.json
+     * @var string
      */
-    protected static $composerFilePath = BP . '/composer.json';
+    private static $changedFileList = '';
 
     /**
-     * @var bool Is tests executes on develop branch
+     * @var bool
      */
-    protected static $isOnDevVersion = false;
+    private static $actualBranch = false;
 
     /**
      *  Set changed files paths and list for all projects
      */
     public static function setUpBeforeClass()
     {
-        foreach (glob(self::$changedFilesPattern) as $changedFile) {
-            self::$changedFileList .= file_get_contents($changedFile) . PHP_EOL;
-        }
+        foreach (glob(self::$branchesFilesPattern) as $branchesFile) {
+            //get the current branchname from the first line
+            $branchName = trim(file($branchesFile)[0]);
+            if ($branchName === 'develop') {
+                self::$actualBranch = true;
+            } else {
+                //get current minor branch name
+                preg_match('|^(\d+\.\d+)|', $branchName, $minorBranch);
+                $branchName = $minorBranch[0];
+
+                //get all version branches
+                preg_match_all('|^(\d+\.\d+)|m', file_get_contents($branchesFile), $matches);
 
-        if (file_exists(self::$composerFilePath)) {
-            $jsonData = json_decode(file_get_contents(self::$composerFilePath));
-            if (substr((string) $jsonData->version, -4) == '-dev') {
-                self::$isOnDevVersion = true;
+                //check is this a latest release branch
+                self::$actualBranch = ($branchName == max($matches[0]));
             }
         }
+
+        foreach (glob(self::$changedFilesPattern) as $changedFile) {
+            self::$changedFileList .= file_get_contents($changedFile) . PHP_EOL;
+        }
     }
 
     /**
@@ -54,15 +65,14 @@ 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');
+        if (!self::$actualBranch) {
+            preg_match_all('|etc/module\.xml$|mi', self::$changedFileList, $matches);
+            $this->assertEmpty(
+                reset($matches),
+                'module.xml changes for patch releases in non-actual branches are not allowed:' . PHP_EOL .
+                implode(PHP_EOL, array_values(reset($matches)))
+            );
         }
-        preg_match_all('|etc/module\.xml$|mi', self::$changedFileList, $matches);
-        $this->assertEmpty(
-            reset($matches),
-            'module.xml changes for patch releases in non-actual branches are not allowed:' . PHP_EOL .
-            implode(PHP_EOL, array_values(reset($matches)))
-        );
     }
 
     /**
@@ -70,14 +80,13 @@ 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');
+        if (!self::$actualBranch) {
+            preg_match_all('|app/code/Magento/[^/]+/Setup/[^/]+$|mi', self::$changedFileList, $matches);
+            $this->assertEmpty(
+                reset($matches),
+                'Code with changes for DB schema or data in non-actual branches are not allowed:' . PHP_EOL .
+                implode(PHP_EOL, array_values(reset($matches)))
+            );
         }
-        preg_match_all('|app/code/Magento/[^/]+/Setup/[^/]+$|mi', self::$changedFileList, $matches);
-        $this->assertEmpty(
-            reset($matches),
-            'Code with changes for DB schema or data in non-actual branches are not allowed:' . PHP_EOL .
-            implode(PHP_EOL, array_values(reset($matches)))
-        );
     }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
index f055f0a732c664dd8ed109d7ec52b178c537a4d0..d120a4543b9ddced597d330ab489de15c80cdb86 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
@@ -4,5 +4,6 @@
  * See COPYING.txt for license details.
  */
 return [
-    '/Test\/Unit/'
+    '/Test\/Unit/',
+    '/lib\/internal\/Magento\/Framework\/DB\/Adapter\/Pdo\/Mysql\.php/',
 ];
diff --git a/lib/internal/Magento/Framework/App/Cache/Type/Dummy.php b/lib/internal/Magento/Framework/App/Cache/Type/Dummy.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea6a3c3e92e7e615740990170d218608aff99836
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Type/Dummy.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Type;
+
+use Magento\Framework\App\CacheInterface;
+
+/**
+ * Dummy cache adapter
+ *
+ * for cases when need to disable interaction with cache
+ * but no specific cache type is used
+ */
+class Dummy implements CacheInterface
+{
+    /**
+     * Required by CacheInterface
+     *
+     * @return null
+     */
+    public function getFrontend()
+    {
+        return null;
+    }
+
+    /**
+     * Pretend to load data from cache by id
+     *
+     * {@inheritdoc}
+     */
+    public function load($identifier)
+    {
+        return null;
+    }
+
+    /**
+     * Pretend to save data
+     *
+     * {@inheritdoc}
+     */
+    public function save($data, $identifier, $tags = [], $lifeTime = null)
+    {
+        return false;
+    }
+
+    /**
+     * Pretend to remove cached data by identifier
+     *
+     * {@inheritdoc}
+     */
+    public function remove($identifier)
+    {
+        return true;
+    }
+
+    /**
+     * Pretend to clean cached data by specific tag
+     *
+     * {@inheritdoc}
+     */
+    public function clean($tags = [])
+    {
+        return true;
+    }
+}
diff --git a/lib/internal/Magento/Framework/DB/Adapter/DuplicateException.php b/lib/internal/Magento/Framework/DB/Adapter/DuplicateException.php
new file mode 100644
index 0000000000000000000000000000000000000000..06c4dfcc30ab26572b0faae1d90d1939989455ba
--- /dev/null
+++ b/lib/internal/Magento/Framework/DB/Adapter/DuplicateException.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\DB\Adapter;
+
+/**
+ * Database duplicate exception
+ */
+class DuplicateException extends \Zend_Db_Adapter_Exception
+{
+}
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index 6399824590a696980b641abcd3d0fc5b4e09cf42..cfbeb4f54c9e29d2f7b320b57c51ae7a7b31a676 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -14,6 +14,7 @@ use Magento\Framework\Cache\FrontendInterface;
 use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\DB\Adapter\ConnectionException;
 use Magento\Framework\DB\Adapter\DeadlockException;
+use Magento\Framework\DB\Adapter\DuplicateException;
 use Magento\Framework\DB\Adapter\LockWaitException;
 use Magento\Framework\DB\Ddl\Table;
 use Magento\Framework\DB\ExpressionConverter;
@@ -232,6 +233,8 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
             1205 => LockWaitException::class,
             // SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock
             1213 => DeadlockException::class,
+            // SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
+            1062 => DuplicateException::class,
         ];
         try {
             parent::__construct($config);
@@ -465,7 +468,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * @param mixed $bind An array of data or data itself to bind to the placeholders.
      * @return \Zend_Db_Statement_Pdo|void
      * @throws \Zend_Db_Adapter_Exception To re-throw \PDOException.
-     * @throws LocalizedException In case multiple queries are attempted at once, to protect from SQL injection
+     * @throws \Zend_Db_Statement_Exception
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     protected function _query($sql, $bind = [])
diff --git a/lib/internal/Magento/Framework/EntityManager/Operation/Create.php b/lib/internal/Magento/Framework/EntityManager/Operation/Create.php
index 7e3dfb2e753caa4ebd8efc72c159b0b3a3d521d4..552fe7bca86f58fb722fab1b08294b4ee41d3734 100644
--- a/lib/internal/Magento/Framework/EntityManager/Operation/Create.php
+++ b/lib/internal/Magento/Framework/EntityManager/Operation/Create.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Framework\EntityManager\Operation;
 
-use Magento\Framework\EntityManager\Operation\CreateInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
 use Magento\Framework\EntityManager\Operation\Create\CreateMain;
 use Magento\Framework\EntityManager\Operation\Create\CreateAttributes;
 use Magento\Framework\EntityManager\Operation\Create\CreateExtensions;
@@ -13,6 +13,8 @@ use Magento\Framework\EntityManager\MetadataPool;
 use Magento\Framework\EntityManager\EventManager;
 use Magento\Framework\EntityManager\TypeResolver;
 use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Exception\AlreadyExistsException;
+use Magento\Framework\Phrase;
 
 /**
  * Class Create
@@ -86,6 +88,7 @@ class Create implements CreateInterface
      * @param array $arguments
      * @return object
      * @throws \Exception
+     * @throws AlreadyExistsException
      */
     public function execute($entity, $arguments = [])
     {
@@ -114,6 +117,9 @@ class Create implements CreateInterface
                 ]
             );
             $connection->commit();
+        } catch (DuplicateException $e) {
+            $connection->rollBack();
+            throw new AlreadyExistsException(new Phrase('Unique constraint violation found'), $e);
         } catch (\Exception $e) {
             $connection->rollBack();
             throw $e;
diff --git a/lib/internal/Magento/Framework/EntityManager/Operation/Update.php b/lib/internal/Magento/Framework/EntityManager/Operation/Update.php
index 22abb464f8cd9ad96713899ca95fc0a3dc87e782..dbc8dc63873498888a40396795f9d6a0b9edca19 100644
--- a/lib/internal/Magento/Framework/EntityManager/Operation/Update.php
+++ b/lib/internal/Magento/Framework/EntityManager/Operation/Update.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Framework\EntityManager\Operation;
 
-use Magento\Framework\EntityManager\Operation\UpdateInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
 use Magento\Framework\EntityManager\Operation\Update\UpdateMain;
 use Magento\Framework\EntityManager\Operation\Update\UpdateAttributes;
 use Magento\Framework\EntityManager\Operation\Update\UpdateExtensions;
@@ -13,6 +13,8 @@ use Magento\Framework\EntityManager\MetadataPool;
 use Magento\Framework\EntityManager\EventManager;
 use Magento\Framework\EntityManager\TypeResolver;
 use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Exception\AlreadyExistsException;
+use Magento\Framework\Phrase;
 
 /**
  * Class Update
@@ -114,6 +116,9 @@ class Update implements UpdateInterface
                 ]
             );
             $connection->commit();
+        } catch (DuplicateException $e) {
+            $connection->rollBack();
+            throw new AlreadyExistsException(new Phrase('Unique constraint violation found'), $e);
         } catch (\Exception $e) {
             $connection->rollBack();
             throw $e;
diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/CreateTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/CreateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e45e8ffac1934859b16fd040505865d2f078eed3
--- /dev/null
+++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/CreateTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\EntityManager\Test\Unit\Operation;
+
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DataObject;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\EntityManager\EntityMetadataInterface;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\EntityManager\Operation\Create;
+use Magento\Framework\EntityManager\Operation\Create\CreateMain;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class CreateTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $metadataPool;
+
+    /**
+     * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceConnection;
+
+    /**
+     * @var CreateMain|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $createMain;
+
+    /**
+     * @var Create
+     */
+    private $create;
+
+    public function setUp()
+    {
+        $this->metadataPool = $this->getMockBuilder(MetadataPool::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->createMain = $this->getMockBuilder(CreateMain::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->create = (new ObjectManager($this))->getObject(Create::class, [
+            'metadataPool' => $this->metadataPool,
+            'resourceConnection' => $this->resourceConnection,
+            'createMain' => $this->createMain,
+        ]);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\AlreadyExistsException
+     */
+    public function testDuplicateExceptionProcessingOnExecute()
+    {
+        $metadata = $this->getMock(EntityMetadataInterface::class);
+        $this->metadataPool->expects($this->any())->method('getMetadata')->willReturn($metadata);
+
+        $connection = $this->getMock(AdapterInterface::class);
+        $connection->expects($this->once())->method('rollback');
+        $this->resourceConnection->expects($this->any())->method('getConnectionByName')->willReturn($connection);
+
+        $this->createMain->expects($this->once())->method('execute')->willThrowException(new DuplicateException());
+
+        $entity = $this->getMockBuilder(DataObject::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->create->execute($entity);
+    }
+}
diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/UpdateTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/UpdateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ec78c2560a28b3d0cd2043b8fa09fe653e49be8
--- /dev/null
+++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Operation/UpdateTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\EntityManager\Test\Unit\Operation;
+
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DataObject;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\EntityManager\EntityMetadataInterface;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\EntityManager\Operation\Update;
+use Magento\Framework\EntityManager\Operation\Update\UpdateMain;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class UpdateTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $metadataPool;
+
+    /**
+     * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceConnection;
+
+    /**
+     * @var UpdateMain|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $updateMain;
+
+    /**
+     * @var Update
+     */
+    private $update;
+
+    public function setUp()
+    {
+        $this->metadataPool = $this->getMockBuilder(MetadataPool::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->updateMain = $this->getMockBuilder(UpdateMain::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->update = (new ObjectManager($this))->getObject(Update::class, [
+            'metadataPool' => $this->metadataPool,
+            'resourceConnection' => $this->resourceConnection,
+            'updateMain' => $this->updateMain,
+        ]);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\AlreadyExistsException
+     */
+    public function testDuplicateExceptionProcessingOnExecute()
+    {
+        $metadata = $this->getMock(EntityMetadataInterface::class);
+        $this->metadataPool->expects($this->any())->method('getMetadata')->willReturn($metadata);
+
+        $connection = $this->getMock(AdapterInterface::class);
+        $connection->expects($this->once())->method('rollback');
+        $this->resourceConnection->expects($this->any())->method('getConnectionByName')->willReturn($connection);
+
+        $this->updateMain->expects($this->once())->method('execute')->willThrowException(new DuplicateException());
+
+        $entity = $this->getMockBuilder(DataObject::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->update->execute($entity);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Exception/AlreadyExistsException.php b/lib/internal/Magento/Framework/Exception/AlreadyExistsException.php
index dd39ec8c709a75fa4c4a8721dd8fdbfed4499c2f..18afdacf53de2676525f70fd76e5b94b3671dddb 100644
--- a/lib/internal/Magento/Framework/Exception/AlreadyExistsException.php
+++ b/lib/internal/Magento/Framework/Exception/AlreadyExistsException.php
@@ -3,9 +3,24 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Framework\Exception;
 
+use Magento\Framework\Phrase;
+
+/**
+ * Class AlreadyExistsException
+ */
 class AlreadyExistsException extends LocalizedException
 {
+    /**
+     * @param Phrase $phrase
+     * @param \Exception $cause
+     */
+    public function __construct(Phrase $phrase = null, \Exception $cause = null)
+    {
+        if ($phrase === null) {
+            $phrase = new Phrase('Unique constraint violation found');
+        }
+        parent::__construct($phrase, $cause);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
index 7febcb450f9720d9999f19704808df90ca69deea..4cd88e356e9cad79a6f0209bb2bab685ffe5f73c 100644
--- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
+++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
@@ -10,6 +10,8 @@ use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\Exception\AlreadyExistsException;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Model\ResourceModel\AbstractResource;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\Phrase;
 
 /**
  * Abstract resource model class
@@ -379,6 +381,7 @@ abstract class AbstractDb extends AbstractResource
      * @return $this
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @throws \Exception
+     * @throws AlreadyExistsException
      * @api
      */
     public function save(\Magento\Framework\Model\AbstractModel $object)
@@ -413,6 +416,10 @@ abstract class AbstractDb extends AbstractResource
             }
             $this->addCommitCallback([$object, 'afterCommitCallback'])->commit();
             $object->setHasDataChanges(false);
+        } catch (DuplicateException $e) {
+            $this->rollBack();
+            $object->setHasDataChanges(true);
+            throw new AlreadyExistsException(new Phrase('Unique constraint violation found'), $e);
         } catch (\Exception $e) {
             $this->rollBack();
             $object->setHasDataChanges(true);
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
index 0a2e6f2262173f244dc0dddf8c53fa44c9bf3558..d13bcdc539aa8c82d7af3b24ea1d32ed93e8431b 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
@@ -7,6 +7,10 @@
 // @codingStandardsIgnoreFile
 
 namespace Magento\Framework\Model\Test\Unit\ResourceModel\Db;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Adapter\DuplicateException;
+use Magento\Framework\Model\AbstractModel;
+use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -14,7 +18,7 @@ namespace Magento\Framework\Model\Test\Unit\ResourceModel\Db;
 class AbstractDbTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb
+     * @var AbstractDb
      */
     protected $_model;
 
@@ -63,7 +67,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->transactionManagerMock);
 
         $this->_model = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             [$contextMock],
             '',
             true,
@@ -116,7 +120,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     public function testAddUniqueFieldArray()
     {
         $this->assertInstanceOf(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             $this->_model->addUniqueField(['someField'])
         );
     }
@@ -134,7 +138,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     {
         $data = 'MainTableName';
         $idFieldNameProperty = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class, '_idFieldName'
+            AbstractDb::class, '_idFieldName'
         );
         $idFieldNameProperty->setAccessible(true);
         $idFieldNameProperty->setValue($this->_model, $data);
@@ -158,7 +162,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     public function testGetMainTable($tableName, $expectedResult)
     {
         $mainTableProperty = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_mainTable'
         );
         $mainTableProperty->setAccessible(true);
@@ -195,7 +199,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('tableName')
         );
         $tablesProperty = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_tables'
         );
         $tablesProperty->setAccessible(true);
@@ -215,7 +219,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetChecksum($checksum, $expected)
     {
-        $connectionMock = $this->getMock(\Magento\Framework\DB\Adapter\AdapterInterface::class, [], [], '', false);
+        $connectionMock = $this->getMock(AdapterInterface::class, [], [], '', false);
         $connectionMock->expects($this->once())->method('getTablesChecksum')->with($checksum)->will(
             $this->returnValue([$checksum => 'checksum'])
         );
@@ -242,7 +246,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     public function testResetUniqueField()
     {
         $uniqueFields = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_uniqueFields'
         );
         $uniqueFields->setAccessible(true);
@@ -254,7 +258,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     public function testGetUniqueFields()
     {
         $uniqueFieldsReflection = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_uniqueFields'
         );
         $uniqueFieldsReflection->setAccessible(true);
@@ -281,14 +285,14 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->_model, $result);
         $this->assertInstanceOf(
             \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
-        $result
+            $result
         );
     }
 
     public function testDelete()
     {
         $connectionInterfaceMock = $this->getMock(
-            \Magento\Framework\DB\Adapter\AdapterInterface::class,
+            AdapterInterface::class,
             [],
             [],
             '',
@@ -297,7 +301,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $contextMock = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false);
         $registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
         $abstractModelMock = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\AbstractModel::class,
+            AbstractModel::class,
             [$contextMock, $registryMock],
             '',
             false,
@@ -311,7 +315,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         );
 
         $abstractModelMock->expects($this->once())->method('getData')->willReturn(['data' => 'value']);
-        $connectionMock = $this->getMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
+        $connectionMock = $this->getMock(AdapterInterface::class);
         $this->transactionManagerMock->expects($this->once())
             ->method('start')
             ->with($connectionInterfaceMock)
@@ -334,13 +338,13 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('tableName')
         );
         $mainTableReflection = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_mainTable'
         );
         $mainTableReflection->setAccessible(true);
         $mainTableReflection->setValue($this->_model, 'tableName');
         $idFieldNameReflection = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_idFieldName'
         );
         $idFieldNameReflection->setAccessible(true);
@@ -351,7 +355,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $abstractModelMock->expects($this->once())->method('afterDelete');
         $abstractModelMock->expects($this->once())->method('afterDeleteCommit');
         $this->assertInstanceOf(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             $this->_model->delete($abstractModelMock)
         );
     }
@@ -361,7 +365,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $contextMock = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false);
         $registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
         $abstractModelMock = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\AbstractModel::class,
+            AbstractModel::class,
             [$contextMock, $registryMock],
             '',
             false,
@@ -381,7 +385,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
     public function testGetDataChanged($getOriginData, $expected)
     {
         $connectionInterfaceMock = $this->getMock(
-            \Magento\Framework\DB\Adapter\AdapterInterface::class,
+            AdapterInterface::class,
             [],
             [],
             '',
@@ -393,7 +397,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $contextMock = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false);
         $registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
         $abstractModelMock = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\AbstractModel::class,
+            AbstractModel::class,
             [$contextMock, $registryMock],
             '',
             false,
@@ -402,7 +406,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             ['__wakeup', 'getOrigData', 'getData']
         );
         $mainTableProperty = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_mainTable'
         );
         $mainTableProperty->setAccessible(true);
@@ -431,13 +435,13 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
 
     public function testPrepareDataForUpdate()
     {
-        $connectionMock = $this->getMock(\Magento\Framework\DB\Adapter\AdapterInterface::class, [], [], '', false);
+        $connectionMock = $this->getMock(AdapterInterface::class, [], [], '', false);
         $context = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject(
             \Magento\Framework\Model\Context::class
         );
         $registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
         $resourceMock = $this->getMock(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             [
                 '_construct',
                 'getConnection',
@@ -449,7 +453,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             false
         );
         $connectionInterfaceMock = $this->getMock(
-            \Magento\Framework\DB\Adapter\AdapterInterface::class,
+            AdapterInterface::class,
             [],
             [],
             '',
@@ -462,7 +466,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
         $abstractModelMock = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\AbstractModel::class,
+            AbstractModel::class,
             [$context, $registryMock, $resourceMock, $resourceCollectionMock]
         );
         $data = 'tableName';
@@ -474,13 +478,13 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('tableName')
         );
         $mainTableReflection = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_mainTable'
         );
         $mainTableReflection->setAccessible(true);
         $mainTableReflection->setValue($this->_model, 'tableName');
         $idFieldNameReflection = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
+            AbstractDb::class,
             '_idFieldName'
         );
         $idFieldNameReflection->setAccessible(true);
@@ -540,7 +544,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         /**
          * Mock SUT so as not to test extraneous logic
          */
-        $model = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class)
+        $model = $this->getMockBuilder(AbstractDb::class)
             ->disableOriginalConstructor()
             ->setMethods(['_prepareDataForSave', 'getIdFieldName', 'getConnection', 'getMainTable'])
             ->getMockForAbstractClass();
@@ -557,7 +561,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $reflectionProperty->setValue($model, $pkIncrement);
 
         // Mocked behavior
-        $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
+        $connectionMock = $this->getMockBuilder(AdapterInterface::class)
             ->disableOriginalConstructor()
             ->setMethods(['lastInsertId'])
             ->getMockForAbstractClass();
@@ -579,7 +583,7 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
 
         //      Only set object id if not PK autoincrement
         $setIdInvokedCount = $pkIncrement ? 1 : 0;
-        $inputObject = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class)
+        $inputObject = $this->getMockBuilder(AbstractModel::class)
             ->disableOriginalConstructor()
             ->getMock();
         $inputObject->expects($this->exactly($setIdInvokedCount))->method('setId');
@@ -591,9 +595,37 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $reflectionMethod->invokeArgs($model, [$inputObject]);
     }
 
+    /**
+     * @return array
+     */
     public function saveNewObjectDataProvider()
     {
         return [[true], [false]];
     }
 
+    /**
+     * @expectedException \Magento\Framework\Exception\AlreadyExistsException
+     */
+    public function testDuplicateExceptionProcessingOnSave()
+    {
+        $connection = $this->getMock(AdapterInterface::class);
+        $connection->expects($this->once())->method('rollback');
+
+        /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $model */
+        $model = $this->getMockBuilder(AbstractDb::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getConnection'])
+            ->getMockForAbstractClass();
+        $model->expects($this->any())->method('getConnection')->willReturn($connection);
+
+        /** @var AbstractModel|\PHPUnit_Framework_MockObject_MockObject $object */
+        $object = $this->getMockBuilder(AbstractModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $object->expects($this->once())->method('hasDataChanges')->willReturn(true);
+        $object->expects($this->once())->method('beforeSave')->willThrowException(new DuplicateException());
+        $object->expects($this->once())->method('setHasDataChanges')->with(true);
+
+        $model->save($object);
+    }
 }
diff --git a/lib/internal/Magento/Framework/View/Config.php b/lib/internal/Magento/Framework/View/Config.php
index 917f632323ea0cda55ab95b55cd663292b5b31d6..b72fe87c4acc4b7155437bc8b478571caa4e72b2 100644
--- a/lib/internal/Magento/Framework/View/Config.php
+++ b/lib/internal/Magento/Framework/View/Config.php
@@ -62,7 +62,7 @@ class Config implements \Magento\Framework\View\ConfigInterface
         if (isset($params['themeModel'])) {
             /** @var \Magento\Framework\View\Design\ThemeInterface $currentTheme */
             $currentTheme = $params['themeModel'];
-            $key = $currentTheme->getCode();
+            $key = $currentTheme->getFullPath();
             if (isset($this->viewConfigs[$key])) {
                 return $this->viewConfigs[$key];
             }
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/View/Test/Unit/ConfigTest.php
index 4295b5d3e24e73810f66e1a16e83f1d0cb6e84f1..2a09783c710e4e4c9334079a67025b452d673974 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/ConfigTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/ConfigTest.php
@@ -40,17 +40,17 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testGetViewConfig()
     {
-        $themeCode = 2;
+        $themeCode = 'area/theme';
 
         $themeMock = $this->getMock(
             \Magento\Theme\Model\Theme::class,
-            ['getCode'],
+            ['getFullPath'],
             [],
             '',
             false
         );
         $themeMock->expects($this->atLeastOnce())
-            ->method('getCode')
+            ->method('getFullPath')
             ->will($this->returnValue($themeCode));
         $params = [
             'themeModel' => $themeMock,
diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
index 66b72857d003397b8a756dc6aae9c0de70c58eeb..167903f62c760ca8ce495efe0dc42c98546d161f 100755
--- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
+++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
@@ -357,6 +357,8 @@ define([
             // escape special chars in directives url to use it in regular expression
             var url = this.makeDirectiveUrl('%directive%').replace(/([$^.?*!+:=()\[\]{}|\\])/g, '\\$1');
             var reg = new RegExp(url.replace('%directive%', '([a-zA-Z0-9,_-]+)'));
+            content = decodeURIComponent(content);
+
             return content.gsub(reg, function(match) {
                 return Base64.mageDecode(match[1]);
             }.bind(this));
diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php
index 701393fd9666102147c5921ad1831a69488ba8fb..1fc8e9db2bf64f3874bbfa457eb3384d91425863 100644
--- a/setup/src/Magento/Setup/Model/PackagesData.php
+++ b/setup/src/Magento/Setup/Model/PackagesData.php
@@ -409,6 +409,7 @@ class PackagesData
                 return in_array(
                     $item['package_type'],
                     [
+                        \Magento\Setup\Model\Grid\TypeMapper::LANGUAGE_PACKAGE_TYPE,
                         \Magento\Setup\Model\Grid\TypeMapper::MODULE_PACKAGE_TYPE,
                         \Magento\Setup\Model\Grid\TypeMapper::EXTENSION_PACKAGE_TYPE,
                         \Magento\Setup\Model\Grid\TypeMapper::THEME_PACKAGE_TYPE,
@@ -491,26 +492,38 @@ class PackagesData
 
                 return array_keys($packageVersions);
             }
-        } else {
-            $versionsPattern = '/^versions\s*\:\s(.+)$/m';
-
-            $commandParams = [
-                self::PARAM_COMMAND => self::COMPOSER_SHOW,
-                self::PARAM_PACKAGE => $package,
-                self::PARAM_AVAILABLE => true
-            ];
-
-            $applicationFactory = $this->objectManagerProvider->get()
-                ->get(\Magento\Framework\Composer\MagentoComposerApplicationFactory::class);
-            /** @var \Magento\Composer\MagentoComposerApplication $application */
-            $application = $applicationFactory->create();
-
-            $result = $application->runComposerCommand($commandParams);
-            $matches = [];
-            preg_match($versionsPattern, $result, $matches);
-            if (isset($matches[1])) {
-                return explode(', ', $matches[1]);
-            }
+        }
+
+        return $this->getAvailableVersionsFromAllRepositories($package);
+    }
+
+    /**
+     * Get available versions of package by "composer show" command
+     *
+     * @param string $package
+     * @return array
+     * @exception \RuntimeException
+     */
+    private function getAvailableVersionsFromAllRepositories($package)
+    {
+        $versionsPattern = '/^versions\s*\:\s(.+)$/m';
+
+        $commandParams = [
+            self::PARAM_COMMAND => self::COMPOSER_SHOW,
+            self::PARAM_PACKAGE => $package,
+            self::PARAM_AVAILABLE => true
+        ];
+
+        $applicationFactory = $this->objectManagerProvider->get()
+            ->get(\Magento\Framework\Composer\MagentoComposerApplicationFactory::class);
+        /** @var \Magento\Composer\MagentoComposerApplication $application */
+        $application = $applicationFactory->create();
+
+        $result = $application->runComposerCommand($commandParams);
+        $matches = [];
+        preg_match($versionsPattern, $result, $matches);
+        if (isset($matches[1])) {
+            return explode(', ', $matches[1]);
         }
 
         throw new \RuntimeException(
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php
index 5a7ead384665446fa7fb3dc82dff33d4b9777133..54a297e7dbe43909c0fe9e929aec95a0239beb73 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php
@@ -22,38 +22,96 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase
      */
     private $packagesData;
 
+    /**
+     * @var ComposerInformation|MockObject
+     */
+    private $composerInformation;
+
+    /**
+     * @var \Magento\Setup\Model\DateTime\TimeZoneProvider|MockObject
+     */
+    private $timeZoneProvider;
+
+    /**
+     * @var \Magento\Setup\Model\PackagesAuth|MockObject
+     */
+    private $packagesAuth;
+
+    /**
+     * @var \Magento\Framework\Filesystem|MockObject
+     */
+    private $filesystem;
+
+    /**
+     * @var \Magento\Setup\Model\ObjectManagerProvider|MockObject
+     */
+    private $objectManagerProvider;
+
+    /**
+     * @var \Magento\Setup\Model\Grid\TypeMapper|MockObject
+     */
+    private $typeMapper;
+
     public function setUp()
     {
-        $composerInformation = $this->getComposerInformation();
-        $timeZoneProvider = $this->getMock(\Magento\Setup\Model\DateTime\TimeZoneProvider::class, [], [], '', false);
+        $this->composerInformation = $this->getComposerInformation();
+        $this->timeZoneProvider = $this->getMockBuilder(\Magento\Setup\Model\DateTime\TimeZoneProvider::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $timeZone = $this->getMock(\Magento\Framework\Stdlib\DateTime\Timezone::class, [], [], '', false);
-        $timeZoneProvider->expects($this->any())->method('get')->willReturn($timeZone);
-        $packagesAuth = $this->getMock(\Magento\Setup\Model\PackagesAuth::class, [], [], '', false);
-        $filesystem = $this->getMock(\Magento\Framework\Filesystem::class, [], [], '', false);
-        $objectManagerProvider = $this->getMock(\Magento\Setup\Model\ObjectManagerProvider::class, [], [], '', false);
+        $this->timeZoneProvider->expects($this->any())->method('get')->willReturn($timeZone);
+        $this->packagesAuth = $this->getMock(\Magento\Setup\Model\PackagesAuth::class, [], [], '', false);
+        $this->filesystem = $this->getMock(\Magento\Framework\Filesystem::class, [], [], '', false);
+        $this->objectManagerProvider = $this->getMockBuilder(\Magento\Setup\Model\ObjectManagerProvider::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManager = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class);
-        $applicationFactory = $this->getMock(
-            \Magento\Framework\Composer\MagentoComposerApplicationFactory::class,
-            [],
-            [],
-            '',
-            false
-        );
+        $appFactory = $this->getMockBuilder(\Magento\Framework\Composer\MagentoComposerApplicationFactory::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $application = $this->getMock(\Magento\Composer\MagentoComposerApplication::class, [], [], '', false);
         $application->expects($this->any())
             ->method('runComposerCommand')
-            ->willReturn('versions: 2.0.1');
-        $applicationFactory->expects($this->any())->method('create')->willReturn($application);
+            ->willReturnMap([
+                [
+                    [
+                        PackagesData::PARAM_COMMAND => PackagesData::COMPOSER_SHOW,
+                        PackagesData::PARAM_PACKAGE => 'magento/package-1',
+                        PackagesData::PARAM_AVAILABLE => true,
+                    ],
+                    null,
+                    'versions: 2.0.1'
+                ],
+                [
+                    [
+                        PackagesData::PARAM_COMMAND => PackagesData::COMPOSER_SHOW,
+                        PackagesData::PARAM_PACKAGE => 'magento/package-2',
+                        PackagesData::PARAM_AVAILABLE => true,
+                    ],
+                    null,
+                    'versions: 2.0.1'
+                ],
+                [
+                    [
+                        PackagesData::PARAM_COMMAND => PackagesData::COMPOSER_SHOW,
+                        PackagesData::PARAM_PACKAGE => 'partner/package-3',
+                        PackagesData::PARAM_AVAILABLE => true,
+                    ],
+                    null,
+                    'versions: 3.0.1'
+                ],
+            ]);
+        $appFactory->expects($this->any())->method('create')->willReturn($application);
         $objectManager->expects($this->any())
             ->method('get')
             ->with(\Magento\Framework\Composer\MagentoComposerApplicationFactory::class)
-            ->willReturn($applicationFactory);
-        $objectManagerProvider->expects($this->any())->method('get')->willReturn($objectManager);
+            ->willReturn($appFactory);
+        $this->objectManagerProvider->expects($this->any())->method('get')->willReturn($objectManager);
 
         $directoryWrite = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\Directory\WriteInterface::class);
         $directoryRead = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\Directory\ReadInterface::class);
-        $filesystem->expects($this->any())->method('getDirectoryRead')->will($this->returnValue($directoryRead));
-        $filesystem->expects($this->any())
+        $this->filesystem->expects($this->any())->method('getDirectoryRead')->will($this->returnValue($directoryRead));
+        $this->filesystem->expects($this->any())
             ->method('getDirectoryWrite')
             ->will($this->returnValue($directoryWrite));
         $directoryWrite->expects($this->any())->method('isExist')->willReturn(true);
@@ -81,32 +139,41 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase
                 . '}}}'
             );
 
-        $typeMapper = $this->getMockBuilder(\Magento\Setup\Model\Grid\TypeMapper::class)
+        $this->typeMapper = $this->getMockBuilder(\Magento\Setup\Model\Grid\TypeMapper::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $typeMapper->expects(static::any())
+        $this->typeMapper->expects(static::any())
             ->method('map')
             ->willReturnMap([
                 [ComposerInformation::MODULE_PACKAGE_TYPE, \Magento\Setup\Model\Grid\TypeMapper::MODULE_PACKAGE_TYPE],
             ]);
 
+        $this->createPackagesData();
+    }
+
+    private function createPackagesData()
+    {
         $this->packagesData = new PackagesData(
-            $composerInformation,
-            $timeZoneProvider,
-            $packagesAuth,
-            $filesystem,
-            $objectManagerProvider,
-            $typeMapper
+            $this->composerInformation,
+            $this->timeZoneProvider,
+            $this->packagesAuth,
+            $this->filesystem,
+            $this->objectManagerProvider,
+            $this->typeMapper
         );
     }
 
     /**
+     * @param array $requiredPackages
+     * @param array $installedPackages
+     * @param array $repo
      * @return ComposerInformation|MockObject
      */
-    private function getComposerInformation()
+    private function getComposerInformation($requiredPackages = [], $installedPackages = [], $repo = [])
     {
         $composerInformation = $this->getMock(ComposerInformation::class, [], [], '', false);
         $composerInformation->expects($this->any())->method('getInstalledMagentoPackages')->willReturn(
+            $installedPackages ?:
             [
                 'magento/package-1' => [
                     'name' => 'magento/package-1',
@@ -117,21 +184,30 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase
                     'name' => 'magento/package-2',
                     'type' => 'magento2-module',
                     'version'=> '1.0.1'
-                ]
+                ],
+                'partner/package-3' => [
+                    'name' => 'partner/package-3',
+                    'type' => 'magento2-module',
+                    'version'=> '3.0.0'
+                ],
             ]
         );
 
         $composerInformation->expects($this->any())->method('getRootRepositories')
-            ->willReturn(['repo1', 'repo2']);
+            ->willReturn($repo ?: ['repo1', 'repo2']);
         $composerInformation->expects($this->any())->method('getPackagesTypes')
             ->willReturn(['magento2-module']);
         $rootPackage = $this->getMock(RootPackage::class, [], ['magento/project', '2.1.0', '2']);
         $rootPackage->expects($this->any())
             ->method('getRequires')
-            ->willReturn([
-                'magento/package-1' => '1.0.0',
-                'magento/package-2' => '1.0.1'
-            ]);
+            ->willReturn(
+                $requiredPackages ?:
+                [
+                    'magento/package-1' => '1.0.0',
+                    'magento/package-2' => '1.0.1',
+                    'partner/package-3' => '3.0.0',
+                ]
+            );
         $composerInformation->expects($this->any())
             ->method('getRootPackage')
             ->willReturn($rootPackage);
@@ -146,19 +222,57 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase
         $this->assertArrayHasKey('date', $latestData['lastSyncDate']);
         $this->assertArrayHasKey('time', $latestData['lastSyncDate']);
         $this->assertArrayHasKey('packages', $latestData);
-        $this->assertSame(2, count($latestData['packages']));
-        $this->assertSame(2, $latestData['countOfUpdate']);
+        $this->assertSame(3, count($latestData['packages']));
+        $this->assertSame(3, $latestData['countOfUpdate']);
         $this->assertArrayHasKey('installPackages', $latestData);
         $this->assertSame(1, count($latestData['installPackages']));
         $this->assertSame(1, $latestData['countOfInstall']);
     }
 
-    public function testGetPackagesForUpdate()
+    /**
+     * @expectedException \RuntimeException
+     * @expectedExceptionMessage Couldn't get available versions for package partner/package-4
+     */
+    public function testGetPackagesForUpdateWithException()
     {
+        $requiredPackages = [
+            'partner/package-4' => '4.0.4',
+        ];
+        $installedPackages = [
+            'partner/package-4' => [
+                'name' => 'partner/package-4',
+                'type' => 'magento2-module',
+                'version'=> '4.0.4'
+            ],
+        ];
+        $this->composerInformation = $this->getComposerInformation($requiredPackages, $installedPackages);
+        $this->createPackagesData();
+        $this->packagesData->getPackagesForUpdate();
+    }
+
+    public function testPackagesForUpdateFromJson()
+    {
+        $this->composerInformation = $this->getComposerInformation([], [], ['https://repo1']);
+        $this->packagesAuth->expects($this->atLeastOnce())
+            ->method('getCredentialBaseUrl')
+            ->willReturn('repo1');
+        $this->createPackagesData();
         $packages = $this->packagesData->getPackagesForUpdate();
         $this->assertEquals(2, count($packages));
         $this->assertArrayHasKey('magento/package-1', $packages);
+        $this->assertArrayHasKey('partner/package-3', $packages);
+        $firstPackage = array_values($packages)[0];
+        $this->assertArrayHasKey('latestVersion', $firstPackage);
+        $this->assertArrayHasKey('versions', $firstPackage);
+    }
+
+    public function testGetPackagesForUpdate()
+    {
+        $packages = $this->packagesData->getPackagesForUpdate();
+        $this->assertEquals(3, count($packages));
+        $this->assertArrayHasKey('magento/package-1', $packages);
         $this->assertArrayHasKey('magento/package-2', $packages);
+        $this->assertArrayHasKey('partner/package-3', $packages);
         $firstPackage = array_values($packages)[0];
         $this->assertArrayHasKey('latestVersion', $firstPackage);
         $this->assertArrayHasKey('versions', $firstPackage);
@@ -167,9 +281,10 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase
     public function testGetInstalledPackages()
     {
         $installedPackages = $this->packagesData->getInstalledPackages();
-        $this->assertEquals(2, count($installedPackages));
+        $this->assertEquals(3, count($installedPackages));
         $this->assertArrayHasKey('magento/package-1', $installedPackages);
         $this->assertArrayHasKey('magento/package-2', $installedPackages);
+        $this->assertArrayHasKey('partner/package-3', $installedPackages);
     }
 
     public function testGetMetaPackagesMap()