diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php
index c76fc3d291ed1710f9deea86322dc07f12bdba25..87fb8d9656d122287a4a18f38776e226db54084e 100644
--- a/app/code/Magento/Catalog/Model/Category.php
+++ b/app/code/Magento/Catalog/Model/Category.php
@@ -25,6 +25,8 @@ use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
  * @method array getAffectedCategoryIds()
  * @method Category setUrlKey(string $urlKey)
  * @method Category setUrlPath(string $urlPath)
+ * @method Category getSkipDeleteChildren()
+ * @method Category setSkipDeleteChildren(boolean $value)
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php
index 57bc0144704ce2c3155242206977291a4a087a7c..f0697d95648484f018b74511579f5d36009cebf4 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php
@@ -9,6 +9,7 @@
 namespace Magento\Catalog\Model\Indexer\Category\Flat;
 
 use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Model\Entity\MetadataPool;
 
 class AbstractAction
 {
@@ -53,6 +54,18 @@ class AbstractAction
      */
     protected $connection;
 
+    /**
+     * @var \Magento\Framework\Model\Entity\EntityMetadata
+     */
+    protected $categoryMetadata;
+
+    /**
+     * Static columns to skip
+     *
+     * @var array
+     */
+    protected $skipStaticColumns = [];
+
     /**
      * @param ResourceConnection $resource
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -61,13 +74,17 @@ class AbstractAction
     public function __construct(
         ResourceConnection $resource,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
+        \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
+        MetadataPool $metadataPool,
+        $skipStaticColumns = []
     ) {
         $this->resource = $resource;
         $this->connection = $resource->getConnection();
         $this->storeManager = $storeManager;
         $this->resourceHelper = $resourceHelper;
+        $this->skipStaticColumns = $skipStaticColumns;
         $this->columns = array_merge($this->getStaticColumns(), $this->getEavColumns());
+        $this->categoryMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class);
     }
 
     /**
@@ -177,13 +194,12 @@ class AbstractAction
     protected function getStaticColumns()
     {
         $columns = [];
-        $columnsToSkip = ['entity_type_id', 'attribute_set_id'];
         $describe = $this->connection->describeTable(
             $this->connection->getTableName($this->getTableName('catalog_category_entity'))
         );
 
         foreach ($describe as $column) {
-            if (in_array($column['COLUMN_NAME'], $columnsToSkip)) {
+            if (in_array($column['COLUMN_NAME'], $this->skipStaticColumns)) {
                 continue;
             }
             $isUnsigned = '';
@@ -364,11 +380,11 @@ class AbstractAction
         $attributesType = ['varchar', 'int', 'decimal', 'text', 'datetime'];
         foreach ($attributesType as $type) {
             foreach ($this->getAttributeTypeValues($type, $entityIds, $storeId) as $row) {
-                if (isset($row['entity_id']) && isset($row['attribute_id'])) {
+                if (isset($row[$this->categoryMetadata->getLinkField()]) && isset($row['attribute_id'])) {
                     $attributeId = $row['attribute_id'];
                     if (isset($attributes[$attributeId])) {
                         $attributeCode = $attributes[$attributeId]['attribute_code'];
-                        $values[$row['entity_id']][$attributeCode] = $row['value'];
+                        $values[$row[$this->categoryMetadata->getLinkField()]][$attributeCode] = $row['value'];
                     }
                 }
             }
@@ -386,18 +402,24 @@ class AbstractAction
      */
     protected function getAttributeTypeValues($type, $entityIds, $storeId)
     {
+        $linkField = $this->categoryMetadata->getLinkField();
         $select = $this->connection->select()->from(
             [
                 'def' => $this->connection->getTableName($this->getTableName('catalog_category_entity_' . $type)),
             ],
-            ['entity_id', 'attribute_id']
+            [$linkField, 'attribute_id']
+        )->joinLeft(
+            [
+                'e' => $this->connection->getTableName($this->getTableName('catalog_category_entity'))
+            ],
+            "def.{$linkField} = e.{$linkField}"
         )->joinLeft(
             [
                 'store' => $this->connection->getTableName(
                     $this->getTableName('catalog_category_entity_' . $type)
                 ),
             ],
-            'store.entity_id = def.entity_id AND store.attribute_id = def.attribute_id ' .
+            "store.{$linkField} = def.{$linkField} AND store.attribute_id = def.attribute_id " .
             'AND store.store_id = ' .
             $storeId,
             [
@@ -408,7 +430,7 @@ class AbstractAction
                 )
             ]
         )->where(
-            'def.entity_id IN (?)',
+            "e.entity_id IN (?)",
             $entityIds
         )->where(
             'def.store_id IN (?)',
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php
index 84390a23058897b899f8b3af03fe4c96dd7b61c0..204a5534a260a3d000f4b000369c2020c4e0d5cf 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php
@@ -68,12 +68,12 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction
                 $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId());
                 $data = [];
                 foreach ($categories[$store->getRootCategoryId()] as $category) {
-                    if (!isset($attributesData[$category['entity_id']])) {
+                    if (!isset($attributesData[$category[$this->categoryMetadata->getLinkField()]])) {
                         continue;
                     }
                     $category['store_id'] = $store->getId();
                     $data[] = $this->prepareValuesToInsert(
-                        array_merge($category, $attributesData[$category['entity_id']])
+                        array_merge($category, $attributesData[$category[$this->categoryMetadata->getLinkField()]])
                     );
                 }
                 $this->connection->insertMultiple(
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php
index 88ce0ac50b363018069086ac43c8193ab9af8a10..4d5961809e61b44707c09b87bd0a4e92dba1fad6 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php
@@ -7,6 +7,7 @@ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action;
 
 use Magento\Catalog\Api\CategoryRepositoryInterface;
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Model\Entity\MetadataPool;
 
 class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction
 {
@@ -19,16 +20,20 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction
      * @param \Magento\Framework\App\ResourceConnection $resource
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
+     * @param MetadataPool $metadataPool
+     * @param array $skipStaticColumns
      * @param CategoryRepositoryInterface $categoryRepository
      */
     public function __construct(
         \Magento\Framework\App\ResourceConnection $resource,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
-        CategoryRepositoryInterface $categoryRepository
+        MetadataPool $metadataPool,
+        CategoryRepositoryInterface $categoryRepository,
+        $skipStaticColumns = []
     ) {
         $this->categoryRepository = $categoryRepository;
-        parent::__construct($resource, $storeManager, $resourceHelper);
+        parent::__construct($resource, $storeManager, $resourceHelper, $metadataPool, $skipStaticColumns);
     }
 
     /**
@@ -122,14 +127,16 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction
         /** @var \Magento\Framework\DB\Select $select */
         $select = $this->connection->select()->from(
             ['cf' => $this->getTableNameByStore($store, $useTempTable)]
-        )->joinLeft(
-            ['ce' => $this->getTableName('catalog_category_entity')],
-            'cf.path = ce.path',
-            []
         )->where(
             "cf.path = {$rootIdExpr} OR cf.path = {$rootCatIdExpr} OR cf.path like {$catIdExpr}"
         )->where(
-            'ce.entity_id IS NULL'
+            'cf.entity_id NOT IN (?)',
+            new \Zend_Db_Expr(
+                $this->connection->select()->from(
+                    ['ce' => $this->getTableName('catalog_category_entity')],
+                    ['entity_id']
+                )
+            )
         );
 
         $sql = $select->deleteFromSelect('cf');
@@ -157,7 +164,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction
         )->where(
             "path = {$rootIdExpr} OR path = {$rootCatIdExpr} OR path like {$catIdExpr}"
         )->where(
-            'entity_id IN (?)',
+            "entity_id IN (?)",
             $ids
         );
 
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php
index 5bfe8e714ba7f9a1ef9984cf9ddbe8c386ad7fd5..b764f3d642ba137919bb7f2a92dce4534b249447 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php
@@ -371,8 +371,11 @@ abstract class AbstractAction
         $rootCatIds = explode('/', $this->getPathFromCategoryId($store->getRootCategoryId()));
         array_pop($rootCatIds);
 
-        $metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
-        $linkField = $metadata->getLinkField();
+        $productMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
+        $categoryMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class);
+        $productLinkField = $productMetadata->getLinkField();
+        $categoryLinkField = $categoryMetadata->getLinkField();
+
         return $this->connection->select()->from(
             ['cc' => $this->getTable('catalog_category_entity')],
             []
@@ -399,35 +402,36 @@ abstract class AbstractAction
             []
         )->joinInner(
             ['cpsd' => $this->getTable('catalog_product_entity_int')],
-            'cpsd.' . $linkField . ' = cpe.' . $linkField . ' AND cpsd.store_id = 0'
+            'cpsd.' . $productLinkField . ' = cpe.' . $productLinkField . ' AND cpsd.store_id = 0'
                 . ' AND cpsd.attribute_id = ' . $statusAttributeId,
             []
         )->joinLeft(
             ['cpss' => $this->getTable('catalog_product_entity_int')],
-            'cpss.' . $linkField . ' = cpe.' . $linkField . ' AND cpss.attribute_id = cpsd.attribute_id' .
+            'cpss.' . $productLinkField . ' = cpe.' . $productLinkField . ' AND cpss.attribute_id = cpsd.attribute_id' .
             ' AND cpss.store_id = ' .
             $store->getId(),
             []
         )->joinInner(
             ['cpvd' => $this->getTable('catalog_product_entity_int')],
-            'cpvd.' . $linkField . ' = cpe. ' . $linkField . ' AND cpvd.store_id = 0' .
+            'cpvd.' . $productLinkField . ' = cpe. ' . $productLinkField . ' AND cpvd.store_id = 0' .
             ' AND cpvd.attribute_id = ' .
             $visibilityAttributeId,
             []
         )->joinLeft(
             ['cpvs' => $this->getTable('catalog_product_entity_int')],
-            'cpvs.' . $linkField . ' = cpe.' . $linkField . ' AND cpvs.attribute_id = cpvd.attribute_id ' .
-            'AND cpvs.store_id = ' .
+            'cpvs.' . $productLinkField . ' = cpe.' . $productLinkField .
+            ' AND cpvs.attribute_id = cpvd.attribute_id ' . 'AND cpvs.store_id = ' .
             $store->getId(),
             []
         )->joinInner(
             ['ccad' => $this->getTable('catalog_category_entity_int')],
-            'ccad.entity_id = cc.entity_id AND ccad.store_id = 0' . ' AND ccad.attribute_id = ' . $isAnchorAttributeId,
+            'ccad.' . $categoryLinkField . ' = cc.' . $categoryLinkField . ' AND ccad.store_id = 0' .
+            ' AND ccad.attribute_id = ' . $isAnchorAttributeId,
             []
         )->joinLeft(
             ['ccas' => $this->getTable('catalog_category_entity_int')],
-            'ccas.entity_id = cc.entity_id AND ccas.attribute_id = ccad.attribute_id' .
-            ' AND ccas.store_id = ' .
+            'ccas.' . $categoryLinkField . ' = cc.' . $categoryLinkField
+            . ' AND ccas.attribute_id = ccad.attribute_id AND ccas.store_id = ' .
             $store->getId(),
             []
         )->where(
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php
index dddca8978fc4d676dc93738298c2f72a791e87a7..b42fc677f718e3fa112be20b85447e6b88795e32 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php
@@ -140,7 +140,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
         $select = $this->getConnection()
             ->select()
             ->from(['attr_table' => $table], [])
-            ->where("attr_table.{$this->getLinkField()} = ?", $object->getId())
+            ->where("attr_table.{$this->getLinkField()} = ?", $object->getData($this->getLinkField()))
             ->where('attr_table.store_id IN (?)', $storeIds);
 
         if ($setId) {
@@ -227,13 +227,14 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
          * for default store id
          * In this case we clear all not default values
          */
+        $entityIdField = $this->getLinkField();
         if ($this->_storeManager->hasSingleStore()) {
             $storeId = $this->getDefaultStoreId();
             $connection->delete(
                 $table,
                 [
                     'attribute_id = ?' => $attribute->getAttributeId(),
-                    $this->getLinkField() . ' = ?' => $object->getId(),
+                    "{$entityIdField} = ?" => $object->getData($entityIdField),
                     'store_id <> ?' => $storeId
                 ]
             );
@@ -243,7 +244,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
             [
                 'attribute_id' => $attribute->getAttributeId(),
                 'store_id' => $storeId,
-                $this->getLinkField() => $object->getData($this->getLinkField()),
+                $entityIdField => $object->getData($entityIdField),
                 'value' => $this->_prepareValueForSave($value, $attribute),
             ]
         );
@@ -296,7 +297,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
                     ->from($table)
                     ->where('attribute_id = ?', $attribute->getAttributeId())
                     ->where('store_id = ?', $this->getDefaultStoreId())
-                    ->where('entity_id = ?', $object->getId());
+                    ->where($this->getLinkField() . ' = ?', $object->getData($this->getLinkField()));
                 $row = $this->getConnection()->fetchOne($select);
 
                 if (!$row) {
@@ -304,7 +305,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
                         [
                             'attribute_id' => $attribute->getAttributeId(),
                             'store_id' => $this->getDefaultStoreId(),
-                            'entity_id' => $object->getId(),
+                            $this->getLinkField() => $object->getData($this->getLinkField()),
                             'value' => $this->_prepareValueForSave($value, $attribute),
                         ]
                     );
@@ -563,7 +564,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
                 ['e' => $this->getTable('catalog_product_entity')],
                 'e.' . $this->getLinkField() . ' = ' . $staticTable . '.' . $this->getLinkField()
             )->where(
-               'e.entity_id = :entity_id'
+                'e.entity_id = :entity_id'
             );
             $attributesData = $connection->fetchRow($select, ['entity_id' => $entityId]);
         }
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
index c7f00697fbf392557eb1c6e4143e847c6929aac9..57492bf78b705c1a7539bdba898eff168a6ad8a1 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
@@ -11,6 +11,9 @@
  */
 namespace Magento\Catalog\Model\ResourceModel;
 
+use Magento\Framework\Model\EntityManager;
+use Magento\Catalog\Api\Data\CategoryInterface;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -66,12 +69,19 @@ class Category extends AbstractResource
     protected $_categoryTreeFactory;
 
     /**
+     * @var EntityManager
+     */
+    protected $entityManager;
+
+    /**
+     * Category constructor.
      * @param \Magento\Eav\Model\Entity\Context $context
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Model\Factory $modelFactory
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param Category\TreeFactory $categoryTreeFactory
      * @param Category\CollectionFactory $categoryCollectionFactory
+     * @param EntityManager $entityManager
      * @param array $data
      */
     public function __construct(
@@ -81,6 +91,7 @@ class Category extends AbstractResource
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Catalog\Model\ResourceModel\Category\TreeFactory $categoryTreeFactory,
         \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
+        EntityManager $entityManager,
         $data = []
     ) {
         parent::__construct(
@@ -92,6 +103,7 @@ class Category extends AbstractResource
         $this->_categoryTreeFactory = $categoryTreeFactory;
         $this->_categoryCollectionFactory = $categoryCollectionFactory;
         $this->_eventManager = $eventManager;
+        $this->entityManager = $entityManager;
 
         $this->connectionName  = 'catalog';
     }
@@ -196,20 +208,16 @@ class Category extends AbstractResource
      */
     public function deleteChildren(\Magento\Framework\DataObject $object)
     {
-        $connection = $this->getConnection();
-        $pathField = $connection->quoteIdentifier('path');
-
-        $select = $connection->select()->from(
-            $this->getEntityTable(),
-            ['entity_id']
-        )->where(
-            $pathField . ' LIKE :c_path'
-        );
-
-        $childrenIds = $connection->fetchCol($select, ['c_path' => $object->getPath() . '/%']);
+        if ($object->getSkipDeleteChildren()) {
+            return $this;
+        }
 
-        if (!empty($childrenIds)) {
-            $connection->delete($this->getEntityTable(), ['entity_id IN (?)' => $childrenIds]);
+        $categories = $this->_categoryCollectionFactory->create();
+        $categories->addAttributeToFilter('path', ['like' => $object->getPath() . '/%']);
+        $childrenIds = $categories->getAllIds();
+        foreach ($categories as $category) {
+            $category->setSkipDeleteChildren(true);
+            $category->delete();
         }
 
         /**
@@ -524,7 +532,7 @@ class Category extends AbstractResource
         $table = $this->getTable([$this->getEntityTablePrefix(), 'int']);
         $connection = $this->getConnection();
         $checkSql = $connection->getCheckSql('c.value_id > 0', 'c.value', 'd.value');
-
+        $linkField = $this->getLinkField();
         $bind = [
             'attribute_id' => $attributeId,
             'store_id' => $storeId,
@@ -536,11 +544,11 @@ class Category extends AbstractResource
             ['COUNT(m.entity_id)']
         )->joinLeft(
             ['d' => $table],
-            'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = m.entity_id',
+            "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = m.{$linkField}",
             []
         )->joinLeft(
             ['c' => $table],
-            "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = m.entity_id",
+            "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = m.{$linkField}",
             []
         )->where(
             'm.path LIKE :c_path'
@@ -576,20 +584,22 @@ class Category extends AbstractResource
      */
     public function findWhereAttributeIs($entityIdsFilter, $attribute, $expectedValue)
     {
+        $linkField = $this->getLinkField();
         $bind = ['attribute_id' => $attribute->getId(), 'value' => $expectedValue];
-        $select = $this->getConnection()->select()->from(
-            $attribute->getBackend()->getTable(),
+        $selectEntities = $this->getConnection()->select()->from(
+            ['ce' => $this->getTable('catalog_category_entity')],
             ['entity_id']
+        )->joinLeft(
+            ['ci' => $attribute->getBackend()->getTable()],
+            "ci.{$linkField} = ce.{$linkField} AND attribute_id = :attribute_id",
+            ['value']
         )->where(
-            'attribute_id = :attribute_id'
-        )->where(
-            'value = :value'
+            'ci.value = :value'
         )->where(
-            'entity_id IN(?)',
+            'ce.entity_id IN (?)',
             $entityIdsFilter
         );
-
-        return $this->getConnection()->fetchCol($select, $bind);
+        return $this->getConnection()->fetchCol($selectEntities, $bind);
     }
 
     /**
@@ -745,10 +755,12 @@ class Category extends AbstractResource
      */
     public function getChildren($category, $recursive = true)
     {
+        $linkField = $this->getLinkField();
         $attributeId = $this->getIsActiveAttributeId();
         $backendTable = $this->getTable([$this->getEntityTablePrefix(), 'int']);
         $connection = $this->getConnection();
         $checkSql = $connection->getCheckSql('c.value_id > 0', 'c.value', 'd.value');
+        $linkField = $this->getLinkField();
         $bind = [
             'attribute_id' => $attributeId,
             'store_id' => $category->getStoreId(),
@@ -760,11 +772,11 @@ class Category extends AbstractResource
             'entity_id'
         )->joinLeft(
             ['d' => $backendTable],
-            'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = m.entity_id',
+            "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = m.{$linkField}",
             []
         )->joinLeft(
             ['c' => $backendTable],
-            'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = m.entity_id',
+            "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = m.{$linkField}",
             []
         )->where(
             $checkSql . ' = :scope'
@@ -979,4 +991,137 @@ class Category extends AbstractResource
         $select->from($this->getEntityTable(), 'COUNT(*)')->where('parent_id != ?', 0);
         return (int)$connection->fetchOne($select);
     }
+
+    /**
+     * Reset firstly loaded attributes
+     *
+     * @param \Magento\Framework\DataObject $object
+     * @param integer $entityId
+     * @param array|null $attributes
+     * @return $this
+     */
+    public function load($object, $entityId, $attributes = [])
+    {
+        $this->_attributes = [];
+        \Magento\Framework\Profiler::start('EAV:load_entity');
+        /**
+         * Load object base row data
+         */
+        $this->entityManager->load(CategoryInterface::class, $object, $entityId);
+
+
+        if (!$this->entityManager->has(\Magento\Catalog\Api\Data\CategoryInterface::class, $entityId)) {
+            $object->isObjectNew(true);
+        }
+
+        $this->loadAttributesMetadata($attributes);
+
+        $this->_loadModelAttributes($object);
+
+        $object->setOrigData();
+
+        $this->_afterLoad($object);
+
+        \Magento\Framework\Profiler::stop('EAV:load_entity');
+        return $this;
+    }
+
+    /**
+     * Save object collected data
+     *
+     * @param   array $saveData array('newObject', 'entityRow', 'insert', 'update', 'delete')
+     * @return $this
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function _processSaveData($saveData)
+    {
+        extract($saveData, EXTR_SKIP);
+        /**
+         * Import variables into the current symbol table from save data array
+         *
+         * @see \Magento\Eav\Model\Entity\AbstractEntity::_collectSaveData()
+         *
+         * @var array $entityRow
+         * @var \Magento\Framework\Model\AbstractModel $newObject
+         * @var array $insert
+         * @var array $update
+         * @var array $delete
+         */
+
+        /**
+         * Process base row
+         */
+        $this->entityManager->save(CategoryInterface::class, $newObject);
+
+        /**
+         * insert attribute values
+         */
+        if (!empty($insert)) {
+            foreach ($insert as $attributeId => $value) {
+                $attribute = $this->getAttribute($attributeId);
+                $this->_insertAttribute($newObject, $attribute, $value);
+            }
+        }
+
+        /**
+         * update attribute values
+         */
+        if (!empty($update)) {
+            foreach ($update as $attributeId => $v) {
+                $attribute = $this->getAttribute($attributeId);
+                $this->_updateAttribute($newObject, $attribute, $v['value_id'], $v['value']);
+            }
+        }
+
+        /**
+         * delete empty attribute values
+         */
+        if (!empty($delete)) {
+            foreach ($delete as $table => $values) {
+                $this->_deleteAttributes($newObject, $table, $values);
+            }
+        }
+
+        $this->_processAttributeValues();
+
+        $newObject->isObjectNew(false);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($object)
+    {
+        try {
+            $this->transactionManager->start($this->getConnection());
+            if (is_numeric($object)) {
+            } elseif ($object instanceof \Magento\Framework\Model\AbstractModel) {
+                $object->beforeDelete();
+            }
+            $this->_beforeDelete($object);
+            $this->entityManager->delete(\Magento\Catalog\Api\Data\CategoryInterface::class, $object);
+
+            $this->_afterDelete($object);
+
+            if ($object instanceof \Magento\Framework\Model\AbstractModel) {
+                $object->isDeleted(true);
+                $object->afterDelete();
+            }
+            $this->transactionManager->commit();
+            if ($object instanceof \Magento\Framework\Model\AbstractModel) {
+                $object->afterDeleteCommit();
+            }
+        } catch (\Exception $e) {
+            $this->transactionManager->rollBack();
+            throw $e;
+        }
+        $this->_eventManager->dispatch(
+            'catalog_category_delete_after_done',
+            ['product' => $object]
+        );
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php
index 0847a8e35e677c5748d1f13cabf640f64f4459fb..9d4cb16f18ceae3149e1f3cf69bd6d4e8595f64a 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Catalog\Model\ResourceModel\Category;
 
+use Magento\Catalog\Api\Data\CategoryInterface;
+use Magento\Framework\Model\Entity\MetadataPool;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -88,15 +91,20 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
     protected $_catalogCategory;
 
     /**
-     * Construct
-     *
+     * @var MetadataPool
+     */
+    protected $metadataPool;
+
+    /**
+     * Tree constructor.
      * @param \Magento\Catalog\Model\ResourceModel\Category $catalogCategory
      * @param \Magento\Framework\App\CacheInterface $cache
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\ResourceConnection $resource
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Catalog\Model\Attribute\Config $attributeConfig
-     * @param \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory
+     * @param Collection\Factory $collectionFactory
+     * @param MetadataPool $metadataPool
      */
     public function __construct(
         \Magento\Catalog\Model\ResourceModel\Category $catalogCategory,
@@ -105,7 +113,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
         \Magento\Framework\App\ResourceConnection $resource,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Catalog\Model\Attribute\Config $attributeConfig,
-        \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory
+        \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory,
+        MetadataPool $metadataPool
     ) {
         $this->_catalogCategory = $catalogCategory;
         $this->_cache = $cache;
@@ -124,6 +133,7 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
         $this->_eventManager = $eventManager;
         $this->_attributeConfig = $attributeConfig;
         $this->_collectionFactory = $collectionFactory;
+        $this->metadataPool = $metadataPool;
     }
 
     /**
@@ -297,31 +307,35 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
      */
     protected function _getInactiveItemIds($collection, $storeId)
     {
-        $filter = $collection->getAllIdsSql();
-        $attributeId = $this->_catalogCategory->getIsActiveAttributeId();
-
-        $conditionSql = $this->_conn->getCheckSql('c.value_id > 0', 'c.value', 'd.value');
-        $table = $this->_coreResource->getTableName('catalog_category_entity_int');
-        $bind = ['attribute_id' => $attributeId, 'store_id' => $storeId, 'zero_store_id' => 0, 'cond' => 0];
-        $select = $this->_conn->select()->from(
-            ['d' => $table],
-            ['d.entity_id']
-        )->where(
-            'd.attribute_id = :attribute_id'
-        )->where(
-            'd.store_id = :zero_store_id'
-        )->where(
-            'd.entity_id IN (?)',
-            new \Zend_Db_Expr($filter)
-        )->joinLeft(
-            ['c' => $table],
-            'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = d.entity_id',
-            []
-        )->where(
-            $conditionSql . ' = :cond'
-        );
+        $linkField = $this->metadataPool->getMetadata(CategoryInterface::class)->getLinkField();
+        $intTable = $this->_coreResource->getTableName('catalog_category_entity_int');
+
+        $select = $collection->getAllIdsSql()
+            ->joinInner(
+                ['d' => $intTable],
+                "e.{$linkField} = d.{$linkField}",
+                []
+            )->joinLeft(
+                ['c' => $intTable],
+                "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = d.{$linkField}",
+                []
+            )->where(
+                'd.attribute_id = :attribute_id'
+            )->where(
+                'd.store_id = :zero_store_id'
+            )->where(
+                $this->_conn->getCheckSql('c.value_id > 0', 'c.value', 'd.value') . ' = :cond'
+            );
 
-        return $this->_conn->fetchCol($select, $bind);
+        return $this->_conn->fetchCol(
+            $select,
+            [
+                'attribute_id' => $this->_catalogCategory->getIsActiveAttributeId(),
+                'store_id' => $storeId,
+                'zero_store_id' => 0,
+                'cond' => 0
+            ]
+        );
     }
 
     /**
@@ -567,6 +581,9 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
      */
     protected function _createCollectionDataSelect($sorted = true, $optionalAttributes = [])
     {
+        $meta = $this->metadataPool->getMetadata(CategoryInterface::class);
+        $linkField = $meta->getLinkField();
+
         $select = $this->_getDefaultCollection($sorted ? $this->_orderField : false)->getSelect();
         // add attributes to select
         $attributes = ['name', 'is_active', 'is_anchor'];
@@ -590,7 +607,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
                 $select->joinLeft(
                     [$tableDefault => $attribute->getBackend()->getTable()],
                     sprintf(
-                        '%1$s.entity_id=e.entity_id AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d',
+                        '%1$s.' . $linkField . '=e.' . $linkField .
+                        ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d',
                         $tableDefault,
                         $attribute->getId(),
                         \Magento\Store\Model\Store::DEFAULT_STORE_ID
@@ -599,7 +617,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp
                 )->joinLeft(
                     [$tableStore => $attribute->getBackend()->getTable()],
                     sprintf(
-                        '%1$s.entity_id=e.entity_id AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d',
+                        '%1$s.' . $linkField . '=e.' . $linkField .
+                        ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d',
                         $tableStore,
                         $attribute->getId(),
                         $this->getStoreId()
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
index 01abfa03a6ab5cb9344ff6bc1f2ba5d0a4b36d41..8dcba6547cd14f61e1ff91b605070824f5084244 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
@@ -71,6 +71,17 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo
         );
     }
 
+    /**
+     * Retrieve Entity Primary Key
+     *
+     * @param \Magento\Eav\Model\Entity\AbstractEntity $entity
+     * @return string
+     */
+    protected function getEntityPkName(\Magento\Eav\Model\Entity\AbstractEntity $entity)
+    {
+        return $entity->getLinkField();
+    }
+
     /**
      * Set store scope
      *
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
index fc6db7a099b7d824d01e532b7e7abc3dbd199113..9f6f6dbf73712655a9f321a58f95be4e837b8b2c 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
@@ -13,6 +13,8 @@ use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
 use Magento\Customer\Api\GroupManagementInterface;
 use Magento\Framework\DB\Select;
 use Magento\Store\Model\Store;
+use Magento\Framework\Model\Entity\MetadataPool;
+use Magento\Catalog\Api\Data\CategoryInterface;
 
 /**
  * Product collection
@@ -1999,7 +2001,10 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
 
         $conditions = [
             'cat_pro.product_id=e.entity_id',
-            $this->getConnection()->quoteInto('cat_pro.category_id=?', $filters['category_id']),
+            $this->getConnection()->quoteInto(
+                'cat_pro.category_id=?',
+                $filters['category_id']
+            ),
         ];
         $joinCond = join(' AND ', $conditions);
 
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
index 21389703ce94bfe22a4f4627477da3c300702a1e..ed40914f76a67652e7f099c35123779f4fc29b4e 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
@@ -50,6 +50,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
     protected $_catalogProductCompareItem;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Url.php b/app/code/Magento/Catalog/Model/ResourceModel/Url.php
index 157edc0b176c0a9fd3d8bf233cda4d10b4aaa903..bff384d42defb4c0bfbec3047db67462f1b0db33 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Url.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Url.php
@@ -11,7 +11,15 @@ namespace Magento\Catalog\Model\ResourceModel;
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Catalog\Api\Data\CategoryInterface;
+use Magento\Framework\Model\Entity\MetadataPool;
 
+/**
+ * Class Url
+ * @package Magento\Catalog\Model\ResourceModel
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
 {
     /**
@@ -88,13 +96,20 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     protected $productResource;
 
     /**
+     * @var MetadataPool
+     */
+    protected $metadataPool;
+
+    /**
+     * Url constructor.
      * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param Product $productResource
      * @param \Magento\Catalog\Model\Category $catalogCategory
      * @param \Psr\Log\LoggerInterface $logger
-     * @param string $connectionName
+     * @param MetadataPool $metadataPool
+     * @param null $connectionName
      */
     public function __construct(
         \Magento\Framework\Model\ResourceModel\Db\Context $context,
@@ -103,6 +118,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         Product $productResource,
         \Magento\Catalog\Model\Category $catalogCategory,
         \Psr\Log\LoggerInterface $logger,
+        MetadataPool $metadataPool,
         $connectionName = null
     ) {
         $this->_storeManager = $storeManager;
@@ -110,6 +126,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         $this->productResource = $productResource;
         $this->_catalogCategory = $catalogCategory;
         $this->_logger = $logger;
+        $this->metadataPool = $metadataPool;
         parent::__construct($context, $connectionName);
     }
 
@@ -150,6 +167,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     protected function _getCategoryAttribute($attributeCode, $categoryIds, $storeId)
     {
+        $linkField = $this->metadataPool->getMetadata(CategoryInterface::class)->getLinkField();
+        $identifierFiled = $this->metadataPool->getMetadata(CategoryInterface::class)->getIdentifierField();
+
         $connection = $this->getConnection();
         if (!isset($this->_categoryAttributes[$attributeCode])) {
             $attribute = $this->_catalogCategory->getResource()->getAttribute($attributeCode);
@@ -181,26 +201,35 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
             );
         } elseif ($this->_categoryAttributes[$attributeCode]['is_global'] || $storeId == 0) {
             $select->from(
-                $attributeTable,
-                ['entity_id', 'value']
+                ['t1' =>$this->getTable('catalog_category_entity')],
+                [$identifierFiled]
+            )->joinLeft(
+                ['e' => $attributeTable],
+                "t1.{$linkField} = e.{$linkField}",
+                ['value']
             )->where(
-                'attribute_id = :attribute_id'
+                "t1.{$identifierFiled} IN(?)",
+                $categoryIds
             )->where(
-                'store_id = ?',
-                0
+                'e.attribute_id = :attribute_id'
             )->where(
-                'entity_id IN(?)',
-                $categoryIds
+                'e.store_id = ?',
+                0
             );
+
             $bind['attribute_id'] = $this->_categoryAttributes[$attributeCode]['attribute_id'];
         } else {
             $valueExpr = $connection->getCheckSql('t2.value_id > 0', 't2.value', 't1.value');
             $select->from(
                 ['t1' => $attributeTable],
-                ['entity_id', 'value' => $valueExpr]
+                [$identifierFiled => 'e.'.$identifierFiled, 'value' => $valueExpr]
             )->joinLeft(
                 ['t2' => $attributeTable],
-                't1.entity_id = t2.entity_id AND t1.attribute_id = t2.attribute_id AND t2.store_id = :store_id',
+                "t1.{$linkField} = t2.{$linkField} AND t1.attribute_id = t2.attribute_id AND t2.store_id = :store_id",
+                []
+            )->joinLeft(
+                ['e' => $this->getTable('catalog_category_entity')],
+                "e.{$linkField} = t1.{$linkField}",
                 []
             )->where(
                 't1.store_id = ?',
@@ -208,9 +237,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
             )->where(
                 't1.attribute_id = :attribute_id'
             )->where(
-                't1.entity_id IN(?)',
+                "e.entity_id IN(?)",
                 $categoryIds
-            );
+            )->group('e.entity_id');
 
             $bind['attribute_id'] = $this->_categoryAttributes[$attributeCode]['attribute_id'];
             $bind['store_id'] = $storeId;
@@ -220,7 +249,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
 
         $attributes = [];
         foreach ($rowSet as $row) {
-            $attributes[$row['entity_id']] = $row['value'];
+            $attributes[$row[$identifierFiled]] = $row['value'];
         }
         unset($rowSet);
         foreach ($categoryIds as $categoryId) {
@@ -374,6 +403,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         $categories = [];
         $connection = $this->getConnection();
 
+        $meta = $this->metadataPool->getMetadata(CategoryInterface::class);
+        $linkField = $meta->getLinkField();
+
         if (!is_array($categoryIds)) {
             $categoryIds = [$categoryIds];
         }
@@ -403,11 +435,11 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         $table = $this->getTable('catalog_category_entity_int');
         $select->joinLeft(
             ['d' => $table],
-            'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = main_table.entity_id',
+            "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = main_table.{$linkField}",
             []
         )->joinLeft(
             ['c' => $table],
-            'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = main_table.entity_id',
+            "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = main_table.{$linkField}",
             []
         );
 
diff --git a/app/code/Magento/Catalog/Setup/InstallSchema.php b/app/code/Magento/Catalog/Setup/InstallSchema.php
index 69761bbe12c984d98e2b62b685df81fcace59df0..ba07738dd423a89c97472fcc7cda9d10f36878f9 100644
--- a/app/code/Magento/Catalog/Setup/InstallSchema.php
+++ b/app/code/Magento/Catalog/Setup/InstallSchema.php
@@ -1233,18 +1233,6 @@ class InstallSchema implements InstallSchemaInterface
                 $installer->getIdxName('catalog_category_product', ['product_id']),
                 ['product_id']
             )
-            ->addForeignKey(
-                $installer->getFkName(
-                    'catalog_category_product',
-                    'category_id',
-                    'catalog_category_entity',
-                    'entity_id'
-                ),
-                'category_id',
-                $installer->getTable('catalog_category_entity'),
-                'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-            )
             ->addForeignKey(
                 $installer->getFkName('catalog_category_product', 'product_id', 'catalog_product_entity', 'entity_id'),
                 'product_id',
diff --git a/app/code/Magento/Catalog/Setup/Recurring.php b/app/code/Magento/Catalog/Setup/Recurring.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5a3f6972b4192583b4c09a8f42bfbe244dc0fb4
--- /dev/null
+++ b/app/code/Magento/Catalog/Setup/Recurring.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Setup;
+
+use Magento\Catalog\Api\Data\CategoryInterface;
+use Magento\Framework\Model\Entity\MetadataPool;
+use Magento\Framework\Setup\ExternalFKSetup;
+use Magento\Framework\Setup\InstallSchemaInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\SchemaSetupInterface;
+
+/**
+ * Catalog recurring setup
+ */
+class Recurring implements InstallSchemaInterface
+{
+    /**
+     * @var MetadataPool
+     */
+    protected $metadataPool;
+
+    /**
+     * @var ExternalFKSetup
+     */
+    protected $externalFKSetup;
+
+    /**
+     * @param MetadataPool $metadataPool
+     * @param ExternalFKSetup $externalFKSetup
+     */
+    public function __construct(
+        MetadataPool $metadataPool,
+        ExternalFKSetup $externalFKSetup
+    ) {
+        $this->metadataPool = $metadataPool;
+        $this->externalFKSetup = $externalFKSetup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $installer = $setup;
+        $installer->startSetup();
+
+        $metadata = $this->metadataPool->getMetadata(CategoryInterface::class);
+        $this->externalFKSetup->install(
+            $installer,
+            $metadata->getEntityTable(),
+            $metadata->getIdentifierField(),
+            'catalog_category_product',
+            'category_id'
+        );
+
+        $installer->endSetup();
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php
index de82e728cc6c7e5bb2500640c15116b457984969..6073db335fe533c8a442ba7ec9d4debe98cb4b34 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php
@@ -8,6 +8,10 @@
 
 namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Category;
 
+use Magento\Catalog\Api\Data\CategoryInterface;
+use Magento\Framework\Model\Entity\EntityMetadata;
+use Magento\Framework\Model\Entity\MetadataPool;
+
 class TreeTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -30,6 +34,14 @@ class TreeTest extends \PHPUnit_Framework_TestCase
      */
     protected $_collectionFactory;
 
+    /**
+     * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataPoolMock;
+
+    /**
+     * {@inheritdoc}
+     */
     protected function setUp()
     {
         $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -71,13 +83,19 @@ class TreeTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+
+        $this->metadataPoolMock = $this->getMockBuilder(MetadataPool::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->_model = $objectHelper->getObject(
             'Magento\Catalog\Model\ResourceModel\Category\Tree',
             [
                 'resource' => $this->_resource,
                 'eventManager' => $eventManager,
                 'attributeConfig' => $this->_attributeConfig,
-                'collectionFactory' => $this->_collectionFactory
+                'collectionFactory' => $this->_collectionFactory,
+                'metadataPool' => $this->metadataPoolMock,
             ]
         );
     }
@@ -134,6 +152,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase
         $select = $this->getMock('Magento\Framework\DB\Select', [], [], '', false);
         $select->expects($this->any())->method('from')->will($this->returnSelf());
         $select->expects($this->any())->method('join')->will($this->returnSelf());
+        $select->expects($this->any())->method('joinInner')->will($this->returnSelf());
         $select->expects($this->any())->method('joinLeft')->will($this->returnSelf());
         $select->expects($this->any())->method('where')->will($this->returnSelf());
 
@@ -167,6 +186,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase
 
         $collection = $this->getMock('Magento\Catalog\Model\ResourceModel\Category\Collection', [], [], '', false);
         $collection->expects($this->never())->method('getAllIds')->will($this->returnValue([]));
+        $collection->expects($this->once())->method('getAllIdsSql')->will($this->returnValue($select));
         $collectionFactory = $this->getMock(
             'Magento\Catalog\Model\ResourceModel\Category\Collection\Factory',
             [],
@@ -182,6 +202,18 @@ class TreeTest extends \PHPUnit_Framework_TestCase
         $storeManager = $this->getMockForAbstractClass('Magento\Store\Model\StoreManagerInterface');
         $storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
 
+        $categoryMetadataMock = $this->getMockBuilder(EntityMetadata::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $categoryMetadataMock->expects($this->any())
+            ->method('getLinkField')
+            ->willReturn('id');
+        $this->metadataPoolMock
+            ->expects($this->any())
+            ->method('getMetadata')
+            ->with(CategoryInterface::class)
+            ->willReturn($categoryMetadataMock);
+
         $model = $objectHelper->getObject(
             'Magento\Catalog\Model\ResourceModel\Category\Tree',
             [
@@ -189,7 +221,8 @@ class TreeTest extends \PHPUnit_Framework_TestCase
                 'resource' => $resource,
                 'eventManager' => $eventManager,
                 'attributeConfig' => $attributeConfig,
-                'collectionFactory' => $collectionFactory
+                'collectionFactory' => $collectionFactory,
+                'metadataPool' => $this->metadataPoolMock
             ]
         );
 
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 7e4742bd14d1eee1955cae44163a26e443271fcd..c3fb3dc30cd779087705e166b6f6a3df153cee32 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -561,6 +561,14 @@
                         <item name="store_id" xsi:type="string">store_id</item>
                     </item>
                 </item>
+                <item name="Magento\Catalog\Api\Data\CategoryInterface" xsi:type="array">
+                    <item name="entityTableName" xsi:type="string">catalog_category_entity</item>
+                    <item name="eavEntityType" xsi:type="string">catalog_category</item>
+                    <item name="identifierField" xsi:type="string">entity_id</item>
+                    <item name="entityContext" xsi:type="array">
+                        <item name="store_id" xsi:type="string">store_id</item>
+                    </item>
+                </item>
             </argument>
         </arguments>
     </type>
@@ -584,4 +592,12 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction">
+        <arguments>
+            <argument name="skipStaticColumns" xsi:type="array">
+                <item name="entity_type_id" xsi:type="string">entity_type_id</item>
+                <item name="attribute_set_id" xsi:type="string">attribute_set_id</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
index 6220d75179e7ed252f5b2f32e3c1693b0f279b6d..38c87413b2b410f375a4c58156e4fbe143f27b35 100644
--- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
+++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php
@@ -34,6 +34,7 @@ class DataProvider
     protected $categoryFactory;
 
     /**
+     * DataProvider constructor.
      * @param ResourceConnection $resource
      * @param ScopeResolverInterface $scopeResolver
      * @param Resolver $layerResolver
diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php
index 1a43b5b7e2ad703bbf1169df697dd092a42a5a2d..37bc592d595fb11633411ff0a5aa1e81e290425e 100644
--- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php
@@ -38,6 +38,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
     private $temporaryStorageFactory;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
index 5338eaddbd12d20af3b93c5e0c57aa85c4dd0db1..5b11136822a8000e75f44ea4d4c4662e2b465f9c 100644
--- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
@@ -7,9 +7,7 @@ namespace Magento\CatalogSearch\Model\ResourceModel\Fulltext;
 
 use Magento\Framework\DB\Select;
 use Magento\Framework\Exception\StateException;
-use Magento\Framework\Search\Adapter\Mysql\Adapter;
 use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage;
-use Magento\Framework\Search\Response\Aggregation\Value;
 use Magento\Framework\Search\Response\QueryResponse;
 
 /**
@@ -38,13 +36,19 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
      */
     private $searchEngine;
 
-    /** @var string */
+    /**
+     * @var string
+     */
     private $queryText;
 
-    /** @var string|null */
+    /**
+     * @var string|null
+     */
     private $order = null;
 
-    /** @var string */
+    /**
+     * @var string
+     */
     private $searchRequestName;
 
     /**
diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
index 82d1b2623550529931f7210cd136aea49ac03ec9..80c85edcce765a88ee7ed8df50ef45fbc74096b6 100644
--- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
@@ -37,6 +37,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
     protected $_attributeCollectionFactory;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
index 19a96e41cf3cd1ce41b36d7f38a1dfd2b79931fd..ecd1d8f822cd3c2f91f9ccea2d829feeb3817d2b 100644
--- a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
+++ b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
@@ -59,13 +59,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
-            ->addForeignKey(
-                $installer->getFkName($tableName, 'category_id', 'catalog_category_entity', 'entity_id'),
-                'category_id',
-                $installer->getTable('catalog_category_entity'),
-                'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-            )
             ->addForeignKey(
                 $installer->getFkName($tableName, 'url_rewrite_id', 'url_rewrite', 'url_rewrite_id'),
                 'url_rewrite_id',
@@ -77,6 +70,5 @@ class InstallSchema implements InstallSchemaInterface
         $installer->getConnection()->createTable($table);
 
         $installer->endSetup();
-
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php b/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php
new file mode 100644
index 0000000000000000000000000000000000000000..1fc00f70d08b60a0674890557e53cbe7d43e9c57
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Setup;
+
+use Magento\Catalog\Api\Data\CategoryInterface;
+use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product as ResourceProduct;
+use Magento\Framework\Model\Entity\MetadataPool;
+use Magento\Framework\Setup\ExternalFKSetup;
+use Magento\Framework\Setup\InstallSchemaInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\SchemaSetupInterface;
+
+/**
+ * CatalogUrlRewrite recurring setup
+ */
+class Recurring implements InstallSchemaInterface
+{
+    /**
+     * @var MetadataPool
+     */
+    protected $metadataPool;
+
+    /**
+     * @var ExternalFKSetup
+     */
+    protected $externalFKSetup;
+
+    /**
+     * @param MetadataPool $metadataPool
+     * @param ExternalFKSetup $externalFKSetup
+     */
+    public function __construct(
+        MetadataPool $metadataPool,
+        ExternalFKSetup $externalFKSetup
+    ) {
+        $this->metadataPool = $metadataPool;
+        $this->externalFKSetup = $externalFKSetup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $installer = $setup;
+        $installer->startSetup();
+
+        $metadata = $this->metadataPool->getMetadata(CategoryInterface::class);
+        $this->externalFKSetup->install(
+            $installer,
+            $metadata->getEntityTable(),
+            $metadata->getIdentifierField(),
+            ResourceProduct::TABLE_NAME,
+            'category_id'
+        );
+
+        $installer->endSetup();
+    }
+}
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index 53b4ec285dd28202a083c1487c27c8e577f0beb2..ff50734d1b8348fbf7636e7274a9518a1477918f 100644
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -1709,7 +1709,7 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
     {
         $data = [
             'attribute_id' => $attribute->getId(),
-            $this->getLinkField() => $object->getData($this->getLinkField()),
+            $entity->getLinkField() => $object->getData($entity->getLinkField()),
         ];
 
         if (!$this->getEntityTable()) {
diff --git a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
index c2f390e90e5d6e5330ca2f3db99bb80074da12a7..a608dc3809e2f77360430f31dca8869eed8022df 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php
@@ -133,7 +133,7 @@ class UpdateHandler
                 }
                 if ((!array_key_exists($attribute->getAttributeCode(), $snapshot)
                     || $snapshot[$attribute->getAttributeCode()] === false)
-                    && array_key_exists($attribute->getAttributeCode(), $data)
+                    && !empty($data[$attribute->getAttributeCode()])
                     && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()])
                 ) {
                     $this->attributePersistor->registerInsert(
@@ -146,7 +146,7 @@ class UpdateHandler
                 }
                 if (array_key_exists($attribute->getAttributeCode(), $snapshot)
                     && $snapshot[$attribute->getAttributeCode()] !== false
-                    && array_key_exists($attribute->getAttributeCode(), $data)
+                    && !empty($data[$attribute->getAttributeCode()])
                     && $snapshot[$attribute->getAttributeCode()] != $data[$attribute->getAttributeCode()]
                     && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()])
                 ) {
diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php
index 65ecfee83f4f36e6c0216871b8c91d588ab4c17b..db2598df93ba2c50381ccb2fbfde621475b73e76 100644
--- a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php
+++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php
@@ -62,6 +62,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
     protected $quoteResource;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php
index 87100f307850e71235f35f7121397ebb0a866ffd..3344cca8eddef29015101596eac107e426427d98 100644
--- a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php
+++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php
@@ -29,6 +29,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\ResourceModel\P
     protected $_customerVisitor;
 
     /**
+     * AbstractCollection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php
index 171a909702ef7cdd7416fab8e440584075a6c123..51199806dde789353c4b2d771455d200b10663d8 100644
--- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php
+++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php
@@ -46,6 +46,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection
     protected $_itemResource;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
@@ -72,7 +73,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection
      * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
      * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
      * @param \Magento\CatalogInventory\Model\ResourceModel\Stock\Item $itemResource
-     * @param mixed $connection
+     * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php
index d7d8aebfdf0c4cc897058d51eb84067878e99c75..a202444afac72a49b0495a9fc5843eb39d17507e 100644
--- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php
+++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php
@@ -59,6 +59,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
     protected $_voteFactory;
 
     /**
+     * Collection constructor.
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
diff --git a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php
index 75e853c13c6024ec0969a2a163d00fce5eafde9d..dc71b469f39a04063d10cbd219251cc9a6ae217c 100644
--- a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php
+++ b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php
@@ -38,21 +38,29 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     protected $_categoryResource;
 
+    /**
+     * @var \Magento\Framework\Model\Entity\MetadataPool
+     */
+    protected $metadataPool;
+
     /**
      * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Model\ResourceModel\Category $categoryResource
+     * @param \Magento\Framework\Model\Entity\MetadataPool $metadataPool
      * @param string $connectionName
      */
     public function __construct(
         \Magento\Framework\Model\ResourceModel\Db\Context $context,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Catalog\Model\ResourceModel\Category $categoryResource,
+        \Magento\Framework\Model\Entity\MetadataPool $metadataPool,
         $connectionName = null
     ) {
         $this->_storeManager = $storeManager;
         $this->_categoryResource = $categoryResource;
         parent::__construct($context, $connectionName);
+        $this->metadataPool = $metadataPool;
     }
 
     /**
@@ -147,6 +155,9 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     protected function _addFilter($storeId, $attributeCode, $value, $type = '=')
     {
+        $meta = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class);
+        $linkField = $meta->getLinkField();
+
         if (!$this->_select instanceof \Magento\Framework\DB\Select) {
             return false;
         }
@@ -181,7 +192,8 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         } else {
             $this->_select->join(
                 ['t1_' . $attributeCode => $attribute['table']],
-                'e.entity_id = t1_' . $attributeCode . '.entity_id AND t1_' . $attributeCode . '.store_id = 0',
+                'e.' . $linkField . ' = t1_' . $attributeCode . '.' . $linkField .
+                ' AND t1_' . $attributeCode . '.store_id = 0',
                 []
             )->where(
                 't1_' . $attributeCode . '.attribute_id=?',
@@ -201,9 +213,9 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
                     $this->getConnection()->quoteInto(
                         't1_' .
                         $attributeCode .
-                        '.entity_id = t2_' .
+                        '.' . $linkField . ' = t2_' .
                         $attributeCode .
-                        '.entity_id AND t1_' .
+                        '.' . $linkField . ' AND t1_' .
                         $attributeCode .
                         '.attribute_id = t2_' .
                         $attributeCode .
diff --git a/composer.lock b/composer.lock
index 5a1312bc6f83baaba2ecc0aebea91dd2a07223e3..d7525677fdd8f1118add45701b401ebbc9dcc361 100644
--- a/composer.lock
+++ b/composer.lock
@@ -277,7 +277,7 @@
                 "type": "zip",
                 "url": "https://api.github.com/repos/magento/composer/zipball/1be267e71debac6e0d9fae4e5144f6095cffbe89",
                 "reference": null,
-                "shasum": "79156c3e7317af1ff64a482ba90ec81c66b82c73"
+                "shasum": "6bfdbff4c23aace1e6d14ab598c81c790375aba0"
             },
             "require": {
                 "composer/composer": "1.0.0-alpha10",
@@ -381,12 +381,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/magento/zf1.git",
-                "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f"
+                "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/magento/zf1/zipball/c9d607bfd9454bc18b9deff737ccd5d044e2ab10",
-                "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f",
+                "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10",
                 "shasum": ""
             },
             "require": {
@@ -420,7 +420,7 @@
                 "ZF1",
                 "framework"
             ],
-            "time": "2015-09-30 13:04:03"
+            "time": "2015-10-29 14:34:55"
         },
         {
             "name": "monolog/monolog",
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php
index d34428003efc501bfa3b952acb78e3e59f620b71..2a82b359c5a8b923d5a621014fac5d91143dac1e 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php
@@ -7,6 +7,8 @@ namespace Magento\Catalog\Block\Adminhtml\Category\Checkboxes;
 
 /**
  * @magentoAppArea adminhtml
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class TreeTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
index eb685c327577e3515c22a6f16d8d925b0de8d637..4a3c8d48a4f71ddf494343bd434eeb983b099c29 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
@@ -152,7 +152,7 @@ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractBackendContro
                     'id' => '2',
                     'path' => '1/2',
                     'url_key' => 'default-category',
-                    'is_anchor' => '0',
+                    'is_anchor' => 'false',
                     'use_default' => [
                         'name' => 1,
                         'is_active' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
index 7255a16fb29b64e0b45da60964787a8ddaa822d1..c425072dc6bf8034c5ec13284883471ac860fa9f 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
@@ -5,6 +5,13 @@
  */
 namespace Magento\Catalog\Helper;
 
+/**
+ * Class CategoryTest
+ * @package Magento\Catalog\Helper
+ *
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
+ */
 class CategoryTest extends \PHPUnit_Framework_TestCase
 {
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
index 4cba91301d9169f6960e67df239d08beeea24837..c41c5ad2d2520f12f21b64388c673c8dd74bb29f 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
@@ -83,6 +83,8 @@ class DataTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @magentoDataFixture Magento/Catalog/_files/categories.php
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
      */
     public function testGetBreadcrumbPath()
     {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
index 6a1cb185479a8951978233509f55ca9b3c2b19c7..762b7d17ff45a64fe88b59f8c0283933cb6f65bc 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
@@ -191,6 +191,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @magentoDataFixture Magento/Catalog/_files/categories.php
+     * @magentoDbIsolation enabled
      * @magentoAppIsolation enabled
      */
     public function testInitProduct()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
index f47f8af6ff8d217aa40e2b44c4ec710615686cc6..9097bd400b368f5d0b0948b2121fbf99102f427b 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
@@ -11,6 +11,7 @@ namespace Magento\Catalog\Model;
  *
  * @see \Magento\Catalog\Model\CategoryTreeTest
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
  * @magentoAppIsolation enabled
  */
 class CategoryTest extends \PHPUnit_Framework_TestCase
@@ -274,6 +275,30 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('5', $category->getPosition());
     }
 
+    /**
+     * @magentoAppArea adminhtml
+     */
+    public function testDeleteChildren()
+    {
+        $this->_model->unsetData();
+        $this->_model->load(4);
+        $this->_model->setSkipDeleteChildren(true);
+        $this->_model->delete();
+
+        $this->_model->unsetData();
+        $this->_model->load(5);
+        $this->assertEquals($this->_model->getId(), 5);
+
+        $this->_model->unsetData();
+        $this->_model->load(3);
+        $this->assertEquals($this->_model->getId(), 3);
+        $this->_model->delete();
+
+        $this->_model->unsetData();
+        $this->_model->load(5);
+        $this->assertEquals($this->_model->getId(), null);
+    }
+
     protected function getCategoryByName($categoryName)
     {
         /* @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
index 3b12d91a0fd298122f1de25f8c4453cdd7516cf6..46a36dbf0a0230214c77a0daadb096387390a985 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
@@ -11,6 +11,8 @@ namespace Magento\Catalog\Model;
  *
  * @see \Magento\Catalog\Model\CategoryTest
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
  */
 class CategoryTreeTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php
index 6df6b1f6753204ad2ca09516d202832fcc0c167f..edc07a3d7ccf609727592183394e3b87e48576a7 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php
@@ -109,7 +109,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             2
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource());
 
         $result = $category->getAllChildren(true);
         $this->assertNotEmpty($result);
@@ -174,7 +174,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             2
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource());
 
         $result = $category->getAllChildren(true);
         $this->assertNotEmpty($result);
@@ -188,7 +188,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             self::$categoryOne
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $categoryOne->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $categoryOne->getResource());
 
         $result = $categoryOne->getAllChildren(true);
         $this->assertNotEmpty($result);
@@ -198,12 +198,12 @@ class FlatTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Catalog\Model\Category $categoryTwo */
         $categoryTwo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Category'
+            \Magento\Catalog\Model\Category::class
         )->load(
             self::$categoryTwo
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $categoryTwo->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $categoryTwo->getResource());
 
         $this->assertEquals(self::$categoryOne, $categoryTwo->getParentId());
         $this->checkCategoryData($categoryTwo);
@@ -264,7 +264,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             2
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource());
 
         $this->checkCategoryData($category);
 
@@ -332,7 +332,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             2
         );
 
-        $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource());
+        $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource());
 
         $result = $category->getAllChildren(true);
         $this->assertNotEmpty($result);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php
index 940a4af8a59ae123847788603d1a437304d87e8b..e253f7e4b3a23768bf1ec9ee946faeb8325aa479 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php
@@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer;
  * Test class for \Magento\Catalog\Model\Layer.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
  */
 class CategoryTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php
index 704e08df7e588f5cc7bbf3ce7e70e5266d7b46cc..2a2f4c6c1da25765fc81ed1a93e511589b575da9 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php
@@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer\Filter;
  * Test class for \Magento\Catalog\Model\Layer\Filter\Category.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
  */
 class CategoryTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
index dc3ef94d5dbc87483401ce1df0dedfda73208c5b..59bccfb1d2bb02c22e3c6519867d639a364db1a6 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
@@ -10,6 +10,8 @@ namespace Magento\Catalog\Model\Layer\Filter\DataProvider;
  * Test class for \Magento\Catalog\Model\Layer\Filter\DataProvider\Price.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
  */
 class PriceTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php
index 08aa17f97530c3fe8ab06610be8a5ebc3635b159..10c3252f6643e4c236d982c1c48faa7fd2f185fb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php
@@ -10,6 +10,8 @@ namespace Magento\Catalog\Model\Layer\Filter;
  *
  * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_weight_filterable.php
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class DecimalTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
index a4ad1e6c5f84a23d436a40fb61eedd47644e7bd4..2fff101b743b59d5663e0d32f6172e6a58e55787 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
@@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer\Filter;
  * Test class for \Magento\Catalog\Model\Layer\Filter\Price.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class PriceTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
index db598982a1b40605e6433896089d0a5fbd44865a..c87b553e18f8b4772ef7a5d562161cafa2508d21 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
@@ -12,6 +12,8 @@ namespace Magento\Catalog\Model;
  * @see \Magento\Catalog\Model\ProductTest
  * @see \Magento\Catalog\Model\ProductPriceTest
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
  */
 class ProductExternalTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php
index 561f099ad9e0a4e95c365c347dcf94a1feb369e1..0359a76e286cc4dd3f8ecd0ddfe3609613ba548d 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php
@@ -14,6 +14,8 @@ use Magento\Framework\App\Filesystem\DirectoryList;
  * @see \Magento\Catalog\Model\ProductExternalTest
  * @see \Magento\Catalog\Model\ProductPriceTest
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class ProductGettersTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
index a7aba33c83e008ab021f15a955b8a70a4f6da34f..e3e6c2588736c9c073def5dd495c80f4cbc9658b 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -14,6 +14,8 @@ use Magento\Framework\App\Filesystem\DirectoryList;
  * @see \Magento\Catalog\Model\ProductExternalTest
  * @see \Magento\Catalog\Model\ProductPriceTest
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class ProductTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php
index 115978c8439f6b7863e0aa598655f719af8e74ee..e114f71d09d0c1657799cbba5e1eb1e7a0b88508 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php
@@ -28,10 +28,10 @@ foreach ($productsToDelete as $sku) {
 //Remove categories
 /** @var Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
 $collection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Category\Collection');
-$collection
-    ->addAttributeToFilter('level', 2)
-    ->load()
-    ->delete();
+foreach ($collection->addAttributeToFilter('level', ['in' => [2, 3, 4]]) as $category) {
+    /** @var \Magento\Catalog\Model\Category $category */
+    $category->delete();
+}
 
 $registry->unregister('isSecureArea');
 $registry->register('isSecureArea', false);
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 c1c6686f1574f3cb6fef7fed2dc1a89c5c0f2b6a..266f4e038570e4834cc5a3e28cc37b9dc4b3c300 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -764,6 +764,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
      * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php
      * @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
+     * @magentoDbIsolation enabled
      * @magentoAppIsolation enabled
      */
     public function testProductsWithMultipleStores()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php
index 322c802e6281b0ae9250ea62089fddff5bb1309a..52931492226fd0accba927552a97474c3d1adfe1 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php
@@ -11,7 +11,7 @@ namespace Magento\CatalogSearch\Model\Layer\Filter;
 /**
  * Test class for \Magento\CatalogSearch\Model\Layer\Filter\Category.
  *
- * @magentoDbIsolation disabled
+ * @magentoDbIsolation enabled
  * @magentoAppIsolation enabled
  * @magentoDataFixture Magento/Catalog/_files/categories.php
  */
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php
index 1f8ba6aef0710512f3303700b73ed83938dc4a4f..3b2356fc756c9c9a538f2472e3238d50a12eabff 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php
@@ -11,6 +11,8 @@ namespace Magento\CatalogSearch\Model\Layer\Filter;
  * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_weight_filterable.php
  * @magentoDataFixture Magento/Catalog/_files/categories.php
  * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/Price/_files/products_base.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class DecimalTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
index 003b558aa42adbc47e6716eafc4db7e20d9d1ca9..ce292c06f02e169e62d80dfa0e51eeb0f85ad01a 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
@@ -9,6 +9,8 @@ namespace Magento\CatalogSearch\Model\Layer\Filter;
  * Test class for \Magento\CatalogSearch\Model\Layer\Filter\Price.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
  */
 class PriceTest extends \PHPUnit_Framework_TestCase
 {
diff --git a/lib/internal/Magento/Framework/Model/EntityManager.php b/lib/internal/Magento/Framework/Model/EntityManager.php
index 140fbd041cde13920b00c42500fd2f8d90f52afb..82d3fa02873a7da9e73db7256211668d81cd3fe4 100644
--- a/lib/internal/Magento/Framework/Model/EntityManager.php
+++ b/lib/internal/Magento/Framework/Model/EntityManager.php
@@ -70,6 +70,19 @@ class EntityManager
         return $operation->execute($entityType, $entity);
     }
 
+    /**
+     * Is entity exists in Entity Manager
+     *
+     * @param string $entityType
+     * @param string $identifier
+     * @return bool
+     * @throws \Exception
+     */
+    public function has($entityType, $identifier)
+    {
+        return $this->metadataPool->getMetadata($entityType)->checkIsEntityExists($identifier);
+    }
+
     /**
      * @param string $entityType
      * @param object $entity
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php
index 22bf6a7e96fb2bcceb8ef5d303b0b1ac0f72310d..0886a9c0611d36b480b988c072e30e99488007df 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php
@@ -151,8 +151,7 @@ class MetadataPoolTest extends \PHPUnit_Framework_TestCase
                         'entityContext' => ['store_id']
                     ]
                 ]
-            ]
-            ,
+            ],
             [
                 'SomeNameSpace\TestInterface',
                 [
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php
index 086d3c44dda1a490f0ad09bd68cdd7bef97e2f6f..be0f86d547589ad922b8c3819c5cf78a2bb2dd22 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php
@@ -22,6 +22,9 @@ class ExtensionPoolTest extends \PHPUnit_Framework_TestCase
      */
     protected $objectManager;
 
+    /**
+     * {@inheritdoc}
+     */
     protected function setUp()
     {
         $this->objectManager = $this->getMockForAbstractClass(
@@ -61,14 +64,41 @@ class ExtensionPoolTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testExecute()
+    /**
+     * @dataProvider executeDataProvider
+     *
+     * @param array $expected
+     * @param string $entityType
+     * @param string $actionName
+     * @return void
+     */
+    public function testExecute(array $expected, $entityType, $actionName)
     {
         $this->assertEquals(
+            $expected,
+            $this->subject->getActions($entityType, $actionName)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        return [
             [
-                'test_extension_1' => 'Test\Extension1\Entity\ReadHandler',
-                'test_extension_2' => 'Test\Extension2\Default\CreateHandler'
+                [
+                    'test_extension_1' => 'Test\Extension1\Entity\ReadHandler',
+                    'test_extension_2' => 'Test\Extension2\Default\CreateHandler'
+                ],
+                'Test\First\Entity',
+                'read'
             ],
-            $this->subject->getActions('Test\First\Entity', 'read')
-        );
+            [
+                [],
+                'Test\First\Entity',
+                'delete'
+            ]
+        ];
     }
 }
diff --git a/lib/internal/Magento/Framework/Mview/Config/Converter.php b/lib/internal/Magento/Framework/Mview/Config/Converter.php
index df06fde50c38305c9b2b9939659cb8ba38fb9e60..bdd814f018dfe1e5faeea1ac16632b307233133a 100644
--- a/lib/internal/Magento/Framework/Mview/Config/Converter.php
+++ b/lib/internal/Magento/Framework/Mview/Config/Converter.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Framework\Mview\Config;
 
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Mview\View\SubscriptionInterface;
+
 class Converter implements \Magento\Framework\Config\ConverterInterface
 {
     /**
@@ -73,7 +76,22 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
                     }
                     $name = $this->getAttributeValue($subscription, 'name');
                     $column = $this->getAttributeValue($subscription, 'entity_column');
-                    $data['subscriptions'][$name] = ['name' => $name, 'column' => $column];
+                    $subscriptionModel = $this->getAttributeValue($subscription, 'subscription_model');
+                    if (!empty($subscriptionModel)
+                        && !in_array(
+                            SubscriptionInterface::class,
+                            class_implements(ltrim($subscriptionModel, '\\'))
+                        )
+                    ) {
+                        throw new \InvalidArgumentException(
+                            'Subscription model must implement ' . SubscriptionInterface::class
+                        );
+                    }
+                    $data['subscriptions'][$name] = [
+                        'name' => $name,
+                        'column' => $column,
+                        'subscription_model' => $subscriptionModel
+                    ];
                 }
                 break;
         }
diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php
index 632a112975e73a28fb49563c28f143818d91d7a6..dde9a3938cb4c066ee2d0c290b7acfad235e40c7 100644
--- a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php
+++ b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php
@@ -232,7 +232,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase
         $this->changelogMock->expects($this->once())
             ->method('drop');
         $subscriptionMock = $this->getMock(
-            'Magento\Framework\Mview\View\Subscription',
+            \Magento\Framework\Mview\View\Subscription::class,
             ['remove'],
             [],
             '',
diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php b/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php
index 0f9ee70ac637804de2461555d2800e2d2c3419fb..158383f5154bf6e449fbdf8696afa9bd8247ea52 100644
--- a/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php
+++ b/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php
@@ -15,8 +15,16 @@ return [
             'action_class' => 'Ogogo\Class\One',
             'group' => 'some_view_group',
             'subscriptions' => [
-                'some_entity' => ['name' => 'some_entity', 'column' => 'entity_id'],
-                'some_product_relation' => ['name' => 'some_product_relation', 'column' => 'product_id'],
+                'some_entity' => [
+                    'name' => 'some_entity',
+                    'column' => 'entity_id',
+                    'subscription_model' => null
+                ],
+                'some_product_relation' => [
+                    'name' => 'some_product_relation',
+                    'column' => 'product_id',
+                    'subscription_model' => null
+                ],
             ],
         ],
     ]
diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php
index 6026a28c83470d55072bd0c5ecdb9853bc905f7b..a0a89bce998cc6165ee200e98d2bd198474b54c8 100644
--- a/lib/internal/Magento/Framework/Mview/View.php
+++ b/lib/internal/Magento/Framework/Mview/View.php
@@ -8,6 +8,8 @@
 
 namespace Magento\Framework\Mview;
 
+use Magento\Framework\Mview\View\SubscriptionFactory;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -48,7 +50,7 @@ class View extends \Magento\Framework\DataObject implements ViewInterface
      * @param ActionFactory $actionFactory
      * @param View\StateInterface $state
      * @param View\ChangelogInterface $changelog
-     * @param View\SubscriptionFactory $subscriptionFactory
+     * @param SubscriptionFactory $subscriptionFactory
      * @param array $data
      */
     public function __construct(
@@ -56,7 +58,7 @@ class View extends \Magento\Framework\DataObject implements ViewInterface
         ActionFactory $actionFactory,
         View\StateInterface $state,
         View\ChangelogInterface $changelog,
-        View\SubscriptionFactory $subscriptionFactory,
+        SubscriptionFactory $subscriptionFactory,
         array $data = []
     ) {
         $this->config = $config;
@@ -175,16 +177,19 @@ class View extends \Magento\Framework\DataObject implements ViewInterface
                 $this->getChangelog()->create();
 
                 // Create subscriptions
-                foreach ($this->getSubscriptions() as $subscription) {
+                foreach ($this->getSubscriptions() as $subscriptionConfig) {
                     /** @var \Magento\Framework\Mview\View\SubscriptionInterface $subscription */
-                    $subscription = $this->subscriptionFactory->create(
+                    $subscriptionInstance = $this->subscriptionFactory->create(
                         [
                             'view' => $this,
-                            'tableName' => $subscription['name'],
-                            'columnName' => $subscription['column'],
+                            'tableName' => $subscriptionConfig['name'],
+                            'columnName' => $subscriptionConfig['column'],
+                            'subscriptionModel' => !empty($subscriptionConfig['subscription_model'])
+                                ? $subscriptionConfig['subscription_model']
+                                : SubscriptionFactory::INSTANCE_NAME,
                         ]
                     );
-                    $subscription->create();
+                    $subscriptionInstance->create();
                 }
 
                 // Update view state
@@ -208,16 +213,19 @@ class View extends \Magento\Framework\DataObject implements ViewInterface
         if ($this->getState()->getMode() != View\StateInterface::MODE_DISABLED) {
             try {
                 // Remove subscriptions
-                foreach ($this->getSubscriptions() as $subscription) {
+                foreach ($this->getSubscriptions() as $subscriptionConfig) {
                     /** @var \Magento\Framework\Mview\View\SubscriptionInterface $subscription */
-                    $subscription = $this->subscriptionFactory->create(
+                    $subscriptionInstance = $this->subscriptionFactory->create(
                         [
                             'view' => $this,
-                            'tableName' => $subscription['name'],
-                            'columnName' => $subscription['column'],
+                            'tableName' => $subscriptionConfig['name'],
+                            'columnName' => $subscriptionConfig['column'],
+                            'subscriptionModel' => !empty($subscriptionConfig['subscriptionModel'])
+                                ? $subscriptionConfig['subscriptionModel']
+                                : SubscriptionFactory::INSTANCE_NAME,
                         ]
                     );
-                    $subscription->remove();
+                    $subscriptionInstance->remove();
                 }
 
                 // Drop changelog table
diff --git a/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php b/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php
index fc31a8f25ceab49e6189934d7c4cef3e25b50d4e..7a27338878d4a7f99a0fdfe72404cfe7b99e71dd 100644
--- a/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php
+++ b/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php
@@ -5,10 +5,26 @@
  */
 namespace Magento\Framework\Mview\View;
 
+/**
+ * Class SubscriptionFactory
+ * @package Magento\Framework\Mview\View
+ *
+ */
 class SubscriptionFactory extends AbstractFactory
 {
     /**
      * Instance name
      */
-    const INSTANCE_NAME = 'Magento\Framework\Mview\View\SubscriptionInterface';
+    const INSTANCE_NAME = SubscriptionInterface::class;
+
+    /**
+     * @param array $data
+     * @return SubscriptionInterface
+     */
+    public function create(array $data = [])
+    {
+        $instanceName = isset($data['subscriptionModel']) ? $data['subscriptionModel'] : self::INSTANCE_NAME;
+        unset($data['subscriptionModel']);
+        return $this->objectManager->create($instanceName, $data);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Mview/etc/mview.xsd b/lib/internal/Magento/Framework/Mview/etc/mview.xsd
index 320a57a0af46e2551077f08d2f73c5ebea308c0a..cda0b197095bc7f1942d1738844c1e1800c59d95 100644
--- a/lib/internal/Magento/Framework/Mview/etc/mview.xsd
+++ b/lib/internal/Magento/Framework/Mview/etc/mview.xsd
@@ -78,6 +78,7 @@
         </xs:annotation>
         <xs:attribute name="name" type="tableNameType" use="required" />
         <xs:attribute name="entity_column" type="entityColumnType" use="required" />
+        <xs:attribute name="subscription_model" type="subscriptionModelType" />
     </xs:complexType>
 
     <xs:simpleType name="entityColumnType">
@@ -101,4 +102,15 @@
             <xs:pattern value="[a-z_]+" />
         </xs:restriction>
     </xs:simpleType>
+
+    <xs:simpleType name="subscriptionModelType">
+        <xs:annotation>
+            <xs:documentation>
+                Subscription model must be a valid PHP class or interface name.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[a-zA-Z_][a-zA-Z0-9\\]*" />
+        </xs:restriction>
+    </xs:simpleType>
 </xs:schema>