diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
index 9cd66815ecf3e0b9307fe5732a92c968d894ad54..6ff14589e82ebfbe5435bbeef8a50cb03e45a0ae 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
@@ -93,7 +93,7 @@ class Form extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
                     'onclick' => "categoryDelete('" . $this->getUrl(
                         'catalog/*/delete',
                         ['_current' => true]
-                    ) . "', true, {$categoryId})",
+                    ) . "')",
                     'class' => 'delete'
                 ]
             );
diff --git a/app/code/Magento/Catalog/Block/Navigation.php b/app/code/Magento/Catalog/Block/Navigation.php
index ed8f5d99d570064c34d8a0195b8865a6e8165f1e..77c1905eed71beb27c1bf1c1e72bc231ff98f5a5 100644
--- a/app/code/Magento/Catalog/Block/Navigation.php
+++ b/app/code/Magento/Catalog/Block/Navigation.php
@@ -173,16 +173,6 @@ class Navigation extends \Magento\Framework\View\Element\Template implements \Ma
         return $this->_currentCategoryKey;
     }
 
-    /**
-     * Get catagories of current store
-     *
-     * @return \Magento\Framework\Data\Tree\Node\Collection
-     */
-    public function getStoreCategories()
-    {
-        return $this->_catalogCategory->getStoreCategories();
-    }
-
     /**
      * Retrieve child categories of current category
      *
@@ -229,161 +219,6 @@ class Navigation extends \Magento\Framework\View\Element\Template implements \Ma
         return $url;
     }
 
-    /**
-     * Return item position representation in menu tree
-     *
-     * @param int $level
-     * @return string
-     */
-    protected function _getItemPosition($level)
-    {
-        if ($level == 0) {
-            $zeroLevelPosition = isset(
-                $this->_itemLevelPositions[$level]
-            ) ? $this->_itemLevelPositions[$level] + 1 : 1;
-            $this->_itemLevelPositions = [];
-            $this->_itemLevelPositions[$level] = $zeroLevelPosition;
-        } elseif (isset($this->_itemLevelPositions[$level])) {
-            $this->_itemLevelPositions[$level]++;
-        } else {
-            $this->_itemLevelPositions[$level] = 1;
-        }
-
-        $position = [];
-        for ($i = 0; $i <= $level; $i++) {
-            if (isset($this->_itemLevelPositions[$i])) {
-                $position[] = $this->_itemLevelPositions[$i];
-            }
-        }
-        return implode('-', $position);
-    }
-
-    /**
-     * Render category to html
-     *
-     * @param Category $category
-     * @param int $level Nesting level number
-     * @param boolean $isLast Whether ot not this item is last, affects list item class
-     * @param boolean $isFirst Whether ot not this item is first, affects list item class
-     * @param boolean $isOutermost Whether ot not this item is outermost, affects list item class
-     * @param string $outermostItemClass Extra class of outermost list items
-     * @param string $childrenWrapClass If specified wraps children list in div with this class
-     * @param boolean $noEventAttributes Whether ot not to add on* attributes to list item
-     * @return string
-     */
-    protected function _renderCategoryMenuItemHtml(
-        $category,
-        $level = 0,
-        $isLast = false,
-        $isFirst = false,
-        $isOutermost = false,
-        $outermostItemClass = '',
-        $childrenWrapClass = '',
-        $noEventAttributes = false
-    ) {
-        if (!$category->getIsActive()) {
-            return '';
-        }
-
-        // get all children
-        if ($this->flatState->isAvailable()) {
-            $children = (array)$category->getChildrenNodes();
-        } else {
-            $children = $category->getChildren();
-        }
-
-        // select active children
-        $activeChildren = [];
-        foreach ($children as $child) {
-            if ($child->getIsActive()) {
-                $activeChildren[] = $child;
-            }
-        }
-
-        $activeChildrenCount = count($activeChildren);
-        $hasActiveChildren = $activeChildrenCount > 0;
-
-        // prepare list item html classes
-        $classes = [];
-        $classes[] = 'level' . $level;
-        $classes[] = 'nav-' . $this->_getItemPosition($level);
-        if ($this->isCategoryActive($category)) {
-            $classes[] = 'active';
-        }
-
-        $linkClass = '';
-        if ($isOutermost && $outermostItemClass) {
-            $classes[] = $outermostItemClass;
-            $linkClass = ' class="' . $outermostItemClass . '"';
-        }
-        if ($isFirst) {
-            $classes[] = 'first';
-        }
-        if ($isLast) {
-            $classes[] = 'last';
-        }
-        if ($hasActiveChildren) {
-            $classes[] = 'parent';
-        }
-
-        // prepare list item attributes
-        $attributes = [];
-        if (count($classes) > 0) {
-            $attributes['class'] = implode(' ', $classes);
-        }
-        if ($hasActiveChildren && !$noEventAttributes) {
-            $attributes['onmouseover'] = 'toggleMenu(this,1)';
-            $attributes['onmouseout'] = 'toggleMenu(this,0)';
-        }
-
-        // assemble list item with attributes
-        $htmlLi = '<li';
-        foreach ($attributes as $attrName => $attrValue) {
-            $htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
-        }
-        $htmlLi .= '>';
-
-        $html = [];
-        $html[] = $htmlLi;
-
-        $html[] = '<a href="' . $this->getCategoryUrl($category) . '"' . $linkClass . '>';
-        $html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
-        $html[] = '</a>';
-
-        // render children
-        $htmlChildren = '';
-        $j = 0;
-        foreach ($activeChildren as $child) {
-            $htmlChildren .= $this->_renderCategoryMenuItemHtml(
-                $child,
-                $level + 1,
-                $j == $activeChildrenCount - 1,
-                $j == 0,
-                false,
-                $outermostItemClass,
-                $childrenWrapClass,
-                $noEventAttributes
-            );
-            $j++;
-        }
-        if (!empty($htmlChildren)) {
-            if ($childrenWrapClass) {
-                $html[] = '<div class="' . $childrenWrapClass . '">';
-            }
-            $html[] = '<ul class="level' . $level . '">';
-            $html[] = $htmlChildren;
-            $html[] = '</ul>';
-            if ($childrenWrapClass) {
-                $html[] = '</div>';
-            }
-        }
-
-        $html[] = '</li>';
-
-        $html = implode("\n", $html);
-        return $html;
-    }
-
     /**
      * Enter description here...
      *
@@ -394,107 +229,6 @@ class Navigation extends \Magento\Framework\View\Element\Template implements \Ma
         return $this->_catalogLayer->getCurrentCategory();
     }
 
-    /**
-     * Enter description here...
-     *
-     * @return string
-     */
-    public function getCurrentCategoryPath()
-    {
-        if ($this->getCurrentCategory()) {
-            return explode(',', $this->getCurrentCategory()->getPathInStore());
-        }
-        return [];
-    }
-
-    /**
-     * Enter description here...
-     *
-     * @param Category $category
-     * @return string
-     */
-    public function drawOpenCategoryItem($category)
-    {
-        $html = '';
-        if (!$category->getIsActive()) {
-            return $html;
-        }
-
-        $html .= '<li';
-
-        if ($this->isCategoryActive($category)) {
-            $html .= ' class="active"';
-        }
-
-        $html .= '>' . "\n";
-        $html .= '<a href="' . $this->getCategoryUrl(
-            $category
-        ) . '">' . '<span>' . $this->escapeHtml(
-            $category->getName()
-        ) . '</span></a>' . "\n";
-
-        if (in_array($category->getId(), $this->getCurrentCategoryPath())) {
-            $children = $category->getChildren();
-            $hasChildren = $children && $children->count();
-
-            if ($hasChildren) {
-                $htmlChildren = '';
-                foreach ($children as $child) {
-                    $htmlChildren .= $this->drawOpenCategoryItem($child);
-                }
-
-                if (!empty($htmlChildren)) {
-                    $html .= '<ul>' . "\n" . $htmlChildren . '</ul>';
-                }
-            }
-        }
-        $html .= '</li>' . "\n";
-
-        return $html;
-    }
-
-    /**
-     * Render categories menu in HTML
-     *
-     * @param int $level Level number for list item class to start from
-     * @param string $outermostItemClass Extra class of outermost list items
-     * @param string $childrenWrapClass If specified wraps children list in div with this class
-     * @return string
-     */
-    public function renderCategoriesMenuHtml($level = 0, $outermostItemClass = '', $childrenWrapClass = '')
-    {
-        $activeCategories = [];
-        foreach ($this->getStoreCategories() as $child) {
-            if ($child->getIsActive()) {
-                $activeCategories[] = $child;
-            }
-        }
-        $activeCategoriesCount = count($activeCategories);
-        $hasActiveCategoriesCount = $activeCategoriesCount > 0;
-
-        if (!$hasActiveCategoriesCount) {
-            return '';
-        }
-
-        $html = '';
-        $j = 0;
-        foreach ($activeCategories as $category) {
-            $html .= $this->_renderCategoryMenuItemHtml(
-                $category,
-                $level,
-                $j == $activeCategoriesCount - 1,
-                $j == 0,
-                true,
-                $outermostItemClass,
-                $childrenWrapClass,
-                true
-            );
-            $j++;
-        }
-
-        return $html;
-    }
-
     /**
      * Return identifiers for produced content
      *
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php
index f5b053679733a438d0da357db58fc75858db8c7a..3c4eded51ce978738835e9d41cc01e32629f3a46 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php
@@ -7,6 +7,23 @@ namespace Magento\Catalog\Controller\Adminhtml\Category;
 
 class Delete extends \Magento\Catalog\Controller\Adminhtml\Category
 {
+    /** @var \Magento\Catalog\Api\CategoryRepositoryInterface */
+    protected $categoryRepository;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory
+     * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory,
+        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
+    ) {
+        parent::__construct($context, $resultRedirectFactory);
+        $this->categoryRepository = $categoryRepository;
+    }
+
     /**
      * Delete category action
      *
@@ -18,14 +35,14 @@ class Delete extends \Magento\Catalog\Controller\Adminhtml\Category
         $resultRedirect = $this->resultRedirectFactory->create();
 
         $categoryId = (int)$this->getRequest()->getParam('id');
+        $parentId = null;
         if ($categoryId) {
             try {
-                $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
+                $category = $this->categoryRepository->get($categoryId);
+                $parentId = $category->getParentId();
                 $this->_eventManager->dispatch('catalog_controller_category_delete', ['category' => $category]);
-
-                $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setDeletedPath($category->getPath());
-
-                $category->delete();
+                $this->_auth->getAuthStorage()->setDeletedPath($category->getPath());
+                $this->categoryRepository->delete($category);
                 $this->messageManager->addSuccess(__('You deleted the category.'));
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
@@ -35,6 +52,6 @@ class Delete extends \Magento\Catalog\Controller\Adminhtml\Category
                 return $resultRedirect->setPath('catalog/*/edit', ['_current' => true]);
             }
         }
-        return $resultRedirect->setPath('catalog/*/', ['_current' => true, 'id' => null]);
+        return $resultRedirect->setPath('catalog/*/', ['_current' => true, 'id' => $parentId]);
     }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
index f17bfc3abd5c1630e0e93082724eb30a8f6e1b1a..7f6dde5cb3ee101c0d2ed9f1dc3b2c1c19cf213a 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
@@ -97,6 +97,7 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Category
                     . $resultPage->getLayout()->getBlock('category.tree')
                         ->getBreadcrumbsJavascript($breadcrumbsPath, 'editingCategoryBreadcrumbs'),
                 'messages' => $resultPage->getLayout()->getMessagesBlock()->getGroupedHtml(),
+                'toolbar' => $resultPage->getLayout()->getBlock('page.actions.toolbar')->toHtml()
             ]);
             $this->_eventManager->dispatch(
                 'category_prepare_ajax_response',
diff --git a/app/code/Magento/Catalog/Model/Resource/Helper.php b/app/code/Magento/Catalog/Model/Resource/Helper.php
index ef2f15133bd8e531a2558f802d1028dc84d004ea..fcd489d68642d628bbe7693fcf3c24cf09f5726a 100644
--- a/app/code/Magento/Catalog/Model/Resource/Helper.php
+++ b/app/code/Magento/Catalog/Model/Resource/Helper.php
@@ -6,14 +6,10 @@ namespace Magento\Catalog\Model\Resource;
 
 /**
  * Eav Mysql resource helper model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Helper extends \Magento\Eav\Model\Resource\Helper
 {
     /**
-     * Construct
-     *
      * @param \Magento\Framework\App\Resource $resource
      * @param string $modulePrefix
      */
@@ -21,61 +17,4 @@ class Helper extends \Magento\Eav\Model\Resource\Helper
     {
         parent::__construct($resource, $modulePrefix);
     }
-
-    /**
-     * Compare Flat style with Describe style columns
-     * If column a different - return false
-     *
-     * @param array $column
-     * @param array $describe
-     * @return bool
-     */
-    public function compareIndexColumnProperties($column, $describe)
-    {
-        $type = $column['type'];
-        if (isset($column['length'])) {
-            $type = sprintf('%s(%s)', $type[0], $column['length']);
-        } else {
-            $type = $type[0];
-        }
-        $length = null;
-        $precision = null;
-        $scale = null;
-
-        $matches = [];
-        if (preg_match('/^((?:var)?char)\((\d+)\)/', $type, $matches)) {
-            $type = $matches[1];
-            $length = $matches[2];
-        } elseif (preg_match('/^decimal\((\d+),(\d+)\)/', $type, $matches)) {
-            $type = 'decimal';
-            $precision = $matches[1];
-            $scale = $matches[2];
-        } elseif (preg_match('/^float\((\d+),(\d+)\)/', $type, $matches)) {
-            $type = 'float';
-            $precision = $matches[1];
-            $scale = $matches[2];
-        } elseif (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)?/', $type, $matches)) {
-            $type = $matches[1];
-        }
-
-        return $describe['DATA_TYPE'] == $type &&
-            $describe['DEFAULT'] == $column['default'] &&
-            (bool)$describe['NULLABLE'] == (bool)$column['nullable'] &&
-            (bool)$describe['UNSIGNED'] == (bool)$column['unsigned'] &&
-            $describe['LENGTH'] == $length &&
-            $describe['SCALE'] == $scale &&
-            $describe['PRECISION'] == $precision;
-    }
-
-    /**
-     * Getting condition isNull(f1,f2) IS NOT Null
-     *
-     * @param string $firstField
-     * @param string $secondField
-     * @return string
-     */
-    public function getIsNullNotNullCondition($firstField, $secondField)
-    {
-        return sprintf('%s IS NOT NULL', $this->_getReadAdapter()->getIfNullSql($firstField, $secondField));
-    }
 }
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
index f88c278afe41d2d4248373f673c46989e7786291..8c8f8d5ed1302601fe726fcd91ee449be1f66ffc 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
@@ -143,6 +143,7 @@ class Source extends AbstractEav
             $subSelect->where('d.entity_id IN(?)', $entityIds);
         }
 
+        $ifNullSql = $adapter->getIfNullSql('pis.value', 'pid.value');
         /**@var $select \Magento\Framework\DB\Select*/
         $select = $adapter->select()->distinct(true)->from(
             ['pid' => new \Zend_Db_Expr(sprintf('(%s)', $subSelect->assemble()))],
@@ -156,14 +157,14 @@ class Source extends AbstractEav
                 'pid.entity_id',
                 'pid.attribute_id',
                 'pid.store_id',
-                'value' => $adapter->getIfNullSql('pis.value', 'pid.value'),
+                'value' => $ifNullSql,
             ]
         )->where(
             'pid.attribute_id IN(?)',
             $attrIds
         );
 
-        $select->where($this->_resourceHelper->getIsNullNotNullCondition('pis.value', 'pid.value'));
+        $select->where($ifNullSql . ' IS NOT NULL');
 
         /**
          * Exclude attribute values that contains NULL
diff --git a/app/code/Magento/Catalog/Model/Resource/Setup.php b/app/code/Magento/Catalog/Model/Resource/Setup.php
index bb2713d989c664079be242150cb4b90e357169a8..8fa1f596b380fd683324bf268fee9346b6afe4bc 100644
--- a/app/code/Magento/Catalog/Model/Resource/Setup.php
+++ b/app/code/Magento/Catalog/Model/Resource/Setup.php
@@ -59,23 +59,13 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
      *
      * @param array $data
      * @return \Magento\Catalog\Model\Category
+     * @codeCoverageIgnore
      */
     public function createCategory($data = [])
     {
         return $this->_categoryFactory->create($data);
     }
 
-    /**
-     * Creates eav attribute resource model
-     *
-     * @param array $data
-     * @return \Magento\Catalog\Model\Resource\Eav\Attribute
-     */
-    public function createEavAttributeResource($data = [])
-    {
-        return $this->_eavAttributeResourceFactory->create($data);
-    }
-
     /**
      * Default entites and attributes
      *
@@ -828,41 +818,4 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
             ]
         ];
     }
-
-    /**
-     * Returns category entity row by category id
-     *
-     * @param int $entityId
-     * @return array
-     */
-    protected function _getCategoryEntityRow($entityId)
-    {
-        $select = $this->getConnection()->select();
-
-        $select->from($this->getTable('catalog_category_entity'));
-        $select->where('entity_id = :entity_id');
-
-        return $this->getConnection()->fetchRow($select, ['entity_id' => $entityId]);
-    }
-
-    /**
-     * Returns category path as array
-     *
-     * @param array $category
-     * @param array $path
-     * @return string
-     */
-    protected function _getCategoryPath($category, $path = [])
-    {
-        $path[] = $category['entity_id'];
-
-        if ($category['parent_id'] != 0) {
-            $parentCategory = $this->_getCategoryEntityRow($category['parent_id']);
-            if ($parentCategory) {
-                $path = $this->_getCategoryPath($parentCategory, $path);
-            }
-        }
-
-        return $path;
-    }
 }
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit.phtml
index 75b59da8d09aa3b5da4483c7fe22493056038a6d..d1d3ec2b11497fd593f8e7346144b79f4e321a0b 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit.phtml
@@ -34,21 +34,16 @@ require([
     * This routine get categoryId explicitly, so even if currently selected tree node is out of sync
     * with this form, we surely delete same category in the tree and at backend
     */
-    function categoryDelete(url, useAjax, categoryId) {
+    function categoryDelete(url) {
         if (confirm('<?php echo __('Are you sure you want to delete this category?') ?>')){
-            if (useAjax){
-                tree.nodeForDelete = categoryId;
-                updateContent(url, {}, true, true);
-            } else {
-                location.href = url;
-            }
+            location.href = url;
         }
     }
 
     /**
      * Update category content area
      */
-    function updateContent(url, params, refreshTree, deleteAction) {
+    function updateContent(url, params, refreshTree) {
         var node        = tree.getNodeById(tree.currentNodeId),
             parentNode  = node && node.parentNode,
             parentId,
@@ -64,23 +59,15 @@ require([
         }
 
         (function($){
-            var $categoryContainer = $('#category-edit-container');
+            var $categoryContainer = $('#category-edit-container'),
+                messagesContainer = $('.messages');
+            messagesContainer.html('');
             $.ajax({
                 url: url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true' ),
                 data: params,
                 context: $('body'),
                 showLoader: true
             }).done(function(data){
-                if (deleteAction && parentNode) {
-                    parentId    = parentNode.id;
-
-                    redirectUrl = !parentNode.isRoot ?
-                        tree.buildUrl(parentId) :
-                        tree.getBaseUrl();
-
-                    location.href = redirectUrl;
-                }
-
                 if (data.content) {
                     $('.page-actions').floatingHeader('destroy');
                     try {
@@ -111,7 +98,10 @@ require([
                 }
 
                 if (data.messages && data.messages.length > 0) {
-                    $('.messages').html(data.messages);
+                    messagesContainer.html(data.messages);
+                }
+                if (data.toolbar) {
+                    $('[data-ui-id="page-actions-toolbar-content-header"]').replaceWith(data.toolbar)
                 }
             });
         })(jQuery);
diff --git a/app/code/Magento/Catalog/view/frontend/templates/navigation/top.phtml b/app/code/Magento/Catalog/view/frontend/templates/navigation/top.phtml
deleted file mode 100644
index 5eed153ff318d6d837bb7d71f307e4770356904b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/view/frontend/templates/navigation/top.phtml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-?>
-<?php
-/**
- * Top menu for store
- *
- * @var $this \Magento\Catalog\Block\Navigation
- */
-?>
-<?php
-/**
- * $this->renderCategoriesMenuHtml() supports optional arguments:
- * int Level number for list item class to start from
- * string Extra class of outermost list items
- * string If specified wraps children list in div with this class
- */
-?>
-<?php $_menu = $this->renderCategoriesMenuHtml(0, 'level-top') ?>
-<?php if ($_menu): ?>
-<div class="nav container">
-    <ul id="nav">
-        <?php echo $_menu ?>
-    </ul>
-</div>
-<?php endif ?>
diff --git a/app/code/Magento/CatalogRule/Plugin/Model/Product/Action.php b/app/code/Magento/CatalogRule/Plugin/Model/Product/Action.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9dbc6742abffc139f7c15d8a0cdfd32c3846aef
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Plugin/Model/Product/Action.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\CatalogRule\Plugin\Model\Product;
+
+use Magento\Catalog\Model\Product\Action as ProductAction;
+use Magento\CatalogRule\Model\Indexer\Product\ProductRuleProcessor;
+
+class Action
+{
+    /**
+     * @var ProductRuleProcessor
+     */
+    protected $productRuleProcessor;
+
+    /**
+     * @param ProductRuleProcessor $productRuleProcessor
+     */
+    public function __construct(ProductRuleProcessor $productRuleProcessor)
+    {
+        $this->productRuleProcessor = $productRuleProcessor;
+    }
+
+    /**
+     * @param ProductAction $object
+     * @param ProductAction $result
+     * @return ProductAction
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormatParameter)
+     */
+    public function afterUpdateAttributes(ProductAction $object, ProductAction $result)
+    {
+        $data = $result->getAttributesData();
+        if (!empty($data['price'])) {
+            $this->productRuleProcessor->reindexList($result->getProductIds());
+        }
+
+        return $result;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/etc/adminhtml/di.xml b/app/code/Magento/CatalogRule/etc/adminhtml/di.xml
index 55eca2f1b83aeaedee7c4f2bdb6a2b2a5141c672..7268cb0de6eda456803dd18572bbb1cd0a1e4e75 100644
--- a/app/code/Magento/CatalogRule/etc/adminhtml/di.xml
+++ b/app/code/Magento/CatalogRule/etc/adminhtml/di.xml
@@ -31,4 +31,7 @@
     <type name="Magento\Catalog\Model\Resource\Eav\Attribute">
         <plugin name="change_product_attribute" type="Magento\CatalogRule\Plugin\Indexer\Product\Attribute"/>
     </type>
+    <type name="Magento\Catalog\Model\Product\Action">
+        <plugin name="price_plugin" type="Magento\CatalogRule\Plugin\Model\Product\Action"/>
+    </type>
 </config>
diff --git a/composer.json b/composer.json
index 4f7d10574a1ab9a6a99c881160014a20b059cbe9..8668bc7f266953d6a866226f641c9e6e8e7e81c7 100644
--- a/composer.json
+++ b/composer.json
@@ -144,7 +144,6 @@
         "magento/framework": "self.version",
         "magento/project-setup": "0.1.0",
         "oyejorge/less.php": "1.7.0",
-        "symfony/yaml": "2.3.x-dev",
         "trentrichardson/jquery-timepicker-addon": "1.4.3",
         "components/handlebars.js": "1.3.0",
         "colinmollenhour/cache-backend-redis": "dev-master#193d377b7fb2e88595578b282fa01a62d1185abc",
diff --git a/composer.lock b/composer.lock
index 1555108c6caf9966bf920872aed2e331e660096f..805bbf13580a0513996448019c7c1abe2231e84f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "92e39ae537cd58698bf74e13721f17f3",
+    "hash": "27bff88b2a866343d0e0bc06fc52080f",
     "packages": [
         {
             "name": "composer/composer",
@@ -336,17 +336,17 @@
         },
         {
             "name": "symfony/console",
-            "version": "v2.6.1",
+            "version": "v2.6.3",
             "target-dir": "Symfony/Component/Console",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Console.git",
-                "reference": "ef825fd9f809d275926547c9e57cbf14968793e8"
+                "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8",
-                "reference": "ef825fd9f809d275926547c9e57cbf14968793e8",
+                "url": "https://api.github.com/repos/symfony/Console/zipball/6ac6491ff60c0e5a941db3ccdc75a07adbb61476",
+                "reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476",
                 "shasum": ""
             },
             "require": {
@@ -389,21 +389,21 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:19:20"
+            "time": "2015-01-06 17:50:02"
         },
         {
             "name": "symfony/finder",
-            "version": "v2.6.1",
+            "version": "v2.6.3",
             "target-dir": "Symfony/Component/Finder",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Finder.git",
-                "reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721"
+                "reference": "16513333bca64186c01609961a2bb1b95b5e1355"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Finder/zipball/0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721",
-                "reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721",
+                "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355",
+                "reference": "16513333bca64186c01609961a2bb1b95b5e1355",
                 "shasum": ""
             },
             "require": {
@@ -436,21 +436,21 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:19:20"
+            "time": "2015-01-03 08:01:59"
         },
         {
             "name": "symfony/process",
-            "version": "v2.6.1",
+            "version": "v2.6.3",
             "target-dir": "Symfony/Component/Process",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Process.git",
-                "reference": "bf0c9bd625f13b0b0bbe39919225cf145dfb935a"
+                "reference": "319794f611bd8bdefbac72beb3f05e847f8ebc92"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Process/zipball/bf0c9bd625f13b0b0bbe39919225cf145dfb935a",
-                "reference": "bf0c9bd625f13b0b0bbe39919225cf145dfb935a",
+                "url": "https://api.github.com/repos/symfony/Process/zipball/319794f611bd8bdefbac72beb3f05e847f8ebc92",
+                "reference": "319794f611bd8bdefbac72beb3f05e847f8ebc92",
                 "shasum": ""
             },
             "require": {
@@ -483,7 +483,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:19:20"
+            "time": "2015-01-06 22:47:52"
         },
         {
             "name": "zendframework/zend-code",
@@ -1876,16 +1876,16 @@
         },
         {
             "name": "league/climate",
-            "version": "2.5.0",
+            "version": "2.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/climate.git",
-                "reference": "8687265629baaedd0fadc75350950ffc5ea53ae6"
+                "reference": "776b6c3b32837832a9f6d94f134b55cb7910ece6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/climate/zipball/8687265629baaedd0fadc75350950ffc5ea53ae6",
-                "reference": "8687265629baaedd0fadc75350950ffc5ea53ae6",
+                "url": "https://api.github.com/repos/thephpleague/climate/zipball/776b6c3b32837832a9f6d94f134b55cb7910ece6",
+                "reference": "776b6c3b32837832a9f6d94f134b55cb7910ece6",
                 "shasum": ""
             },
             "require": {
@@ -1921,7 +1921,7 @@
                 "php",
                 "terminal"
             ],
-            "time": "2014-11-08 02:33:31"
+            "time": "2015-01-08 02:28:23"
         },
         {
             "name": "lusitanian/oauth",
@@ -2833,17 +2833,17 @@
         },
         {
             "name": "symfony/config",
-            "version": "v2.5.8",
+            "version": "v2.5.9",
             "target-dir": "Symfony/Component/Config",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Config.git",
-                "reference": "92f0b4c625b8c42d394b53f879d2795d84bb8c4f"
+                "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Config/zipball/92f0b4c625b8c42d394b53f879d2795d84bb8c4f",
-                "reference": "92f0b4c625b8c42d394b53f879d2795d84bb8c4f",
+                "url": "https://api.github.com/repos/symfony/Config/zipball/c7309e33b719433d5cf3845d0b5b9608609d8c8e",
+                "reference": "c7309e33b719433d5cf3845d0b5b9608609d8c8e",
                 "shasum": ""
             },
             "require": {
@@ -2877,21 +2877,21 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:15:53"
+            "time": "2015-01-03 08:01:13"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.5.8",
+            "version": "v2.5.9",
             "target-dir": "Symfony/Component/DependencyInjection",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/DependencyInjection.git",
-                "reference": "b4afda3c24867a17f93237ac1fcce917cc9d7695"
+                "reference": "b04e6782962f8e3312274fd16fb6b37a8210a1c3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b4afda3c24867a17f93237ac1fcce917cc9d7695",
-                "reference": "b4afda3c24867a17f93237ac1fcce917cc9d7695",
+                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b04e6782962f8e3312274fd16fb6b37a8210a1c3",
+                "reference": "b04e6782962f8e3312274fd16fb6b37a8210a1c3",
                 "shasum": ""
             },
             "require": {
@@ -2899,8 +2899,8 @@
             },
             "require-dev": {
                 "symfony/config": "~2.2",
-                "symfony/expression-language": "~2.4",
-                "symfony/yaml": "~2.0"
+                "symfony/expression-language": "~2.4,>=2.4.10",
+                "symfony/yaml": "~2.1"
             },
             "suggest": {
                 "symfony/config": "",
@@ -2934,21 +2934,21 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 21:48:32"
+            "time": "2015-01-05 08:51:41"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v2.6.1",
+            "version": "v2.6.3",
             "target-dir": "Symfony/Component/EventDispatcher",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/EventDispatcher.git",
-                "reference": "720fe9bca893df7ad1b4546649473b5afddf0216"
+                "reference": "40ff70cadea3785d83cac1c8309514b36113064e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216",
-                "reference": "720fe9bca893df7ad1b4546649473b5afddf0216",
+                "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/40ff70cadea3785d83cac1c8309514b36113064e",
+                "reference": "40ff70cadea3785d83cac1c8309514b36113064e",
                 "shasum": ""
             },
             "require": {
@@ -2956,10 +2956,10 @@
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/config": "~2.0",
+                "symfony/config": "~2.0,>=2.0.5",
                 "symfony/dependency-injection": "~2.6",
                 "symfony/expression-language": "~2.6",
-                "symfony/stopwatch": "~2.2"
+                "symfony/stopwatch": "~2.3"
             },
             "suggest": {
                 "symfony/dependency-injection": "",
@@ -2992,21 +2992,21 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:19:20"
+            "time": "2015-01-05 14:28:40"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.5.8",
+            "version": "v2.5.9",
             "target-dir": "Symfony/Component/Filesystem",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Filesystem.git",
-                "reference": "e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42"
+                "reference": "d3c24d7d6e9c342008d8421b2fade460311647ea"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42",
-                "reference": "e5fc05a3a1dbb4ea0bed80fe7bd21ba3cab88c42",
+                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/d3c24d7d6e9c342008d8421b2fade460311647ea",
+                "reference": "d3c24d7d6e9c342008d8421b2fade460311647ea",
                 "shasum": ""
             },
             "require": {
@@ -3039,21 +3039,21 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:15:53"
+            "time": "2015-01-03 21:04:44"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v2.6.1",
+            "version": "v2.6.3",
             "target-dir": "Symfony/Component/Stopwatch",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Stopwatch.git",
-                "reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc"
+                "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/261abd360cfb6ac65ea93ffd82073e2011d034fc",
-                "reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc",
+                "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/e8da5286132ba75ce4b4275fbf0f4cd369bfd71c",
+                "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c",
                 "shasum": ""
             },
             "require": {
@@ -3086,7 +3086,54 @@
             ],
             "description": "Symfony Stopwatch Component",
             "homepage": "http://symfony.com",
-            "time": "2014-12-02 20:19:20"
+            "time": "2015-01-03 08:01:59"
+        },
+        {
+            "name": "symfony/yaml",
+            "version": "v2.6.3",
+            "target-dir": "Symfony/Component/Yaml",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Yaml.git",
+                "reference": "82462a90848a52c2533aa6b598b107d68076b018"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018",
+                "reference": "82462a90848a52c2533aa6b598b107d68076b018",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Yaml\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                },
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "Symfony Yaml Component",
+            "homepage": "http://symfony.com",
+            "time": "2015-01-03 15:33:07"
         }
     ],
     "aliases": [],
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 425044b2bdd626b6dea92862fe818cc8b1a239c4..fa7d5001d208786259a3a92246fa715d6086df5e 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -328,6 +328,12 @@ return [
     ['displayFullSummary', 'Magento\Tax\Model\Config'],
     ['displayZeroTax', 'Magento\Tax\Model\Config'],
     ['drawItem', 'Magento\Catalog\Block\Navigation'],
+    ['getStoreCategories', 'Magento\Catalog\Block\Navigation'],
+    ['_getItemPosition', 'Magento\Catalog\Block\Navigation'],
+    ['_renderCategoryMenuItemHtml', 'Magento\Catalog\Block\Navigation'],
+    ['getCurrentCategoryPath', 'Magento\Catalog\Block\Navigation'],
+    ['drawOpenCategoryItem', 'Magento\Catalog\Block\Navigation'],
+    ['renderCategoriesMenuHtml', 'Magento\Catalog\Block\Navigation'],
     ['dropKey', 'Magento\Framework\DB\Adapter\Pdo\Mysql'],
     ['escapeJs', 'Magento\Backend\Block\Catalog\Product\Edit\Tab\Super\Config'],
     ['eventClean', 'Magento\Reports\Model\Event\Observer'],
@@ -2008,5 +2014,10 @@ return [
     ],
     ['getLinksConfig', 'Magento\Downloadable\Block\Catalog\Product\Links'],
     ['getAuthorizationAmounts', 'Magento\Paypal\Model\Config'],
-    ['cleanTransactions', 'Magento\Paypal\Model\Observer']
+    ['cleanTransactions', 'Magento\Paypal\Model\Observer'],
+    ['compareIndexColumnProperties', 'Magento\Catalog\Model\Resource\Helper'],
+    ['getIsNullNotNullCondition', 'Magento\Catalog\Model\Resource\Helper'],
+    ['_getCategoryPath', 'Magento\Catalog\Model\Resource\Setup'],
+    ['_getCategoryEntityRow', 'Magento\Catalog\Model\Resource\Setup'],
+    ['createEavAttributeResource', 'Magento\Catalog\Model\Resource\Setup'],
 ];
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/DeleteTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/DeleteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..09221eff20db82013daf71291bc185629db7b537
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/DeleteTest.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class DeleteTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Catalog\Controller\Adminhtml\Category\Delete */
+    protected $unit;
+
+    /** @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resultRedirect;
+
+    /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $request;
+
+    /** @var \Magento\Catalog\Api\CategoryRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryRepository;
+
+    /** @var \Magento\Backend\Model\Auth\StorageInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $authStorage;
+
+    protected function setUp()
+    {
+        $context = $this->getMock('Magento\Backend\App\Action\Context', [], [], '', false);
+        $resultRedirectFactory = $this->getMock(
+            'Magento\Backend\Model\View\Result\RedirectFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->request = $this->getMockForAbstractClass(
+            'Magento\Framework\App\RequestInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getParam', 'getPost']
+        );
+        $auth = $this->getMock(
+            'Magento\Backend\Model\Auth',
+            ['getAuthStorage'],
+            [],
+            '',
+            false
+        );
+        $this->authStorage = $this->getMock(
+            'Magento\Backend\Model\Auth\StorageInterface',
+            ['processLogin', 'processLogout', 'isLoggedIn', 'prolong', 'setDeletedPath'],
+            [],
+            '',
+            false
+        );
+        $eventManager = $this->getMockForAbstractClass(
+            'Magento\Framework\Event\ManagerInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['dispatch']
+        );
+        $response = $this->getMockForAbstractClass(
+            'Magento\Framework\App\ResponseInterface',
+            [],
+            '',
+            false
+        );
+        $messageManager = $this->getMockForAbstractClass(
+            'Magento\Framework\Message\ManagerInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['addSuccess']
+        );
+        $this->categoryRepository = $this->getMock('Magento\Catalog\Api\CategoryRepositoryInterface');
+        $context->expects($this->any())
+            ->method('getRequest')
+            ->will($this->returnValue($this->request));
+        $context->expects($this->any())
+            ->method('getResponse')
+            ->will($this->returnValue($response));
+        $context->expects($this->any())
+            ->method('getMessageManager')
+            ->will($this->returnValue($messageManager));
+        $context->expects($this->any())
+            ->method('getEventManager')
+            ->will($this->returnValue($eventManager));
+        $context->expects($this->any())
+            ->method('getAuth')
+            ->will($this->returnValue($auth));
+        $auth->expects($this->any())
+            ->method('getAuthStorage')
+            ->will($this->returnValue($this->authStorage));
+
+        $this->resultRedirect = $this->getMock('Magento\Backend\Model\View\Result\Redirect', [], [], '', false);
+        $resultRedirectFactory->expects($this->any())->method('create')->willReturn($this->resultRedirect);
+
+        $this->unit = (new ObjectManagerHelper($this))->getObject(
+            'Magento\Catalog\Controller\Adminhtml\Category\Delete',
+            [
+                'context' => $context,
+                'resultRedirectFactory' => $resultRedirectFactory,
+                'categoryRepository' => $this->categoryRepository
+            ]
+        );
+    }
+
+    public function testDeleteWithoutCategoryId()
+    {
+        $this->request->expects($this->any())->method('getParam')->with('id')->willReturn(null);
+        $this->resultRedirect->expects($this->once())->method('setPath')
+            ->with('catalog/*/', ['_current' => true, 'id' => null]);
+        $this->categoryRepository->expects($this->never())->method('get');
+
+        $this->unit->execute();
+    }
+
+    public function testDelete()
+    {
+        $categoryId = 5;
+        $parentId = 7;
+        $this->request->expects($this->any())->method('getParam')->with('id')->willReturn($categoryId);
+        $category = $this->getMock('Magento\Catalog\Model\Category', ['getParentId', 'getPath'], [], '', false);
+        $category->expects($this->once())->method('getParentId')->willReturn($parentId);
+        $category->expects($this->once())->method('getPath')->willReturn('category-path');
+        $this->categoryRepository->expects($this->once())->method('get')->with($categoryId)->willReturn($category);
+        $this->authStorage->expects($this->once())->method('setDeletedPath')->with('category-path');
+        $this->resultRedirect->expects($this->once())->method('setPath')
+            ->with('catalog/*/', ['_current' => true, 'id' => $parentId]);
+
+        $this->unit->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/SetupTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/SetupTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..557582b27a5035e74157f753fb8e472e895c14c7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/SetupTest.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Model\Resource;
+
+class SetupTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Catalog\Model\Resource\Setup */
+    protected $unit;
+
+    protected function setUp()
+    {
+        $this->unit = (new \Magento\TestFramework\Helper\ObjectManager($this))->getObject(
+            'Magento\Catalog\Model\Resource\Setup'
+        );
+    }
+
+    public function testGetDefaultEntitiesContainAllAttributes()
+    {
+        $defaultEntities = $this->unit->getDefaultEntities();
+
+        $this->assertEquals(
+            [
+                'name',
+                'is_active',
+                'description',
+                'image',
+                'meta_title',
+                'meta_keywords',
+                'meta_description',
+                'display_mode',
+                'landing_page',
+                'is_anchor',
+                'path',
+                'position',
+                'all_children',
+                'path_in_store',
+                'children',
+                'custom_design',
+                'custom_design_from',
+                'custom_design_to',
+                'page_layout',
+                'custom_layout_update',
+                'level',
+                'children_count',
+                'available_sort_by',
+                'default_sort_by',
+                'include_in_menu',
+                'custom_use_parent_settings',
+                'custom_apply_to_products',
+                'filter_price_range',
+            ],
+            array_keys($defaultEntities['catalog_category']['attributes'])
+        );
+
+        $this->assertEquals(
+            [
+                'name',
+                'sku',
+                'description',
+                'short_description',
+                'price',
+                'special_price',
+                'special_from_date',
+                'special_to_date',
+                'cost',
+                'weight',
+                'manufacturer',
+                'meta_title',
+                'meta_keyword',
+                'meta_description',
+                'image',
+                'small_image',
+                'thumbnail',
+                'media_gallery',
+                'old_id',
+                'group_price',
+                'tier_price',
+                'color',
+                'news_from_date',
+                'news_to_date',
+                'gallery',
+                'status',
+                'minimal_price',
+                'visibility',
+                'custom_design',
+                'custom_design_from',
+                'custom_design_to',
+                'custom_layout_update',
+                'page_layout',
+                'category_ids',
+                'options_container',
+                'required_options',
+                'has_options',
+                'image_label',
+                'small_image_label',
+                'thumbnail_label',
+                'created_at',
+                'updated_at',
+                'country_of_manufacture',
+                'quantity_and_stock_status',
+            ],
+            array_keys($defaultEntities['catalog_product']['attributes'])
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogRule/Plugin/Model/Product/ActionTest.php b/dev/tests/unit/testsuite/Magento/CatalogRule/Plugin/Model/Product/ActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..189e4b63018d71651287e8817f60accba65bc133
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogRule/Plugin/Model/Product/ActionTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\CatalogRule\Plugin\Model\Product;
+
+class ActionTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogRule\Plugin\Model\Product\Action */
+    protected $action;
+
+    /** @var \Magento\CatalogRule\Model\Indexer\Product\ProductRuleProcessor|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productRuleProcessor;
+
+    protected function setUp()
+    {
+        $this->productRuleProcessor = $this->getMockBuilder(
+            'Magento\CatalogRule\Model\Indexer\Product\ProductRuleProcessor'
+        )->disableOriginalConstructor()
+        ->setMethods(['reindexList'])
+        ->getMock();
+
+        $this->action = new Action($this->productRuleProcessor);
+    }
+
+    public function testAfterUpdateAttributes()
+    {
+        $subject = $this->getMockBuilder('Magento\Catalog\Model\Product\Action')
+            ->disableOriginalConstructor()
+            ->setMethods([])
+            ->getMock();
+
+        $result = $this->getMockBuilder('Magento\Catalog\Model\Product\Action')
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributesData', 'getProductIds'])
+            ->getMock();
+
+        $result->expects($this->once())
+            ->method('getAttributesData')
+            ->willReturn([]);
+
+        $result->expects($this->never())
+            ->method('getProductIds');
+
+        $this->productRuleProcessor->expects($this->never())
+            ->method('reindexList');
+
+        $this->action->afterUpdateAttributes($subject, $result);
+    }
+
+    public function testAfterUpdateAttributesWithPrice()
+    {
+        $productIds = [1, 2, 3];
+        $subject = $this->getMockBuilder('Magento\Catalog\Model\Product\Action')
+            ->disableOriginalConstructor()
+            ->setMethods([])
+            ->getMock();
+
+        $result = $this->getMockBuilder('Magento\Catalog\Model\Product\Action')
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributesData', 'getProductIds'])
+            ->getMock();
+
+        $result->expects($this->once())
+            ->method('getAttributesData')
+            ->willReturn(['price' => 100]);
+
+        $result->expects($this->once())
+            ->method('getProductIds')
+            ->willReturn($productIds);
+
+        $this->productRuleProcessor->expects($this->once())
+            ->method('reindexList')
+            ->with($productIds);
+
+        $this->action->afterUpdateAttributes($subject, $result);
+    }
+}