diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
index e56e622bf96d5..f7190d6f899f6 100644
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,22 @@
+Update as of 7/3/2012
+=====================
+* Refactored backend (admin) menu generation:
+  * Menu is separated from `adminhtml.xml` files into `menu.xml` files
+  * Rendering menu became responsibility of `Mage_Backend` instead of `Mage_Adminhtml` module
+  * Implemented XML-Schema for `menu.xml`
+  * Actions with menu items defined in schema: add, remove, move, update, change parent and position
+* Refactored customers import feature. New ability to provide import data in 3 files: master file (key customer information) + address file (customer id + address info) + financial file (customer id + reward points & store credit)
+* Optimized memory consumption in integration tests:
+  * Found and eliminated memory leaks in `Mage_Core_Model_App_Area`, `Mage_Core_Model_Layout`
+  * Manually unset objects from PHPUnit test case object in `tearDown()` in integration tests. Garbage collector didn't purge them because of these references
+  * Disabled running `integrity` test suite by default in integration tests
+* Improvements in visual design editor JavaScript:
+  * eliminated dependency of code on HTML-literals, reduced code coupling between templates and JavaScript files
+  * implemented blocking unwanted JavaScript activity in visual design editor mode
+* Various fixes in UX, code stability, modularity
+* GitHub requests:
+  * [#23](https://github.com/magento/magento2/pull/23) -- added `Mage_Customer_Block_Account_Navigation::removeLink()`
+
 Update as of 6/20/2012
 =====================
 * Implemented locale translation inheritance
@@ -8,7 +27,7 @@ Update as of 6/20/2012
 * Implemented optional tracking of changes in view files fallback - cached by default, tracked in developer mode
 * Introduced `@magentoDbIsolation` annotation in integration tests - isolates DB modifications made by tests
 * Started refactoring of Visual Design Editor Javascript architecture
-* Github requests:
+* GitHub requests:
   * [#25](https://github.com/magento/magento2/issues/25) Removed unused `Mage_Core_Block_Abstract::getHelper()` method
 * Fixed:
   * "$_FILES array is empty" messages in exception log upon installation
@@ -26,8 +45,8 @@ Update as of 6/7/2012
 * Eliminated "after commit callback" workaround from integration tests by implementing "transparent transactions" capability in integration testing framework
 * Refactored admin authentication/authorization in RSS module. Removed program termination and covered the controllers with tests
 * Removed HTML-report feature of copy-paste detector which never worked anyway (`dev/tests/static/framework/Inspection/CopyPasteDetector/html_report.xslt` and all related code)
-* Github requests:
-** [#19](https://github.com/magento/magento2/pull/19) Implemented "soft" dependency between modules and performed several improvements in the related code, covered with tests
+* GitHub requests:
+  * [#19](https://github.com/magento/magento2/pull/19) Implemented "soft" dependency between modules and performed several improvements in the related code, covered with tests
 
 Update as of 5/31/2012
 ======================
diff --git a/app/code/core/Mage/Admin/Model/Config.php b/app/code/core/Mage/Admin/Model/Config.php
index 4e064fdc7e28f..941e6a73f89d1 100644
--- a/app/code/core/Mage/Admin/Model/Config.php
+++ b/app/code/core/Mage/Admin/Model/Config.php
@@ -333,20 +333,4 @@ public function getAdminhtmlConfig()
     {
         return $this->_adminhtmlConfig;
     }
-
-    /**
-     * Get menu item label by item path
-     *
-     * @param string $path
-     * @return string
-     */
-    public function getMenuItemLabel($path)
-    {
-        $moduleName = 'Mage_Adminhtml_Helper_Data';
-        $menuNode = $this->getAdminhtmlConfig()->getNode('menu/' . str_replace('/', '/children/', trim($path, '/')));
-        if ($menuNode->getAttribute('module')) {
-            $moduleName = (string)$menuNode->getAttribute('module');
-        }
-        return $this->_getHelper($moduleName)->__((string)$menuNode->title);
-    }
 }
diff --git a/app/code/core/Mage/AdminNotification/etc/adminhtml.xml b/app/code/core/Mage/AdminNotification/etc/adminhtml.xml
index 5b832ebd0e77f..053695bdc3975 100644
--- a/app/code/core/Mage/AdminNotification/etc/adminhtml.xml
+++ b/app/code/core/Mage/AdminNotification/etc/adminhtml.xml
@@ -60,15 +60,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <system>
-            <children>
-                <adminnotification translate="title" module="Mage_AdminNotification">
-                    <title>Notifications</title>
-                    <action>adminhtml/notification</action>
-                    <sort_order>15</sort_order>
-                </adminnotification>
-            </children>
-        </system>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/AdminNotification/etc/adminhtml/menu.xml b/app/code/core/Mage/AdminNotification/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..a2d90079d57db
--- /dev/null
+++ b/app/code/core/Mage/AdminNotification/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_AdminNotification
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_AdminNotification::system_adminnotification" title="Notifications" module="Mage_AdminNotification" sortOrder="15" parent="Mage_Adminhtml::system" action="adminhtml/notification" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Adminhtml/Block/Report/Product/Viewed/Grid.php b/app/code/core/Mage/Adminhtml/Block/Report/Product/Viewed/Grid.php
index 44f3d36e28296..73b80875ba618 100644
--- a/app/code/core/Mage/Adminhtml/Block/Report/Product/Viewed/Grid.php
+++ b/app/code/core/Mage/Adminhtml/Block/Report/Product/Viewed/Grid.php
@@ -45,7 +45,7 @@ class Mage_Adminhtml_Block_Report_Product_Viewed_Grid extends Mage_Adminhtml_Blo
      *
      * @var string
      */
-    protected $_resourceCollectionName  = 'Mage_Reports_Model_Resource_Product_Viewed_Collection';
+    protected $_resourceCollectionName  = 'Mage_Reports_Model_Resource_Report_Product_Viewed_Collection';
 
     /**
      * Init grid parameters
diff --git a/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php b/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
index 44d3eab20dbfd..893d9d445d0ab 100644
--- a/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
+++ b/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
@@ -350,12 +350,16 @@ protected function _getSystemConfigPathsParts($paths)
         $result = $urlParams = $prefixParts = array();
         $scopeLabel = Mage::helper('Mage_Adminhtml_Helper_Data')->__('GLOBAL');
         if ($paths) {
+            /** @var $menu Mage_Backend_Model_Menu */
+            $menu = Mage::getSingleton('Mage_Backend_Model_Menu_Config')->getMenu();
+            $item = $menu->get('Mage_Adminhtml::system');
             // create prefix path parts
             $prefixParts[] = array(
-                'title' => Mage::getSingleton('Mage_Admin_Model_Config')->getMenuItemLabel('system'),
+                'title' => $item->getModuleHelper()->__($item->getTitle()),
             );
+            $item = $menu->get('Mage_Adminhtml::system_config');
             $prefixParts[] = array(
-                'title' => Mage::getSingleton('Mage_Admin_Model_Config')->getMenuItemLabel('system/config'),
+                'title' => $item->getModuleHelper()->__($item->getTitle()),
                 'url' => $this->getUrl('adminhtml/system_config/'),
             );
 
diff --git a/app/code/core/Mage/Adminhtml/Controller/Sales/Creditmemo.php b/app/code/core/Mage/Adminhtml/Controller/Sales/Creditmemo.php
index d01031cae914b..c36b0384ae255 100644
--- a/app/code/core/Mage/Adminhtml/Controller/Sales/Creditmemo.php
+++ b/app/code/core/Mage/Adminhtml/Controller/Sales/Creditmemo.php
@@ -48,7 +48,7 @@ protected function _construct()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/order')
+            ->_setActiveMenu('Mage_Sales::sales_order')
             ->_addBreadcrumb($this->__('Sales'), $this->__('Sales'))
             ->_addBreadcrumb($this->__('Credit Memos'),$this->__('Credit Memos'));
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/Controller/Sales/Invoice.php b/app/code/core/Mage/Adminhtml/Controller/Sales/Invoice.php
index 4862a09e050f8..3199448d9c04a 100644
--- a/app/code/core/Mage/Adminhtml/Controller/Sales/Invoice.php
+++ b/app/code/core/Mage/Adminhtml/Controller/Sales/Invoice.php
@@ -48,7 +48,7 @@ protected function _construct()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/order')
+            ->_setActiveMenu('Mage_Sales::sales_order')
             ->_addBreadcrumb($this->__('Sales'), $this->__('Sales'))
             ->_addBreadcrumb($this->__('Invoices'),$this->__('Invoices'));
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/Controller/Sales/Shipment.php b/app/code/core/Mage/Adminhtml/Controller/Sales/Shipment.php
index 3ef138463c650..cc82fbf1a013c 100644
--- a/app/code/core/Mage/Adminhtml/Controller/Sales/Shipment.php
+++ b/app/code/core/Mage/Adminhtml/Controller/Sales/Shipment.php
@@ -48,7 +48,7 @@ protected function _construct()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/order')
+            ->_setActiveMenu('Mage_Sales::sales_order')
             ->_addBreadcrumb($this->__('Sales'), $this->__('Sales'))
             ->_addBreadcrumb($this->__('Shipments'),$this->__('Shipments'));
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Admin/Page.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Admin/Page.php
index 97818fd3ff5ae..39864b4de5327 100644
--- a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Admin/Page.php
+++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Admin/Page.php
@@ -34,136 +34,87 @@
  */
 class Mage_Adminhtml_Model_System_Config_Source_Admin_Page
 {
-    protected $_url;
+    /**
+     * Menu model
+     *
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menu;
+
+    /**
+     * Object factory
+     *
+     * @var Mage_Core_Model_Config
+     */
+    protected $_objectFactory;
+
+    /**
+     * Default construct
+     */
+    public function __construct(array $data = array())
+    {
+        $this->_menu = isset($data['menu']) ?
+            $data['menu'] :
+            Mage::getSingleton('Mage_Backend_Model_Menu_Config')->getMenu();
+
+        $this->_objectFactory = isset($data['objectFactory']) ? $data['objectFactory'] : Mage::getConfig();
+    }
 
     public function toOptionArray()
     {
         $options = array();
-        $menu    = $this->_buildMenuArray();
-
-        $this->_createOptions($options, $menu);
-
+        $this->_createOptions($options, $this->_menu);
         return $options;
     }
 
-    protected function _createOptions(&$optionArray, $menuNode)
+    /**
+     * Get menu filter iterator
+     *
+     * @param Mage_Backend_Model_Menu $menu menu model
+     * @return Mage_Backend_Model_Menu_Filter_Iterator
+     */
+    protected function _getMenuIterator(Mage_Backend_Model_Menu $menu)
+    {
+        return $this->_objectFactory->getModelInstance('Mage_Backend_Model_Menu_Filter_Iterator', $menu->getIterator());
+    }
+
+    /**
+     * Create options array
+     *
+     * @param array $optionArray
+     * @param Mage_Backend_Model_Menu $menu
+     * @param int $level
+     */
+    protected function _createOptions(&$optionArray, Mage_Backend_Model_Menu $menu, $level = 0)
     {
         $nonEscapableNbspChar = html_entity_decode('&#160;', ENT_NOQUOTES, 'UTF-8');
+        $paddingString = str_repeat($nonEscapableNbspChar, ($level * 4));
 
-        foreach ($menuNode as $menu) {
+        foreach ($this->_getMenuIterator($menu) as $menuItem) {
 
-            if (!empty($menu['url'])) {
+            /**@var  $menuItem Mage_Backend_Model_Menu_Item */
+            if ($menuItem->getAction()) {
                 $optionArray[] = array(
-                    'label' => str_repeat($nonEscapableNbspChar, ($menu['level'] * 4)) . $menu['label'],
-                    'value' => $menu['path'],
+                    'label' =>  $paddingString . $menuItem->getTitle(),
+                    'value' => $menuItem->getId(),
                 );
 
-                if (isset($menu['children'])) {
-                    $this->_createOptions($optionArray, $menu['children']);
+                if ($menuItem->hasChildren()) {
+                    $this->_createOptions($optionArray, $menuItem->getChildren(), $level + 1);
                 }
             }
             else {
                 $children = array();
 
-                if(isset($menu['children'])) {
-                    $this->_createOptions($children, $menu['children']);
+                if($menuItem->hasChildren()) {
+                    $this->_createOptions($children, $menuItem->getChildren(), $level + 1);
                 }
 
                 $optionArray[] = array(
-                    'label' => str_repeat($nonEscapableNbspChar, ($menu['level'] * 4)) . $menu['label'],
+                    'label' => $paddingString . $menuItem->getTitle(),
                     'value' => $children,
                 );
             }
         }
     }
-
-    protected function _getUrlModel()
-    {
-        if (is_null($this->_url)) {
-            $this->_url = Mage::getModel('Mage_Adminhtml_Model_Url');
-        }
-        return $this->_url;
-    }
-
-    protected function _buildMenuArray(Varien_Simplexml_Element $parent=null, $path='', $level=0)
-    {
-        if (is_null($parent)) {
-            $parent = Mage::getSingleton('Mage_Admin_Model_Config')->getAdminhtmlConfig()->getNode('menu');
-        }
-
-        $parentArr = array();
-        $sortOrder = 0;
-        foreach ($parent->children() as $childName=>$child) {
-            if ((1 == $child->disabled)
-                || ($child->depends && !$this->_checkDepends($child->depends))
-            ) {
-                continue;
-            }
-
-            $menuArr = array();
-            $menuArr['label'] = $this->_getHelperValue($child);
-
-            $menuArr['sort_order'] = $child->sort_order ? (int)$child->sort_order : $sortOrder;
-
-            if ($child->action) {
-                $menuArr['url'] = (string)$child->action;
-            } else {
-                $menuArr['url'] = '';
-            }
-
-            $menuArr['level'] = $level;
-            $menuArr['path'] = $path . $childName;
-
-            if ($child->children) {
-                $menuArr['children'] = $this->_buildMenuArray($child->children, $path.$childName.'/', $level+1);
-            }
-            $parentArr[$childName] = $menuArr;
-
-            $sortOrder++;
-        }
-
-        uasort($parentArr, array($this, '_sortMenu'));
-
-        while (list($key, $value) = each($parentArr)) {
-            $last = $key;
-        }
-        if (isset($last)) {
-            $parentArr[$last]['last'] = true;
-        }
-
-        return $parentArr;
-    }
-
-    protected function _sortMenu($a, $b)
-    {
-        return $a['sort_order']<$b['sort_order'] ? -1 : ($a['sort_order']>$b['sort_order'] ? 1 : 0);
-    }
-
-    protected function _checkDepends(Varien_Simplexml_Element $depends)
-    {
-        if ($depends->module) {
-            $modulesConfig = Mage::getConfig()->getNode('modules');
-            foreach ($depends->module as $module) {
-                if (!$modulesConfig->$module || !$modulesConfig->$module->is('active')) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    protected function _getHelperValue(Varien_Simplexml_Element $child)
-    {
-        $helperName         = 'Mage_Adminhtml_Helper_Data';
-        $titleNodeName      = 'title';
-        $childAttributes    = $child->attributes();
-        if (isset($childAttributes['module'])) {
-            $helperName     = (string)$childAttributes['module'];
-        }
-
-        $titleNodeName = 'title';
-
-        return Mage::helper($helperName)->__((string)$child->$titleNodeName);
-    }
 }
diff --git a/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php b/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
index 210c73f52ab07..de1076af2e027 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
@@ -37,7 +37,7 @@ class Mage_Adminhtml_Api_RoleController extends Mage_Adminhtml_Controller_Action
     protected function _initAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('system/services/roles');
+        $this->_setActiveMenu('Mage_Api::system_api_roles');
         $this->_addBreadcrumb($this->__('Web services'), $this->__('Web services'));
         $this->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'));
         $this->_addBreadcrumb($this->__('Roles'), $this->__('Roles'));
diff --git a/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php b/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php
index 057b53a0d075c..2c53eec41c26d 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php
@@ -29,7 +29,7 @@ class Mage_Adminhtml_Api_UserController extends Mage_Adminhtml_Controller_Action
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('system/services/users')
+            ->_setActiveMenu('Mage_Api::system_api_users')
             ->_addBreadcrumb($this->__('Web Services'), $this->__('Web Services'))
             ->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'))
             ->_addBreadcrumb($this->__('Users'), $this->__('Users'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/CacheController.php b/app/code/core/Mage/Adminhtml/controllers/CacheController.php
index ef5498b742441..e446ac275306c 100644
--- a/app/code/core/Mage/Adminhtml/controllers/CacheController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/CacheController.php
@@ -44,7 +44,7 @@ public function indexAction()
         $this->_title($this->__('System'))->_title($this->__('Cache Management'));
 
         $this->loadLayout()
-            ->_setActiveMenu('system/cache')
+            ->_setActiveMenu('Mage_Adminhtml::system_cache')
             ->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
index b2d1f7f359671..926beb68ae97f 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
@@ -199,7 +199,7 @@ public function editAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/categories');
+        $this->_setActiveMenu('Mage_Catalog::catalog_categories');
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true)
             ->setContainerCssClass('catalog-categories');
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php
index abedfe7fcd09d..8c4ac365d727d 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php
@@ -53,7 +53,7 @@ protected function _initAction()
             $this->loadLayout('popup');
         } else {
             $this->loadLayout()
-                ->_setActiveMenu('catalog/attributes')
+                ->_setActiveMenu('Mage_Catalog::catalog_attributes')
                 ->_addBreadcrumb(Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'), Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'))
                 ->_addBreadcrumb(
                     Mage::helper('Mage_Catalog_Helper_Data')->__('Manage Product Attributes'),
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/ReviewController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/ReviewController.php
index 399cc90c7ef9e..31ae0ca6ec47d 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/ReviewController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/ReviewController.php
@@ -54,7 +54,7 @@ public function indexAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/review');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_reviews_all');
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Review_Main'));
 
@@ -75,7 +75,7 @@ public function pendingAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/review');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_reviews_pending');
 
         Mage::register('usePendingFilter', true);
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Review_Main'));
@@ -92,7 +92,7 @@ public function editAction()
         $this->_title($this->__('Edit Review'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/review');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_reviews_all');
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Review_Edit'));
 
@@ -108,7 +108,7 @@ public function newAction()
         $this->_title($this->__('New Review'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/review');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_reviews_all');
 
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php
index 75e92f9a2f681..09f33632970e1 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php
@@ -43,7 +43,7 @@ public function indexAction()
         $this->_setTypeId();
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/sets');
+        $this->_setActiveMenu('Mage_Catalog::catalog_attributes_sets');
 
         $this->_addBreadcrumb(Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'), Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'));
         $this->_addBreadcrumb(
@@ -80,7 +80,7 @@ public function editAction()
         Mage::register('current_attribute_set', $attributeSet);
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/sets');
+        $this->_setActiveMenu('Mage_Catalog::catalog_attributes_sets');
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
 
         $this->_addBreadcrumb(Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'), Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'));
@@ -189,7 +189,7 @@ public function addAction()
         $this->_setTypeId();
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/sets');
+        $this->_setActiveMenu('Mage_Catalog::catalog_attributes_sets');
 
         $this->_addContent(
             $this->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Toolbar_Add')
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
index b5c98932e3a3a..363e7a44887c8 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
@@ -206,7 +206,7 @@ public function newAction()
                 strtolower($this->getFullActionName()),
                 'adminhtml_catalog_product_'.$product->getTypeId() . $_additionalLayoutPart
             ));
-            $this->_setActiveMenu('catalog/products');
+            $this->_setActiveMenu('Mage_Catalog::catalog_products');
         }
 
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
@@ -250,7 +250,7 @@ public function editAction()
             'adminhtml_catalog_product_'.$product->getTypeId() . $_additionalLayoutPart
         ));
 
-        $this->_setActiveMenu('catalog/products');
+        $this->_setActiveMenu('Mage_Catalog::catalog_products');
 
         if (!Mage::app()->isSingleStoreMode() && ($switchBlock = $this->getLayout()->getBlock('store_switcher'))) {
             $switchBlock->setDefaultStoreName($this->__('Default Values'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php
index a1dea614b5edd..63de802a118dd 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php
@@ -30,7 +30,7 @@ class Mage_Adminhtml_Catalog_SearchController extends Mage_Adminhtml_Controller_
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('catalog/search')
+            ->_setActiveMenu('Mage_CatalogSearch::catalog_search')
             ->_addBreadcrumb(Mage::helper('Mage_Catalog_Helper_Data')->__('Search'), Mage::helper('Mage_Catalog_Helper_Data')->__('Search'))
         ;
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Checkout/AgreementController.php b/app/code/core/Mage/Adminhtml/controllers/Checkout/AgreementController.php
index f42466fdf8060..4b1a34fdf7187 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Checkout/AgreementController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Checkout/AgreementController.php
@@ -153,7 +153,7 @@ public function deleteAction()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/checkoutagreement')
+            ->_setActiveMenu('Mage_Checkout::sales_checkoutagreement')
             ->_addBreadcrumb(Mage::helper('Mage_Checkout_Helper_Data')->__('Sales'), Mage::helper('Mage_Checkout_Helper_Data')->__('Sales'))
             ->_addBreadcrumb(Mage::helper('Mage_Checkout_Helper_Data')->__('Checkout Conditions'), Mage::helper('Mage_Checkout_Helper_Data')->__('Checkout Terms and Conditions'))
         ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Cms/BlockController.php b/app/code/core/Mage/Adminhtml/controllers/Cms/BlockController.php
index 6851e455f27c4..b499d7c940e2b 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Cms/BlockController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Cms/BlockController.php
@@ -43,7 +43,7 @@ protected function _initAction()
     {
         // load layout, set active menu and breadcrumbs
         $this->loadLayout()
-            ->_setActiveMenu('cms/block')
+            ->_setActiveMenu('Mage_Cms::cms_block')
             ->_addBreadcrumb(Mage::helper('Mage_Cms_Helper_Data')->__('CMS'), Mage::helper('Mage_Cms_Helper_Data')->__('CMS'))
             ->_addBreadcrumb(Mage::helper('Mage_Cms_Helper_Data')->__('Static Blocks'), Mage::helper('Mage_Cms_Helper_Data')->__('Static Blocks'))
         ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php b/app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php
index 96afce8b73035..c54ae4f4ecc26 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php
@@ -44,7 +44,7 @@ protected function _initAction()
     {
         // load layout, set active menu and breadcrumbs
         $this->loadLayout()
-            ->_setActiveMenu('cms/page')
+            ->_setActiveMenu('Mage_Cms::cms_page')
             ->_addBreadcrumb(Mage::helper('Mage_Cms_Helper_Data')->__('CMS'), Mage::helper('Mage_Cms_Helper_Data')->__('CMS'))
             ->_addBreadcrumb(Mage::helper('Mage_Cms_Helper_Data')->__('Manage Pages'), Mage::helper('Mage_Cms_Helper_Data')->__('Manage Pages'))
         ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Customer/GroupController.php b/app/code/core/Mage/Adminhtml/controllers/Customer/GroupController.php
index d401df57f1b9b..60cb929a6450c 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Customer/GroupController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Customer/GroupController.php
@@ -52,7 +52,7 @@ public function indexAction()
         $this->_title($this->__('Customers'))->_title($this->__('Customer Groups'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('customer/group');
+        $this->_setActiveMenu('Mage_Customer::customer_group');
         $this->_addBreadcrumb(Mage::helper('Mage_Customer_Helper_Data')->__('Customers'), Mage::helper('Mage_Customer_Helper_Data')->__('Customers'));
         $this->_addBreadcrumb(Mage::helper('Mage_Customer_Helper_Data')->__('Customer Groups'), Mage::helper('Mage_Customer_Helper_Data')->__('Customer Groups'));
         $this->renderLayout();
@@ -65,7 +65,7 @@ public function newAction()
     {
         $this->_initGroup();
         $this->loadLayout();
-        $this->_setActiveMenu('customer/group');
+        $this->_setActiveMenu('Mage_Customer::customer_group');
         $this->_addBreadcrumb(Mage::helper('Mage_Customer_Helper_Data')->__('Customers'), Mage::helper('Mage_Customer_Helper_Data')->__('Customers'));
         $this->_addBreadcrumb(Mage::helper('Mage_Customer_Helper_Data')->__('Customer Groups'), Mage::helper('Mage_Customer_Helper_Data')->__('Customer Groups'), $this->getUrl('*/customer_group'));
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Customer/OnlineController.php b/app/code/core/Mage/Adminhtml/controllers/Customer/OnlineController.php
index 18a3c4701571f..c31a80ebb29e0 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Customer/OnlineController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Customer/OnlineController.php
@@ -37,7 +37,7 @@ public function indexAction()
 
         $this->loadLayout();
 
-        $this->_setActiveMenu('customer/online');
+        $this->_setActiveMenu('Mage_Customer::customer_online');
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Customer_Online', 'customers'));
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/CustomerController.php b/app/code/core/Mage/Adminhtml/controllers/CustomerController.php
index b2bdca970cdd5..15b3cfc448ab4 100644
--- a/app/code/core/Mage/Adminhtml/controllers/CustomerController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/CustomerController.php
@@ -65,7 +65,7 @@ public function indexAction()
         /**
          * Set active menu item
          */
-        $this->_setActiveMenu('customer/manage');
+        $this->_setActiveMenu('Mage_Customer::customer_manage');
 
         /**
          * Append customers block to content
@@ -146,7 +146,7 @@ public function editAction()
         /**
          * Set active menu item
          */
-        $this->_setActiveMenu('customer/new');
+        $this->_setActiveMenu('Mage_Customer::customer');
 
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/DashboardController.php b/app/code/core/Mage/Adminhtml/controllers/DashboardController.php
index 41cda09b36e00..b5da784d369b8 100644
--- a/app/code/core/Mage/Adminhtml/controllers/DashboardController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/DashboardController.php
@@ -38,7 +38,7 @@ public function indexAction()
         $this->_title($this->__('Dashboard'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('dashboard');
+        $this->_setActiveMenu('Mage_Adminhtml::dashboard');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Dashboard'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Dashboard'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/Newsletter/ProblemController.php b/app/code/core/Mage/Adminhtml/controllers/Newsletter/ProblemController.php
index 4af483ab86aa1..25fc01fb8e33f 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Newsletter/ProblemController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Newsletter/ProblemController.php
@@ -47,7 +47,7 @@ public function indexAction()
         );
         $this->loadLayout();
 
-        $this->_setActiveMenu('newsletter/problem');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_problem');
 
         $this->_addBreadcrumb(Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter Problem Reports'), Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter Problem Reports'));
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php b/app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php
index 07506ff12846c..904938164e874 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php
@@ -47,7 +47,7 @@ public function indexAction()
 
         $this->loadLayout();
 
-        $this->_setActiveMenu('newsletter/queue');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_queue');
 
         $this->_addContent(
             $this->getLayout()->createBlock('Mage_Adminhtml_Block_Newsletter_Queue', 'queue')
@@ -203,7 +203,7 @@ public function editAction()
 
         $this->loadLayout();
 
-        $this->_setActiveMenu('newsletter/queue');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_queue');
 
         $this->_addBreadcrumb(
             Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter Queue'), 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Newsletter/SubscriberController.php b/app/code/core/Mage/Adminhtml/controllers/Newsletter/SubscriberController.php
index 6db51db1cab71..90ba5a7a2ebd4 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Newsletter/SubscriberController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Newsletter/SubscriberController.php
@@ -45,7 +45,7 @@ public function indexAction()
 
         $this->loadLayout();
 
-        $this->_setActiveMenu('newsletter/subscriber');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_subscriber');
 
         $this->_addBreadcrumb(Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter'), Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter'));
         $this->_addBreadcrumb(Mage::helper('Mage_Newsletter_Helper_Data')->__('Subscribers'), Mage::helper('Mage_Newsletter_Helper_Data')->__('Subscribers'));
diff --git a/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php b/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php
index b2ecf192f0669..43467934ac29d 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php
@@ -66,7 +66,7 @@ public function indexAction ()
             return;
         }
         $this->loadLayout();
-        $this->_setActiveMenu('newsletter/template');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_template');
         $this->_addBreadcrumb(Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter Templates'), Mage::helper('Mage_Newsletter_Helper_Data')->__('Newsletter Templates'));
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Newsletter_Template', 'template'));
         $this->renderLayout();
@@ -109,7 +109,7 @@ public function editAction ()
         Mage::register('_current_template', $model);
 
         $this->loadLayout();
-        $this->_setActiveMenu('newsletter/template');
+        $this->_setActiveMenu('Mage_Newsletter::newsletter_template');
 
         if ($model->getId()) {
             $breadcrumbTitle = Mage::helper('Mage_Newsletter_Helper_Data')->__('Edit Template');
diff --git a/app/code/core/Mage/Adminhtml/controllers/NotificationController.php b/app/code/core/Mage/Adminhtml/controllers/NotificationController.php
index 5ffc283b20953..5b8f705ec1dd4 100644
--- a/app/code/core/Mage/Adminhtml/controllers/NotificationController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/NotificationController.php
@@ -39,7 +39,7 @@ public function indexAction()
         $this->_title($this->__('System'))->_title($this->__('Notifications'));
 
         $this->loadLayout()
-            ->_setActiveMenu('system/notification')
+            ->_setActiveMenu('Mage_AdminNotification::system_adminnotification')
             ->_addBreadcrumb(Mage::helper('Mage_AdminNotification_Helper_Data')->__('Messages Inbox'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Messages Inbox'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Notification_Inbox'))
             ->renderLayout();
diff --git a/app/code/core/Mage/Adminhtml/controllers/Poll/AnswerController.php b/app/code/core/Mage/Adminhtml/controllers/Poll/AnswerController.php
index 9ce9aa159683b..22e15c5e004af 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Poll/AnswerController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Poll/AnswerController.php
@@ -38,7 +38,7 @@ public function editAction()
     {
         $this->loadLayout();
 
-        $this->_setActiveMenu('cms/poll');
+        $this->_setActiveMenu('Mage_Poll::cms_poll');
         $this->_addBreadcrumb(Mage::helper('Mage_Poll_Helper_Data')->__('Poll Manager'),
                               Mage::helper('Mage_Poll_Helper_Data')->__('Poll Manager'), $this->getUrl('*/*/'));
         $this->_addBreadcrumb(Mage::helper('Mage_Poll_Helper_Data')->__('Edit Poll Answer'),
diff --git a/app/code/core/Mage/Adminhtml/controllers/PollController.php b/app/code/core/Mage/Adminhtml/controllers/PollController.php
index 5d5a52e201bff..8a08775d8b8d4 100644
--- a/app/code/core/Mage/Adminhtml/controllers/PollController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/PollController.php
@@ -39,7 +39,7 @@ public function indexAction()
         $this->_title($this->__('CMS'))->_title($this->__('Polls'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('cms/poll');
+        $this->_setActiveMenu('Mage_Poll::cms_poll');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Poll Manager'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Poll Manager'));
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Poll_Poll'));
@@ -59,7 +59,7 @@ public function editAction()
             Mage::register('poll_data', $pollModel);
 
             $this->loadLayout();
-            $this->_setActiveMenu('cms/poll');
+            $this->_setActiveMenu('Mage_Poll::cms_poll');
             $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Poll Manager'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Poll Manager'), $this->getUrl('*/*/'));
             $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Edit Poll'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Edit Poll'));
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Promo/CatalogController.php b/app/code/core/Mage/Adminhtml/controllers/Promo/CatalogController.php
index db127fd529f49..e663edffe28ed 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Promo/CatalogController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Promo/CatalogController.php
@@ -43,7 +43,7 @@ class Mage_Adminhtml_Promo_CatalogController extends Mage_Adminhtml_Controller_A
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('promo/catalog')
+            ->_setActiveMenu('Mage_CatalogRule::promo_catalog')
             ->_addBreadcrumb(
                 Mage::helper('Mage_CatalogRule_Helper_Data')->__('Promotions'),
                 Mage::helper('Mage_CatalogRule_Helper_Data')->__('Promotions')
diff --git a/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php b/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php
index 09dfceb15a507..fc1ff2416c3a6 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php
@@ -46,7 +46,7 @@ protected function _initRule()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('promo/quote')
+            ->_setActiveMenu('Mage_SalesRule::promo_quote')
             ->_addBreadcrumb(Mage::helper('Mage_SalesRule_Helper_Data')->__('Promotions'), Mage::helper('Mage_SalesRule_Helper_Data')->__('Promotions'))
         ;
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/controllers/PromoController.php b/app/code/core/Mage/Adminhtml/controllers/PromoController.php
index c614c06831d51..fb21b4a656e1e 100644
--- a/app/code/core/Mage/Adminhtml/controllers/PromoController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/PromoController.php
@@ -37,7 +37,7 @@ class Mage_Adminhtml_PromoController extends Mage_Adminhtml_Controller_Action
     public function indexAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('promo');
+        $this->_setActiveMenu('Mage_CatalogRule::promo');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Promotions'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Promo'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/RatingController.php b/app/code/core/Mage/Adminhtml/controllers/RatingController.php
index b778c00991e3b..d5f8610f5e426 100644
--- a/app/code/core/Mage/Adminhtml/controllers/RatingController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/RatingController.php
@@ -39,7 +39,7 @@ public function indexAction()
         $this->_initEnityId();
         $this->loadLayout();
 
-        $this->_setActiveMenu('catalog/ratings');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_ratings');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Ratings'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Ratings'));
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Rating_Rating'));
 
@@ -58,7 +58,7 @@ public function editAction()
 
         $this->_title($ratingModel->getId() ? $ratingModel->getRatingCode() : $this->__('New Rating'));
 
-        $this->_setActiveMenu('catalog/ratings');
+        $this->_setActiveMenu('Mage_Review::catalog_reviews_ratings_ratings');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Ratings'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Ratings'));
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Rating_Edit'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/CustomerController.php b/app/code/core/Mage/Adminhtml/controllers/Report/CustomerController.php
index a858fa8e892f5..5357a6467bc6a 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/CustomerController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/CustomerController.php
@@ -53,7 +53,7 @@ public function accountsAction()
              ->_title($this->__('New Accounts'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/customer/accounts')
+            ->_setActiveMenu('Mage_Reports::report_customers_accounts')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('New Accounts'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('New Accounts'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Customer_Accounts'))
             ->renderLayout();
@@ -90,7 +90,7 @@ public function ordersAction()
              ->_title($this->__('Customers by Number of Orders'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/customer/orders')
+            ->_setActiveMenu('Mage_Reports::report_customers_orders')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers by Number of Orders'),
                 Mage::helper('Mage_Reports_Helper_Data')->__('Customers by Number of Orders'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Customer_Orders'))
@@ -128,7 +128,7 @@ public function totalsAction()
              ->_title($this->__('Customers by Orders Total'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/customer/totals')
+            ->_setActiveMenu('Mage_Reports::report_customers_totals')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers by Orders Total'),
                 Mage::helper('Mage_Reports_Helper_Data')->__('Customers by Orders Total'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Customer_Totals'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php
index cfa8c7175582b..10e35459ca9d0 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php
@@ -57,7 +57,7 @@ public function soldAction()
              ->_title($this->__('Products Ordered'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/product/sold')
+            ->_setActiveMenu('Mage_Reports::report_products_sold')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Products Ordered'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Ordered'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Product_Sold'))
             ->renderLayout();
@@ -102,7 +102,7 @@ public function viewedAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_PRODUCT_VIEWED_FLAG_CODE, 'viewed');
 
         $this->_initAction()
-            ->_setActiveMenu('report/products/viewed')
+            ->_setActiveMenu('Mage_Reports::report_products_viewed')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Products Most Viewed Report'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Products Most Viewed Report'));
 
         $gridBlock = $this->getLayout()->getBlock('report_product_viewed.grid');
@@ -151,7 +151,7 @@ public function lowstockAction()
              ->_title($this->__('Low Stock'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/product/lowstock')
+            ->_setActiveMenu('Mage_Reports::report_products_lowstock')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Low Stock'), Mage::helper('Mage_Reports_Helper_Data')->__('Low Stock'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Product_Lowstock'))
             ->renderLayout();
@@ -196,7 +196,7 @@ public function downloadsAction()
              ->_title($this->__('Downloads'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/product/downloads')
+            ->_setActiveMenu('Mage_Downloadable::report_products_downloads')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Downloads'), Mage::helper('Mage_Reports_Helper_Data')->__('Downloads'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Product_Downloads'))
             ->renderLayout();
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/ReviewController.php b/app/code/core/Mage/Adminhtml/controllers/Report/ReviewController.php
index 893b50399a9b5..845906dcb80c1 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/ReviewController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/ReviewController.php
@@ -52,7 +52,7 @@ public function customerAction()
              ->_title($this->__('Customer Reviews'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/review/customer')
+            ->_setActiveMenu('Mage_Review::report_review_customer')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Review_Customer'))
             ->renderLayout();
@@ -89,7 +89,7 @@ public function productAction()
              ->_title($this->__('Product Reviews'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/review/product')
+            ->_setActiveMenu('Mage_Review::report_review_product')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Review_Product'))
             ->renderLayout();
@@ -127,7 +127,7 @@ public function productDetailAction()
              ->_title($this->__('Details'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/review/productDetail')
+            ->_setActiveMenu('Mage_Review::report_review')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'))
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Product Reviews'), Mage::helper('Mage_Reports_Helper_Data')->__('Product Reviews'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Review_Detail'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/SalesController.php b/app/code/core/Mage/Adminhtml/controllers/Report/SalesController.php
index 0b2b0f0e41f72..1814539c6796a 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/SalesController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/SalesController.php
@@ -52,7 +52,7 @@ public function salesAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_ORDER_FLAG_CODE, 'sales');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/sales')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_sales')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Sales Report'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Sales Report'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_sales.grid');
@@ -73,7 +73,7 @@ public function bestsellersAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_BESTSELLERS_FLAG_CODE, 'bestsellers');
 
         $this->_initAction()
-            ->_setActiveMenu('report/products/bestsellers')
+            ->_setActiveMenu('Mage_Reports::report_products_bestsellers')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Products Bestsellers Report'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Products Bestsellers Report'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_bestsellers.grid');
@@ -158,7 +158,7 @@ public function taxAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_TAX_FLAG_CODE, 'tax');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/tax')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_tax')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tax'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tax'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_tax.grid');
@@ -201,7 +201,7 @@ public function shippingAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_SHIPPING_FLAG_CODE, 'shipping');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/shipping')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_shipping')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Shipping'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Shipping'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_shipping.grid');
@@ -244,7 +244,7 @@ public function invoicedAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_INVOICE_FLAG_CODE, 'invoiced');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/invoiced')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_invoiced')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Total Invoiced'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Total Invoiced'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_invoiced.grid');
@@ -287,7 +287,7 @@ public function refundedAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_REFUNDED_FLAG_CODE, 'refunded');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/refunded')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_refunded')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Total Refunded'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Total Refunded'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_refunded.grid');
@@ -330,7 +330,7 @@ public function couponsAction()
         $this->_showLastExecutionTime(Mage_Reports_Model_Flag::REPORT_COUPONS_FLAG_CODE, 'coupons');
 
         $this->_initAction()
-            ->_setActiveMenu('report/sales/coupons')
+            ->_setActiveMenu('Mage_Reports::report_salesroot_coupons')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Coupons'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Coupons'));
 
         $gridBlock = $this->getLayout()->getBlock('report_sales_coupons.grid');
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/ShopcartController.php b/app/code/core/Mage/Adminhtml/controllers/Report/ShopcartController.php
index b52cf7286a561..e8957c6278a49 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/ShopcartController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/ShopcartController.php
@@ -49,7 +49,7 @@ public function customerAction()
              ->_title($this->__('Customer Shopping Carts'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/shopcart/customer')
+            ->_setActiveMenu('Mage_Reports::report_shopcart_customer')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Shopcart_Customer'))
             ->renderLayout();
@@ -86,7 +86,7 @@ public function productAction()
              ->_title($this->__('Products in Carts'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/shopcart/product')
+            ->_setActiveMenu('Mage_Reports::report_shopcart_product')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Shopcart_Product'))
             ->renderLayout();
@@ -123,7 +123,7 @@ public function abandonedAction()
              ->_title($this->__('Abandoned Carts'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/shopcart/abandoned')
+            ->_setActiveMenu('Mage_Reports::report_shopcart_abandoned')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Abandoned Carts'), Mage::helper('Mage_Reports_Helper_Data')->__('Abandoned Carts'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Shopcart_Abandoned'))
             ->renderLayout();
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/StatisticsController.php b/app/code/core/Mage/Adminhtml/controllers/Report/StatisticsController.php
index 64fb57d14b1b0..7b6cc54066d23 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/StatisticsController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/StatisticsController.php
@@ -179,7 +179,7 @@ public function indexAction()
         $this->_title($this->__('Reports'))->_title($this->__('Sales'))->_title($this->__('Refresh Statistics'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/statistics/refreshstatistics')
+            ->_setActiveMenu('Mage_Reports::report_statistics')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Refresh Statistics'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Refresh Statistics'))
             ->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/Report/TagController.php b/app/code/core/Mage/Adminhtml/controllers/Report/TagController.php
index ad5ff358a25d0..e73513b1ef224 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Report/TagController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Report/TagController.php
@@ -52,7 +52,7 @@ public function customerAction()
              ->_title($this->__('Customers'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/customer')
+            ->_setActiveMenu('Mage_Tag::report_tags_customer')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Tag_Customer'))
             ->renderLayout();
@@ -89,7 +89,7 @@ public function productAction()
              ->_title($this->__('Products'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/product')
+            ->_setActiveMenu('Mage_Tag::report_tags_product')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Poducts Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Tag_Product'))
             ->renderLayout();
@@ -127,7 +127,7 @@ public function popularAction()
              ->_title($this->__('Popular'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/popular')
+            ->_setActiveMenu('Mage_Tag::report_tags_popular')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Popular Tags'), Mage::helper('Mage_Reports_Helper_Data')->__('Popular Tags'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Tag_Popular'))
             ->renderLayout();
@@ -167,7 +167,7 @@ public function customerDetailAction()
              ->_title($detailBlock->getHeaderText());
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/customerDetail')
+            ->_setActiveMenu('Mage_Tag::report_tags')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Customers Report'))
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Customer Tags'), Mage::helper('Mage_Reports_Helper_Data')->__('Customer Tags'))
             ->_addContent($detailBlock)
@@ -208,7 +208,7 @@ public function productDetailAction()
              ->_title($detailBlock->getHeaderText());
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/productDetail')
+            ->_setActiveMenu('Mage_Tag::report_tags')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'), Mage::helper('Mage_Reports_Helper_Data')->__('Products Report'))
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Product Tags'), Mage::helper('Mage_Reports_Helper_Data')->__('Product Tags'))
             ->_addContent($detailBlock)
@@ -249,7 +249,7 @@ public function tagDetailAction()
              ->_title($detailBlock->getHeaderText());
 
         $this->_initAction()
-            ->_setActiveMenu('report/tag/tagDetail')
+            ->_setActiveMenu('Mage_Tag::report_tags')
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Popular Tags'), Mage::helper('Mage_Reports_Helper_Data')->__('Popular Tags'))
             ->_addBreadcrumb(Mage::helper('Mage_Reports_Helper_Data')->__('Tag Detail'), Mage::helper('Mage_Reports_Helper_Data')->__('Tag Detail'))
             ->_addContent($detailBlock)
diff --git a/app/code/core/Mage/Adminhtml/controllers/ReportController.php b/app/code/core/Mage/Adminhtml/controllers/ReportController.php
index 91ecd1d96ae8a..0b65e32fc4665 100644
--- a/app/code/core/Mage/Adminhtml/controllers/ReportController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/ReportController.php
@@ -41,40 +41,6 @@ public function _initAction()
     }
 
 
-/*
-    public function wishlistAction()
-    {
-        $this->_initAction()
-            ->_setActiveMenu('report/wishlist')
-            ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Wishlist Report'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Wishlist Report'))
-            ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Wishlist'))
-            ->renderLayout();
-    }
-
-    /**
-     * Export wishlist report grid to CSV format
-     * /
-    public function exportWishlistCsvAction()
-    {
-        $fileName   = 'wishlist.csv';
-        $content    = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Wishlist_Grid')
-            ->getCsvFile();
-
-        $this->_prepareDownloadResponse($fileName, $content);
-    }
-
-    /**
-     * Export wishlist report to Excel XML format
-     * /
-    public function exportWishlistExcelAction()
-    {
-        $fileName   = 'wishlist.xml';
-        $content    = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Wishlist_Grid')
-            ->getExcelFile($fileName);
-
-        $this->_prepareDownloadResponse($fileName, $content);
-    }
-*/
     public function searchAction()
     {
         $this->_title($this->__('Reports'))->_title($this->__('Search Terms'));
@@ -82,7 +48,7 @@ public function searchAction()
         Mage::dispatchEvent('on_view_report', array('report' => 'search'));
 
         $this->_initAction()
-            ->_setActiveMenu('report/search')
+            ->_setActiveMenu('Mage_Reports::report_search')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Search Terms'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Search Terms'))
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Report_Search'))
             ->renderLayout();
@@ -111,23 +77,6 @@ public function exportSearchExcelAction()
 
         $this->_prepareDownloadResponse($fileName, $content);
     }
-/*
-    public function ordersAction()
-    {
-        $this->_initAction()
-            ->_setActiveMenu('report/orders')
-            ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Recent Orders'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Recent Orders'))
-            ->renderLayout();
-    }
-
-    public function totalsAction()
-    {
-        $this->_initAction()
-            ->_setActiveMenu('report/totals')
-            ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Order Totals'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Order Totals'))
-            ->renderLayout();
-    }
-*/
 
     protected function _isAllowed()
     {
@@ -135,11 +84,6 @@ protected function _isAllowed()
             case 'search':
                 return Mage::getSingleton('Mage_Backend_Model_Auth_Session')->isAllowed('report/search');
                 break;
-            /*
-            case 'customers':
-                return Mage::getSingleton('Mage_Backend_Model_Auth_Session')->isAllowed('report/shopcart');
-                break;
-            */
             default:
                 return Mage::getSingleton('Mage_Backend_Model_Auth_Session')->isAllowed('report');
                 break;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Billing/AgreementController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Billing/AgreementController.php
index f19f87e3e7018..bc6f667566fe3 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Billing/AgreementController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Billing/AgreementController.php
@@ -41,7 +41,7 @@ public function indexAction()
             ->_title($this->__('Billing Agreements'));
 
         $this->loadLayout()
-            ->_setActiveMenu('sales/billing_agreement')
+            ->_setActiveMenu('Mage_Sales::sales_billing_agreement')
             ->renderLayout();
     }
 
@@ -69,7 +69,7 @@ public function viewAction()
                 ->_title(sprintf("#%s", $agreementModel->getReferenceId()));
 
             $this->loadLayout()
-                ->_setActiveMenu('sales/billing_agreement')
+                ->_setActiveMenu('Mage_Sales::sales_billing_agreement')
                 ->renderLayout();
             return;
         }
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php
index c6f1d222ec70a..78db2720b6379 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php
@@ -332,7 +332,7 @@ public function indexAction()
         $this->_initSession();
         $this->loadLayout();
 
-        $this->_setActiveMenu('sales/order')
+        $this->_setActiveMenu('Mage_Sales::sales_order')
             ->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php
index 780d64da8dd9f..8021b0dbc0b7c 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php
@@ -196,7 +196,7 @@ public function viewAction()
             $this->loadLayout();
             $this->getLayout()->getBlock('sales_creditmemo_view')
                 ->updateBackButtonUrl($this->getRequest()->getParam('come_from'));
-            $this->_setActiveMenu('sales/order')
+            $this->_setActiveMenu('Mage_Sales::sales_order')
                 ->renderLayout();
         } else {
             $this->_forward('noRoute');
@@ -231,7 +231,7 @@ public function newAction()
             }
 
             $this->loadLayout()
-                ->_setActiveMenu('sales/order')
+                ->_setActiveMenu('Mage_Sales::sales_order')
                 ->renderLayout();
         } else {
             $this->_forward('noRoute');
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/EditController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/EditController.php
index 3084cca7ba09a..b09ee4c5c65b7 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/EditController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/EditController.php
@@ -70,7 +70,7 @@ public function indexAction()
         $this->loadLayout();
 
         $this->_initSession()
-            ->_setActiveMenu('sales/order')
+            ->_setActiveMenu('Mage_Sales::sales_order')
             ->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php
index 05278cf0fbf88..5cd3552f2193f 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php
@@ -147,7 +147,7 @@ public function viewAction()
             $this->_title(sprintf("#%s", $invoice->getIncrementId()));
 
             $this->loadLayout()
-                ->_setActiveMenu('sales/order');
+                ->_setActiveMenu('Mage_Sales::sales_order');
             $this->getLayout()->getBlock('sales_invoice_view')
                 ->updateBackButtonUrl($this->getRequest()->getParam('come_from'));
             $this->renderLayout();
@@ -183,7 +183,7 @@ public function newAction()
             }
 
             $this->loadLayout()
-                ->_setActiveMenu('sales/order')
+                ->_setActiveMenu('Mage_Sales::sales_order')
                 ->renderLayout();
         } else {
             $this->_redirect('*/sales_order/view', array('order_id'=>$this->getRequest()->getParam('order_id')));
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
index 3d6514ccc524f..60fa60fbe9652 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
@@ -133,7 +133,7 @@ public function viewAction()
             $this->loadLayout();
             $this->getLayout()->getBlock('sales_shipment_view')
                 ->updateBackButtonUrl($this->getRequest()->getParam('come_from'));
-            $this->_setActiveMenu('sales/order')
+            $this->_setActiveMenu('Mage_Sales::sales_order')
                 ->renderLayout();
         } else {
             $this->_forward('noRoute');
@@ -165,7 +165,7 @@ public function newAction()
             }
 
             $this->loadLayout()
-                ->_setActiveMenu('sales/order')
+                ->_setActiveMenu('Mage_Sales::sales_order')
                 ->renderLayout();
         } else {
             $this->_redirect('*/sales_order/view', array('order_id'=>$this->getRequest()->getParam('order_id')));
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/StatusController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/StatusController.php
index 7bd27423c3e5c..8c18a3db18980 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/StatusController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/StatusController.php
@@ -64,7 +64,7 @@ protected function _initStatus()
     public function indexAction()
     {
         $this->_title($this->__('Sales'))->_title($this->__('Order Statuses'));
-        $this->loadLayout()->_setActiveMenu('system')->renderLayout();
+        $this->loadLayout()->_setActiveMenu('Mage_Adminhtml::system')->renderLayout();
     }
 
     /**
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php
index e002da16ffbd2..e891015d4e8d0 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php
@@ -57,7 +57,7 @@ protected function _construct()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/order')
+            ->_setActiveMenu('Mage_Sales::sales_order')
             ->_addBreadcrumb($this->__('Sales'), $this->__('Sales'))
             ->_addBreadcrumb($this->__('Orders'), $this->__('Orders'));
         return $this;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Recurring/ProfileController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Recurring/ProfileController.php
index 5ef0e55d88128..42eccc7657c1e 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/Recurring/ProfileController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Recurring/ProfileController.php
@@ -40,7 +40,7 @@ public function indexAction()
     {
         $this->_title(Mage::helper('Mage_Sales_Helper_Data')->__('Sales'))->_title(Mage::helper('Mage_Sales_Helper_Data')->__('Recurring Profiles'))
             ->loadLayout()
-            ->_setActiveMenu('sales/recurring_profile')
+            ->_setActiveMenu('Mage_Sales::sales_recurring_profile')
             ->renderLayout();
         return $this;
     }
@@ -54,7 +54,7 @@ public function viewAction()
             $this->_title(Mage::helper('Mage_Sales_Helper_Data')->__('Sales'))->_title(Mage::helper('Mage_Sales_Helper_Data')->__('Recurring Profiles'));
             $profile = $this->_initProfile();
             $this->loadLayout()
-                ->_setActiveMenu('sales/recurring_profile')
+                ->_setActiveMenu('Mage_Sales::sales_recurring_profile')
                 ->_title(Mage::helper('Mage_Sales_Helper_Data')->__('Profile #%s', $profile->getReferenceId()))
                 ->renderLayout()
             ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/TransactionsController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/TransactionsController.php
index 71898097a2846..2dfeb908ab419 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Sales/TransactionsController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Sales/TransactionsController.php
@@ -65,7 +65,7 @@ public function indexAction()
             ->_title($this->__('Transactions'));
 
         $this->loadLayout()
-            ->_setActiveMenu('sales/transactions')
+            ->_setActiveMenu('Mage_Sales::sales_transactions')
             ->renderLayout();
     }
 
@@ -92,7 +92,7 @@ public function viewAction()
             ->_title(sprintf("#%s", $txn->getTxnId()));
 
         $this->loadLayout()
-            ->_setActiveMenu('sales/transactions')
+            ->_setActiveMenu('Mage_Sales::sales_transactions')
             ->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/SitemapController.php b/app/code/core/Mage/Adminhtml/controllers/SitemapController.php
index a4df76346ebc0..05d8328ebf910 100644
--- a/app/code/core/Mage/Adminhtml/controllers/SitemapController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/SitemapController.php
@@ -42,7 +42,7 @@ protected function _initAction()
     {
         // load layout, set active menu and breadcrumbs
         $this->loadLayout()
-            ->_setActiveMenu('catalog/system_sitemap')
+            ->_setActiveMenu('Mage_Sitemap::catalog_sitemap')
             ->_addBreadcrumb(
                 Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'),
                 Mage::helper('Mage_Catalog_Helper_Data')->__('Catalog'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php b/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php
index 13f5b14b8db97..892fc1fcb5d27 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php
@@ -39,7 +39,7 @@ public function indexAction()
         $this->_title($this->__('System'))->_title($this->__('My Account'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system/account');
+        $this->_setActiveMenu('Mage_Adminhtml::system_myaccount');
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_System_Account_Edit'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/BackupController.php b/app/code/core/Mage/Adminhtml/controllers/System/BackupController.php
index 1a9f3d6bdfc46..4faf5d8d066c3 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/BackupController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/BackupController.php
@@ -46,7 +46,7 @@ public function indexAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('system');
+        $this->_setActiveMenu('Mage_Adminhtml::system');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'));
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tools'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tools'));
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Backups'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Backup'));
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php b/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php
index 99ef8106e1c55..0b92fd06a2832 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php
@@ -89,7 +89,7 @@ public function editAction()
 
         $this->loadLayout();
 
-        $this->_setActiveMenu('system/config');
+        $this->_setActiveMenu('Mage_Adminhtml::system_config');
         $this->getLayout()->getBlock('menu')->setAdditionalCacheKeyInfo(array($current));
 
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'),
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Convert/GuiController.php b/app/code/core/Mage/Adminhtml/controllers/System/Convert/GuiController.php
index d022f2c9bbd90..09283bbe0d3e0 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/Convert/GuiController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/Convert/GuiController.php
@@ -53,7 +53,7 @@ public function indexAction()
         /**
          * Set active menu item
          */
-        $this->_setActiveMenu('system/convert');
+        $this->_setActiveMenu('Mage_Adminhtml::system_convert');
 
         /**
          * Append profiles block to content
@@ -97,7 +97,7 @@ public function editAction()
 
         $this->_title($profile->getId() ? $profile->getName() : $this->__('New Profile'));
 
-        $this->_setActiveMenu('system/convert');
+        $this->_setActiveMenu('Mage_Adminhtml::system_convert');
 
 
         $this->_addContent(
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php b/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php
index 4accb1a76181e..dba0670af3dd0 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php
@@ -75,7 +75,7 @@ public function indexAction()
         /**
          * Set active menu item
          */
-        $this->_setActiveMenu('system/convert');
+        $this->_setActiveMenu('Mage_Adminhtml::system_convert');
 
         /**
          * Append profiles block to content
@@ -123,7 +123,7 @@ public function editAction()
 
         $this->_title($profile->getId() ? $profile->getName() : $this->__('New Profile'));
 
-        $this->_setActiveMenu('system/convert');
+        $this->_setActiveMenu('Mage_Adminhtml::system_convert');
 
         $this->_addContent(
             $this->getLayout()->createBlock('Mage_Adminhtml_Block_System_Convert_Profile_Edit')
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/CurrencyController.php b/app/code/core/Mage/Adminhtml/controllers/System/CurrencyController.php
index 344b1287fb341..9776f9fd69f69 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/CurrencyController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/CurrencyController.php
@@ -56,7 +56,7 @@ public function indexAction()
         $this->_title($this->__('System'))->_title($this->__('Manage Currency Rates'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system/currency');
+        $this->_setActiveMenu('Mage_Adminhtml::system_currency');
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_System_Currency'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/DesignController.php b/app/code/core/Mage/Adminhtml/controllers/System/DesignController.php
index 86fa2d9daf57d..f2bf325e81456 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/DesignController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/DesignController.php
@@ -32,7 +32,7 @@ public function indexAction()
         $this->_title($this->__('System'))->_title($this->__('Design'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system');
+        $this->_setActiveMenu('Mage_Adminhtml::system');
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_System_Design'));
         $this->renderLayout();
     }
@@ -54,7 +54,7 @@ public function editAction()
         $this->_title($this->__('System'))->_title($this->__('Design'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system');
+        $this->_setActiveMenu('Mage_Adminhtml::system');
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
 
         $id  = (int) $this->getRequest()->getParam('id');
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php b/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php
index f8a1192ff0312..dfc174fe571a3 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php
@@ -43,7 +43,7 @@ public function indexAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('system/email_template');
+        $this->_setActiveMenu('Mage_Adminhtml::system_email_template');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Transactional Emails'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Transactional Emails'));
 
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_System_Email_Template', 'template'));
@@ -75,7 +75,7 @@ public function editAction()
     {
         $this->loadLayout();
         $template = $this->_initTemplate('id');
-        $this->_setActiveMenu('system/email_template');
+        $this->_setActiveMenu('Mage_Adminhtml::system_email_template');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Transactional Emails'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Transactional Emails'), $this->getUrl('*/*'));
 
         if ($this->getRequest()->getParam('id')) {
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/StoreController.php b/app/code/core/Mage/Adminhtml/controllers/System/StoreController.php
index 6c9081a33af12..cde7f64768859 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/StoreController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/StoreController.php
@@ -43,7 +43,7 @@ protected function _initAction()
     {
         // load layout, set active menu and breadcrumbs
         $this->loadLayout()
-            ->_setActiveMenu('system/store')
+            ->_setActiveMenu('Mage_Adminhtml::system_store')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'))
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Stores'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Manage Stores'))
         ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/System/VariableController.php b/app/code/core/Mage/Adminhtml/controllers/System/VariableController.php
index c31223a50fe33..f7bd4ac0d5c75 100644
--- a/app/code/core/Mage/Adminhtml/controllers/System/VariableController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/System/VariableController.php
@@ -41,7 +41,7 @@ class Mage_Adminhtml_System_VariableController extends Mage_Adminhtml_Controller
     protected function _initLayout()
     {
         $this->loadLayout()
-            ->_setActiveMenu('system/variable')
+            ->_setActiveMenu('Mage_Adminhtml::system_variable')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Custom Variables'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Custom Variables'));
         return $this;
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/SystemController.php b/app/code/core/Mage/Adminhtml/controllers/SystemController.php
index 4c4f7536f6c8e..3050961dc91f7 100644
--- a/app/code/core/Mage/Adminhtml/controllers/SystemController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/SystemController.php
@@ -36,7 +36,7 @@ class Mage_Adminhtml_SystemController extends Mage_Adminhtml_Controller_Action
     public function indexAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('system');
+        $this->_setActiveMenu('Mage_Adminhtml::system');
         $this->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('System'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/TagController.php b/app/code/core/Mage/Adminhtml/controllers/TagController.php
index 9fcb912d04012..aa903c7911673 100644
--- a/app/code/core/Mage/Adminhtml/controllers/TagController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/TagController.php
@@ -37,7 +37,7 @@ class Mage_Adminhtml_TagController extends Mage_Adminhtml_Controller_Action
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('catalog/tag')
+            ->_setActiveMenu('Mage_Tag::catalog_tag')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'))
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tags'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Tags'));
 
@@ -81,7 +81,7 @@ public function indexAction()
 
         $this->_initAction()
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('All Tags'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('All Tags'))
-            ->_setActiveMenu('catalog/tag/all')
+            ->_setActiveMenu('Mage_Tag::catalog_tag_all')
             ->renderLayout();
     }
 
@@ -234,7 +234,7 @@ public function pendingAction()
 
         $this->_initAction()
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Pending Tags'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Pending Tags'))
-            ->_setActiveMenu('catalog/tag/pending')
+            ->_setActiveMenu('Mage_Tag::catalog_tag_pending')
             ->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/Class/CustomerController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/Class/CustomerController.php
index 601d50ed87762..7990e9279c81f 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Tax/Class/CustomerController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Tax/Class/CustomerController.php
@@ -167,7 +167,7 @@ public function deleteAction()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/tax/tax_class_customer')
+            ->_setActiveMenu('Mage_Tax::sales_tax_classes_customer')
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Sales'), Mage::helper('Mage_Tax_Helper_Data')->__('Sales'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Tax'), Mage::helper('Mage_Tax_Helper_Data')->__('Tax'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Manage Customer Tax Classes'), Mage::helper('Mage_Tax_Helper_Data')->__('Manage Customer Tax Classes'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/Class/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/Class/ProductController.php
index bdf1604187d6d..5283f137a8f1f 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Tax/Class/ProductController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Tax/Class/ProductController.php
@@ -166,7 +166,7 @@ public function deleteAction()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/tax/tax_class_product')
+            ->_setActiveMenu('Mage_Tax::sales_tax_classes_product')
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Sales'), Mage::helper('Mage_Tax_Helper_Data')->__('Sales'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Tax'), Mage::helper('Mage_Tax_Helper_Data')->__('Tax'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Manage Product Tax Classes'), Mage::helper('Mage_Tax_Helper_Data')->__('Manage Product Tax Classes'))
diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php
index 9c135427fda18..0fa4530dc2c12 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php
@@ -228,7 +228,7 @@ public function exportXmlAction()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/tax_rates')
+            ->_setActiveMenu('Mage_Tax::sales_tax_rates')
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Sales'), Mage::helper('Mage_Tax_Helper_Data')->__('Sales'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Tax'), Mage::helper('Mage_Tax_Helper_Data')->__('Tax'));
         return $this;
@@ -247,7 +247,7 @@ public function importExportAction()
         $this->_title($this->__('Import and Export Tax Rates'));
 
         $this->loadLayout()
-            ->_setActiveMenu('sales/tax_importExport')
+            ->_setActiveMenu('Mage_Tax::sales_tax_import_export')
             ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Tax_Rate_ImportExport'))
             ->renderLayout();
     }
diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php
index e50d8d6c8b6df..e67fb5ac75bb7 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php
@@ -156,7 +156,7 @@ public function deleteAction()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('sales/tax/rule')
+            ->_setActiveMenu('Mage_Tax::sales_tax_rules')
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Tax'), Mage::helper('Mage_Tax_Helper_Data')->__('Tax'))
             ->_addBreadcrumb(Mage::helper('Mage_Tax_Helper_Data')->__('Tax Rules'), Mage::helper('Mage_Tax_Helper_Data')->__('Tax Rules'))
         ;
diff --git a/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php b/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php
index 8109c88570663..febbaa15a306e 100644
--- a/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php
@@ -67,7 +67,7 @@ public function indexAction()
     {
         $this->_initRegistry();
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/urlrewrite');
+        $this->_setActiveMenu('Mage_Catalog::catalog_urlrewrite');
         $this->_addContent(
             $this->getLayout()->createBlock('Mage_Adminhtml_Block_Urlrewrite')
         );
@@ -85,7 +85,7 @@ public function editAction()
         $this->_title($this->__('URL Rewrite'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('catalog/urlrewrite');
+        $this->_setActiveMenu('Mage_Catalog::catalog_urlrewrite');
         $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Urlrewrite_Edit'));
         $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
         $this->renderLayout();
diff --git a/app/code/core/Mage/Adminhtml/etc/adminhtml.xml b/app/code/core/Mage/Adminhtml/etc/adminhtml.xml
index 5e1b47ace4308..c69a3c1a37a1d 100644
--- a/app/code/core/Mage/Adminhtml/etc/adminhtml.xml
+++ b/app/code/core/Mage/Adminhtml/etc/adminhtml.xml
@@ -26,86 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <dashboard translate="title" module="Mage_Adminhtml">
-            <title>Dashboard</title>
-            <sort_order>10</sort_order>
-            <action>adminhtml/dashboard</action>
-        </dashboard>
-        <system translate="title" module="Mage_Adminhtml">
-            <title>System</title>
-            <sort_order>90</sort_order>
-            <!-- action>adminhtml/system</action -->
-            <children>
-                <myaccount translate="title">
-                    <title>My Account</title>
-                    <action>adminhtml/system_account</action>
-                    <sort_order>10</sort_order>
-                </myaccount>
-                <tools translate="title">
-                    <title>Tools</title>
-                    <sort_order>20</sort_order>
-                </tools>
-                <design translate="title">
-                    <title>Design</title>
-                    <sort_order>30</sort_order>
-                    <children>
-                        <schedule translate="title">
-                            <title>Schedule</title>
-                            <action>adminhtml/system_design</action>
-                            <sort_order>10</sort_order>
-                        </schedule>
-                    </children>
-                </design>
-                <convert translate="title">
-                    <title>Import/Export</title>
-                    <sort_order>40</sort_order>
-                    <children>
-                        <gui translate="title">
-                            <title>Dataflow - Profiles</title>
-                            <action>adminhtml/system_convert_gui</action>
-                            <sort_order>30</sort_order>
-                        </gui>
-                        <profiles translate="title">
-                            <title>Dataflow - Advanced Profiles</title>
-                            <action>adminhtml/system_convert_profile</action>
-                            <sort_order>40</sort_order>
-                        </profiles>
-                    </children>
-                </convert>
-                <currency translate="title">
-                    <title>Manage Currency Rates</title>
-                    <action>adminhtml/system_currency</action>
-                    <sort_order>50</sort_order>
-                </currency>
-                <email_template translate="title">
-                    <title>Transactional Emails</title>
-                    <action>adminhtml/system_email_template</action>
-                    <sort_order>60</sort_order>
-                </email_template>
-                <variable translate="title">
-                    <title>Custom Variables</title>
-                    <action>adminhtml/system_variable</action>
-                    <sort_order>65</sort_order>
-                </variable>
-                <cache translate="title">
-                    <title>Cache Management</title>
-                    <action>adminhtml/cache</action>
-                    <sort_order>90</sort_order>
-                </cache>
-                <store translate="title" module="Mage_Core">
-                    <title>Manage Stores</title>
-                    <action>adminhtml/system_store/</action>
-                    <sort_order>100</sort_order>
-                </store>
-                <config translate="title">
-                    <title>Configuration</title>
-                    <action>adminhtml/system_config</action>
-                    <sort_order>110</sort_order>
-                </config>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <all>
diff --git a/app/code/core/Mage/Adminhtml/etc/adminhtml/menu.xml b/app/code/core/Mage/Adminhtml/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..a2dc5c9837e1b
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/etc/adminhtml/menu.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Adminhtml::dashboard" title="Dashboard" module="Mage_Adminhtml" sortOrder="10" action="adminhtml/dashboard" />
+        <add id="Mage_Adminhtml::system" title="System" module="Mage_Adminhtml" sortOrder="90" />
+        <add id="Mage_Adminhtml::system_myaccount" title="My Account" module="Mage_Adminhtml" sortOrder="10" parent="Mage_Adminhtml::system" action="adminhtml/system_account" />
+        <add id="Mage_Adminhtml::system_tools" title="Tools" module="Mage_Adminhtml" sortOrder="20" parent="Mage_Adminhtml::system" />
+        <add id="Mage_Adminhtml::system_design" title="Design" module="Mage_Adminhtml" sortOrder="30" parent="Mage_Adminhtml::system" />
+        <add id="Mage_Adminhtml::system_design_schedule" title="Schedule" module="Mage_Adminhtml" sortOrder="10" parent="Mage_Adminhtml::system_design" action="adminhtml/system_design" />
+        <add id="Mage_Adminhtml::system_convert" title="Import/Export" module="Mage_Adminhtml" sortOrder="40" parent="Mage_Adminhtml::system" />
+        <add id="Mage_Adminhtml::system_convert_gui" title="Dataflow - Profiles" module="Mage_Adminhtml" sortOrder="30" parent="Mage_Adminhtml::system_convert" action="adminhtml/system_convert_gui" />
+        <add id="Mage_Adminhtml::system_convert_profiles" title="Dataflow - Advanced Profiles" module="Mage_Adminhtml" sortOrder="40" parent="Mage_Adminhtml::system_convert" action="adminhtml/system_convert_profile" />
+        <add id="Mage_Adminhtml::system_currency" title="Manage Currency Rates" module="Mage_Adminhtml" sortOrder="50" parent="Mage_Adminhtml::system" action="adminhtml/system_currency" />
+        <add id="Mage_Adminhtml::system_email_template" title="Transactional Emails" module="Mage_Adminhtml" sortOrder="60" parent="Mage_Adminhtml::system" action="adminhtml/system_email_template" />
+        <add id="Mage_Adminhtml::system_variable" title="Custom Variables" module="Mage_Adminhtml" sortOrder="65" parent="Mage_Adminhtml::system" action="adminhtml/system_variable" />
+        <add id="Mage_Adminhtml::system_cache" title="Cache Management" module="Mage_Adminhtml" sortOrder="90" parent="Mage_Adminhtml::system" action="adminhtml/cache" />
+        <add id="Mage_Adminhtml::system_store" title="Manage Stores" module="Mage_Core" sortOrder="100" parent="Mage_Adminhtml::system" action="adminhtml/system_store/" />
+        <add id="Mage_Adminhtml::system_config" title="Configuration" module="Mage_Adminhtml" sortOrder="110" parent="Mage_Adminhtml::system" action="adminhtml/system_config" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/admin/page.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/admin/page.phtml
index 30e0a13f8d910..021c45ac96226 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/admin/page.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/admin/page.phtml
@@ -29,7 +29,7 @@
     "type":"Mage_Core_Block_Template",
     "children":{
         "header":{ "label":"Header", "type":"Mage_Adminhtml_Block_Page_Header" },
-        "menu":{ "label":"Top navigation", "type":"Mage_Adminhtml_Block_Page_Menu" },
+        "menu":{ "label":"Top navigation", "type":"Mage_Backend_Block_Menu" },
         "breadcrumbs":{ "label":"Breadcrumbs", "type":"Mage_Adminhtml_Block_Widget_Breadcrumbs" },
         "content":{ "label":"Content block", "type":"Mage_Core_Block_Template" },
         "left":{ "label":"Left navigation", "type":"Mage_Core_Block_Template" },
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/admin/popup.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/admin/popup.phtml
index 69c93163f2e85..a6f78781e9f3d 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/admin/popup.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/admin/popup.phtml
@@ -29,7 +29,7 @@
     "type":"Mage_Core_Block_Template",
     "children":{
         "header":{ "label":"Header", "type":"Mage_Adminhtml_Block_Page_Header" },
-        "menu":{ "label":"Top navigation", "type":"Mage_Adminhtml_Block_Page_Menu" },
+        "menu":{ "label":"Top navigation", "type":"Mage_Backend_Block_Menu" },
         "breadcrumbs":{ "label":"Breadcrumbs", "type":"Mage_Adminhtml_Block_Widget_Breadcrumbs" },
         "content":{ "label":"Content block", "type":"Mage_Core_Block_Template" },
         "left":{ "label":"Left navigation", "type":"Mage_Core_Block_Template" },
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
index 11e0b210671f2..322b246279db9 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
@@ -32,7 +32,7 @@
             <action method="setTitle" translate="title"><title>Catalog</title></action>
         </referense>
         <reference name="menu">
-            <action method="setActive"><menupath>catalog/products</menupath></action>
+            <action method="setActive"><itemId>Mage_Catalog::catalog_products</itemId></action>
         </reference>
         <reference name="content">
             <block type="Mage_Adminhtml_Block_Catalog_Product" name="products_list">
@@ -103,6 +103,7 @@
     </adminhtml_catalog_product_options>
 
     <adminhtml_catalog_product_grid>
+        <update handle="formkey"/>
         <container name="root" label="Root" output="1">
             <block type="Mage_Adminhtml_Block_Catalog_Product_Grid" name="admin.product.grid"/>
         </container>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/customer.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/customer.xml
index 1ba7c6ef4dc12..8bb788e47c46c 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/customer.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/customer.xml
@@ -113,6 +113,7 @@
     </adminhtml_customer_newsletter>
 
     <adminhtml_customer_grid>
+        <update handle="formkey"/>
         <container name="root" label="Root" output="1">
             <block type="Mage_Adminhtml_Block_Customer_Grid" name="admin.customer.grid"/>
         </container>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
index 40d34fc4b0790..8e7fae386d95d 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
@@ -101,7 +101,6 @@ Supported layout update handles (special):
 
             <block type="Mage_Adminhtml_Block_Page_Notices" name="global_notices" as="global_notices" template="page/notices.phtml" />
             <block type="Mage_Adminhtml_Block_Page_Header" name="header" as="header"></block>
-            <block type="Mage_Adminhtml_Block_Page_Menu" name="menu" as="menu"></block>
             <container name="notifications" as="notifications" label="Notifications">
                 <block type="Mage_Adminhtml_Block_Notification_Baseurl" name="notification_baseurl" as="notification_baseurl" template="notification/baseurl.phtml"></block>
                 <block type="Mage_Adminhtml_Block_Cache_Notifications" name="cache_notifications" template="system/cache/notifications.phtml"></block>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/tag.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/tag.xml
index 67c0e7f7aa5e8..1ff60f7434ed6 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/tag.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/tag.xml
@@ -63,12 +63,14 @@
     </adminhtml_tag_pending>
 
     <adminhtml_tag_ajaxgrid>
+        <update handle="formkey"/>
         <container name="root" label="Root" output="1">
             <block type="Mage_Adminhtml_Block_Tag_Tag_Grid" name="adminhtml.tag.tag.grid"/>
         </container>
     </adminhtml_tag_ajaxgrid>
 
     <adminhtml_tag_ajaxpendinggrid>
+        <update handle="formkey"/>
         <container name="root" label="Root" output="1">
             <block type="Mage_Adminhtml_Block_Tag_Grid_Pending" name="adminhtml.tag.grid.pending"/>
         </container>
diff --git a/app/code/core/Mage/Api/etc/adminhtml.xml b/app/code/core/Mage/Api/etc/adminhtml.xml
index 601041d27104e..5dfb93fdc5095 100644
--- a/app/code/core/Mage/Api/etc/adminhtml.xml
+++ b/app/code/core/Mage/Api/etc/adminhtml.xml
@@ -59,26 +59,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <system>
-            <children>
-                <api translate="title" module="Mage_Api">
-                    <title>Web Services</title>
-                    <sort_order>25</sort_order>
-                    <children>
-                        <users translate="title">
-                            <title>SOAP/XML-RPC - Users</title>
-                            <action>adminhtml/api_user</action>
-                            <sort_order>10</sort_order>
-                        </users>
-                        <roles translate="title">
-                            <title>SOAP/XML-RPC - Roles</title>
-                            <action>adminhtml/api_role</action>
-                            <sort_order>20</sort_order>
-                        </roles>
-                    </children>
-                </api>
-            </children>
-        </system>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Api/etc/adminhtml/menu.xml b/app/code/core/Mage/Api/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..722de4b537e56
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Api::system_api" title="Web Services" module="Mage_Api" sortOrder="25" parent="Mage_Adminhtml::system" />
+        <add id="Mage_Api::system_api_users" title="SOAP/XML-RPC - Users" module="Mage_Api" sortOrder="10" parent="Mage_Api::system_api" action="adminhtml/api_user" />
+        <add id="Mage_Api::system_api_roles" title="SOAP/XML-RPC - Roles" module="Mage_Api" sortOrder="20" parent="Mage_Api::system_api" action="adminhtml/api_role" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/AttributeController.php b/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/AttributeController.php
index bf6b66a620bec..67faba015776e 100644
--- a/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/AttributeController.php
+++ b/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/AttributeController.php
@@ -42,7 +42,7 @@ public function indexAction()
              ->_title($this->__('Web Services'))
              ->_title($this->__('REST Attributes'));
 
-        $this->loadLayout()->_setActiveMenu('system/services/attributes');
+        $this->loadLayout()->_setActiveMenu('Mage_Api2::system_api_rest_attributes');
 
         $this->_addBreadcrumb($this->__('Web services'), $this->__('Web services'))
             ->_addBreadcrumb($this->__('REST Attributes'), $this->__('REST Attributes'))
@@ -57,7 +57,7 @@ public function indexAction()
     public function editAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('system/services/attributes');
+            ->_setActiveMenu('Mage_Api2::system_api_rest_attributes');
 
         $type = $this->getRequest()->getParam('type');
 
diff --git a/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/RoleController.php b/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/RoleController.php
index a6e5470c52ee5..2551cc242a1e4 100644
--- a/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/RoleController.php
+++ b/app/code/core/Mage/Api2/controllers/Adminhtml/Api2/RoleController.php
@@ -42,7 +42,7 @@ public function indexAction()
              ->_title($this->__('Web Services'))
              ->_title($this->__('REST Roles'));
 
-        $this->loadLayout()->_setActiveMenu('system/services/roles');
+        $this->loadLayout()->_setActiveMenu('Mage_Api2::system_api_rest_roles');
         $this->_addBreadcrumb($this->__('Web services'), $this->__('Web services'));
         $this->_addBreadcrumb($this->__('REST Roles'), $this->__('REST Roles'));
         $this->_addBreadcrumb($this->__('Roles'), $this->__('Roles'));
@@ -83,7 +83,7 @@ public function newAction()
              ->_title($this->__('Web Services'))
              ->_title($this->__('Rest Roles'));
 
-        $this->loadLayout()->_setActiveMenu('system/services/roles');
+        $this->loadLayout()->_setActiveMenu('Mage_Api2::system_api_rest_roles');
         $this->_addBreadcrumb($this->__('Web services'), $this->__('Web services'));
         $this->_addBreadcrumb($this->__('REST Roles'), $this->__('REST Roles'));
         $this->_addBreadcrumb($this->__('Roles'), $this->__('Roles'));
@@ -112,7 +112,7 @@ public function editAction()
             return;
         }
 
-        $this->loadLayout()->_setActiveMenu('system/services/roles');
+        $this->loadLayout()->_setActiveMenu('Mage_Api2::system_api_rest_roles');
 
         $this->_title($this->__('System'))
              ->_title($this->__('Web Services'))
diff --git a/app/code/core/Mage/Api2/etc/adminhtml.xml b/app/code/core/Mage/Api2/etc/adminhtml.xml
index 4b0ff88c5997a..7b210ceb892bb 100644
--- a/app/code/core/Mage/Api2/etc/adminhtml.xml
+++ b/app/code/core/Mage/Api2/etc/adminhtml.xml
@@ -70,24 +70,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <system>
-            <children>
-                <api>
-                    <children>
-                        <rest_roles translate="title" module="Mage_Api2">
-                            <title>REST - Roles</title>
-                            <sort_order>30</sort_order>
-                            <action>adminhtml/api2_role</action>
-                        </rest_roles>
-                        <rest_attributes translate="title" module="Mage_Api2">
-                            <title>REST - Attributes</title>
-                            <sort_order>40</sort_order>
-                            <action>adminhtml/api2_attribute</action>
-                        </rest_attributes>
-                    </children>
-                </api>
-            </children>
-        </system>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Api2/etc/adminhtml/menu.xml b/app/code/core/Mage/Api2/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..a020f71a2937c
--- /dev/null
+++ b/app/code/core/Mage/Api2/etc/adminhtml/menu.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api2
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Api2::system_api_rest_roles" title="REST - Roles" module="Mage_Api2" sortOrder="30" parent="Mage_Api::system_api" action="adminhtml/api2_role" />
+        <add id="Mage_Api2::system_api_rest_attributes" title="REST - Attributes" module="Mage_Api2" sortOrder="40" parent="Mage_Api::system_api" action="adminhtml/api2_attribute" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Backend/Block/Menu.php b/app/code/core/Mage/Backend/Block/Menu.php
index b1d730e8d2dd9..53e902fae5692 100644
--- a/app/code/core/Mage/Backend/Block/Menu.php
+++ b/app/code/core/Mage/Backend/Block/Menu.php
@@ -38,6 +38,17 @@ class Mage_Backend_Block_Menu extends Mage_Backend_Block_Template
 {
     const CACHE_TAGS = 'BACKEND_MAINMENU';
 
+
+    /**
+     * @var string
+     */
+    protected $_containerRendererBlock;
+
+    /**
+     * @var string
+     */
+    protected $_itemRendererBlock;
+
     /**
      * Backend URL instance
      *
@@ -45,6 +56,13 @@ class Mage_Backend_Block_Menu extends Mage_Backend_Block_Template
      */
     protected $_url;
 
+    /**
+     * Current selected item
+     *
+     * @var Mage_Backend_Model_Menu_Item|null|bool
+     */
+    protected $_activeItemModel = null;
+
     /**
      * Initialize template and cache settings
      *
@@ -52,7 +70,6 @@ class Mage_Backend_Block_Menu extends Mage_Backend_Block_Template
     protected function _construct()
     {
         parent::_construct();
-        $this->setTemplate('Mage_Backend::menu.phtml');
         $this->_url = Mage::getModel('Mage_Backend_Model_Url');
         $this->setCacheTags(array(self::CACHE_TAGS));
     }
@@ -89,285 +106,111 @@ public function getCacheKeyInfo()
     }
 
     /**
-     * Retrieve Adminhtml Menu array
-     *
-     * @return array
-     */
-    public function getMenuArray()
-    {
-        return $this->_buildMenuArray();
-    }
-
-    /**
-     * Retrieve Title value for menu node
-     *
-     * @param Varien_Simplexml_Element $child
-     * @return string
-     */
-    protected function _getHelperValue(Varien_Simplexml_Element $child)
-    {
-        $helperName         = 'Mage_Backend_Helper_Data';
-        $titleNodeName      = 'title';
-        $childAttributes    = $child->attributes();
-        if (isset($childAttributes['module'])) {
-            $helperName     = (string)$childAttributes['module'];
-        }
-//        if (isset($childAttributes['translate'])) {
-//            $titleNodeName  = (string)$childAttributes['translate'];
-//        }
-
-        return Mage::helper($helperName)->__((string)$child->$titleNodeName);
-    }
-
-    /**
-     * Recursive Build Menu array
+     * Processing block html after rendering
      *
-     * @param Varien_Simplexml_Element $parent
-     * @param string $path
-     * @param int $level
-     * @return array
+     * @param   string $html
+     * @return  string
      */
-    protected function _buildMenuArray(Varien_Simplexml_Element $parent=null, $path='', $level=0)
+    protected function _afterToHtml($html)
     {
-        if (is_null($parent)) {
-            $parent = Mage::getSingleton('Mage_Admin_Model_Config')->getAdminhtmlConfig()->getNode('menu');
-        }
-
-        $parentArr = array();
-        $sortOrder = 0;
-        foreach ($parent->children() as $childName => $child) {
-            if (1 == $child->disabled) {
-                continue;
-            }
-
-            $aclResource = 'admin/' . ($child->resource ? (string)$child->resource : $path . $childName);
-            if (!$this->_checkAcl($aclResource) || !$this->_isEnabledModuleOutput($child)) {
-                continue;
-            }
-
-            if ($child->depends && !$this->_checkDepends($child->depends)) {
-                continue;
-            }
-
-            $menuArr = array();
-
-            $menuArr['label'] = $this->_getHelperValue($child);
-
-            $menuArr['sort_order'] = $child->sort_order ? (int)$child->sort_order : $sortOrder;
-
-            if ($child->action) {
-                $menuArr['url'] = $this->_url->getUrl((string)$child->action, array('_cache_secret_key' => true));
-            } else {
-                $menuArr['url'] = '#';
-                $menuArr['click'] = 'return false';
-            }
-
-            $menuArr['active'] = ($this->getActive()==$path.$childName)
-                || (strpos($this->getActive(), $path.$childName.'/')===0);
-
-            $menuArr['level'] = $level;
-
-            if ($child->children) {
-                $menuArr['children'] = $this->_buildMenuArray($child->children, $path.$childName.'/', $level+1);
-            }
-            $parentArr[$childName] = $menuArr;
-
-            $sortOrder++;
-        }
-
-        uasort($parentArr, array($this, '_sortMenu'));
-
-        while (list($key, $value) = each($parentArr)) {
-            $last = $key;
-        }
-        if (isset($last)) {
-            $parentArr[$last]['last'] = true;
-        }
+        $html = preg_replace_callback(
+            '#'.Mage_Backend_Model_Url::SECRET_KEY_PARAM_NAME.'/\$([^\/].*)/([^\$].*)\$#U',
+            array($this, '_callbackSecretKey'),
+            $html
+        );
 
-        return $parentArr;
+        return $html;
     }
 
     /**
-     * Sort menu comparison function
+     * Replace Callback Secret Key
      *
-     * @param int $a
-     * @param int $b
-     * @return int
+     * @param array $match
+     * @return string
      */
-    protected function _sortMenu($a, $b)
+    protected function _callbackSecretKey($match)
     {
-        return $a['sort_order']<$b['sort_order'] ? -1 : ($a['sort_order']>$b['sort_order'] ? 1 : 0);
+        return Mage_Backend_Model_Url::SECRET_KEY_PARAM_NAME . '/'
+            . $this->_url->getSecretKey($match[1], $match[2]);
     }
 
     /**
-     * Check Depends
-     *
-     * @param Varien_Simplexml_Element $depends
-     * @return bool
+     * Get menu config model
+     * @return Mage_Backend_Model_Menu
      */
-    protected function _checkDepends(Varien_Simplexml_Element $depends)
+    public function getMenuModel()
     {
-        if ($depends->module) {
-            $modulesConfig = Mage::getConfig()->getNode('modules');
-            foreach ($depends->module as $module) {
-                if (!$modulesConfig->$module || !$modulesConfig->$module->is('active')) {
-                    return false;
-                }
-            }
-        }
-
-        if ($depends->config) {
-            foreach ($depends->config as $path) {
-                if (!Mage::getStoreConfigFlag((string)$path)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
+        return Mage::getSingleton('Mage_Backend_Model_Menu_Config')->getMenu();
     }
 
     /**
-     * Check is Allow menu item for admin user
-     *
-     * @param string $resource
-     * @return bool
+     * Render menu container
+     * @param $menu
+     * @param $level
+     * @return string HTML
      */
-    protected function _checkAcl($resource)
+    public function renderMenuContainer($menu, $level = 0)
     {
-        try {
-            $res =  Mage::getSingleton('Mage_Backend_Model_Auth_Session')->isAllowed($resource);
-        } catch (Exception $e) {
-            return false;
-        }
-        return $res;
+        $block = $this->getChildBlock($this->getContainerRendererBlock());
+        $block->setMenu($menu);
+        $block->setLevel($level);
+        $block->setMenuBlock($this);
+        return $block->toHtml();
     }
 
     /**
-     * Processing block html after rendering
-     *
-     * @param   string $html
-     * @return  string
+     * Set container renderer block name
+     * @param string $renderer
+     * @return Mage_Backend_Block_Menu
      */
-    protected function _afterToHtml($html)
+    public function setContainerRendererBlock($renderer)
     {
-        $html = preg_replace_callback('#'.Mage_Backend_Model_Url::SECRET_KEY_PARAM_NAME.'/\$([^\/].*)/([^\$].*)\$#U', array($this, '_callbackSecretKey'), $html);
-
-        return $html;
+        $this->_containerRendererBlock = $renderer;
+        return $this;
     }
 
     /**
-     * Replace Callback Secret Key
-     *
-     * @param array $match
+     * Get container renderer block name
      * @return string
      */
-    protected function _callbackSecretKey($match)
+    public function getContainerRendererBlock()
     {
-        return Mage_Backend_Model_Url::SECRET_KEY_PARAM_NAME . '/'
-            . $this->_url->getSecretKey($match[1], $match[2]);
+        return $this->_containerRendererBlock;
     }
 
     /**
-     * Render HTML menu recursively starting from the specified level
-     *
-     * @param array $menu
-     * @param int $level
-     * @return string
+     * Set item renderer block name
+     * @param string $renderer
+     * @return Mage_Backend_Block_Menu
      */
-    protected function _renderMenuLevel(array $menu, $level = 0)
+    public function setItemRendererBlock($renderer)
     {
-        $result = '<ul' . (!$level ? ' id="nav"' : '') . '>';
-        foreach ($menu as $item) {
-            $hasChildren = !empty($item['children']);
-            $cssClasses = array('level' . $level);
-            if (!$level && !empty($item['active'])) {
-                $cssClasses[] = 'active';
-            }
-            if ($hasChildren) {
-                $cssClasses[] = 'parent';
-            }
-            if (!empty($level) && !empty($item['last'])) {
-                $cssClasses[] = 'last';
-            }
-            $result .= '<li'
-                . ($hasChildren ? ' onmouseover="Element.addClassName(this,\'over\')"' : '')
-                . ($hasChildren ? ' onmouseout="Element.removeClassName(this,\'over\')"' : '')
-                . ' class="' . implode(' ', $cssClasses) . '">'
-                . '<a'
-                . ' href="' . $item['url'] . '"'
-                . (!empty($item['title']) ? ' title="' . $item['title'] . '"' : '')
-                . (!empty($item['click']) ? ' onclick="' . $item['click'] . '"' : '')
-                . ($level === 0 && !empty($item['active']) ? ' class="active"' : '')
-                . '>'
-                . '<span>' . Mage::helper('Mage_Backend_Helper_Data')->escapeHtml($item['label']) . '</span>'
-                . '</a>'
-            ;
-            if ($hasChildren) {
-                $result .= $this->_renderMenuLevel($item['children'], $level + 1);
-            }
-            $result .= '</li>';
-        }
-        $result .= '</ul>';
-        return $result;
+        $this->_itemRendererBlock = $renderer;
+        return $this;
     }
 
     /**
-     * Render HTML menu
-     *
+     * Get item renderer block name
      * @return string
      */
-    public function renderMenu()
+    public function getItemRendererBlock()
     {
-        return $this->_renderMenuLevel($this->_buildMenuArray());
+        return $this->_itemRendererBlock;
     }
 
     /**
-     * Get menu level HTML code
+     * Get current selected menu item
      *
-     * @param array $menu
-     * @param int $level
-     * @return string
+     * @return Mage_Backend_Model_Menu_Item|null|bool
      */
-    public function getMenuLevel($menu, $level = 0)
+    public function getActiveItemModel()
     {
-        $html = '<ul ' . (!$level ? 'id="nav"' : '') . '>' . PHP_EOL;
-        foreach ($menu as $item) {
-            $html .= '<li ' . (!empty($item['children']) ? 'onmouseover="Element.addClassName(this,\'over\')" '
-                . 'onmouseout="Element.removeClassName(this,\'over\')"' : '') . ' class="'
-                . (!$level && !empty($item['active']) ? ' active' : '') . ' '
-                . (!empty($item['children']) ? ' parent' : '')
-                . (!empty($level) && !empty($item['last']) ? ' last' : '')
-                . ' level' . $level . '"> <a href="' . $item['url'] . '" '
-                . (!empty($item['title']) ? 'title="' . $item['title'] . '"' : '') . ' '
-                . (!empty($item['click']) ? 'onclick="' . $item['click'] . '"' : '') . ' class="'
-                . ($level === 0 && !empty($item['active']) ? 'active' : '') . '"><span>'
-                . $this->escapeHtml($item['label']) . '</span></a>' . PHP_EOL;
-
-            if (!empty($item['children'])) {
-                $html .= $this->getMenuLevel($item['children'], $level + 1);
+        if (is_null($this->_activeItemModel)) {
+            $this->_activeItemModel = $this->getMenuModel()->get($this->getActive());
+            if (false == ($this->_activeItemModel instanceof Mage_Backend_Model_Menu_Item)) {
+                $this->_activeItemModel = false;
             }
-            $html .= '</li>' . PHP_EOL;
         }
-        $html .= '</ul>' . PHP_EOL;
-
-        return $html;
-    }
-
-    /**
-     * Check is module output enabled
-     *
-     * @param Varien_Simplexml_Element $child
-     * @return bool
-     */
-    protected function _isEnabledModuleOutput(Varien_Simplexml_Element $child)
-    {
-        $helperName      = 'Mage_Backend_Helper_Data';
-        $childAttributes = $child->attributes();
-        if (isset($childAttributes['module'])) {
-            $helperName  = (string)$childAttributes['module'];
-        }
-
-        return Mage::helper($helperName)->isModuleOutputEnabled();
+        return $this->_activeItemModel;
     }
 }
diff --git a/app/code/core/Mage/Backend/Block/Menu/Container.php b/app/code/core/Mage/Backend/Block/Menu/Container.php
new file mode 100644
index 0000000000000..9b7ba884a71ac
--- /dev/null
+++ b/app/code/core/Mage/Backend/Block/Menu/Container.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Backend menu item block
+ *
+ * @category   Mage
+ * @package    Mage_Backend
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Backend_Block_Menu_Container extends Mage_Backend_Block_Template
+{
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menu;
+
+    /**
+     * Set menu model
+     * @return Mage_Backend_Model_Menu
+     */
+    public function getMenu()
+    {
+        return $this->_menu;
+    }
+
+    /**
+     * Get menu filter iterator
+     * @return Mage_Backend_Model_Menu_Filter_Iterator
+     */
+    public function getMenuIterator()
+    {
+        return Mage::getModel('Mage_Backend_Model_Menu_Filter_Iterator', $this->getMenu()->getIterator());
+    }
+
+    /**
+     * Get menu model
+     *
+     * @param Mage_Backend_Model_Menu $menu
+     * @return Mage_Backend_Block_Menu_Container
+     */
+    public function setMenu(Mage_Backend_Model_Menu $menu)
+    {
+        $this->_menu = $menu;
+        return $this;
+    }
+
+    /**
+     * Render menu item element
+     * @param Mage_Backend_Model_Menu_Item $menuItem
+     * @return string
+     */
+    public function renderMenuItem(Mage_Backend_Model_Menu_Item $menuItem)
+    {
+        /**
+         * Save current level
+         */
+        $currentLevel = $this->getLevel();
+
+        /**
+         * Render child blocks
+         * @var Mage_Backend_Block_Menu_Item
+         */
+        $block = $this->getMenuBlock()->getChildBlock($this->getMenuBlock()->getItemRendererBlock());
+        $block->setMenuItem($menuItem);
+        $block->setLevel($currentLevel);
+        $block->setContainerRenderer($this->getMenuBlock());
+        $output = $block->toHtml();
+
+        /**
+         * Set current level, because it will be changed in child block
+         */
+        $this->setLevel($currentLevel);
+        return $output;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Block/Menu/Item.php b/app/code/core/Mage/Backend/Block/Menu/Item.php
new file mode 100644
index 0000000000000..ab3a5eb989b14
--- /dev/null
+++ b/app/code/core/Mage/Backend/Block/Menu/Item.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Backend menu item block
+ *
+ * @category   Mage
+ * @package    Mage_Backend
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Backend_Block_Menu_Item extends Mage_Backend_Block_Template
+{
+    /**
+     * @var Mage_Backend_Block_Menu
+     */
+    protected $_containerRenderer;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Item
+     */
+    protected $_menuItem;
+
+    /**
+     * Set menu model
+     * @return Mage_Backend_Model_Menu_Item
+     */
+    public function getMenuItem()
+    {
+        return $this->_menuItem;
+    }
+
+    /**
+     * Get menu item model
+     *
+     * @param Mage_Backend_Model_Menu_Item $menuItem
+     * @return Mage_Backend_Block_Menu_Item
+     */
+    public function setMenuItem(Mage_Backend_Model_Menu_Item $menuItem)
+    {
+        $this->_menuItem = $menuItem;
+        return $this;
+    }
+
+    /**
+     * Check whether given item is currently selected
+     *
+     * @param Mage_Backend_Model_Menu_Item $item
+     * @return bool
+     */
+    public function isItemActive(Mage_Backend_Model_Menu_Item $item)
+    {
+        $itemModel = $this->getContainerRenderer()->getActiveItemModel();
+        $output = false;
+
+        if ($this->getLevel() == 0
+            && $itemModel instanceof Mage_Backend_Model_Menu_Item
+            && ($itemModel->getId() == $item->getId()
+                || (strpos($itemModel->getFullPath(), $item->getFullPath() . '/') === 0))
+        ) {
+            $output = true;
+        }
+        return $output;
+    }
+
+    /**
+     * Current menu item is last
+     * @return bool
+     */
+    public function isLast()
+    {
+        return ($this->getLevel() == 0
+            && (bool)$this->getContainerRenderer()->getMenuModel()->isLast($this->getMenuItem()));
+    }
+
+    /**
+     * @return Mage_Backend_Block_Menu
+     */
+    public function getContainerRenderer()
+    {
+        return $this->_containerRenderer;
+    }
+
+    /**
+     * @param Mage_Backend_Block_Menu $block
+     * @return Mage_Backend_Block_Menu_Item
+     */
+    public function setContainerRenderer(Mage_Backend_Block_Menu $block)
+    {
+        $this->_containerRenderer = $block;
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid.php b/app/code/core/Mage/Backend/Block/Widget/Grid.php
index 8ab34a8db0927..3ac090d4241a3 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid.php
@@ -464,7 +464,7 @@ protected function _addColumnFilterToCollection($column)
             } else {
                 $cond = $column->getFilter()->getCondition();
                 if ($field && isset($cond)) {
-                    $this->getCollection()->addFieldToFilter($field , $cond);
+                    $this->getCollection()->addFieldToFilter($field, $cond);
                 }
             }
         }
diff --git a/app/code/core/Mage/Backend/Controller/ActionAbstract.php b/app/code/core/Mage/Backend/Controller/ActionAbstract.php
index 786a348181fd8..2ddebd4da089b 100644
--- a/app/code/core/Mage/Backend/Controller/ActionAbstract.php
+++ b/app/code/core/Mage/Backend/Controller/ActionAbstract.php
@@ -80,12 +80,12 @@ protected function _getHelper()
 
     /**
      * Define active menu item in menu block
-     * @param $menuPath
+     * @param string $itemId current active menu item
      * @return Mage_Backend_Controller_ActionAbstract
      */
-    protected function _setActiveMenu($menuPath)
+    protected function _setActiveMenu($itemId)
     {
-        $this->getLayout()->getBlock('menu')->setActive($menuPath);
+        $this->getLayout()->getBlock('menu')->setActive($itemId);
         return $this;
     }
 
diff --git a/app/code/core/Mage/Backend/Model/Menu.php b/app/code/core/Mage/Backend/Model/Menu.php
new file mode 100644
index 0000000000000..9f96e86368f09
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu.php
@@ -0,0 +1,239 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Backend menu model
+ */
+class Mage_Backend_Model_Menu extends ArrayObject
+{
+    /**
+     * Path in tree structure
+     *
+     * @var string
+     */
+    protected $_path = '';
+
+    /**
+     * @var Mage_Backend_Model_Menu_Logger
+     */
+    protected $_logger;
+
+    /**
+     * @param array $array
+     */
+    public function __construct($array = array())
+    {
+        if (isset($array['path'])) {
+            $this->_path = $array['path'] . '/';
+            unset($array['path']);
+        }
+        if (isset($array['logger'])) {
+            $this->_logger = $array['logger'];
+            unset($array['logger']);
+        } else {
+            throw new InvalidArgumentException('Logger object is a required parameter');
+        }
+        $this->setIteratorClass('Mage_Backend_Model_Menu_Iterator');
+        parent::__construct($array);
+    }
+
+    /**
+     * Add child to menu item
+     *
+     * @param Mage_Backend_Model_Menu_Item $item
+     * @param string $parentId
+     * @param int $index
+     * @throws InvalidArgumentException
+     */
+    public function add(Mage_Backend_Model_Menu_Item $item, $parentId = null, $index = null)
+    {
+        if (!is_null($parentId)) {
+            $parentItem = $this->get($parentId);
+            if ($parentItem === null) {
+                throw new InvalidArgumentException("Item with identifier {$parentId} does not exist");
+            }
+            $parentItem->getChildren()->add($item, null, $index);
+        } else {
+            $index = intval($index);
+            if (!isset($this[$index])) {
+                $this->offsetSet($index, $item);
+                $item->setPath($this->getFullPath());
+                $this->_logger->log(sprintf('Add of item with id %s was processed', $item->getId()));
+            } else {
+                $this->add($item, $parentId, $index + 1);
+            }
+        }
+    }
+
+    /**
+     * Retrieve menu item by id
+     *
+     * @param string $itemId
+     * @return Mage_Backend_Model_Menu_Item|null
+     */
+    public function get($itemId)
+    {
+        $result = null;
+        foreach ($this as $item) {
+            /** @var $item Mage_Backend_Model_Menu_Item */
+            if ($item->getId() == $itemId) {
+                $result = $item;
+                break;
+            }
+
+            if ($item->hasChildren() && ($result = $item->getChildren()->get($itemId))) {
+                break;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Move menu item
+     *
+     * @param string $itemId
+     * @param string $toItemId
+     * @param int $sortIndex
+     */
+    public function move($itemId, $toItemId, $sortIndex = null)
+    {
+        $item = $this->get($itemId);
+        if ($item === null) {
+            throw new InvalidArgumentException("Item with identifier {$itemId} does not exist");
+        }
+        $this->remove($itemId);
+        $this->add($item, $toItemId, $sortIndex);
+    }
+
+    /**
+     * Remove menu item by id
+     *
+     * @param string $itemId
+     * @return bool
+     */
+    public function remove($itemId)
+    {
+        $result = false;
+        foreach ($this as $key => $item) {
+            /** @var $item Mage_Backend_Model_Menu_Item */
+            if ($item->getId() == $itemId) {
+                unset($this[$key]);
+                $result = true;
+                $this->_logger->log(sprintf('Remove on item with id %s was processed', $item->getId()));
+                break;
+            }
+
+            if ($item->hasChildren() && ($result = $item->getChildren()->remove($itemId))) {
+                break;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Change order of an item in its parent menu
+     *
+     * @param string $itemId
+     * @param int $position
+     * @return bool
+     */
+    public function reorder($itemId, $position)
+    {
+        $result = false;
+        foreach ($this as $key => $item) {
+            /** @var $item Mage_Backend_Model_Menu_Item */
+            if ($item->getId() == $itemId) {
+                unset($this[$key]);
+                $this->add($item, null, $position);
+                $result = true;
+                break;
+            } else if ($item->hasChildren() && $result = $item->getChildren()->reorder($itemId, $position)) {
+                break;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Check whether provided item is last in list
+     *
+     * @param Mage_Backend_Model_Menu_Item $item
+     * @return bool
+     */
+    public function isLast(Mage_Backend_Model_Menu_Item $item)
+    {
+        return $this->offsetGet(max(array_keys($this->getArrayCopy())))->getId() == $item->getId();
+    }
+
+    /**
+     * Set path in tree
+     *
+     * @param $path
+     */
+    public function setPath($path)
+    {
+        $this->_path = $path . '/';
+        /** @var $child Mage_Backend_Model_Menu_Item */
+        foreach ($this as $child) {
+            $child->setPath($this->getFullPath());
+        }
+    }
+
+    /**
+     * Retrieve full path to node in tree
+     *
+     * @return string
+     */
+    public function getFullPath()
+    {
+        return $this->_path;
+    }
+
+    /**
+     * Find first menu item that user is able to access
+     *
+     * @return Mage_Backend_Model_Menu_Item|null
+     */
+    public function getFirstAvailable()
+    {
+        $result = null;
+        /** @var $item Mage_Backend_Model_Menu_Item */
+        foreach ($this as $item) {
+            if ($item->isAllowed() && !$item->isDisabled()) {
+                if ($item->hasChildren()) {
+                    $result = $item->getChildren()->getFirstAvailable();
+                    if (false == is_null($result)) {
+                        break;
+                    }
+                } else {
+                    $result = $item;
+                    break;
+                }
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Builder.php b/app/code/core/Mage/Backend/Model/Menu/Builder.php
new file mode 100644
index 0000000000000..573ac181931f9
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Builder.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu builder object. Retrieves commands (Mage_Backend_Model_Menu_Builder_CommandAbstract)
+ * to build menu (Mage_Backend_Model_Menu)
+ */
+class Mage_Backend_Model_Menu_Builder
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Builder_CommandAbstract[]
+     */
+    protected $_commands = array();
+
+    /**
+     * @var Mage_Backend_Model_Menu_Item_Factory
+     */
+    protected $_itemFactory;
+
+    /**
+     * Root menu
+     *
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menu;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException
+     */
+    public function __construct(array $data = array())
+    {
+        if (!isset($data['itemFactory']) || !($data['itemFactory'] instanceof Mage_Backend_Model_Menu_Item_Factory)) {
+            throw new InvalidArgumentException('Wrong item factory provided');
+        }
+        $this->_itemFactory = $data['itemFactory'];
+
+        if (!isset($data['menu']) || !($data['menu'] instanceof Mage_Backend_Model_Menu)) {
+            throw new InvalidArgumentException();
+        }
+        $this->_menu = $data['menu'];
+    }
+
+    /**
+     * Process provided command object
+     *
+     * @param Mage_Backend_Model_Menu_Builder_CommandAbstract $command
+     * @return Mage_Backend_Model_Menu_Builder
+     */
+    public function processCommand(Mage_Backend_Model_Menu_Builder_CommandAbstract $command)
+    {
+        if (!isset($this->_commands[$command->getId()])) {
+            $this->_commands[$command->getId()] = $command;
+        } else {
+            $this->_commands[$command->getId()]->chain($command);
+        }
+        return $this;
+    }
+
+    /**
+     * @return Mage_Backend_Model_Menu
+     * @throws OutOfRangeException in case given parent id does not exists
+     */
+    public function getResult()
+    {
+        /** @var $items Mage_Backend_Model_Menu_Item[] */
+        $params = array();
+        $items = array();
+
+        // Create menu items
+        foreach ($this->_commands as $id => $command) {
+            $params[$id] = $command->execute();
+            $item = $this->_itemFactory->createFromArray($params[$id]);
+            $items[$id] = $item;
+        }
+
+        // Build menu tree based on "parent" param
+        foreach($items as $id => $item) {
+            $sortOrder = isset($params[$id]['sortOrder']) ? $params[$id]['sortOrder'] : null;
+            $parentId = isset($params[$id]['parent']) ? $params[$id]['parent'] : null;
+            $isRemoved = isset($params[$id]['removed']);
+
+            if ($isRemoved) {
+                continue;
+            }
+            if (!$parentId) {
+                $this->_menu->add($item, null, $sortOrder);
+            } else {
+                if (!isset($items[$parentId])) {
+                    throw new OutOfRangeException(sprintf('Specified invalid parent id (%s)', $parentId));
+                }
+                if (isset($params[$parentId]['removed'])) {
+                    continue;
+                }
+                $items[$parentId]->getChildren()->add($item, null, $sortOrder);
+            }
+        }
+
+        return $this->_menu;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Add.php b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Add.php
new file mode 100644
index 0000000000000..ea6bcfd907ade
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Add.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Builder command to add menu items
+ */
+class Mage_Backend_Model_Menu_Builder_Command_Add extends Mage_Backend_Model_Menu_Builder_CommandAbstract
+{
+    /**
+     * List of params that command requires for execution
+     *
+     * @var array
+     */
+    protected $_requiredParams = array(
+        "id",
+        "title",
+        "module"
+    );
+
+    /**
+     * Add command as last in the list of callbacks
+     *
+     * @param Mage_Backend_Model_Menu_Builder_CommandAbstract $command
+     * @return Mage_Backend_Model_Menu_Builder_CommandAbstract
+     * @throws InvalidArgumentException
+     */
+    public function chain(Mage_Backend_Model_Menu_Builder_CommandAbstract $command)
+    {
+        if ($command instanceof Mage_Backend_Model_Menu_Builder_Command_Add) {
+            throw new InvalidArgumentException("Two 'add' commands cannot have equal id (" . $command->getId() . ")");
+        }
+        return parent::chain($command);
+    }
+
+    /**
+     * Add missing data to item
+     *
+     * @param array $itemParams
+     * @return array
+     */
+    protected function _execute(array $itemParams)
+    {
+        foreach($this->_data as $key => $value) {
+            $itemParams[$key] = isset($itemParams[$key]) ? $itemParams[$key] : $value;
+        }
+        return $itemParams;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Remove.php b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Remove.php
new file mode 100644
index 0000000000000..86fe1e49bd175
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Remove.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Command to remove menu item
+ */
+class Mage_Backend_Model_Menu_Builder_Command_Remove extends Mage_Backend_Model_Menu_Builder_CommandAbstract
+{
+    /**
+     * Mark item as removed
+     *
+     * @param array $itemParams
+     * @return array
+     */
+    protected function _execute(array $itemParams)
+    {
+        $itemParams['id'] = $this->getId();
+        $itemParams['removed'] = true;
+        return $itemParams;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Update.php b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Update.php
new file mode 100644
index 0000000000000..e69c56a6f2cc1
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Builder/Command/Update.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Command to update menu item data
+ */
+class Mage_Backend_Model_Menu_Builder_Command_Update extends Mage_Backend_Model_Menu_Builder_CommandAbstract
+{
+    /**
+     * Update item data
+     *
+     * @param array $itemParams
+     * @return array
+     */
+    protected function _execute(array $itemParams)
+    {
+        foreach ($this->_data as $key => $value) {
+            $itemParams[$key] = $value;
+        }
+        return $itemParams;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Builder/CommandAbstract.php b/app/code/core/Mage/Backend/Model/Menu/Builder/CommandAbstract.php
new file mode 100644
index 0000000000000..d97e8162d8adf
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Builder/CommandAbstract.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu builder command
+ */
+abstract class Mage_Backend_Model_Menu_Builder_CommandAbstract
+{
+    /**
+     * List of required params
+     *
+     * @var array
+     */
+    protected $_requiredParams = array("id");
+
+    /**
+     * Command params array
+     *
+     * @var array
+     */
+    protected $_data = array();
+
+    /**
+     * Next command in the chain
+     *
+     * @var Mage_Backend_Model_Menu_Builder_CommandAbstract
+     */
+    protected $_next = null;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException
+     */
+    public function __construct(array $data = array())
+    {
+        foreach($this->_requiredParams as $param) {
+            if (!isset($data[$param]) || is_null($data[$param])) {
+                throw new InvalidArgumentException("Missing required param " . $param);
+            }
+        }
+        $this->_data = $data;
+    }
+
+    /**
+     * Retreive id of element to apply command to
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->_data['id'];
+    }
+
+    /**
+     * Add command as last in the list of callbacks
+     *
+     * @param Mage_Backend_Model_Menu_Builder_CommandAbstract $command
+     * @return Mage_Backend_Model_Menu_Builder_CommandAbstract
+     * @throws InvalidArgumentException if invalid chaining command is supplied
+     */
+    public function chain(Mage_Backend_Model_Menu_Builder_CommandAbstract $command)
+    {
+        if (is_null($this->_next)) {
+            $this->_next = $command;
+        } else {
+            $this->_next->chain($command);
+        }
+        return $this;
+    }
+
+    /**
+     * Execute command and pass control to chained commands
+     *
+     * @param array $itemParams
+     * @return array
+     */
+    public function execute(array $itemParams = array())
+    {
+        $itemParams = $this->_execute($itemParams);
+        if (!is_null($this->_next)) {
+            $itemParams = $this->_next->execute($itemParams);
+        }
+        return $itemParams;
+    }
+
+    /**
+     * Execute internal command actions
+     *
+     * @param array $itemParams
+     * @return array
+     */
+    protected abstract function _execute(array $itemParams);
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Config.php b/app/code/core/Mage/Backend/Model/Menu/Config.php
new file mode 100644
index 0000000000000..b3c56f3c741bb
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Config.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Menu_Config
+{
+    const CACHE_ID = 'backend_menu_config';
+
+    /**
+     * @var Mage_Core_Model_Cache
+     */
+    protected $_cache;
+
+    /**
+     * @var Mage_Core_Model_Config
+     */
+    protected $_appConfig;
+
+    /**
+     * @var Mage_Core_Model_Event_Manager
+     */
+    protected $_eventManager;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Builder
+     */
+    protected $_menuBuilder;
+    /**
+     * Menu model
+     *
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menu;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Logger
+     */
+    protected $_logger;
+
+    public function __construct(array $arguments = array())
+    {
+        $this->_cache = isset($arguments['cache']) ? $arguments['cache'] : Mage::app()->getCacheInstance();
+        $this->_appConfig = isset($arguments['appConfig']) ? $arguments['appConfig'] : Mage::getConfig();
+        $this->_eventManager = isset($arguments['eventManager'])
+            ? $arguments['eventManager']
+            : Mage::getSingleton('Mage_Core_Model_Event_Manager');
+
+        $this->_logger = isset($arguments['logger'])
+            ? $arguments['logger']
+            : Mage::getSingleton('Mage_Backend_Model_Menu_Logger');
+
+        $this->_menuBuilder = isset($arguments['menuBuilder'])
+            ? $arguments['menuBuilder']
+            : Mage::getSingleton('Mage_Backend_Model_Menu_Builder', array(
+                'menu' => Mage::getSingleton('Mage_Backend_Model_Menu_Factory')->getMenuInstance(),
+                'itemFactory' => Mage::getSingleton('Mage_Backend_Model_Menu_Item_Factory'),
+            ));
+    }
+
+    /**
+     * Build menu model from config
+     *
+     * @return Mage_Backend_Model_Menu
+     * @throws InvalidArgumentException|BadMethodCallException|OutOfRangeException|Exception
+     */
+    public function getMenu()
+    {
+        try {
+            $this->_initMenu();
+            return $this->_menu;
+        } catch (InvalidArgumentException $e) {
+            $this->_logger->logException($e);
+            throw $e;
+        } catch (BadMethodCallException $e) {
+            $this->_logger->logException($e);
+            throw $e;
+        } catch (OutOfRangeException $e) {
+            $this->_logger->logException($e);
+            throw $e;
+        } catch (Exception $e) {
+            throw $e;
+        }
+    }
+
+    /**
+     * Initialize menu object
+     *
+     * @return void
+     */
+    protected function _initMenu()
+    {
+        if (!$this->_menu) {
+            /* @var $director Mage_Backend_Model_Menu_Director_Dom */
+            $director = $this->_appConfig->getModelInstance(
+                'Mage_Backend_Model_Menu_Director_Dom',
+                array(
+                    'config' => $this->_getDom(),
+                    'factory' => $this->_appConfig,
+                    'logger' => $this->_logger
+                )
+            );
+            $director->buildMenu($this->_menuBuilder);
+            $this->_menu = $this->_menuBuilder->getResult();
+            $this->_eventManager->dispatch('backend_menu_load_after', array('menu' => $this->_menu));
+        }
+    }
+
+    /**
+     * @return DOMDocument
+     */
+    protected function _getDom()
+    {
+        $mergedConfigXml = $this->_loadCache();
+        if ($mergedConfigXml) {
+            $mergedConfig = new DOMDocument();
+            $mergedConfig->loadXML($mergedConfigXml);
+        } else {
+            $fileList = $this->getMenuConfigurationFiles();
+            $mergedConfig = $this->_appConfig
+                ->getModelInstance('Mage_Backend_Model_Menu_Config_Menu', $fileList)->getMergedConfig();
+            $this->_saveCache($mergedConfig->saveXML());
+        }
+        return $mergedConfig;
+    }
+
+    protected function _loadCache()
+    {
+        if ($this->_cache->canUse('config')) {
+            return $this->_cache->load(self::CACHE_ID);
+        }
+        return false;
+    }
+
+    protected function _saveCache($xml)
+    {
+        if ($this->_cache->canUse('config')) {
+            $this->_cache->save($xml, self::CACHE_ID, array(Mage_Core_Model_Config::CACHE_TAG));
+        }
+        return $this;
+    }
+
+    /**
+     * Return array menu configuration files
+     *
+     * @return array
+     */
+    public function getMenuConfigurationFiles()
+    {
+        $files = $this->_appConfig
+            ->getModuleConfigurationFiles('adminhtml' . DIRECTORY_SEPARATOR . 'menu.xml');
+        return (array) $files;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Config/Menu.php b/app/code/core/Mage/Backend/Model/Menu/Config/Menu.php
new file mode 100644
index 0000000000000..5d38d46701bcc
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Config/Menu.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu configuration files handler
+ */
+class Mage_Backend_Model_Menu_Config_Menu extends Magento_Config_XmlAbstract
+{
+    /**
+     * Path to menu.xsd
+     *
+     * @return string
+     */
+    public function getSchemaFile()
+    {
+        return __DIR__ . '/menu.xsd';
+    }
+
+    /**
+     * Extract configuration data from the DOM structure
+     *
+     * @param DOMDocument $dom
+     * @return array
+     */
+    protected function _extractData(DOMDocument $dom)
+    {
+        return array();
+    }
+
+    /**
+     * Getter for initial menu.xml contents
+     *
+     * @return string
+     */
+    protected function _getInitialXml()
+    {
+        return '<?xml version="1.0" encoding="utf-8"?><config><menu></menu></config>';
+    }
+
+    /**
+     * Variables are identified by module and name
+     *
+     * @return array
+     */
+    protected function _getIdAttributes()
+    {
+        return array();
+    }
+
+    /**
+     * Get merged configuration
+     * @return DOMDocument
+     */
+    public function getMergedConfig()
+    {
+        return $this->_getDomConfigModel()->getDom();
+    }
+
+    /**
+     * Get Dom configuration model
+     * @return Mage_Backend_Model_Menu_Config_Menu_Dom
+     */
+    protected function _getDomConfigModel()
+    {
+        if (is_null($this->_domConfig)) {
+            $this->_domConfig = new Mage_Backend_Model_Menu_Config_Menu_Dom(
+                $this->_getInitialXml(),
+                $this->_getIdAttributes()
+            );
+        }
+        return $this->_domConfig;
+    }
+
+    /**
+     * Perform xml validation
+     * @return Magento_Config_XmlAbstract
+     * @throws Magento_Exception if invalid XML-file passed
+     */
+    public function validate()
+    {
+        return $this->_performValidate();
+    }
+
+    /**
+     * Get if xml files must be runtime validated
+     * @return boolean
+     */
+    protected function _isRuntimeValidated()
+    {
+        return false;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Config/Menu/Dom.php b/app/code/core/Mage/Backend/Model/Menu/Config/Menu/Dom.php
new file mode 100644
index 0000000000000..200cb2924c09f
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Config/Menu/Dom.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu configuration files handler
+ */
+class Mage_Backend_Model_Menu_Config_Menu_Dom extends Magento_Config_Dom
+{
+
+    /**
+     * Getter for node by path
+     *
+     * @param string $nodePath
+     * @throws Magento_Exception an exception is possible if original document contains multiple fixed nodes
+     * @return DOMElement | null
+     */
+    protected function _getMatchedNode($nodePath)
+    {
+        if (!preg_match('/^\/config(\/menu)?$/i', $nodePath)) {
+            return null;
+        }
+        return parent::_getMatchedNode($nodePath);
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Config/menu.xsd b/app/code/core/Mage/Backend/Model/Menu/Config/menu.xsd
new file mode 100644
index 0000000000000..525f58b341212
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Config/menu.xsd
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Framework
+ * @subpackage  Config
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="config">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="menu">
+                     <xs:complexType>
+                        <xs:sequence>
+                            <xs:choice maxOccurs="unbounded" minOccurs="0">
+                                <xs:element name="add">
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            Action designed for adding new item to existing items as a child
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                    <xs:complexType>
+                                        <xs:attribute name="id" type="typeId" use="required" />
+                                        <xs:attribute name="title" type="typeTitle" use="required" />
+                                        <xs:attribute name="module" type="typeModule" use="required" />
+                                        <xs:attribute name="sortOrder" type="xs:int" use="optional" />
+                                        <xs:attribute name="action" type="typeAction" use="optional" />
+                                        <xs:attribute name="parent" type="typeId" use="optional" />
+                                        <xs:attribute name="toolTip" type="typeTitle" use="optional" />
+                                        <xs:attribute name="resource" type="typeResource" use="optional" />
+                                        <xs:attribute name="dependsOnModule" type="typeModule" use="optional" />
+                                        <xs:attribute name="dependsOnConfig" type="typeDependsConfig" use="optional" />
+                                    </xs:complexType>
+                                </xs:element>
+                                <xs:element name="update">
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            Action designed for updating existing menu items attributes
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                    <xs:complexType>
+                                        <xs:attribute name="id" type="typeId" use="required" />
+                                        <xs:attribute name="title" type="typeTitle" use="optional" />
+                                        <xs:attribute name="module" type="typeModule" use="optional" />
+                                        <xs:attribute name="sortOrder" type="xs:int" use="optional" />
+                                        <xs:attribute name="action" type="typeAction" use="optional" />
+                                        <xs:attribute name="parent" type="typeId" use="optional" />
+                                        <xs:attribute name="toolTip" type="typeTitle" use="optional" />
+                                        <xs:attribute name="resource" type="typeResource" use="optional" />
+                                        <xs:attribute name="dependsOnModule" type="typeModule" use="optional" />
+                                        <xs:attribute name="dependsOnConfig" type="typeDependsConfig" use="optional" />
+                                    </xs:complexType>
+                                </xs:element>
+                                <xs:element name="remove">
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            Action designed for removing existing menu item with its children
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                    <xs:complexType>
+                                        <xs:attribute name="id" type="typeId" use="required" />
+                                    </xs:complexType>
+                                </xs:element>
+                            </xs:choice>
+                        </xs:sequence>
+                    </xs:complexType>
+
+                    <xs:unique name="uniqueAddItemId">
+                        <xs:annotation>
+                            <xs:documentation>
+                                Attribute id is unique under add actions
+                            </xs:documentation>
+                        </xs:annotation>
+                        <xs:selector xpath="add"/>
+                        <xs:field xpath="@id"/>
+                    </xs:unique>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:simpleType name="typeId">
+        <xs:annotation>
+            <xs:documentation>
+                Item id attribute can has only [a-z0-9/_]. Minimal length 3 symbol. Case insensitive.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[A-Za-z0-9/_:]{3,}" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeAction">
+        <xs:annotation>
+            <xs:documentation>
+                Item action attribute can has only [a-zA-Z0-9/_]. Minimal length 3 symbol
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[a-zA-Z0-9/_]{3,}" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeTitle">
+        <xs:annotation>
+            <xs:documentation>
+                Item title attribute minimal length 3 symbol
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:minLength value="3" />
+            <xs:maxLength value="50" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeModule">
+        <xs:annotation>
+            <xs:documentation>
+                Item module attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[A-Za-z0-9_]{3,}" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeResource">
+        <xs:annotation>
+            <xs:documentation>
+                Item resource attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[A-Za-z0-9_/]{3,}" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeDependsConfig">
+        <xs:annotation>
+            <xs:documentation>
+                Item resource attribute can has only [a-z0-9_]. Minimal length 3 symbol. Case insensitive.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[A-Za-z0-9_/]{3,}" />
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/app/code/core/Mage/Backend/Model/Menu/Director/Dom.php b/app/code/core/Mage/Backend/Model/Menu/Director/Dom.php
new file mode 100644
index 0000000000000..ba42ba13d3dee
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Director/Dom.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Menu_Director_Dom extends Mage_Backend_Model_Menu_DirectorAbstract
+{
+    /**
+     * Extracted config data
+     * @var array
+     */
+    protected $_extractedData = array();
+
+    /**
+     * @var Mage_Backend_Model_Menu_Logger
+     */
+    protected $_logger;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException if config storage is not present in $data array
+     */
+    public function __construct(array $data = array())
+    {
+        parent::__construct($data);
+        if (false == ($this->_configModel instanceof DOMDocument)) {
+            throw new InvalidArgumentException('Configuration storage model is not instance of DOMDocument');
+        }
+
+        if (isset($data['logger'])) {
+            $this->_logger = $data['logger'];
+        } else {
+            throw new InvalidArgumentException("Logger model is required parameter");
+        }
+
+        if (false == ($this->_logger instanceof Mage_Backend_Model_Menu_Logger)) {
+            throw new InvalidArgumentException('Logger model is not an instance of Mage_Core_Model_Log');
+        }
+
+        $this->_extractData();
+    }
+
+    /**
+     * Extract data from DOMDocument
+     * @return Mage_Backend_Model_Menu_Director_Dom
+     */
+    protected function _extractData()
+    {
+        $attributeNamesList = array(
+            'id',
+            'title',
+            'toolTip',
+            'module',
+            'sortOrder',
+            'action',
+            'parent',
+            'resource',
+            'dependsOnModule',
+            'dependsOnConfig',
+        );
+        $xpath = new DOMXPath($this->_configModel);
+        $nodeList = $xpath->query('/config/menu/*');
+        for ($i = 0; $i < $nodeList->length; $i++) {
+            $item = array();
+            $node = $nodeList->item($i);
+            $item['type'] = $node->nodeName;
+            foreach ($attributeNamesList as $name) {
+                if ($node->hasAttribute($name)) {
+                    $item[$name] = $node->getAttribute($name);
+                }
+            }
+            $this->_extractedData[] = $item;
+        }
+    }
+
+    /**
+     * Get data that were extracted from config storage
+     * @return array
+     */
+    public function getExtractedData()
+    {
+        return $this->_extractedData;
+    }
+
+    /**
+     * Get command object
+     * @param array $data command params
+     * @return Mage_Backend_Model_Menu_Builder_CommandAbstract
+     */
+    protected function _getCommand($data)
+    {
+        switch ($data['type']) {
+            case 'update':
+                $command = $this->_factory->getModelInstance(
+                    'Mage_Backend_Model_Menu_Builder_Command_Update',
+                    $data
+                );
+                $this->_logger->log(sprintf('Update on item with id %s was processed', $command->getId()));
+                break;
+
+            case 'remove':
+                $command = $this->_factory->getModelInstance(
+                    'Mage_Backend_Model_Menu_Builder_Command_Remove',
+                    $data
+                );
+                $this->_logger->log(sprintf('Remove on item with id %s was processed', $command->getId()));
+                break;
+
+            default:
+                $command = $this->_factory->getModelInstance(
+                    'Mage_Backend_Model_Menu_Builder_Command_Add',
+                    $data
+                );
+                break;
+        }
+        return $command;
+    }
+
+    /**
+     *
+     * @param Mage_Backend_Model_Menu_Builder $builder
+     * @throws InvalidArgumentException if invalid builder object
+     * @return Mage_Backend_Model_Menu_DirectorAbstract
+     */
+    public function buildMenu(Mage_Backend_Model_Menu_Builder $builder)
+    {
+        foreach ($this->getExtractedData() as $data) {
+            $command = $this->_getCommand($data);
+            $builder->processCommand($command);
+        }
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/DirectorAbstract.php b/app/code/core/Mage/Backend/Model/Menu/DirectorAbstract.php
new file mode 100644
index 0000000000000..ee252525e331a
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/DirectorAbstract.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+abstract class Mage_Backend_Model_Menu_DirectorAbstract
+{
+    /**
+     * Configuration data
+     * @var
+     */
+    protected $_configModel;
+
+    /**
+     * Factory model
+     * @var Mage_Core_Model_Config
+     */
+    protected $_factory;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException if config storage is not present in $data array
+     */
+    public function __construct(array $data = array())
+    {
+        if (isset($data['config'])) {
+            $this->_configModel = $data['config'];
+        } else {
+            throw new InvalidArgumentException('Configuration storage model is required parameter');
+        }
+
+        if (isset($data['factory'])) {//} && $data['factory'] instanceof Mage_Core_Model_Config) {
+            $this->_factory = $data['factory'];
+        } else {
+            throw new InvalidArgumentException('Configuration factory model is required parameter');
+        }
+    }
+
+    /**
+     * Apply menu commands to builder object
+     * @abstract
+     * @param  Mage_Backend_Model_Menu_Builder $builder
+     * @return Mage_Backend_Model_Menu_DirectorAbstract
+     */
+    abstract public function buildMenu(Mage_Backend_Model_Menu_Builder $builder);
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Factory.php b/app/code/core/Mage/Backend/Model/Menu/Factory.php
new file mode 100644
index 0000000000000..efbab6de6cebe
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Factory.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Menu_Factory
+{
+    /**
+     * Retrieve menu object
+     *
+     * @param array $arguments
+     * @return false|Mage_Core_Model_Abstract
+     */
+    public function getMenuInstance(array $arguments = array())
+    {
+        $arguments = array_merge(array('logger' => Mage::getSingleton('Mage_Backend_Model_Menu_Logger')), $arguments);
+        return Mage::getModel('Mage_Backend_Model_Menu', $arguments);
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Filter/Iterator.php b/app/code/core/Mage/Backend/Model/Menu/Filter/Iterator.php
new file mode 100644
index 0000000000000..ba7d33a879cf1
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Filter/Iterator.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu filter iterator
+ */
+class Mage_Backend_Model_Menu_Filter_Iterator extends FilterIterator
+{
+    /**
+     * Check whether the current element of the iterator is acceptable
+     *
+     * @return bool true if the current element is acceptable, otherwise false.
+     */
+    public function accept()
+    {
+        return !($this->current()->isDisabled() || !($this->current()->isAllowed()));
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Item.php b/app/code/core/Mage/Backend/Model/Menu/Item.php
new file mode 100644
index 0000000000000..edadaedca971e
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Item.php
@@ -0,0 +1,479 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu item. Should be used to create nested menu structures with Mage_Backend_Model_Menu
+ */
+class Mage_Backend_Model_Menu_Item
+{
+    /**
+     * Menu item id
+     *
+     * @var string
+     */
+    protected $_id;
+
+    /**
+     * Menu item title
+     *
+     * @var string
+     */
+    protected $_title;
+
+    /**
+     * Module of menu item
+     *
+     * @var Mage_Core_Helper_Abstract
+     */
+    protected $_moduleHelper;
+
+    /**
+     * Menu item sort index in list
+     *
+     * @var string
+     */
+    protected $_sortIndex = null;
+
+    /**
+     * Menu item action
+     *
+     * @var string
+     */
+    protected $_action = null;
+
+    /**
+     * Parent menu item id
+     *
+     * @var string
+     */
+    protected $_parentId = null;
+
+    /**
+     * Acl resource of menu item
+     *
+     * @var string
+     */
+    protected $_resource;
+
+    /**
+     * Item tooltip text
+     *
+     * @var string
+     */
+    protected $_tooltip;
+
+    /**
+     * Path from root element in tree
+     *
+     * @var string
+     */
+    protected $_path = '';
+
+    /**
+     * Acl
+     *
+     * @var Mage_Backend_Model_Auth_Session
+     */
+    protected $_acl;
+
+    /**
+     * Module that item is dependent on
+     *
+     * @var string|null
+     */
+    protected $_dependsOnModule;
+
+    /**
+     * Global config option that item is dependent on
+     *
+     * @var string|null
+     */
+    protected $_dependsOnConfig;
+
+    /**
+     * Submenu item list
+     *
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_submenu;
+
+    /**
+     * @var Mage_Core_Model_Config
+     */
+    protected $_appConfig;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Factory
+     */
+    protected $_menuFactory;
+
+    /**
+     * @var Mage_Backend_Model_Url
+     */
+    protected $_urlModel;
+
+    /**
+     * @var Mage_Core_Model_Store_Config
+     */
+    protected $_storeConfig;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Item_Validator
+     */
+    protected $_validator;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException
+     * @throws BadMethodCallException
+     */
+    public function __construct(array $data = array())
+    {
+        if (!isset($data['validator'])
+            || !$data['validator'] instanceof Mage_Backend_Model_Menu_Item_Validator) {
+            throw new InvalidArgumentException('Wrong validator object provided');
+        }
+
+        $this->_validator = $data['validator'];
+        $this->_validator->validate($data);
+
+        $this->_acl = $data['acl'];
+        $this->_appConfig = $data['appConfig'];
+        $this->_storeConfig = $data['storeConfig'];
+        $this->_menuFactory = $data['menuFactory'];
+        $this->_urlModel = $data['urlModel'];
+
+        $this->_id = $data['id'];
+        $this->_title = $data['title'];
+        $this->_moduleHelper = $data['module'];
+        $this->_action = isset($data['action']) ? $data['action'] : null;
+        $this->_resource = isset($data['resource']) ? $data['resource'] : null;
+        $this->_dependsOnModule = isset($data['dependsOnModule']) ? $data['dependsOnModule'] : null;
+        $this->_dependsOnConfig = isset($data['dependsOnConfig']) ? $data['dependsOnConfig'] : null;
+        $this->_tooltip = isset($data['toolTip']) ? $data['toolTip'] : '';
+    }
+
+    /**
+     * Retrieve item id
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    /**
+     * Check whether item has subnodes
+     *
+     * @return bool
+     */
+    public function hasChildren()
+    {
+        return !is_null($this->_submenu) && (bool) $this->_submenu->count();
+    }
+
+    /**
+     * Retrieve submenu
+     *
+     * @return Mage_Backend_Model_Menu
+     */
+    public function getChildren()
+    {
+        if (!$this->_submenu) {
+            $this->_submenu = $this->_menuFactory
+                ->getMenuInstance(
+                    array('path' => $this->getFullPath())
+            );
+        }
+        return $this->_submenu;
+    }
+
+    /**
+     * Retrieve full path from root element
+     *
+     * @return string
+     */
+    public function getFullPath()
+    {
+        /*
+         * TODO: Remove id manipulation after acl is transfered to ids
+         */
+        $id = $this->_id;
+        $start = strrpos($this->_id, ':');
+        if ($start) {
+            if ($this->_path) {
+                $path = str_replace('/', '_', $this->_path);
+                $start = strpos($this->_id, $path) + strlen($path);
+            } else {
+                if ($start) {
+                    $start++;
+                }
+            }
+            $id = substr($this->_id, $start);
+        }
+        return $this->_path . $id;
+    }
+
+    /**
+     * Retrieve menu item url
+     *
+     * @return string
+     */
+    public function getUrl()
+    {
+        if ((bool) $this->_action) {
+            return $this->_urlModel->getUrl((string)$this->_action, array('_cache_secret_key' => true));
+        }
+        return '#';
+    }
+
+    /**
+     * Retrieve menu item action
+     *
+     * @return string
+     */
+    public function getAction()
+    {
+        return $this->_action;
+    }
+
+    /**
+     * Set Item action
+     *
+     * @param string $action
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setAction($action)
+    {
+        $this->_validator->validateParam('action', $action);
+        $this->_action = $action;
+        return $this;
+    }
+
+    /**
+     * Chechk whether item has javascript callback on click
+     *
+     * @return bool
+     */
+    public function hasClickCallback()
+    {
+        return $this->getUrl() == '#';
+    }
+
+    /**
+     * Retrieve item click callback
+     *
+     * @return bool
+     */
+    public function getClickCallback()
+    {
+        if ($this->getUrl() == '#') {
+            return 'return false;';
+        }
+        return '';
+    }
+
+    /**
+     * Retrieve tooltip text title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    /**
+     * Set Item title
+     *
+     * @param string $title
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setTitle($title)
+    {
+        $this->_validator->validateParam('title', $title);
+        $this->_title = $title;
+        return $this;
+    }
+
+    /**
+     * Check whether item has tooltip text
+     *
+     * @return bool
+     */
+    public function hasTooltip()
+    {
+        return (bool) $this->_tooltip;
+    }
+
+    /**
+     * Retrieve item tooltip text
+     *
+     * @return string
+     */
+    public function getTooltip()
+    {
+        return $this->_tooltip;
+    }
+
+    /**
+     * Set Item tooltip
+     *
+     * @param string $tooltip
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setTooltip($tooltip)
+    {
+        $this->_validator->validateParam('toolTip', $tooltip);
+        $this->_tooltip = $tooltip;
+        return $this;
+    }
+
+    /**
+     * Retrieve module helper object linked to item.
+     * Should be used to translate item labels
+     *
+     * @return Mage_Core_Helper_Abstract
+     */
+    public function getModuleHelper()
+    {
+        return $this->_moduleHelper;
+    }
+
+    /**
+     * Set Item module
+     *
+     * @param Mage_Core_Helper_Abstract $helper
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setModuleHelper(Mage_Core_Helper_Abstract $helper)
+    {
+        $this->_validator->validateParam('module', $helper);
+        $this->_moduleHelper = $helper;
+        return $this;
+    }
+
+    /**
+     * Set Item module dependency
+     *
+     * @param string $moduleName
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setModuleDependency($moduleName)
+    {
+        $this->_validator->validateParam('dependsOnModule', $moduleName);
+        $this->_dependsOnModule = $moduleName;
+        return $this;
+    }
+
+    /**
+     * Set Item config dependency
+     *
+     * @param string $configPath
+     * @return Mage_Backend_Model_Menu_Item
+     * @throws InvalidArgumentException
+     */
+    public function setConfigDependency($configPath)
+    {
+        $this->_validator->validateParam('depenedsOnConfig', $configPath);
+        $this->_dependsOnConfig = $configPath;
+        return $this;
+    }
+
+    /**
+     * Check whether item is disabled. Disabled items are not shown to user
+     *
+     * @return bool
+     */
+    public function isDisabled()
+    {
+        return !$this->_moduleHelper->isModuleOutputEnabled()
+            || !$this->_isModuleDependenciesAvailable()
+            || !$this->_isConfigDependenciesAvailable();
+    }
+
+    /**
+     * Check whether module that item depends on is active
+     *
+     * @return bool
+     */
+    protected function _isModuleDependenciesAvailable()
+    {
+        if ($this->_dependsOnModule) {
+            $module = $this->_dependsOnModule;
+            $modulesConfig = $this->_appConfig->getNode('modules');
+            return ($modulesConfig->$module && $modulesConfig->$module->is('active'));
+        }
+        return true;
+    }
+
+    /**
+     * Check whether config dependency is available
+     *
+     * @return bool
+     */
+    protected function _isConfigDependenciesAvailable()
+    {
+        if ($this->_dependsOnConfig) {
+            return $this->_storeConfig->getConfigFlag((string)$this->_dependsOnConfig);
+        }
+        return true;
+    }
+
+    /**
+     * Check whether item is allowed to the user
+     *
+     * @return bool
+     */
+    public function isAllowed()
+    {
+        try {
+            $aclResource = 'admin/' . ($this->_resource ? (string)$this->_resource : $this->getFullPath());
+            return $this->_acl->isAllowed($aclResource);
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+
+    /**
+     * Set path in structure
+     *
+     * @param string $path
+     */
+    public function setPath($path)
+    {
+        $this->_path = $path;
+        if ($this->_submenu) {
+            $this->_submenu->setPath($this->getFullPath());
+        }
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Item/Factory.php b/app/code/core/Mage/Backend/Model/Menu/Item/Factory.php
new file mode 100644
index 0000000000000..57b8a15273053
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Item/Factory.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Menu_Item_Factory
+{
+    /**
+     * ACL
+     *
+     * @var Mage_Backend_Model_Auth_Session
+     */
+    protected $_acl;
+
+    /**
+     * @var Mage_Core_Model_Config
+     */
+    protected $_objectFactory;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Factory
+     */
+    protected $_menuFactory;
+
+    /**
+     * @var Mage_Core_Helper_Abstract[]
+     */
+    protected $_helpers = array();
+
+    /**
+     * @var Mage_Backend_Model_Url
+     */
+    protected $_urlModel;
+
+    /**
+     * Application Configuration
+     *
+     * @var Mage_Core_Model_Config
+     */
+    protected $_appConfig;
+
+    /**
+     * Store Configuration
+     *
+     * @var Mage_Core_Model_Store_Config
+     */
+    protected $_storeConfig;
+
+    /**
+     * Menu item parameter validator
+     *
+     * @var Mage_Backend_Model_Menu_Item_Validator
+     */
+    protected $_validator;
+
+    /**
+     * @param array $data
+     * @throws InvalidArgumentException
+     */
+    public function __construct(array $data = array())
+    {
+        $this->_acl = isset($data['acl']) ? $data['acl'] : Mage::getSingleton('Mage_Backend_Model_Auth_Session');
+        if (!($this->_acl instanceof Mage_Backend_Model_Auth_Session)) {
+            throw new InvalidArgumentException('Wrong acl object provided');
+        }
+
+        $this->_objectFactory = isset($data['objectFactory']) ? $data['objectFactory'] : Mage::getConfig();
+        if (!($this->_objectFactory instanceof Mage_Core_Model_Config)) {
+            throw new InvalidArgumentException('Wrong object factory provided');
+        }
+
+        $this->_menuFactory = isset($data['menuFactory'])
+            ? $data['menuFactory']
+            : Mage::getModel('Mage_Backend_Model_Menu_Factory');
+        if (!($this->_menuFactory instanceof Mage_Backend_Model_Menu_Factory)) {
+            throw new InvalidArgumentException('Wrong menu factory provided');
+        }
+
+        $this->_appConfig = isset($data['appConfig']) ? $data['appConfig']: Mage::getConfig();
+        if (!($this->_appConfig instanceof Mage_Core_Model_Config)) {
+            throw new InvalidArgumentException('Wrong application config provided');
+        }
+
+        $this->_storeConfig = isset($data['storeConfig'])
+            ? $data['storeConfig']
+            : Mage::getSingleton('Mage_Core_Model_Store_Config');
+        if (!($this->_storeConfig instanceof Mage_Core_Model_Store_Config)) {
+            throw new InvalidArgumentException('Wrong store config provided');
+        }
+
+        $this->_urlModel = isset($data['urlModel']) ? $data['urlModel'] : Mage::getSingleton('Mage_Backend_Model_Url');
+        if (!($this->_urlModel instanceof Mage_Backend_Model_Url)) {
+            throw new InvalidArgumentException('Wrong url model provided');
+        }
+
+        $this->_validator = isset($data['validator'])
+            ? $data['validator']
+            : Mage::getSingleton('Mage_Backend_Model_Menu_Item_Validator');
+        if (!($this->_validator instanceof Mage_Backend_Model_Menu_Item_Validator)) {
+            throw new InvalidArgumentException('Wrong item validator model provided');
+        }
+
+        if (isset($data['helpers'])) {
+            $this->_helpers = $data['helpers'];
+        }
+    }
+
+    /**
+     * Create menu item from array
+     *
+     * @param array $data
+     * @return Mage_Backend_Model_Menu_Item
+     */
+    public function createFromArray(array $data = array())
+    {
+        $module = 'Mage_Backend_Helper_Data';
+        if (isset($data['module'])) {
+            $module = $data['module'];
+        }
+
+        $data['module'] = isset($this->_helpers[$module]) ? $this->_helpers[$module] : Mage::helper($module);
+        $data['acl'] = $this->_acl;
+        $data['appConfig'] = $this->_appConfig;
+        $data['storeConfig'] = $this->_storeConfig;
+        $data['menuFactory'] = $this->_menuFactory;
+        $data['urlModel'] = $this->_urlModel;
+        $data['validator'] = $this->_validator;
+        return $this->_objectFactory->getModelInstance('Mage_Backend_Model_Menu_Item', $data);
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Menu/Item/Validator.php b/app/code/core/Mage/Backend/Model/Menu/Item/Validator.php
new file mode 100644
index 0000000000000..605d75e8efca2
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Item/Validator.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Menu_Item_Validator
+{
+    /**
+     * The list of required params
+     *
+     * @var array
+     */
+    protected $_required = array(
+        'acl', 'appConfig', 'menuFactory', 'urlModel', 'storeConfig', 'id', 'title', 'module'
+    );
+
+    /**
+     * The list of required param types
+     *
+     * @var array
+     */
+    protected $_requiredTypes = array(
+        'acl' => 'Mage_Backend_Model_Auth_Session',
+        'appConfig' => 'Mage_Core_Model_Config',
+        'menuFactory' => 'Mage_Backend_Model_Menu_Factory',
+        'urlModel' => 'Mage_Backend_Model_Url',
+        'storeConfig' => 'Mage_Core_Model_Store_Config',
+        'module' => 'Mage_Core_Helper_Abstract'
+    );
+
+    /**
+     * List of created item ids
+     *
+     * @var array
+     */
+    protected $_ids = array();
+
+    /**
+     * The list of primitive validators
+     *
+     * @var Zend_Validate[]
+     */
+    protected $_validators = array();
+
+    public function __construct()
+    {
+        $idValidator = new Zend_Validate();
+        $idValidator->addValidator(new Zend_Validate_StringLength(array('min' => 3)));
+        $idValidator->addValidator(new Zend_Validate_Regex('/^[A-Za-z0-9\/:_]+$/'));
+
+        $attributeValidator = new Zend_Validate();
+        $attributeValidator->addValidator(new Zend_Validate_StringLength(array('min' => 3)));
+        $attributeValidator->addValidator(new Zend_Validate_Regex('/^[A-Za-z0-9\/_]+$/'));
+
+        $textValidator = new Zend_Validate_StringLength(array('min' => 3, 'max' => 50));
+
+        $titleValidator = $tooltipValidator = $textValidator;
+        $actionValidator = $resourceValidator = $resourceValidator = $moduleDependencyValidator
+            = $configDependencyValidator = $attributeValidator;
+
+        $this->_validators['id'] = $idValidator;
+        $this->_validators['title'] = $titleValidator;
+        $this->_validators['action'] = $actionValidator;
+        $this->_validators['resource'] = $resourceValidator;
+        $this->_validators['dependsOnModule'] = $moduleDependencyValidator;
+        $this->_validators['dependsOnConfig'] = $configDependencyValidator;
+        $this->_validators['toolTip'] = $tooltipValidator;
+    }
+    /**
+     * Validate menu item params
+     *
+     * @param $data
+     * @throws InvalidArgumentException
+     * @throws BadMethodCallException
+     */
+    public function validate($data)
+    {
+        foreach ($this->_required as $param) {
+            if (!isset($data[$param])) {
+                throw new BadMethodCallException('Missing required param ' . $param);
+            }
+        }
+
+        if (array_search($data['id'], $this->_ids) !== false) {
+            throw new InvalidArgumentException('Item with id ' . $data ['id'] . ' already exists');
+        }
+
+        foreach ($data as $param => $value) {
+            if (isset($this->_requiredTypes[$param]) && !($data[$param] instanceof $this->_requiredTypes[$param])) {
+                throw new InvalidArgumentException(
+                    'Wrong param ' . $param . ': Expected ' . $this->_requiredTypes[$param] . ', received '
+                        . get_class($data[$param])
+                );
+            } elseif (!is_null($data[$param])
+                && isset($this->_validators[$param])
+                && !$this->_validators[$param]->isValid($value)
+            ) {
+                throw new InvalidArgumentException(
+                    "Param " . $param . " doesn't pass validation: "
+                        . implode('; ', $this->_validators[$param]->getMessages())
+                );
+            }
+        }
+        $this->_ids[] = $data['id'];
+    }
+
+    /**
+     * Validate incoming param
+     *
+     * @param string $param
+     * @param mixed $value
+     * @throws InvalidArgumentException
+     */
+    public function validateParam($param, $value)
+    {
+        if (in_array($param, $this->_required) && is_null($value)) {
+            throw new InvalidArgumentException('Param ' . $param . ' is required');
+        }
+
+        if (!is_null($value) && isset($this->_validators[$param]) && !$this->_validators[$param]->isValid($value)) {
+            throw new InvalidArgumentException(
+                'Param ' . $param . ' doesn\'t pass validation: '
+                    . implode('; ', $this->_validators[$param]->getMessages())
+            );
+        }
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Page/Menu.php b/app/code/core/Mage/Backend/Model/Menu/Iterator.php
similarity index 77%
rename from app/code/core/Mage/Adminhtml/Block/Page/Menu.php
rename to app/code/core/Mage/Backend/Model/Menu/Iterator.php
index 0683372009590..82a57f5d4b43d 100644
--- a/app/code/core/Mage/Adminhtml/Block/Page/Menu.php
+++ b/app/code/core/Mage/Backend/Model/Menu/Iterator.php
@@ -19,20 +19,22 @@
  * needs please refer to http://www.magentocommerce.com for more information.
  *
  * @category    Mage
- * @package     Mage_Adminhtml
+ * @package     Mage_Backend
  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
 /**
- * Adminhtml menu block
- *
- * @category   Mage
- * @package    Mage_Adminhtml
- * @author     Magento Core Team <core@magentocommerce.com>
- * @deprecated Moved to module Mage_Backend
+ * Menu iterator
  */
-class Mage_Adminhtml_Block_Page_Menu extends Mage_Backend_Block_Menu
+class Mage_Backend_Model_Menu_Iterator extends ArrayIterator
 {
-
+    /**
+     * Rewind to first element
+     */
+    public function rewind()
+    {
+        $this->ksort();
+        parent::rewind();
+    }
 }
diff --git a/app/code/core/Mage/Backend/Model/Menu/Logger.php b/app/code/core/Mage/Backend/Model/Menu/Logger.php
new file mode 100644
index 0000000000000..c4cedbbc5cbcc
--- /dev/null
+++ b/app/code/core/Mage/Backend/Model/Menu/Logger.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Menu logger model
+ *
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Backend_Model_Menu_Logger extends Mage_Core_Model_Logger
+{
+    const MENU_DEBUG_FILE = 'menu-debug.log';
+
+    /**
+     * Log wrapper
+     *
+     * @param string $message
+     * @param int $level
+     * @param string $file
+     * @param bool $forceLog
+     * @return void
+     */
+    public function log($message, $level = null, $file = '', $forceLog = false)
+    {
+        if (empty($file)) {
+            $file = self::MENU_DEBUG_FILE;
+        }
+        parent::log($message, $level, $file, $forceLog);
+    }
+
+    /**
+     * Log exception wrapper
+     *
+     * @param Exception $e
+     */
+    public function logException(Exception $e)
+    {
+        $this->log("\n" . $e->__toString(), Zend_Log::ERR);
+    }
+}
diff --git a/app/code/core/Mage/Backend/Model/Url.php b/app/code/core/Mage/Backend/Model/Url.php
index 3ea1cd02eba8f..a79426ca003f1 100644
--- a/app/code/core/Mage/Backend/Model/Url.php
+++ b/app/code/core/Mage/Backend/Model/Url.php
@@ -33,7 +33,7 @@ class Mage_Backend_Model_Url extends Mage_Core_Model_Url
     /**
      * xpath to startup page in configuration
      */
-    const XML_PATH_STARTUP_PAGE = 'admin/startup/page';
+    const XML_PATH_STARTUP_MENU_ITEM = 'admin/startup/menu_item_id';
 
     /**
      * Authentication session
@@ -43,26 +43,24 @@ class Mage_Backend_Model_Url extends Mage_Core_Model_Url
     protected $_session;
 
     /**
-     * @var Mage_Admin_Model_Config
+     * @var Mage_Backend_Model_Menu
      */
-    protected $_adminConfig;
+    protected $_menu;
 
     /**
      * Startup page url from config
      * @var string
      */
-    protected $_startupPageUrl;
+    protected $_startupMenuItemId;
 
     public function __construct(array $data = array())
     {
         parent::__construct($data);
-        $this->_adminConfig = isset($data['adminConfig']) ?
-            $data['adminConfig'] :
-            Mage::getSingleton('Mage_Admin_Model_Config');
+        $this->_startupMenuItemId = isset($data['startupMenuItemId']) ?
+            $data['startupMenuItemId'] :
+            Mage::getStoreConfig(self::XML_PATH_STARTUP_MENU_ITEM);
 
-        $this->_startupPageUrl = isset($data['startupPageUrl']) ?
-            $data['startupPageUrl'] :
-            Mage::getStoreConfig(self::XML_PATH_STARTUP_PAGE);
+        $this->_menu = isset($data['menu']) ? $data['menu'] : null;
     }
 
 
@@ -212,12 +210,11 @@ public function renewSecretUrls()
      */
     public function getStartupPageUrl()
     {
-        $aclResource = 'admin/' . $this->_startupPageUrl;
+        $aclResource = 'admin/' . $this->_startupMenuItemId;
         if ($this->_getSession()->isAllowed($aclResource)) {
-            $nodePath = 'menu/' . join('/children/', explode('/', $this->_startupPageUrl)) . '/action';
-            $url = $this->_adminConfig->getAdminhtmlConfig()->getNode($nodePath);
-            if ($url) {
-                return $url;
+            $menuItem = $this->_getMenu()->get($this->_startupMenuItemId);
+            if ($menuItem && $menuItem->getAction()) {
+                return $menuItem->getAction();
             }
         }
         return $this->findFirstAvailableMenu();
@@ -226,35 +223,37 @@ public function getStartupPageUrl()
     /**
      * Find first menu item that user is able to access
      *
-     * @param Mage_Core_Model_Config_Element $parent
-     * @param string $path
-     * @param integer $level
      * @return string
      */
-    public function findFirstAvailableMenu($parent = null, $path = '', $level = 0)
+    public function findFirstAvailableMenu()
     {
-        if ($parent == null) {
-            $parent = $this->_adminConfig->getAdminhtmlConfig()->getNode('menu');
-        }
-        foreach ($parent->children() as $childName => $child) {
-            $aclResource = 'admin/' . $path . $childName;
-            if ($this->_getSession()->isAllowed($aclResource)) {
-                if (!$child->children) {
-                    return (string)$child->action;
-                } else if ($child->children) {
-                    $action = $this->findFirstAvailableMenu($child->children, $path . $childName . '/', $level + 1);
-                    return $action ? $action : (string)$child->action;
-                }
+        /* @var $menu Mage_Backend_Model_Menu_Item */
+        $menu = $this->_getMenu();
+        $item = $menu->getFirstAvailable();
+        $action = $item ? $item->getAction() : null;
+        if (!$item) {
+            $user = $this->_getSession()->getUser();
+            if ($user) {
+                $user->setHasAvailableResources(false);
             }
+            $action = '*/*/denied';
         }
-        $user = $this->_getSession()->getUser();
-        if ($user) {
-            $user->setHasAvailableResources(false);
-        }
-        return '*/*/denied';
-    }
+        return $action;
 
+    }
 
+    /**
+     * Get Menu model
+     *
+     * @return Mage_Backend_Model_Menu
+     */
+    protected function _getMenu()
+    {
+        if (is_null($this->_menu)) {
+            $this->_menu = Mage::getSingleton('Mage_Backend_Model_Menu_Config')->getMenu();
+        }
+        return $this->_menu;
+    }
 
     /**
      * Set custom auth session
diff --git a/app/code/core/Mage/Backend/etc/config.xml b/app/code/core/Mage/Backend/etc/config.xml
index d412b7ed01c70..18e03544134ee 100644
--- a/app/code/core/Mage/Backend/etc/config.xml
+++ b/app/code/core/Mage/Backend/etc/config.xml
@@ -46,6 +46,13 @@
         <backend>
             <auth/>
         </backend>
+        <cache>
+            <types>
+                <config translate="description" module="Mage_Backend">
+                    <description>System(config.xml, local.xml) and modules configuration files(config.xml, menu.xml).</description>
+                </config>
+            </types>
+        </cache>
     </global>
     <admin>
         <routers>
diff --git a/app/code/core/Mage/Backend/view/adminhtml/layout.xml b/app/code/core/Mage/Backend/view/adminhtml/layout.xml
index 32165c2527bc9..d06896a6ca19f 100644
--- a/app/code/core/Mage/Backend/view/adminhtml/layout.xml
+++ b/app/code/core/Mage/Backend/view/adminhtml/layout.xml
@@ -26,6 +26,17 @@
  */
  -->
 <layout>
+    <default>
+        <reference name="root" after="header">
+            <block type="Mage_Backend_Block_Menu" name="menu" as="menu" template="Mage_Backend::menu.phtml">
+                <block type="Mage_Backend_Block_Menu_Container" name="menu_container_renderer" template="Mage_Backend::menu/container.phtml" />
+                <block type="Mage_Backend_Block_Menu_Item" name="menu_item_renderer" template="Mage_Backend::menu/item.phtml" />
+                <action method="setContainerRendererBlock"><renderer>menu_container_renderer</renderer></action>
+                <action method="setItemRendererBlock"><renderer>menu_item_renderer</renderer></action>
+            </block>
+        </reference>
+    </default>
+
     <adminhtml_auth_login>
         <container name="root" label="Root" output="1">
             <block type="Mage_Backend_Block_Template" name="content" template="admin/login.phtml">
diff --git a/app/code/core/Mage/Backend/view/adminhtml/menu.phtml b/app/code/core/Mage/Backend/view/adminhtml/menu.phtml
index 93bafd3c362b2..c3ff88c590386 100644
--- a/app/code/core/Mage/Backend/view/adminhtml/menu.phtml
+++ b/app/code/core/Mage/Backend/view/adminhtml/menu.phtml
@@ -26,11 +26,7 @@
 ?>
 
 <div class="nav-bar">
-<!-- menu start -->
-<?php echo $this->getMenuLevel($this->getMenuArray()); ?>
-<!-- menu end -->
-
+    <?php echo $this->renderMenuContainer($this->getMenuModel()); ?>
     <a id="page-help-link" href="<?php echo Mage::helper('Mage_Backend_Helper_Data')->getPageHelpUrl() ?>"><?php echo $this->__('Get help for this page') ?></a>
     <script type="text/javascript">$('page-help-link').target = 'magento_page_help'</script>
-
 </div>
diff --git a/app/code/core/Mage/Backend/view/adminhtml/menu/container.phtml b/app/code/core/Mage/Backend/view/adminhtml/menu/container.phtml
new file mode 100644
index 0000000000000..6947fadefabc0
--- /dev/null
+++ b/app/code/core/Mage/Backend/view/adminhtml/menu/container.phtml
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+
+<ul <?php echo (!$this->getLevel() ? 'id="nav"' : '') ?>>
+    <?php foreach ($this->getMenuIterator() as $menuItem) : ?>
+        <?php echo $this->renderMenuItem($menuItem); ?>
+    <?php endforeach; ?>
+</ul>
diff --git a/app/code/core/Mage/Backend/view/adminhtml/menu/item.phtml b/app/code/core/Mage/Backend/view/adminhtml/menu/item.phtml
new file mode 100644
index 0000000000000..1c7c463090bc0
--- /dev/null
+++ b/app/code/core/Mage/Backend/view/adminhtml/menu/item.phtml
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+
+<li <?php echo ($this->getMenuItem()->hasChildren() ? 'onmouseover="Element.addClassName(this,\'over\')" onmouseout="Element.removeClassName(this,\'over\')"' : ''); ?>
+    class="<?php echo ($this->isItemActive($this->getMenuItem()) ? 'active' : '') . ' ' . ($this->getMenuItem()->hasChildren() ? 'parent' : '') . ' ' . ($this->isLast() ? 'last' : '') . ' ' . ('level' . $this->getLevel()); ?>">
+    <a href="<?php echo $this->getMenuItem()->getUrl(); ?>" <?php echo ($this->getMenuItem()->hasTooltip() ? 'title="' . $this->getMenuItem()->getModuleHelper()->__($this->getMenuItem()->getTooltip()) . '"' : '') . ($this->getMenuItem()->hasClickCallback() ? ' onclick="' . $this->getMenuItem()->getClickCallback() . '"' : ''); ?> class="<?php echo ($this->isItemActive($this->getMenuItem()) ? 'active' : ''); ?>">
+        <span><?php echo $this->escapeHtml($this->getMenuItem()->getModuleHelper()->__($this->getMenuItem()->getTitle())); ?> </span>
+    </a>
+    <?php if ($this->getMenuItem()->hasChildren()) : ?>
+        <?php echo $this->getContainerRenderer()->renderMenuContainer($this->getMenuItem()->getChildren(), $this->getLevel() + 1); ?>
+    <?php endif; ?>
+</li>
+
diff --git a/app/code/core/Mage/Backup/etc/adminhtml.xml b/app/code/core/Mage/Backup/etc/adminhtml.xml
index a8c2bccf7fadd..6f5360658999d 100644
--- a/app/code/core/Mage/Backup/etc/adminhtml.xml
+++ b/app/code/core/Mage/Backup/etc/adminhtml.xml
@@ -26,20 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <tools>
-                    <children>
-                        <backup translate="title" module="Mage_Backup">
-                            <title>Backups</title>
-                            <action>adminhtml/system_backup</action>
-                        </backup>
-                    </children>
-                </tools>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Backup/etc/adminhtml/menu.xml b/app/code/core/Mage/Backup/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..940e89ea1e1dd
--- /dev/null
+++ b/app/code/core/Mage/Backup/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backup
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Backup::system_tools_backup" title="Backups" module="Mage_Backup" parent="Mage_Adminhtml::system_tools" action="adminhtml/system_backup" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Bundle/view/frontend/layout.xml b/app/code/core/Mage/Bundle/view/frontend/layout.xml
index f20d6d5a921b0..757a2ac2b78cc 100644
--- a/app/code/core/Mage/Bundle/view/frontend/layout.xml
+++ b/app/code/core/Mage/Bundle/view/frontend/layout.xml
@@ -90,7 +90,7 @@ Adding custom product price block
 Partof block for simple products
 -->
 
-   <catalog_product_view_type_simple>
+    <catalog_product_view_type_simple>
         <reference name="product.info.upsell">
             <action method="addPriceBlockType"><type>bundle</type><block>Mage_Bundle_Block_Catalog_Product_Price</block><template>catalog/product/price.phtml</template></action>
             <action method="setItemLimit"><type>bundle</type><limit>4</limit></action>
@@ -120,6 +120,22 @@ Shopping cart item renderer
         </reference>
     </checkout_cart_index>
 
+    <checkout_cart_configure_type_bundle translate="label" module="Mage_Bundle" type="page" parent="checkout_cart_configure">
+        <label>Configure Bundle Cart Item</label>
+        <update handle="catalog_product_view_type_bundle"/>
+        <reference name="product.info.addtocart.bundle">
+            <action method="setTemplate"><template>Mage_Checkout::cart/item/configure/updatecart.phtml</template></action>
+        </reference>
+    </checkout_cart_configure_type_bundle>
+
+    <checkout_cart_configurefailed_type_bundle  translate="label" module="Mage_Bundle" type="page" parent="checkout_cart_configure">
+        <label>Configure Bundle Cart Item</label>
+        <update handle="catalog_product_view_type_bundle"/>
+        <reference name="product.info.addtocart.bundle">
+            <action method="setTemplate"><template>Mage_Checkout::cart/item/configure/updatecart.phtml</template></action>
+        </reference>
+    </checkout_cart_configurefailed_type_bundle>
+
 <!--
 Onepage Checkout Review Page
 -->
diff --git a/app/code/core/Mage/Captcha/Helper/Data.php b/app/code/core/Mage/Captcha/Helper/Data.php
index bb6dbee4f2c50..a44f380aa0cc1 100755
--- a/app/code/core/Mage/Captcha/Helper/Data.php
+++ b/app/code/core/Mage/Captcha/Helper/Data.php
@@ -59,6 +59,118 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
      */
     protected $_captcha = array();
 
+    /**
+     * @var Mage_Core_Model_Config_Options
+     */
+    protected $_option;
+
+    /**
+     * @var Mage_Core_Model_Store
+     */
+    protected $_store;
+
+    /**
+     * @var Mage_Core_Model_Config
+     */
+    protected $_config;
+
+    /**
+     * @var Mage_Core_Model_Website
+     */
+    protected $_website;
+
+    /**
+     * Get Config
+     * @return Mage_Core_Model_Config
+     */
+    public function getConfig()
+    {
+        if (empty($this->_config)) {
+            $this->_config = Mage::getConfig();
+        }
+        return $this->_config;
+    }
+
+    /**
+     * Set config
+     *
+     * @param Mage_Core_Model_Config $config
+     */
+    public function setConfig($config)
+    {
+        $this->_config = $config;
+    }
+
+    /**
+     * Set store
+     *
+     * @param Mage_Core_Model_Store $store
+     */
+    public function setStore($store)
+    {
+        $this->_store = $store;
+    }
+
+    /**
+     * Get store
+     *
+     * @param null|string|bool|int|Mage_Core_Model_Store $storeName
+     * @return Mage_Core_Model_Store
+     * @throws Mage_Core_Model_Store_Exception
+     */
+    public function getStore($storeName = null)
+    {
+        if (empty($this->_store)) {
+            $this->_store = Mage::app()->getStore($storeName);
+        }
+        return $this->_store;
+    }
+
+    /**
+     * Set option
+     *
+     * @param Mage_Core_Model_Config_Options $option
+     */
+    public function setOption($option)
+    {
+        $this->_option = $option;
+    }
+
+    /**
+     * Get option
+     *
+     * @return Mage_Core_Model_Config_Options
+     */
+    public function getOption()
+    {
+        if (empty($this->_option)) {
+            $this->_option = $this->getConfig()->getOptions();
+        }
+        return $this->_option;
+    }
+
+    /**
+     * Set website
+     * @param Mage_Core_Model_Website $website
+     */
+    public function setWebsite($website)
+    {
+        $this->_website = $website;
+    }
+
+    /**
+     * Get website
+     * @param string $websiteCode
+     * @return Mage_Core_Model_Website
+     */
+    public function getWebsite($websiteCode)
+    {
+        if (empty($this->_website)) {
+            $this->_website =  Mage::app()->getWebsite($websiteCode);
+        }
+        return $this->_website;
+    }
+
     /**
      * Get Captcha
      *
@@ -69,7 +181,10 @@ public function getCaptcha($formId)
     {
         if (!array_key_exists($formId, $this->_captcha)) {
             $type = ucfirst($this->getConfigNode('type'));
-            $this->_captcha[$formId] = Mage::getModel('Mage_Captcha_Model_' . $type, array('formId' => $formId));
+            $this->_captcha[$formId] = $this->getConfig()->getModelInstance(
+                'Mage_Captcha_Model_' . $type,
+                array('formId' => $formId, 'helper' => $this)
+            );
         }
         return $this->_captcha[$formId];
     }
@@ -83,10 +198,12 @@ public function getCaptcha($formId)
      */
     public function getConfigNode($id, $store = null)
     {
-        $areaCode = Mage::app()->getStore($store)->isAdmin() ? 'admin' : 'customer';
-        return Mage::getStoreConfig( $areaCode . '/captcha/' . $id, $store);
+        $areaCode = $this->getStore($store)->isAdmin() ? 'admin' : 'customer';
+        return $this->getStore($store)->getConfig( $areaCode . '/captcha/' . $id, $store);
     }
 
+
+
     /**
      * Get list of available fonts
      * Return format:
@@ -96,13 +213,13 @@ public function getConfigNode($id, $store = null)
      */
     public function getFonts()
     {
-        $node = Mage::getConfig()->getNode(Mage_Captcha_Helper_Data::XML_PATH_CAPTCHA_FONTS);
+        $node = $this->getConfig()->getNode(Mage_Captcha_Helper_Data::XML_PATH_CAPTCHA_FONTS);
         $fonts = array();
         if ($node) {
             foreach ($node->children() as $fontName => $fontNode) {
                $fonts[$fontName] = array(
                    'label' => (string)$fontNode->label,
-                   'path' => Mage::getBaseDir('base') . DS . $fontNode->path
+                   'path' => $this->getOption()->getDir('base') . DIRECTORY_SEPARATOR . $fontNode->path
                );
             }
         }
@@ -117,8 +234,8 @@ public function getFonts()
      */
     public function getImgDir($website = null)
     {
-        $websiteCode = Mage::app()->getWebsite($website)->getCode();
-        $captchaDir = Mage::getBaseDir('media') . DS . 'captcha' . DS . $websiteCode . DS;
+        $captchaDir = $this->getOption()->getDir('media') . DIRECTORY_SEPARATOR . 'captcha' . DIRECTORY_SEPARATOR
+            . $this->getWebsite($website)->getCode() . DIRECTORY_SEPARATOR;
         $io = new Varien_Io_File();
         $io->checkAndCreateFolder($captchaDir, 0755);
         return $captchaDir;
@@ -132,7 +249,6 @@ public function getImgDir($website = null)
      */
     public function getImgUrl($website = null)
     {
-        $websiteCode = Mage::app()->getWebsite($website)->getCode();
-        return Mage::getBaseUrl('media') . 'captcha' . '/' . $websiteCode . '/';
+        return $this->getStore()->getBaseUrl('media') . 'captcha' . '/' . $this->getWebsite($website)->getCode() . '/';
     }
 }
diff --git a/app/code/core/Mage/Captcha/Model/Zend.php b/app/code/core/Mage/Captcha/Model/Zend.php
index 0ad8c42d2182d..b39431114a7b3 100755
--- a/app/code/core/Mage/Captcha/Model/Zend.php
+++ b/app/code/core/Mage/Captcha/Model/Zend.php
@@ -73,6 +73,17 @@ class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha
      */
     protected  $_formId;
 
+
+    /**
+     * @var Mage_Captcha_Model_Resource_Log
+     */
+    protected $_resourceModel;
+
+    /**
+     * @var
+     */
+    protected $_session;
+
     /**
      * Zend captcha constructor
      *
@@ -80,11 +91,14 @@ class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha
      */
     public function __construct($params)
     {
-        if (!isset($params['formId'])) {
+        if (!is_array($params) || !isset($params['formId'])) {
             throw new Exception('formId is mandatory');
         }
+
         $this->_formId = $params['formId'];
-        $this->setExpiration($this->getTimeout());
+        $this->_helper = isset($params['helper']) ? $params['helper'] : null;
+        $this->_resourceModel = isset($params['resourceModel']) ? $params['resourceModel'] : null;
+        $this->_session = isset($params['session']) ? $params['session'] : null;
     }
 
     /**
@@ -164,7 +178,7 @@ protected function _getAllowedAttemptsFromSameIp()
      */
     protected function _isOverLimitIpAttempt()
     {
-        $countAttemptsByIp = Mage::getResourceModel('Mage_Captcha_Model_Resource_Log')->countAttemptsByRemoteAddress();
+        $countAttemptsByIp = $this->_getResourceModel()->countAttemptsByRemoteAddress();
         return $countAttemptsByIp >= $this->_getAllowedAttemptsFromSameIp();
     }
 
@@ -177,7 +191,7 @@ protected function _isOverLimitIpAttempt()
     protected function _isOverLimitLoginAttempts($login)
     {
         if ($login != false) {
-            $countAttemptsByLogin = Mage::getResourceModel('Mage_Captcha_Model_Resource_Log')->countAttemptsByUserLogin($login);
+            $countAttemptsByLogin = $this->_getResourceModel()->countAttemptsByUserLogin($login);
             return ($countAttemptsByLogin >= $this->_getAllowedAttemptsForSameLogin());
         }
         return false;
@@ -190,9 +204,7 @@ protected function _isOverLimitLoginAttempts($login)
      */
     protected function _isUserAuth()
     {
-        return Mage::app()->getStore()->isAdmin()
-            ? Mage::getSingleton('Mage_Backend_Model_Auth_Session')->isLoggedIn()
-            : Mage::getSingleton('Mage_Customer_Model_Session')->isLoggedIn();
+        return $this->getSession()->isLoggedIn();
     }
 
     /**
@@ -212,7 +224,17 @@ public function isCaseSensitive()
      */
     public function getFont()
     {
-        return $this->_getFontPath();
+        $font = (string)$this->_getHelper()->getConfigNode('font');
+        $fonts = $this->_getHelper()->getFonts();
+
+        if (isset($fonts[$font])) {
+            $fontPath = $fonts[$font]['path'];
+        } else {
+            $fontData = array_shift($fonts);
+            $fontPath = $fontData['path'];
+        }
+
+        return $fontPath;
     }
 
     /**
@@ -220,7 +242,7 @@ public function getFont()
      *
      * @return int
      */
-    public function getTimeout()
+    public function getExpiration()
     {
         if (!$this->_expiration) {
             /**
@@ -232,6 +254,16 @@ public function getTimeout()
         return $this->_expiration;
     }
 
+    /**
+     * Get timeout for session token
+     *
+     * @return int
+     */
+    public function getTimeout()
+    {
+        return $this->getExpiration();
+    }
+
     /**
      * Get captcha image directory
      *
@@ -239,7 +271,7 @@ public function getTimeout()
      */
     public function getImgDir()
     {
-        return $this->_helper->getImgDir();
+        return $this->_getHelper()->getImgDir();
     }
 
     /**
@@ -249,7 +281,7 @@ public function getImgDir()
      */
     public function getImgUrl()
     {
-        return $this->_helper->getImgUrl();
+        return $this->_getHelper()->getImgUrl();
     }
 
     /**
@@ -271,17 +303,22 @@ public function isCorrect($word)
             $storedWord = strtolower($storedWord);
             $word = strtolower($word);
         }
-        return $word == $storedWord;
+        return $word === $storedWord;
     }
 
     /**
      * Returns session instance
      *
-     * @return Mage_Customer_Model_Session
+     * @return Mage_Customer_Model_Session|Mage_Backend_Model_Auth_Session
      */
     public function getSession()
     {
-        return Mage::getSingleton('Mage_Customer_Model_Session');
+        if (empty($this->_session)) {
+            $this->_session =  Mage::app()->getStore()->isAdmin()
+                ? Mage::getSingleton('Mage_Backend_Model_Auth_Session')
+                : Mage::getSingleton('Mage_Customer_Model_Session');
+        }
+        return $this->_session;
     }
 
      /**
@@ -303,7 +340,7 @@ public function getImgSrc()
     public function logAttempt($login)
     {
         if ($this->_isEnabled() && in_array($this->_formId, $this->_getTargetForms())) {
-            Mage::getResourceModel('Mage_Captcha_Model_Resource_Log')->logAttempt($login);
+            $this->_getResourceModel()->logAttempt($login);
             if ($this->_isOverLimitLoginAttempts($login)) {
                 $this->getSession()->setData($this->_getFormIdKey('show_captcha'), 1);
             }
@@ -311,26 +348,6 @@ public function logAttempt($login)
         return $this;
     }
 
-    /**
-     * Returns path for the font file, chosen to generate captcha
-     *
-     * @return string
-     */
-    protected function _getFontPath()
-    {
-        $font = (string)$this->_getHelper()->getConfigNode('font');
-        $fonts = $this->_getHelper()->getFonts();
-
-        if (isset($fonts[$font])) {
-            $fontPath = $fonts[$font]['path'];
-        } else {
-            $fontData = array_shift($fonts);
-            $fontPath = $fontData['path'];
-        }
-
-        return $fontPath;
-    }
-
     /**
      * Returns captcha helper
      *
@@ -409,6 +426,12 @@ protected function _isShowAlways()
             return true;
         }
 
+        if ((string)$this->_getHelper()->getConfigNode('mode') == Mage_Captcha_Helper_Data::MODE_AFTER_FAIL
+            && $this->_getAllowedAttemptsForSameLogin() == 0
+        ) {
+            return true;
+        }
+
         $alwaysFor = $this->_getHelper()->getConfigNode('always_for');
         foreach ($alwaysFor as $nodeFormId => $isAlwaysFor) {
             if ($isAlwaysFor && $this->_formId == $nodeFormId) {
@@ -501,4 +524,16 @@ protected function _gc()
     {
         //do nothing
     }
+
+    /**
+     * Get Resource Model
+     * @return Mage_Captcha_Model_Resource_Log
+     */
+    protected function _getResourceModel()
+    {
+        if (empty($this->_resourceModel)) {
+            $this->_resourceModel = Mage::getResourceModel('Mage_Captcha_Model_Resource_Log');
+        }
+        return $this->_resourceModel;
+    }
 }
diff --git a/app/code/core/Mage/Captcha/view/frontend/layout.xml b/app/code/core/Mage/Captcha/view/frontend/layout.xml
index a3a1d146576dd..a78ea9ed014aa 100644
--- a/app/code/core/Mage/Captcha/view/frontend/layout.xml
+++ b/app/code/core/Mage/Captcha/view/frontend/layout.xml
@@ -70,7 +70,7 @@
     </customer_account_create>
     <checkout_onepage_index>
         <reference name="checkout.onepage.login">
-            <container name="form.additional.info" label="Form Additional Info">
+            <container name="login.form.additional.info" label="Form Additional Info">
                 <block type="Mage_Captcha_Block_Captcha" name="captcha">
                     <reference name="head">
                         <action method="addJs"><file>mage/captcha.js</file></action>
@@ -86,6 +86,7 @@
                 <block type="Mage_Captcha_Block_Captcha" name="captcha.guest.checkout">
                     <reference name="head">
                         <action method="addJs"><file>mage/captcha.js</file></action>
+                        <action method="addJs"><file>Mage_Captcha::onepage.js</file></action>
                     </reference>
                     <action method="setFormId"><formId>guest_checkout</formId></action>
                     <action method="setImgWidth"><width>230</width></action>
@@ -94,6 +95,7 @@
                 <block type="Mage_Captcha_Block_Captcha" name="captcha.register.during.checkout">
                     <reference name="head">
                         <action method="addJs"><file>mage/captcha.js</file></action>
+                        <action method="addJs"><file>Mage_Captcha::onepage.js</file></action>
                     </reference>
                     <action method="setFormId"><formId>register_during_checkout</formId></action>
                     <action method="setImgWidth"><width>230</width></action>
diff --git a/app/code/core/Mage/Captcha/view/frontend/onepage.js b/app/code/core/Mage/Captcha/view/frontend/onepage.js
new file mode 100644
index 0000000000000..f0e337ed57e6b
--- /dev/null
+++ b/app/code/core/Mage/Captcha/view/frontend/onepage.js
@@ -0,0 +1,58 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     base_default
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+document.observe('billing-request:completed', function(event) {
+    if (typeof window.checkout != 'undefined') {
+        if (window.checkout.method == 'guest' && $('guest_checkout')){
+            $('guest_checkout').captcha.refresh()
+        }
+        if (window.checkout.method == 'register' && $('register_during_checkout')){
+            $('register_during_checkout').captcha.refresh()
+        }
+    }
+});
+
+
+document.observe('login:setMethod', function(event) {
+    var switchCaptchaElement = function(shown, hidden) {
+        var inputPrefix = 'captcha-input-box-', imagePrefix = 'captcha-image-box-';
+        if ($(inputPrefix + hidden)) {
+            $(inputPrefix + hidden).hide();
+            $(imagePrefix + hidden).hide();
+        }
+        if ($(inputPrefix + shown)) {
+            $(inputPrefix + shown).show();
+            $(imagePrefix + shown).show();
+        }
+    };
+
+    switch (event.memo.method) {
+        case 'guest':
+            switchCaptchaElement('guest_checkout', 'register_during_checkout');
+            break;
+        case 'register':
+            switchCaptchaElement('register_during_checkout', 'guest_checkout');
+            break;
+    }
+});
diff --git a/app/code/core/Mage/Captcha/view/frontend/zend.phtml b/app/code/core/Mage/Captcha/view/frontend/zend.phtml
index 00110e6253a37..2eb9620dd6290 100644
--- a/app/code/core/Mage/Captcha/view/frontend/zend.phtml
+++ b/app/code/core/Mage/Captcha/view/frontend/zend.phtml
@@ -34,8 +34,8 @@
         <input name="<?php echo Mage_Captcha_Helper_Data::INPUT_NAME_FIELD_VALUE ?>[<?php echo $this->getFormId()?>]" type="text" class="input-text required-entry" id="captcha_<?php echo $this->getFormId() ?>" />
     </div>
 </li>
-<li>
-    <div class="captcha-image" id="captcha-image-box-<?php echo $this->getFormId()?>">
+<li id="captcha-image-box-<?php echo $this->getFormId()?>">
+    <div class="captcha-image">
         <img id="captcha-reload" class="captcha-reload" src="<?php echo $this->getSkinUrl('Mage_Captcha::reload.png') ?>" alt="<?php echo $this->__('Reload captcha') ?>" onclick="$('<?php echo $this->getFormId()?>').captcha.refresh(this)">
         <img id="<?php echo $this->getFormId() ?>" class="captcha-img" height="<?php echo $this->getImgHeight() ?>" src="<?php echo $captcha->getImgSrc() ?>"/>
         <?php if ($captcha->isCaseSensitive()) :?>
diff --git a/app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php b/app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php
index 776d5b752045f..fde80299b6ba2 100755
--- a/app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php
+++ b/app/code/core/Mage/Catalog/Model/Resource/Category/Flat.php
@@ -470,12 +470,25 @@ public function rebuild($stores = null)
             $stores = array($stores);
         }
 
+        $this->_createTables($stores);
+        $this->_populateFlatTables($stores);
+
+        return $this;
+    }
+
+    /**
+     * Populate category flat tables with data
+     *
+     * @param array $stores
+     * @return Mage_Catalog_Model_Resource_Category_Flat
+     */
+    protected function _populateFlatTables($stores)
+    {
         $rootId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
         $categories = array();
         $categoriesIds = array();
         /* @var $store Mage_Core_Model_Store */
         foreach ($stores as $store) {
-            $this->_createTable($store->getId());
 
             if (!isset($categories[$store->getRootCategoryId()])) {
                 $select = $this->_getWriteAdapter()->select()
@@ -528,20 +541,25 @@ protected function _prepareValuesToInsert($data)
     }
 
     /**
-     * Create Flate Table(s)
+     * Create category flat table for specified store.
+     * Table is created only if DDL operations are allowed
      *
-     * @param array|int $stores
+     * @param int $store
      * @return Mage_Catalog_Model_Resource_Category_Flat
      */
-    public function createTable($stores)
+    public function createTable($store)
     {
-        return $this->_createTable($stores);
+        if ($this->_getWriteAdapter()->getTransactionLevel() > 0) {
+            return $this;
+        }
+        return $this->_createTable($store);
     }
 
     /**
-     * Creating table and adding attributes as fields to table
+     * Create table and add attributes as fields for specified store.
+     * This routine assumes that DDL operations are allowed
      *
-     * @param array|integer $store
+     * @param int $store
      * @return Mage_Catalog_Model_Resource_Category_Flat
      */
     protected function _createTable($store)
@@ -1409,13 +1427,21 @@ public function getStoresRootCategories($storeIds = null)
     }
 
     /**
-     * Creating table and adding attributes as fields to table for all stores
+     * Create category flat tables and add attributes as fields.
+     * Tables are created only if DDL operations are allowed
      *
+     * @param array $stores if empty, create tables for all stores of the application
      * @return Mage_Catalog_Model_Resource_Category_Flat
      */
-    protected function _createTables()
+    protected function _createTables($stores = array())
     {
-        foreach (Mage::app()->getStores() as $store) {
+        if ($this->_getWriteAdapter()->getTransactionLevel() > 0) {
+            return $this;
+        }
+        if (empty($stores)) {
+            $stores = Mage::app()->getStores();
+        }
+        foreach ($stores as $store) {
             $this->_createTable($store->getId());
         }
         return $this;
diff --git a/app/code/core/Mage/Catalog/etc/adminhtml.xml b/app/code/core/Mage/Catalog/etc/adminhtml.xml
index 5986aa3a0348f..8c62c0c41ff83 100644
--- a/app/code/core/Mage/Catalog/etc/adminhtml.xml
+++ b/app/code/core/Mage/Catalog/etc/adminhtml.xml
@@ -26,47 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog translate="title" module="Mage_Catalog">
-            <title>Catalog</title>
-            <sort_order>30</sort_order>
-            <!--action>adminhtml/catalog</action-->
-            <depends>
-                <module>Mage_Catalog</module>
-            </depends>
-            <children>
-                <products translate="title" module="Mage_Catalog">
-                    <title>Manage Products</title>
-                    <action>adminhtml/catalog_product/</action>
-                    <sort_order>0</sort_order>
-                </products>
-                <categories translate="title" module="Mage_Catalog">
-                    <title>Manage Categories</title>
-                    <action>adminhtml/catalog_category/</action>
-                    <sort_order>10</sort_order>
-                </categories>
-                <attributes translate="title" module="Mage_Catalog">
-                    <title>Attributes</title>
-                    <children>
-                        <attributes translate="title" module="Mage_Catalog">
-                            <title>Manage Attributes</title>
-                            <action>adminhtml/catalog_product_attribute/</action>
-                        </attributes>
-                        <sets translate="title" module="Mage_Catalog">
-                            <title>Manage Attribute Sets</title>
-                            <action>adminhtml/catalog_product_set/</action>
-                        </sets>
-                    </children>
-                    <sort_order>20</sort_order>
-                </attributes>
-                <urlrewrite translate="title" module="Mage_Catalog">
-                    <title>URL Rewrite Management</title>
-                    <action>adminhtml/urlrewrite/index</action>
-                    <sort_order>30</sort_order>
-                </urlrewrite>
-            </children>
-        </catalog>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Catalog/etc/adminhtml/menu.xml b/app/code/core/Mage/Catalog/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..6d49646a8953f
--- /dev/null
+++ b/app/code/core/Mage/Catalog/etc/adminhtml/menu.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Catalog::catalog" title="Catalog" module="Mage_Catalog" sortOrder="30" dependsOnModule="Mage_Catalog" />
+        <add id="Mage_Catalog::catalog_products" title="Manage Products" module="Mage_Catalog" sortOrder="0" parent="Mage_Catalog::catalog" action="adminhtml/catalog_product/" />
+        <add id="Mage_Catalog::catalog_categories" title="Manage Categories" module="Mage_Catalog" sortOrder="10" parent="Mage_Catalog::catalog" action="adminhtml/catalog_category/" />
+        <add id="Mage_Catalog::catalog_attributes" title="Attributes" module="Mage_Catalog" sortOrder="20" parent="Mage_Catalog::catalog" />
+        <add id="Mage_Catalog::catalog_attributes_attributes" title="Manage Attributes" module="Mage_Catalog" parent="Mage_Catalog::catalog_attributes" action="adminhtml/catalog_product_attribute/" />
+        <add id="Mage_Catalog::catalog_attributes_sets" title="Manage Attribute Sets" module="Mage_Catalog" parent="Mage_Catalog::catalog_attributes" action="adminhtml/catalog_product_set/" />
+        <add id="Mage_Catalog::catalog_urlrewrite" title="URL Rewrite Management" module="Mage_Catalog" sortOrder="30" parent="Mage_Catalog::catalog" action="adminhtml/urlrewrite/index" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/CatalogRule/etc/adminhtml.xml b/app/code/core/Mage/CatalogRule/etc/adminhtml.xml
index 94b8a61f86665..6d0738acb89ad 100644
--- a/app/code/core/Mage/CatalogRule/etc/adminhtml.xml
+++ b/app/code/core/Mage/CatalogRule/etc/adminhtml.xml
@@ -26,19 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <promo translate="title" module="Mage_CatalogRule">
-            <title>Promotions</title>
-            <sort_order>50</sort_order>
-            <children>
-                <catalog translate="title" module="Mage_CatalogRule">
-                    <title>Catalog Price Rules</title>
-                    <action>adminhtml/promo_catalog/</action>
-                    <depends><module>Mage_Catalog</module></depends>
-                </catalog>
-            </children>
-         </promo>
-     </menu>
      <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/CatalogRule/etc/adminhtml/menu.xml b/app/code/core/Mage/CatalogRule/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..4373d055e6406
--- /dev/null
+++ b/app/code/core/Mage/CatalogRule/etc/adminhtml/menu.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_CatalogRule
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_CatalogRule::promo" title="Promotions" module="Mage_CatalogRule" sortOrder="50" />
+        <add id="Mage_CatalogRule::promo_catalog" title="Catalog Price Rules" module="Mage_CatalogRule" parent="Mage_CatalogRule::promo" action="adminhtml/promo_catalog/" dependsOnModule="Mage_Catalog" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/CatalogSearch/etc/adminhtml.xml b/app/code/core/Mage/CatalogSearch/etc/adminhtml.xml
index e35d35a25a851..579d150d9c709 100644
--- a/app/code/core/Mage/CatalogSearch/etc/adminhtml.xml
+++ b/app/code/core/Mage/CatalogSearch/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog>
-            <children>
-                <search translate="title" module="Mage_CatalogSearch">
-                    <title>Search Terms</title>
-                    <action>adminhtml/catalog_search/</action>
-                    <sort_order>40</sort_order>
-                </search>
-            </children>
-        </catalog>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/CatalogSearch/etc/adminhtml/menu.xml b/app/code/core/Mage/CatalogSearch/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..7c8241008ce4a
--- /dev/null
+++ b/app/code/core/Mage/CatalogSearch/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_CatalogSearch
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_CatalogSearch::catalog_search" title="Search Terms" module="Mage_CatalogSearch" sortOrder="40" parent="Mage_Catalog::catalog" action="adminhtml/catalog_search/" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Checkout/etc/adminhtml.xml b/app/code/core/Mage/Checkout/etc/adminhtml.xml
index 78e1cd654b4da..1c93d6959546c 100644
--- a/app/code/core/Mage/Checkout/etc/adminhtml.xml
+++ b/app/code/core/Mage/Checkout/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <sales>
-            <children>
-                <checkoutagreement translate="title" module="Mage_Checkout">
-                    <sort_order>100</sort_order>
-                    <title>Terms and conditions</title>
-                    <action>adminhtml/checkout_agreement/</action>
-                </checkoutagreement>
-            </children>
-         </sales>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Checkout/etc/adminhtml/menu.xml b/app/code/core/Mage/Checkout/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..4a1abe1c98f02
--- /dev/null
+++ b/app/code/core/Mage/Checkout/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Checkout::sales_checkoutagreement" title="Terms and conditions" module="Mage_Checkout" sortOrder="100" parent="Mage_Sales::sales" action="adminhtml/checkout_agreement/" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Checkout/view/frontend/layout.xml b/app/code/core/Mage/Checkout/view/frontend/layout.xml
index d305505866b4f..a59790d00d956 100644
--- a/app/code/core/Mage/Checkout/view/frontend/layout.xml
+++ b/app/code/core/Mage/Checkout/view/frontend/layout.xml
@@ -103,23 +103,11 @@ Default layout, loads most of the pages
         </reference>
     </checkout_cart_configure>
 
-    <checkout_cart_configure_type_downloadable translate="label" module="Mage_Downloadable" type="page" parent="checkout_cart_configure">
-        <label>Configure Cart Item (Downloadable)</label>
-        <update handle="catalog_product_view_type_downloadable"/>
-    </checkout_cart_configure_type_downloadable>
-
     <checkout_cart_configure_type_configurable translate="label" module="Mage_Catalog" type="page" parent="checkout_cart_configure">
         <label>Configure Cart Item (Configurable)</label>
         <update handle="catalog_product_view_type_configurable"/>
     </checkout_cart_configure_type_configurable>
 
-    <checkout_cart_configure_type_bundle translate="label" module="Mage_Bundle" type="page" parent="checkout_cart_configure">
-        <label>Configure Cart Item (Bundle)</label>
-        <update handle="catalog_product_view_type_bundle"/>
-        <reference name="product.info.addtocart.bundle">
-            <action method="setTemplate"><template>Mage_Checkout::cart/item/configure/updatecart.phtml</template></action>
-        </reference>
-    </checkout_cart_configure_type_bundle>
 <!--
 Multi address shipping checkout main layout,
 will be rendered on all checkout pages
diff --git a/app/code/core/Mage/Checkout/view/frontend/onepage/login.phtml b/app/code/core/Mage/Checkout/view/frontend/onepage/login.phtml
index 0a4eebf9302b8..4abeb1a4544d2 100644
--- a/app/code/core/Mage/Checkout/view/frontend/onepage/login.phtml
+++ b/app/code/core/Mage/Checkout/view/frontend/onepage/login.phtml
@@ -81,7 +81,7 @@
                         <input type="password" class="input-text required-entry" id="login-password" name="login[password]" />
                     </div>
                 </li>
-                <?php echo $this->getChildHtml('form.additional.info'); ?>
+                <?php echo $this->getChildHtml('login.form.additional.info'); ?>
             </ul>
         </fieldset>
         </form>
diff --git a/app/code/core/Mage/Cms/etc/adminhtml.xml b/app/code/core/Mage/Cms/etc/adminhtml.xml
index 8f2220b415dcc..c53d9b63acb3b 100644
--- a/app/code/core/Mage/Cms/etc/adminhtml.xml
+++ b/app/code/core/Mage/Cms/etc/adminhtml.xml
@@ -26,24 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <cms translate="title" module="Mage_Cms">
-            <title>CMS</title>
-            <sort_order>70</sort_order>
-            <children>
-                <page translate="title" module="Mage_Cms">
-                    <title>Pages</title>
-                    <action>adminhtml/cms_page</action>
-                    <sort_order>0</sort_order>
-                </page>
-                <block translate="title" module="Mage_Cms">
-                    <title>Static Blocks</title>
-                    <action>adminhtml/cms_block</action>
-                    <sort_order>10</sort_order>
-                </block>
-            </children>
-         </cms>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Cms/etc/adminhtml/menu.xml b/app/code/core/Mage/Cms/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..e3c332a385872
--- /dev/null
+++ b/app/code/core/Mage/Cms/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Cms
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Cms::cms" title="CMS" module="Mage_Cms" sortOrder="70" />
+        <add id="Mage_Cms::cms_page" title="Pages" module="Mage_Cms" sortOrder="0" parent="Mage_Cms::cms" action="adminhtml/cms_page" />
+        <add id="Mage_Cms::cms_block" title="Static Blocks" module="Mage_Cms" sortOrder="10" parent="Mage_Cms::cms" action="adminhtml/cms_block" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Connect/controllers/Adminhtml/Extension/CustomController.php b/app/code/core/Mage/Connect/controllers/Adminhtml/Extension/CustomController.php
index de1b09d1037a6..bf0451f87bc59 100644
--- a/app/code/core/Mage/Connect/controllers/Adminhtml/Extension/CustomController.php
+++ b/app/code/core/Mage/Connect/controllers/Adminhtml/Extension/CustomController.php
@@ -58,7 +58,7 @@ public function editAction()
              ->_title($this->__('Edit Extension'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system/extension/custom');
+        $this->_setActiveMenu('Mage_Connect::system_extensions_custom');
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Connect/etc/adminhtml.xml b/app/code/core/Mage/Connect/etc/adminhtml.xml
index c969d6f53c6ad..393c6a8062bc2 100644
--- a/app/code/core/Mage/Connect/etc/adminhtml.xml
+++ b/app/code/core/Mage/Connect/etc/adminhtml.xml
@@ -26,24 +26,4 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <extensions translate="title" module="Mage_Connect">
-                    <title>Magento Connect</title>
-                    <sort_order>80</sort_order>
-                    <children>
-                        <local translate="title">
-                            <title>Magento Connect Manager</title>
-                            <action>adminhtml/extension_local</action>
-                        </local>
-                        <custom translate="title">
-                            <title>Package Extensions</title>
-                            <action>adminhtml/extension_custom</action>
-                        </custom>
-                    </children>
-                </extensions>
-            </children>
-        </system>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Connect/etc/adminhtml/menu.xml b/app/code/core/Mage/Connect/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..e470289d19cbd
--- /dev/null
+++ b/app/code/core/Mage/Connect/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Connect
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Connect::system_extensions" title="Magento Connect" module="Mage_Connect" sortOrder="80" parent="Mage_Adminhtml::system" />
+        <add id="Mage_Connect::system_extensions_local" title="Magento Connect Manager" module="Mage_Connect" parent="Mage_Connect::system_extensions" action="adminhtml/extension_local" />
+        <add id="Mage_Connect::system_extensions_custom" title="Package Extensions" module="Mage_Connect" parent="Mage_Connect::system_extensions" action="adminhtml/extension_custom" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Connect/view/adminhtml/layout.xml b/app/code/core/Mage/Connect/view/adminhtml/layout.xml
index 298618bf5ede2..979838fbdd2fc 100644
--- a/app/code/core/Mage/Connect/view/adminhtml/layout.xml
+++ b/app/code/core/Mage/Connect/view/adminhtml/layout.xml
@@ -56,7 +56,7 @@
     </adminhtml_extension_custom_edit>
     
     <adminhtml_extension_custom_loadtab>
-        <container name="root" label="Root">
+        <container name="root" label="Root" output="1">
             <block type="Mage_Connect_Block_Adminhtml_Extension_Custom_Edit_Tab_Load" name="connect_extension_load_local_package_grid"
                 template="extension/custom/load.phtml">
                 <block type="Mage_Connect_Block_Adminhtml_Extension_Custom_Edit_Tab_Grid" name="local_package_grid" />
@@ -65,9 +65,8 @@
     </adminhtml_extension_custom_loadtab>
     
     <adminhtml_extension_custom_grid>
-        <container name="root" label="Root">
+        <container name="root" label="Root" output="1">
             <block type="Mage_Connect_Block_Adminhtml_Extension_Custom_Edit_Tab_Grid" name="connect_extension_edit_local_package_grid" />
         </container>
     </adminhtml_extension_custom_grid>
 </layout>
-
diff --git a/app/code/core/Mage/Core/Block/Abstract.php b/app/code/core/Mage/Core/Block/Abstract.php
index b8142be8cd9eb..2fa391e118af2 100644
--- a/app/code/core/Mage/Core/Block/Abstract.php
+++ b/app/code/core/Mage/Core/Block/Abstract.php
@@ -614,6 +614,19 @@ protected function _toHtml()
         return '';
     }
 
+    /**
+     * Retrieve data-ui-id attribute which will distinguish link/input/container/anything else in template among others
+     * Function takes an arbitrary amount of parameters
+     *
+     * @return string
+     */
+    public function getUiId()
+    {
+        $rawId = $this->_nameInLayout . '-' . implode('-', func_get_args());
+        $normalizedId = trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($rawId)), '-');
+        return ' data-ui-id="' . $normalizedId . '" ';
+    }
+
     /**
      * Returns url model class name
      *
diff --git a/app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php b/app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
index 3d305c09f93cb..234873f6ffb9c 100644
--- a/app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
+++ b/app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
@@ -24,16 +24,33 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+/**
+ * Abstract router class
+ */
 abstract class Mage_Core_Controller_Varien_Router_Abstract
 {
+    /**
+     * @var Mage_Core_Controller_Varien_Front
+     */
     protected $_front;
 
-    public function setFront($front)
+    /**
+     * Assign front controller instance
+     *
+     * @param $front Mage_Core_Controller_Varien_Front
+     * @return Mage_Core_Controller_Varien_Router_Abstract
+     */
+    public function setFront(Mage_Core_Controller_Varien_Front $front)
     {
         $this->_front = $front;
         return $this;
     }
 
+    /**
+     * Retrieve front controller instance
+     *
+     * @return Mage_Core_Controller_Varien_Front
+     */
     public function getFront()
     {
         return $this->_front;
diff --git a/app/code/core/Mage/Core/Model/App.php b/app/code/core/Mage/Core/Model/App.php
index 5dba29a1ed08f..7783bd92af773 100644
--- a/app/code/core/Mage/Core/Model/App.php
+++ b/app/code/core/Mage/Core/Model/App.php
@@ -805,7 +805,7 @@ public function loadAreaPart($area, $part)
     public function getArea($code)
     {
         if (!isset($this->_areas[$code])) {
-            $this->_areas[$code] = new Mage_Core_Model_App_Area($code, $this);
+            $this->_areas[$code] = new Mage_Core_Model_App_Area($code);
         }
         return $this->_areas[$code];
     }
diff --git a/app/code/core/Mage/Core/Model/App/Area.php b/app/code/core/Mage/Core/Model/App/Area.php
index 71439e6fcc956..09c68ac703bc9 100644
--- a/app/code/core/Mage/Core/Model/App/Area.php
+++ b/app/code/core/Mage/Core/Model/App/Area.php
@@ -56,26 +56,13 @@ class Mage_Core_Model_App_Area
     protected $_code;
 
     /**
-     * Area application
+     * Constructor
      *
-     * @var Mage_Core_Model_App
+     * @param string $areaCode
      */
-    protected $_application;
-
-    public function __construct($areaCode, $application)
+    public function __construct($areaCode)
     {
         $this->_code = $areaCode;
-        $this->_application = $application;
-    }
-
-    /**
-     * Retrieve area application
-     *
-     * @return Mage_Core_Model_App
-     */
-    public function getApplication()
-    {
-        return $this->_application;
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Model/Event/Manager.php b/app/code/core/Mage/Core/Model/Event/Manager.php
new file mode 100644
index 0000000000000..9d509bae00f82
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Event/Manager.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Event manager. Used to dispatch global events
+ */
+class Mage_Core_Model_Event_Manager
+{
+    /**
+     * Dispatch global event with provided params
+     *
+     * @param string $eventName
+     * @param array $params
+     * @return Mage_Core_Model_App
+     */
+    public function dispatch($eventName, $params)
+    {
+        return Mage::dispatchEvent($eventName, $params);
+    }
+}
diff --git a/app/code/core/Mage/Core/Model/Layout.php b/app/code/core/Mage/Core/Model/Layout.php
index 8f132c8785b74..4a0935d076bc1 100644
--- a/app/code/core/Mage/Core/Model/Layout.php
+++ b/app/code/core/Mage/Core/Model/Layout.php
@@ -164,6 +164,17 @@ public function __construct(array $arguments = array())
         $this->_renderingOutput = new Varien_Object;
     }
 
+    /**
+     * Cleanup circular references between layout & blocks
+     *
+     * Destructor should be called explicitly in order to work around the PHP bug
+     * https://bugs.php.net/bug.php?id=62468
+     */
+    public function __destruct()
+    {
+        $this->_blocks = array();
+    }
+
     /**
      * Retrieve the layout update instance
      *
diff --git a/app/code/core/Mage/Core/Model/Logger.php b/app/code/core/Mage/Core/Model/Logger.php
new file mode 100644
index 0000000000000..152791760b619
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Logger.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Logger model
+ *
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Core_Model_Logger
+{
+    /**
+     * Log wrapper
+     *
+     * @param string $message
+     * @param int $level
+     * @param string $file
+     * @param bool $forceLog
+     * @return void
+     */
+    public function log($message, $level = null, $file = '', $forceLog = false)
+    {
+        Mage::log($message, $level, $file, $forceLog);
+    }
+
+    /**
+     * Log exception wrapper
+     *
+     * @param Exception $e
+     * @return void
+     */
+    public function logException(Exception $e)
+    {
+        Mage::logException($e);
+    }
+}
diff --git a/app/code/core/Mage/Core/Model/Store/Config.php b/app/code/core/Mage/Core/Model/Store/Config.php
new file mode 100644
index 0000000000000..964c7f281aadd
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Store/Config.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Core_Model_Store_Config
+{
+    /**
+     * Retrieve store config value
+     *
+     * @param string $path
+     * @return mixed
+     */
+    public function getConfig($path)
+    {
+        return Mage::getStoreConfig($path);
+    }
+
+    /**
+     * Retrieve store config flag
+     *
+     * @param string $path
+     * @return bool
+     */
+    public function getConfigFlag($path)
+    {
+        return Mage::getStoreConfigFlag($path);
+    }
+}
diff --git a/app/code/core/Mage/Core/etc/config.xml b/app/code/core/Mage/Core/etc/config.xml
index 18aac3cfe5056..066cac0d1ceac 100644
--- a/app/code/core/Mage/Core/etc/config.xml
+++ b/app/code/core/Mage/Core/etc/config.xml
@@ -294,7 +294,7 @@
         </web>
         <admin>
             <startup>
-                <page>dashboard</page>
+                <menu_item_id>dashboard</menu_item_id>
             </startup>
             <url>
                 <use_custom>0</use_custom>
diff --git a/app/code/core/Mage/Core/etc/system.xml b/app/code/core/Mage/Core/etc/system.xml
index 15e869cf54426..e23646333fde2 100644
--- a/app/code/core/Mage/Core/etc/system.xml
+++ b/app/code/core/Mage/Core/etc/system.xml
@@ -955,7 +955,7 @@
                     <show_in_website>0</show_in_website>
                     <show_in_store>0</show_in_store>
                     <fields>
-                        <page translate="label">
+                        <menu_item_id translate="label">
                             <label>Startup Page</label>
                             <frontend_type>select</frontend_type>
                             <source_model>Mage_Adminhtml_Model_System_Config_Source_Admin_Page</source_model>
@@ -963,7 +963,7 @@
                             <show_in_default>1</show_in_default>
                             <show_in_website>0</show_in_website>
                             <show_in_store>0</show_in_store>
-                        </page>
+                        </menu_item_id>
                     </fields>
                 </startup>
                 <url translate="label">
diff --git a/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/System/CurrencysymbolController.php b/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/System/CurrencysymbolController.php
index 81ba0dff773d3..a1e9e974aad56 100644
--- a/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/System/CurrencysymbolController.php
+++ b/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/System/CurrencysymbolController.php
@@ -40,7 +40,7 @@ public function indexAction()
     {
         // set active menu and breadcrumbs
         $this->loadLayout()
-            ->_setActiveMenu('system/currency')
+            ->_setActiveMenu('Mage_Adminhtml::system_currency')
             ->_addBreadcrumb(
                 Mage::helper('Mage_CurrencySymbol_Helper_Data')->__('System'),
                 Mage::helper('Mage_CurrencySymbol_Helper_Data')->__('System')
diff --git a/app/code/core/Mage/CurrencySymbol/etc/adminhtml.xml b/app/code/core/Mage/CurrencySymbol/etc/adminhtml.xml
index 2c98705e055e7..6563150b5776f 100644
--- a/app/code/core/Mage/CurrencySymbol/etc/adminhtml.xml
+++ b/app/code/core/Mage/CurrencySymbol/etc/adminhtml.xml
@@ -26,28 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <currency translate="title" module="Mage_CurrencySymbol">
-                    <title>Manage Currency</title>
-                    <children>
-                        <rates translate="title">
-                            <title>Rates</title>
-                            <action>adminhtml/system_currency</action>
-                            <sort_order>50</sort_order>
-                        </rates>
-                        <symbols translate="title">
-                            <title>Symbols</title>
-                            <action>adminhtml/system_currencysymbol</action>
-                            <sort_order>100</sort_order>
-                        </symbols>
-                    </children>
-                    <sort_order>50</sort_order>
-                </currency>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/CurrencySymbol/etc/adminhtml/menu.xml b/app/code/core/Mage/CurrencySymbol/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..ab42b57f7b0e5
--- /dev/null
+++ b/app/code/core/Mage/CurrencySymbol/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_CurrencySymbol
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <update id="Mage_Adminhtml::system_currency" title="Manage Currency" module="Mage_CurrencySymbol" sortOrder="50" parent="Mage_Adminhtml::system" />
+        <add id="Mage_CurrencySymbol::system_currency_rates" title="Rates" module="Mage_CurrencySymbol" sortOrder="50" parent="Mage_Adminhtml::system_currency" action="adminhtml/system_currency" />
+        <add id="Mage_CurrencySymbol::system_currency_symbols" title="Symbols" module="Mage_CurrencySymbol" sortOrder="100" parent="Mage_Adminhtml::system_currency" action="adminhtml/system_currencysymbol" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Customer/Block/Account/Navigation.php b/app/code/core/Mage/Customer/Block/Account/Navigation.php
index 2a5e403a31ee3..e6d342df4ed49 100644
--- a/app/code/core/Mage/Customer/Block/Account/Navigation.php
+++ b/app/code/core/Mage/Customer/Block/Account/Navigation.php
@@ -50,6 +50,18 @@ public function addLink($name, $path, $label, $urlParams=array())
         return $this;
     }
 
+    /**
+     * Removes a link from the navigation
+     *
+     * @param string $name
+     * @return Mage_Customer_Block_Account_Navigation
+     */
+    public function removeLink($name)
+    {
+        unset($this->_links[$name]);
+        return $this;
+    }
+
     public function setActive($path)
     {
         $this->_activeLink = $this->_completePath($path);
diff --git a/app/code/core/Mage/Customer/etc/adminhtml.xml b/app/code/core/Mage/Customer/etc/adminhtml.xml
index f028fb122d06e..e665b98ccdc7a 100644
--- a/app/code/core/Mage/Customer/etc/adminhtml.xml
+++ b/app/code/core/Mage/Customer/etc/adminhtml.xml
@@ -26,30 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <customer translate="title" module="Mage_Customer">
-            <title>Customers</title>
-            <sort_order>40</sort_order>
-            <!-- action>adminhtml/customer/</action -->
-            <children>
-                <manage translate="title" module="Mage_Customer">
-                    <title>Manage Customers</title>
-                    <action>adminhtml/customer/</action>
-                    <sort_order>0</sort_order>
-                </manage>
-                <group translate="title" module="Mage_Customer">
-                    <title>Customer Groups</title>
-                    <action>adminhtml/customer_group/</action>
-                    <sort_order>10</sort_order>
-                </group>
-                <online translate="title" module="Mage_Customer">
-                    <title>Online Customers</title>
-                    <action>adminhtml/customer_online/</action>
-                    <sort_order>100</sort_order>
-                </online>
-            </children>
-         </customer>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Customer/etc/adminhtml/menu.xml b/app/code/core/Mage/Customer/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..eb32bb0456eb6
--- /dev/null
+++ b/app/code/core/Mage/Customer/etc/adminhtml/menu.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Customer::customer" title="Customers" module="Mage_Customer" sortOrder="40" />
+        <add id="Mage_Customer::customer_manage" title="Manage Customers" module="Mage_Customer" sortOrder="0" parent="Mage_Customer::customer" action="adminhtml/customer/" />
+        <add id="Mage_Customer::customer_group" title="Customer Groups" module="Mage_Customer" sortOrder="10" parent="Mage_Customer::customer" action="adminhtml/customer_group/" />
+        <add id="Mage_Customer::customer_online" title="Online Customers" module="Mage_Customer" sortOrder="100" parent="Mage_Customer::customer" action="adminhtml/customer_online/" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Customer/view/frontend/widget/name.phtml b/app/code/core/Mage/Customer/view/frontend/widget/name.phtml
index 440903405a00c..f95b75f4d4419 100644
--- a/app/code/core/Mage/Customer/view/frontend/widget/name.phtml
+++ b/app/code/core/Mage/Customer/view/frontend/widget/name.phtml
@@ -64,7 +64,7 @@ For checkout/onepage/shipping.phtml:
     <div class="field name-firstname">
         <label for="<?php echo $this->getFieldId('firstname')?>" class="required"><em>*</em><?php echo $this->getStoreLabel('firstname') ?></label>
         <div class="input-box">
-            <input type="text" id="<?php echo $this->getFieldId('firstname')?>" name="<?php echo $this->getFieldName('firstname')?>" value="<?php echo $this->escapeHtml($this->getObject()->getFirstname()) ?>" title="<?php echo $this->getStoreLabel('firstname') ?>" maxlength="255" class="input-text <?php echo $this->helper('Mage_Customer_Helper_Address')->getAttributeValidationClass('firstname') ?>" <?php echo $this->getFieldParams() ?> />
+            <input type="text" id="<?php echo $this->getFieldId('firstname')?>" name="<?php echo $this->getFieldName('firstname')?>" value="<?php echo $this->escapeHtml($this->getObject()->getFirstname()) ?>" title="<?php echo $this->getStoreLabel('firstname') ?>" class="input-text <?php echo $this->helper('Mage_Customer_Helper_Address')->getAttributeValidationClass('firstname') ?>" <?php echo $this->getFieldParams() ?> />
         </div>
     </div>
 <?php if ($this->showMiddlename()): ?>
@@ -79,7 +79,7 @@ For checkout/onepage/shipping.phtml:
     <div class="field name-lastname">
         <label for="<?php echo $this->getFieldId('lastname')?>" class="required"><em>*</em><?php echo $this->getStoreLabel('lastname') ?></label>
         <div class="input-box">
-            <input type="text" id="<?php echo $this->getFieldId('lastname')?>" name="<?php echo $this->getFieldName('lastname')?>" value="<?php echo $this->escapeHtml($this->getObject()->getLastname()) ?>" title="<?php echo $this->getStoreLabel('lastname') ?>" maxlength="255" class="input-text <?php echo $this->helper('Mage_Customer_Helper_Address')->getAttributeValidationClass('lastname') ?>" <?php echo $this->getFieldParams() ?> />
+            <input type="text" id="<?php echo $this->getFieldId('lastname')?>" name="<?php echo $this->getFieldName('lastname')?>" value="<?php echo $this->escapeHtml($this->getObject()->getLastname()) ?>" title="<?php echo $this->getStoreLabel('lastname') ?>" class="input-text <?php echo $this->helper('Mage_Customer_Helper_Address')->getAttributeValidationClass('lastname') ?>" <?php echo $this->getFieldParams() ?> />
         </div>
     </div>
 <?php if ($this->showSuffix()): ?>
diff --git a/app/code/core/Mage/DesignEditor/controllers/Adminhtml/System/Design/EditorController.php b/app/code/core/Mage/DesignEditor/controllers/Adminhtml/System/Design/EditorController.php
index 5be3c40936a9e..30da890e3afbf 100644
--- a/app/code/core/Mage/DesignEditor/controllers/Adminhtml/System/Design/EditorController.php
+++ b/app/code/core/Mage/DesignEditor/controllers/Adminhtml/System/Design/EditorController.php
@@ -36,7 +36,7 @@ public function indexAction()
     {
         $this->_title($this->__('System'))->_title($this->__('Design'))->_title($this->__('Editor'));
         $this->loadLayout();
-        $this->_setActiveMenu('system/design/editor');
+        $this->_setActiveMenu('Mage_DesignEditor::system_design_editor');
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/DesignEditor/etc/adminhtml.xml b/app/code/core/Mage/DesignEditor/etc/adminhtml.xml
index e563d313fe0c5..23b9c5bbe2d11 100644
--- a/app/code/core/Mage/DesignEditor/etc/adminhtml.xml
+++ b/app/code/core/Mage/DesignEditor/etc/adminhtml.xml
@@ -26,21 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <design>
-                    <children>
-                        <editor translate="title" module="Mage_DesignEditor">
-                            <title>Editor</title>
-                            <action>adminhtml/system_design_editor</action>
-                            <sort_order>20</sort_order>
-                        </editor>
-                    </children>
-                </design>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/DesignEditor/etc/adminhtml/menu.xml b/app/code/core/Mage/DesignEditor/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..8a46113f28a6f
--- /dev/null
+++ b/app/code/core/Mage/DesignEditor/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_DesignEditor
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_DesignEditor::system_design_editor" title="Editor" module="Mage_DesignEditor" sortOrder="20" parent="Mage_Adminhtml::system_design" action="adminhtml/system_design_editor" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/DesignEditor/view/frontend/js/base.js b/app/code/core/Mage/DesignEditor/view/frontend/js/base.js
index 020f8f70a9ab1..1931a09386241 100644
--- a/app/code/core/Mage/DesignEditor/view/frontend/js/base.js
+++ b/app/code/core/Mage/DesignEditor/view/frontend/js/base.js
@@ -1,4 +1,4 @@
-/**
+/**
  * Magento
  *
  * NOTICE OF LICENSE
@@ -15,168 +15,138 @@
  *
  * Do not edit or add to this file if you wish to upgrade Magento to newer
  * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_DesignEditor
- * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-
-( function ( $ ) {
-
-    /**
-     * Widget tree
-     */
-    $.widget( "Mage.tree" , {
-        options:{
-            ui: {
-                select_limit: 1,
-                selected_parent_close: false
-            },
-            themes: {
-                dots:  false,
-                icons: false
-            },
-            callback: {
-                onselect: function( e, data ) {
-                    var leaf = $( data.rslt.obj ),
-                        cellElement = $( this ).parents( '.vde_toolbar_cell' );
-                    if ( cellElement.hasClass( 'active' ) ){
-                        cellElement.removeClass( 'active' );
-                        $( this ).trigger( 'changetitle.menu', [ $.trim( leaf.find( 'a:first' ).text() ) ] );
-                        window.location = leaf.find( 'a:first' ).attr( 'href' );
-                    }
-                }
-            }
-        },
-        _create: function() {
-            var self = this;
-            this.element.on( 'loaded.jstree' , function ( e, data ) {
-                self.element.data( 'selected' ) ?
-                    self.element.jstree( 'select_node' , self.element.find( self.element.data( 'selected' ) ) ):
-                    $.noop();
-            });
-            this.element.jstree( this.options );
-            this.element.on( 'select_node.jstree', this.options.callback.onselect );
-        }
-    });
-
-    /**
-     * Widget sScroll
-     */
-    $.widget( "Mage.sScroll", {
-        options:{
-            color: '#cccccc',
-            alwaysVisible: true,
-            opacity: 1,
-            height: 'auto',
-            size: 9
-        },
-        _create: function() {
-            this.element.slimScroll( this.options );
-        }
-    });
-
-    /**
-     * Widget menu
-     */
-    $.widget( "Mage.menu", {
-        options:{
-            type: 'popup',
-            titleSelector: ':first-child',
-            titleTextSelector : '.vde_toolbar_cell_value',
-            activeClass : 'active',
-            activeEventName: 'activate_toolbar_cell.vde'
-        },
-        _create: function() {
-            this._bind();
-        },
-        _bind: function(){
-            var self = this;
-            this.element
-                .on( 'hide.menu', function( e ){self.hide( e )} )
-                .on( 'changetitle.menu', function( e, title ) {
-                    self.element.find( self.options.titleTextSelector ).text( title );
-                })
-                .find( this.options.titleSelector ).first()
-                .on( 'click.menu', function( e ){
-                    self.element.hasClass( self.options.activeClass ) ?
-                        self.hide( e ):
-                        self.show( e );
-                })
-            $( 'body' ).on( 'click', function( e ) {
-                $( ':'+self.namespace+'-'+self.widgetName ).not( $( e.target )
-                    .parents( ':'+self.namespace+'-'+self.widgetName ).first()).menu( 'hide' );
-            })
-        },
-        show: function( e ){
-            this.element.addClass( this.options.activeClass ).trigger( this.options.activeEventName );
-        },
-        hide:function( e ){
-            this.element.removeClass( this.options.activeClass );
-        }
-    });
-
-    /**
-     * Widget menu - tree view
-     */
-    var menuBasePrototype = $.Mage.menu.prototype;
-    $.widget( "Mage.menu", $.extend({}, menuBasePrototype, {
-        _create: function() {
-            menuBasePrototype._create.apply(this, arguments);
-            if ( this.options.treeSelector ) {
-                this.element.find( this.options.treeSelector ).size() ?
-                this.element.find( this.options.treeSelector ).tree() :
-                $.noop();
-            }
-        }
-    }));
-
-    /**
-     * Widget menu - slimScroll view
-     */
-    var menuTreePrototype = $.Mage.menu.prototype;
-    $.widget( "Mage.menu", $.extend({}, menuTreePrototype, {
-        _create: function() {
-            var self = this;
-            menuTreePrototype._create.apply(this, arguments);
-            if(this.options.slimScroll) {
-                this.options.treeSelector && this.element.find( this.options.treeSelector ).size() ?
-                    this.element
-                        .one( 'activate_toolbar_cell.vde', function () {
-                            self.element.find( ':Mage-tree' ).sScroll();
-                    }) :
-                    $.noop();
-            }
-        }
-    }));
-
-    /**
-     * Widget checkbox
-     */
-    $.widget( "Mage.checkbox", {
-        options:{
-            checkedClass : 'checked'
-        },
-        _create: function() {
-            this._bind();
-        },
-        _bind: function(){
-            var self = this;
-            this.element.on( 'click', function(){
-                self._click();
-            })
-        },
-        _click: function(){
-            if ( this.element.hasClass( this.options.checkedClass ) ) {
-                this.element.removeClass( this.options.checkedClass );
-                this.options.unCheckedEvent ? this.element.trigger(this.options.unCheckedEvent) : $.noop();
-            } else {
-                this.element.addClass( this.options.checkedClass );
-                this.options.checkedEvent ? this.element.trigger(this.options.checkedEvent) : $.noop();
-            }
-        }
-    });
-
-})( jQuery );
\ No newline at end of file
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_DesignEditor
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+(function($) {
+
+    /**
+     * Widget tree
+     */
+    $.widget('vde.vde_tree', {
+        options: {
+            ui: {
+                select_limit: 1,
+                selected_parent_close: false
+            },
+            themes: {
+                dots: false,
+                icons: false
+            }
+        },
+        _create: function () {
+            this._bind();
+            this.element.jstree(this.options);
+        },
+        _bind: function() {
+            var self = this;
+            this.element
+                .on('loaded.jstree', function (e, data) {
+                    var selectNode = self.element.data('selected');
+                    if (selectNode) {
+                        self.element.jstree('select_node', self.element.find(selectNode));
+                    }
+                })
+                .on('select_node.jstree', function (e, data) {
+                    var link = $(data.rslt.obj).find('a:first');
+                    $(this).trigger('link_selected.' + self.widgetName, [link]);
+                    if (data.rslt.e) { // User clicked the link, not just tree initialization
+                        window.location = link.attr('href');
+                    }
+                });
+        }
+    });
+
+    /**
+     * Widget menu
+     */
+    $.widget('vde.vde_menu', {
+        options: {
+            type: 'popup',
+            titleSelector: '.vde_toolbar_cell_title',
+            titleTextSelector: '.vde_toolbar_cell_value',
+            activeClass: 'active'
+        },
+        _create: function () {
+            this._bind();
+            if (this.options.treeSelector) {
+                var tree = this.element.find(this.options.treeSelector);
+                if (tree.size()) {
+                    tree.vde_tree();
+                    if (this.options.slimScroll) {
+                        var self = this;
+                        this.element
+                            .one('activate_toolbar_cell.' + self.widgetName, function () {
+                                self.element.find(self.options.treeSelector).slimScroll({
+                                    color: '#cccccc',
+                                    alwaysVisible: true,
+                                    opacity: 1,
+                                    height: 'auto',
+                                    size: 9
+                                });
+                        })
+                    }
+                }
+            }
+        },
+        _bind: function () {
+            var self = this,
+                titleText = self.element.find(self.options.titleTextSelector);
+            this.element
+                .on('change_title.' + self.widgetName, function(e, title) {
+                    titleText.text(title);
+                })
+                .on('link_selected.vde_tree', function(e, link) {
+                    titleText.text(link.text());
+                })
+                .find(this.options.titleSelector)
+                .on('click.' + self.widgetName, function(e) {
+                    self.element.hasClass(self.options.activeClass) ?
+                        self.hide(e):
+                        self.show(e);
+                })
+            $('body').on('click', function(e) {
+                var widgetInstancesSelector = ':' + self.namespace + '-' + self.widgetName;
+                $(widgetInstancesSelector).not($(e.target).parents(widgetInstancesSelector)).vde_menu('hide');
+            })
+        },
+        show: function(e) {
+            this.element.addClass(this.options.activeClass).trigger('activate_toolbar_cell.' + this.widgetName);
+        },
+        hide: function(e) {
+            this.element.removeClass(this.options.activeClass);
+        }
+    });
+
+    /**
+     * Widget checkbox
+     */
+    $.widget('vde.vde_checkbox', {
+        options: {
+            checkedClass: 'checked'
+        },
+        _create: function () {
+            this._bind();
+        },
+        _bind: function () {
+            var self = this;
+            this.element.on('click', function () {
+                self._click();
+            })
+        },
+        _click: function () {
+            if (this.element.hasClass(this.options.checkedClass)) {
+                this.element.removeClass(this.options.checkedClass);
+                this.element.trigger('unchecked.' + this.widgetName);
+            } else {
+                this.element.addClass(this.options.checkedClass);
+                this.element.trigger('checked.' + this.widgetName);
+            }
+        }
+    });
+})(jQuery);
\ No newline at end of file
diff --git a/app/code/core/Mage/DesignEditor/view/frontend/js/design_editor.js b/app/code/core/Mage/DesignEditor/view/frontend/js/design_editor.js
index ee5db01b53725..03ac8d4589680 100644
--- a/app/code/core/Mage/DesignEditor/view/frontend/js/design_editor.js
+++ b/app/code/core/Mage/DesignEditor/view/frontend/js/design_editor.js
@@ -1,4 +1,4 @@
-/**
+/**
  * Magento
  *
  * NOTICE OF LICENSE
@@ -15,188 +15,183 @@
  *
  * Do not edit or add to this file if you wish to upgrade Magento to newer
  * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_DesignEditor
- * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-
-( function ( $ ) {
-
-    /**
-     * Widget block
-     */
-    $.widget( "vde.block", { _create: function(){}} );
-
-    /**
-     * Widget container
-     */
-    $.widget( "vde.container", $.ui.sortable, {
-        options : {
-            tolerance: 'pointer',
-            revert: true,
-            connectWithSelector : '.vde_element_wrapper.vde_container',
-            placeholder: 'vde_placeholder',
-            hoverClass: 'vde_container_hover',
-            items: '.vde_element_wrapper.vde_draggable',
-            helper: 'clone',
-            appendTo: 'body'
-        },
-        _create: function() {
-            var self = this;
-            this.element.data( "sortable", this );
-            self.options =  $.extend( {}, self.options, {
-                start: function( event, ui ) {
-                    ui.placeholder.css( { height: $( ui.helper ).outerHeight( true ) } );
-                    $(this).sortable('option', 'connectWith', $(self.options.connectWithSelector).not(ui.item))
-                        .sortable('refresh');
-                },
-                over: function( event, ui ) {
-                    self.element.addClass( self.options.hoverClass );
-                },
-                out: function( event, ui ) {
-                    self.element.removeClass( self.options.hoverClass );
-                }
-            });
-            $.ui.sortable.prototype._create.apply( this, arguments );
-        }
-    });
-
-    /**
-     * Widget panel
-     */
-    $.widget( "vde.panel" , {
-        options:{
-            cellSelector : '.vde_toolbar_cell',
-            handlesHierarchySelector : '#vde_handles_hierarchy',
-            treeSelector : '#vde_handles_tree'
-        },
-        _create: function() {
-            this._initCells();
-        },
-        _initCells : function(){
-            var self = this;
-            this.element.find( this.options.cellSelector ).each( function(){
-                $( this ).is( self.options.handlesHierarchySelector ) ?
-                    $( this ).menu( {treeSelector : self.options.treeSelector, slimScroll:true } ) :
-                    $( this ).menu();
-            });
-            this.element.find( this.options.cellSelector ).menu();
-        }
-    });
-
-    /**
-     * Widget page
-     */
-    $.widget( "vde.page", {
-        options:{
-            containerSelector : '.vde_element_wrapper.vde_container',
-            panelSelector : '#vde_toolbar',
-            highlightElementSelector : '.vde_element_wrapper',
-            highlightElementTitleSelector : '.vde_element_title',
-            highlightCheckboxSelector : '#vde_highlighting',
-            cookieHighlightingName : 'vde_highlighting'
-        },
-        _create: function() {
-            this._initContainers();
-            this._initPanel();
-        },
-        _initContainers : function(){
-            $( this.options.containerSelector )
-                .container().disableSelection();
-        },
-        _initPanel : function(){
-            $( this.options.panelSelector ).panel();
-        }
-    });
-
-    /**
-     * Widget page highlight functionality
-     */
-    var pageBasePrototype = $.vde.page.prototype;
-    $.widget( "vde.page", $.extend({}, pageBasePrototype, {
-        _create: function() {
-            pageBasePrototype._create.apply( this, arguments );
-            if( this.options.highlightElementSelector ) {
-                this._initHighlighting();
-                this._bind();
-            }
-        },
-        _bind: function(){
-            var self = this;
-            this.element
-                .on( 'highlightelements.vde', function(){ self._highlight(); })
-                .on( 'unhighlightelements.vde', function(){ self._unhighlight(); });
-        },
-        _initHighlighting: function(){
-            this.options.highlightCheckboxSelector ?
-                $( this.options.highlightCheckboxSelector )
-                    .checkbox({checkedEvent:'highlightelements.vde', unCheckedEvent:'unhighlightelements.vde'}) :
-                $.noop();
-            this.highlightBlocks = {};
-            if (Mage.Cookies.get(this.options.cookieHighlightingName) == 'off') {
-                this._processMarkers();
-            }
-
-        },
-        _highlight: function(){
-            var self = this;
-            Mage.Cookies.clear( this.options.cookieHighlightingName );
-            $( this.options.highlightElementSelector ).each(function () {
-                $( this )
-                    .append( self._getChildren( $( this ).attr( 'id' ) ) )
-                    .show()
-                    .children( self.options.highlightElementTitleSelector ).slideDown( 'fast' );
-            });
-            this.highlightBlocks = {};
-        },
-        _unhighlight: function(){
-            var self = this;
-            Mage.Cookies.set( this.options.cookieHighlightingName, "off" );
-            $( this.options.highlightElementSelector ).each( function () {
-                var elem = $( this );
-                elem.children( self.options.highlightElementTitleSelector ).slideUp( 'fast', function () {
-                    var children = elem.contents( ':not('+self.options.highlightElementTitleSelector+')' );
-                    var parentId = elem.attr( 'id' );
-                    children.each( function(){
-                        self._storeChild( parentId, this );
-                    });
-                    elem.after( children ).hide();
-                });
-            });
-        },
-        _processMarkers : function () {
-            var self = this,
-                parentsIdsStack = [],
-                currentParentId;
-            $('*').contents().each(function(){
-                if ( this.nodeType == Node.COMMENT_NODE ) {
-                    if ( this.data.substr(0, 9) == 'start_vde' ) {
-                        currentParentId = this.data.substr( 6, this.data.length );
-                        parentsIdsStack.push( currentParentId );
-                        this.parentNode.removeChild( this );
-                    } else if ( this.data.substr( 0, 7 ) == 'end_vde' ) {
-                        if ( this.data.substr( 4, this.data.length ) !== currentParentId ) {
-                            throw "Could not find closing element for opened '" + currentParentId + "' element";
-                        }
-                        parentsIdsStack.pop();
-                        currentParentId = parentsIdsStack[ parentsIdsStack.length - 1 ];
-                        this.parentNode.removeChild( this );
-                    }
-                } else if ( currentParentId ) {
-                    self._storeChild( currentParentId, this );
-                }
-            })
-        },
-        _storeChild : function ( parentId, child ) {
-            ( !this.highlightBlocks[ parentId ] ) ? this.highlightBlocks[ parentId ] = [] : $.noop();
-            this.highlightBlocks[ parentId ].push( child );
-        },
-        _getChildren : function ( parentId ) {
-            return ( !this.highlightBlocks[parentId] ) ? [] : this.highlightBlocks[ parentId ];
-        }
-    }));
-
-})( jQuery );
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_DesignEditor
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+(function($) {
+
+    /**
+     * Widget container
+     */
+    $.widget('vde.vde_container', $.ui.sortable, {
+        options: {
+            tolerance: 'pointer',
+            revert: true,
+            connectWithSelector: '.vde_element_wrapper.vde_container',
+            placeholder: 'vde_placeholder',
+            hoverClass: 'vde_container_hover',
+            items: '.vde_element_wrapper.vde_draggable',
+            helper: 'clone',
+            appendTo: 'body'
+        },
+        _create: function () {
+            this.element.data('sortable', this);
+            var self = this;
+            this.options = $.extend({}, this.options, {
+                start: function(event, ui) {
+                    ui.placeholder.css({height: $(ui.helper).outerHeight(true)});
+                    $(this).sortable('option', 'connectWith', $(self.options.connectWithSelector).not(ui.item))
+                        .sortable('refresh');
+                },
+                over: function(event, ui) {
+                    self.element.addClass(self.options.hoverClass);
+                },
+                out: function(event, ui) {
+                    self.element.removeClass(self.options.hoverClass);
+                }
+            });
+            $.ui.sortable.prototype._create.apply(this, arguments);
+        }
+    });
+
+    /**
+     * Widget panel
+     */
+    $.widget('vde.vde_panel', {
+        options: {
+            cellSelector: '.vde_toolbar_cell',
+            handlesHierarchySelector: '#vde_handles_hierarchy',
+            treeSelector: '#vde_handles_tree'
+        },
+        _create: function () {
+            var self = this;
+            this.element.find(this.options.cellSelector).each(function () {
+                var params = $(this).is(self.options.handlesHierarchySelector) ? {treeSelector: self.options.treeSelector, slimScroll: true } : {};
+                $(this).vde_menu(params);
+            });
+        }
+    });
+
+    /**
+     * Widget page
+     */
+    $.widget('vde.vde_page', {
+        options: {
+            containerSelector: '.vde_element_wrapper.vde_container',
+            panelSelector: '#vde_toolbar',
+            highlightElementSelector: '.vde_element_wrapper',
+            highlightElementTitleSelector: '.vde_element_title',
+            highlightCheckboxSelector: '#vde_highlighting',
+            cookieHighlightingName: 'vde_highlighting'
+        },
+        _create: function () {
+            this._initContainers();
+            this._initPanel();
+        },
+        _initContainers: function () {
+            $(this.options.containerSelector)
+                .vde_container().disableSelection();
+        },
+        _initPanel: function () {
+            $(this.options.panelSelector).vde_panel();
+        }
+    });
+
+    /**
+     * Widget page highlight functionality
+     */
+    var pageBasePrototype = $.vde.vde_page.prototype;
+    $.widget('vde.vde_page', $.extend({}, pageBasePrototype, {
+        _create: function () {
+            pageBasePrototype._create.apply(this, arguments);
+            if (this.options.highlightElementSelector) {
+                this._initHighlighting();
+                this._bind();
+            }
+        },
+        _bind: function () {
+            var self = this;
+            this.element
+                .on('checked.vde_checkbox', function () {
+                    self._highlight();
+                })
+                .on('unchecked.vde_checkbox', function () {
+                    self._unhighlight();
+                });
+        },
+        _initHighlighting: function () {
+            if (this.options.highlightCheckboxSelector) {
+                $(this.options.highlightCheckboxSelector)
+                    .vde_checkbox();
+            }
+            this.highlightBlocks = {};
+            if (Mage.Cookies.get(this.options.cookieHighlightingName) == 'off') {
+                this._processMarkers();
+            }
+
+        },
+        _highlight: function () {
+            Mage.Cookies.clear(this.options.cookieHighlightingName);
+            var self = this;
+            $(this.options.highlightElementSelector).each(function () {
+                $(this)
+                    .append(self._getChildren($(this).attr('id')))
+                    .show()
+                    .children(self.options.highlightElementTitleSelector).slideDown('fast');
+            });
+            this.highlightBlocks = {};
+        },
+        _unhighlight: function () {
+            Mage.Cookies.set(this.options.cookieHighlightingName, 'off');
+            var self = this;
+            $(this.options.highlightElementSelector).each(function () {
+                var elem = $(this);
+                elem.children(self.options.highlightElementTitleSelector).slideUp('fast', function () {
+                    var children = elem.contents(':not(' + self.options.highlightElementTitleSelector + ')');
+                    var parentId = elem.attr('id');
+                    children.each(function () {
+                        self._storeChild(parentId, this);
+                    });
+                    elem.after(children).hide();
+                });
+            });
+        },
+        _processMarkers: function () {
+            var self = this,
+                parentsIdsStack = [],
+                currentParentId;
+            $('*').contents().each(function () {
+                if (this.nodeType == Node.COMMENT_NODE) {
+                    if (this.data.substr(0, 9) == 'start_vde') {
+                        currentParentId = this.data.substr(6, this.data.length);
+                        parentsIdsStack.push(currentParentId);
+                        this.parentNode.removeChild(this);
+                    } else if (this.data.substr(0, 7) == 'end_vde') {
+                        if (this.data.substr(4, this.data.length) !== currentParentId) {
+                            throw "Could not find closing element for opened '" + currentParentId + "' element";
+                        }
+                        parentsIdsStack.pop();
+                        currentParentId = parentsIdsStack[parentsIdsStack.length - 1];
+                        this.parentNode.removeChild(this);
+                    }
+                } else if (currentParentId) {
+                    self._storeChild(currentParentId, this);
+                }
+            })
+        },
+        _storeChild: function(parentId, child) {
+            if (!this.highlightBlocks[parentId]) {
+                this.highlightBlocks[parentId] = [];
+            }
+            this.highlightBlocks[parentId].push(child);
+        },
+        _getChildren: function(parentId) {
+            return (!this.highlightBlocks[parentId]) ? [] : this.highlightBlocks[parentId];
+        }
+    }));
+})( jQuery );
diff --git a/app/code/core/Mage/DesignEditor/view/frontend/js/settimeout_override.js b/app/code/core/Mage/DesignEditor/view/frontend/js/settimeout_override.js
new file mode 100644
index 0000000000000..721f635abfb4f
--- /dev/null
+++ b/app/code/core/Mage/DesignEditor/view/frontend/js/settimeout_override.js
@@ -0,0 +1,77 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_DesignEditor
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+(function() {
+
+    var bindBeforeUnload = function() {
+        window.onbeforeunload = function(e) {
+            var e = e || window.event;
+            var messageText = 'Automatic redirect has been triggered.';
+            // For IE and Firefox
+            if (e) {
+                e.returnValue = messageText;
+            }
+            // For Chrome and Safari
+            return messageText;
+        };
+    }
+
+    var unbindBeforeUnload = function () {
+        window.onbeforeunload = null;
+    }
+
+    window.setTimeout = (function(oldSetTimeout) {
+        return function(func, delay) {
+            return oldSetTimeout(function() {
+                try {
+                    bindBeforeUnload();
+                    func();
+                    unbindBeforeUnload();
+                }
+                catch (exception) {
+                    unbindBeforeUnload();
+                    throw exception;
+                }
+            }, delay);
+        };
+    })(window.setTimeout);
+
+    window.setInterval = (function(oldSetInterval) {
+        return function(func, delay) {
+            return oldSetInterval(function() {
+                try {
+                    bindBeforeUnload();
+                    func();
+                    unbindBeforeUnload();
+                }
+                catch (exception) {
+                    unbindBeforeUnload();
+                    throw exception;
+                }
+            }, delay);
+        };
+    })(window.setInterval);
+
+})();
diff --git a/app/code/core/Mage/DesignEditor/view/frontend/layout.xml b/app/code/core/Mage/DesignEditor/view/frontend/layout.xml
index 1ac3fa7b6cc86..38448fbd8b775 100644
--- a/app/code/core/Mage/DesignEditor/view/frontend/layout.xml
+++ b/app/code/core/Mage/DesignEditor/view/frontend/layout.xml
@@ -28,6 +28,7 @@
 <layout>
     <design_editor_toolbar>
         <reference name="head">
+            <action method="addJs"><file>Mage_DesignEditor::js/settimeout_override.js</file></action>
             <action method="addJs"><file>jquery/jquery-1.7.1.min.js</file></action>
             <action method="addJs"><file>mage/jquery-no-conflict.js</file></action>
             <action method="addJs"><file>jquery/jquery-ui-1.8.18.custom.min.js</file></action>
diff --git a/app/code/core/Mage/DesignEditor/view/frontend/toolbar.phtml b/app/code/core/Mage/DesignEditor/view/frontend/toolbar.phtml
index 686c14c6978b8..ccdfd5089cf1b 100644
--- a/app/code/core/Mage/DesignEditor/view/frontend/toolbar.phtml
+++ b/app/code/core/Mage/DesignEditor/view/frontend/toolbar.phtml
@@ -1,5 +1,5 @@
-<?php
-/**
+<?php
+/**
  * Magento
  *
  * NOTICE OF LICENSE
@@ -16,25 +16,25 @@
  *
  * Do not edit or add to this file if you wish to upgrade Magento to newer
  * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    design
- * @package     Mage_DesignEditor
- * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php /** @var $this Mage_DesignEditor_Block_Toolbar */ ?>
-<div id="vde_toolbar">
-    <?php $messages = $this->getMessages(); ?>
-    <?php foreach ($messages as $message): ?>
-        <p class="item-msg <?php echo $message->getType() ?>"><?php echo $this->escapeHtml($message->getCode()) ?></p>
-    <?php endforeach; ?>
-    <?php echo $this->getChildHtml(); ?>
-</div>
-
-<script type="text/javascript">
-(function ($) {
-    $( document ).ready( function( ){ $( window ).page(<?php echo $this->getOptionsJson(); ?>); } );
-})(jQuery);
-</script>
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     Mage_DesignEditor
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php /** @var $this Mage_DesignEditor_Block_Toolbar */ ?>
+<div id="vde_toolbar">
+    <?php $messages = $this->getMessages(); ?>
+    <?php foreach ($messages as $message): ?>
+        <p class="item-msg <?php echo $message->getType() ?>"><?php echo $this->escapeHtml($message->getCode()) ?></p>
+    <?php endforeach; ?>
+    <?php echo $this->getChildHtml(); ?>
+</div>
+
+<script type="text/javascript">
+(function ($) {
+    $( document ).ready( function( ){ $( window ).vde_page(<?php echo $this->getOptionsJson(); ?>); } );
+})(jQuery);
+</script>
diff --git a/app/code/core/Mage/Downloadable/etc/adminhtml.xml b/app/code/core/Mage/Downloadable/etc/adminhtml.xml
index 3d0068bcfead3..87cc34e2acf17 100644
--- a/app/code/core/Mage/Downloadable/etc/adminhtml.xml
+++ b/app/code/core/Mage/Downloadable/etc/adminhtml.xml
@@ -45,18 +45,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <report>
-            <children>
-                <products>
-                    <children>
-                        <downloads translate="title" module="Mage_Reports">
-                            <title>Downloads</title>
-                            <action>adminhtml/report_product/downloads</action>
-                        </downloads>
-                    </children>
-                </products>
-            </children>
-        </report>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Downloadable/etc/adminhtml/menu.xml b/app/code/core/Mage/Downloadable/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..88bb9ce02f3ca
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Downloadable::report_products_downloads" title="Downloads" module="Mage_Reports" parent="Mage_Reports::report_products" action="adminhtml/report_product/downloads" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Downloadable/view/frontend/layout.xml b/app/code/core/Mage/Downloadable/view/frontend/layout.xml
index 657ea17cbdcee..41ee32913efe6 100644
--- a/app/code/core/Mage/Downloadable/view/frontend/layout.xml
+++ b/app/code/core/Mage/Downloadable/view/frontend/layout.xml
@@ -51,6 +51,16 @@
         </reference>
     </checkout_cart_index>
 
+    <checkout_cart_configure_type_downloadable translate="label" module="Mage_Downloadable" type="page" parent="checkout_cart_configure">
+        <label>Configure Cart Item</label>
+        <update handle="catalog_product_view_type_downloadable"/>
+    </checkout_cart_configure_type_downloadable>
+
+    <checkout_cart_configurefailed_type_downloadable translate="label" module="Mage_Downloadable" type="page" parent="checkout_cart_configure">
+        <label>Configure Cart Item</label>
+        <update handle="catalog_product_view_type_downloadable"/>
+    </checkout_cart_configurefailed_type_downloadable>
+
     <checkout_onepage_review>
         <reference name="order_review">
             <action method="addItemRender"><type>downloadable</type><block>Mage_Downloadable_Block_Checkout_Cart_Item_Renderer</block><template>checkout/onepage/review/item.phtml</template></action>
diff --git a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php
index 55eee8341f92e..05e93e3901ea1 100644
--- a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php
+++ b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php
@@ -42,7 +42,7 @@ class Mage_GoogleShopping_Adminhtml_Googleshopping_ItemsController extends Mage_
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('catalog/googleshopping/items')
+            ->_setActiveMenu('Mage_GoogleShopping::catalog_googleshopping_items')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'))
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Google Content'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Google Content'));
         return $this;
diff --git a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/TypesController.php b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/TypesController.php
index eab4b06f09ed7..e194491fc4d2a 100644
--- a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/TypesController.php
+++ b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/TypesController.php
@@ -73,7 +73,7 @@ protected function _initItemType()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('catalog/googleshopping/types')
+            ->_setActiveMenu('Mage_GoogleShopping::catalog_googleshopping_types')
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Catalog'))
             ->_addBreadcrumb(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Google Content'), Mage::helper('Mage_Adminhtml_Helper_Data')->__('Google Content'));
         return $this;
diff --git a/app/code/core/Mage/GoogleShopping/etc/adminhtml.xml b/app/code/core/Mage/GoogleShopping/etc/adminhtml.xml
index 1232cea22b275..5909846a6c2ed 100644
--- a/app/code/core/Mage/GoogleShopping/etc/adminhtml.xml
+++ b/app/code/core/Mage/GoogleShopping/etc/adminhtml.xml
@@ -26,26 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog>
-            <children>
-                <googleshopping translate="title" module="Mage_GoogleShopping">
-                    <title>Google Content</title>
-                    <children>
-                        <types translate="title" module="Mage_GoogleShopping">
-                            <title>Manage Attributes</title>
-                            <action>adminhtml/googleshopping_types</action>
-                        </types>
-                        <items translate="title" module="Mage_GoogleShopping">
-                            <title>Manage Items</title>
-                            <action>adminhtml/googleshopping_items</action>
-                        </items>
-                    </children>
-                    <sort_order>70</sort_order>
-                </googleshopping>
-             </children>
-        </catalog>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/GoogleShopping/etc/adminhtml/menu.xml b/app/code/core/Mage/GoogleShopping/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..06f4f8ba44668
--- /dev/null
+++ b/app/code/core/Mage/GoogleShopping/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_GoogleShopping
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_GoogleShopping::catalog_googleshopping" title="Google Content" module="Mage_GoogleShopping" sortOrder="70" parent="Mage_Catalog::catalog" />
+        <add id="Mage_GoogleShopping::catalog_googleshopping_types" title="Manage Attributes" module="Mage_GoogleShopping" parent="Mage_GoogleShopping::catalog_googleshopping" action="adminhtml/googleshopping_types" />
+        <add id="Mage_GoogleShopping::catalog_googleshopping_items" title="Manage Items" module="Mage_GoogleShopping" parent="Mage_GoogleShopping::catalog_googleshopping" action="adminhtml/googleshopping_items" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/ImportExport/Block/Adminhtml/Export/Edit/Form.php b/app/code/core/Mage/ImportExport/Block/Adminhtml/Export/Edit/Form.php
index 6bb9a4c7adaec..0485c72a80c77 100644
--- a/app/code/core/Mage/ImportExport/Block/Adminhtml/Export/Edit/Form.php
+++ b/app/code/core/Mage/ImportExport/Block/Adminhtml/Export/Edit/Form.php
@@ -75,7 +75,7 @@ protected function _prepareForm()
             'label'    => $helper->__('Export Format Version'),
             'required' => false,
             'onchange' => 'editForm.handleExportFormatVersionSelector();',
-            'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Export_Format_Version')->toOptionArray()
+            'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Format_Version')->toOptionArray()
         ));
         $fieldsets['customer'] = $form->addFieldset('customer_entity_fieldset',
             array(
diff --git a/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Before.php b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Before.php
new file mode 100644
index 0000000000000..6b215c54d3fe9
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Before.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Block before import form
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_ImportExport_Block_Adminhtml_Import_Before extends Mage_Backend_Block_Template
+{
+    /**
+     * Get JS array string of allowed customer behaviours
+     *
+     * @param string $importVersion
+     * @return string
+     */
+    public function getJsAllowedCustomerBehaviours($importVersion)
+    {
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+        $allowedBehaviours = $helper->getAllowedCustomerBehaviours($importVersion);
+        return Zend_Json::encode($allowedBehaviours);
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Form.php
index d41bfd57b49b6..25c611084c12f 100644
--- a/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Form.php
+++ b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Form.php
@@ -34,7 +34,7 @@
 class Mage_ImportExport_Block_Adminhtml_Import_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
 {
     /**
-     * Add fieldset
+     * Add fieldsets
      *
      * @return Mage_ImportExport_Block_Adminhtml_Import_Edit_Form
      */
@@ -47,22 +47,65 @@ protected function _prepareForm()
             'method'  => 'post',
             'enctype' => 'multipart/form-data'
         ));
-        $fieldset = $form->addFieldset('base_fieldset', array('legend' => $helper->__('Import Settings')));
-        $fieldset->addField('entity', 'select', array(
+
+        // base fieldset
+        $fieldsets['base'] = $form->addFieldset('base_fieldset', array('legend' => $helper->__('Import Settings')));
+        $fieldsets['base']->addField('entity', 'select', array(
             'name'     => 'entity',
             'title'    => $helper->__('Entity Type'),
             'label'    => $helper->__('Entity Type'),
             'required' => true,
+            'onchange' => 'editForm.handleEntityTypeSelector();',
             'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Import_Entity')->toOptionArray()
         ));
-        $fieldset->addField('behavior', 'select', array(
+        $fieldsets['base']->addField('behavior', 'select', array(
             'name'     => 'behavior',
             'title'    => $helper->__('Import Behavior'),
             'label'    => $helper->__('Import Behavior'),
             'required' => true,
             'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Import_Behavior')->toOptionArray()
         ));
-        $fieldset->addField(Mage_ImportExport_Model_Import::FIELD_NAME_SOURCE_FILE, 'file', array(
+
+        // fieldset for format version
+        $fieldsets['version'] = $form->addFieldset('import_format_version_fieldset',
+            array(
+                'legend' => $helper->__('Import Format Version'),
+                'style'  => 'display:none'
+            )
+        );
+        $fieldsets['version']->addField('file_format_version', 'select', array(
+            'name'     => 'file_format_version',
+            'title'    => $helper->__('Import Format Version'),
+            'label'    => $helper->__('Import Format Version'),
+            'required' => true,
+            'onchange' => 'editForm.handleImportFormatVersionSelector();',
+            'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Format_Version')->toOptionArray()
+        ));
+
+        // fieldset for customer entity
+        $fieldsets['customer'] = $form->addFieldset('customer_entity_fieldset',
+            array(
+                'legend' => $helper->__('Customer Entity Type'),
+                'style'  => 'display:none'
+            )
+        );
+        $fieldsets['customer']->addField('customer_entity', 'select', array(
+            'name'     => 'customer_entity',
+            'title'    => $helper->__('Customer Entity Type'),
+            'label'    => $helper->__('Customer Entity Type'),
+            'required' => false,
+            'disabled' => true,
+            'values'   => Mage::getModel('Mage_ImportExport_Model_Source_Import_Customer_Entity')->toOptionArray()
+        ));
+
+        // fieldset for file uploading
+        $fieldsets['upload'] = $form->addFieldset('upload_file_fieldset',
+            array(
+                'legend' => $helper->__('File to Import'),
+                'style'  => 'display:none'
+            )
+        );
+        $fieldsets['upload']->addField(Mage_ImportExport_Model_Import::FIELD_NAME_SOURCE_FILE, 'file', array(
             'name'     => Mage_ImportExport_Model_Import::FIELD_NAME_SOURCE_FILE,
             'label'    => $helper->__('Select File to Import'),
             'title'    => $helper->__('Select File to Import'),
diff --git a/app/code/core/Mage/ImportExport/Helper/Data.php b/app/code/core/Mage/ImportExport/Helper/Data.php
index f714b36fd495e..713cbb8d9753a 100644
--- a/app/code/core/Mage/ImportExport/Helper/Data.php
+++ b/app/code/core/Mage/ImportExport/Helper/Data.php
@@ -39,6 +39,22 @@ class Mage_ImportExport_Helper_Data extends Mage_Core_Helper_Data
     const XML_PATH_EXPORT_LOCAL_VALID_PATH = 'general/file/importexport_local_valid_paths';
     const XML_PATH_BUNCH_SIZE = 'general/file/bunch_size';
 
+    /**
+     * Array of allowed customer behaviours for import
+     *
+     * @var array
+     */
+    protected $_allowedCustomerBehaviours = array(
+        Mage_ImportExport_Model_Source_Format_Version::VERSION_1 => array(
+            Mage_ImportExport_Model_Import::BEHAVIOR_APPEND,
+            Mage_ImportExport_Model_Import::BEHAVIOR_REPLACE,
+            Mage_ImportExport_Model_Import::BEHAVIOR_DELETE,
+        ),
+        Mage_ImportExport_Model_Source_Format_Version::VERSION_2 => array(
+            Mage_ImportExport_Model_Import::BEHAVIOR_APPEND,
+        ),
+    );
+
     /**
      * Maximum size of uploaded files.
      *
@@ -69,4 +85,18 @@ public function getBunchSize()
     {
         return (int)Mage::getStoreConfig(self::XML_PATH_BUNCH_SIZE);
     }
+
+    /**
+     * Get array of allowed customer behaviours for defined import version
+     *
+     * @param $importVersion
+     * @return array
+     */
+    public function getAllowedCustomerBehaviours($importVersion)
+    {
+        if (isset($this->_allowedCustomerBehaviours[$importVersion])) {
+            return $this->_allowedCustomerBehaviours[$importVersion];
+        }
+        return array();
+    }
 }
diff --git a/app/code/core/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/Address.php b/app/code/core/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/Address.php
index 7f22fdd4bf4bf..a6eb0c0013081 100644
--- a/app/code/core/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/Address.php
+++ b/app/code/core/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/Address.php
@@ -35,7 +35,7 @@ class Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address
     extends Mage_ImportExport_Model_Export_Entity_V2_Eav_Abstract
 {
     /**#@+
-     * Permanent column names.
+     * Permanent column names
      *
      * Names that begins with underscore is not an attribute.
      * This name convention is for to avoid interference with same attribute name.
@@ -45,6 +45,23 @@ class Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address
     const COL_ADDRESS_ID = '_entity_id';
     /**#@-*/
 
+    /**#@+
+     * Particular columns that contains of customer default addresses
+     */
+    const COLUMN_NAME_DEFAULT_BILLING  = '_address_default_billing_';
+    const COLUMN_NAME_DEFAULT_SHIPPING = '_address_default_shipping_';
+    /**#@-*/
+
+    /**
+     * Default addresses column names to appropriate customer attribute code
+     *
+     * @var array
+     */
+    protected static $_defaultAddressAttributeMapping = array(
+        self::COLUMN_NAME_DEFAULT_BILLING  => 'default_billing',
+        self::COLUMN_NAME_DEFAULT_SHIPPING => 'default_shipping'
+    );
+
     /**
      * Constructor
      *
@@ -57,10 +74,22 @@ public function __construct()
         $this->_permanentAttributes = array(self::COL_WEBSITE, self::COL_EMAIL, self::COL_ADDRESS_ID);
 
         $this->_initWebsites(true);
+        $this->setFileName($this->getEntityTypeCode());
+    }
+
+    /**
+     * Customer default addresses column name to customer attribute mapping array
+     *
+     * @static
+     * @return array
+     */
+    public static function getDefaultAddressAttributeMapping()
+    {
+        return self::$_defaultAddressAttributeMapping;
     }
 
     /**
-     * Export process.
+     * Export process
      *
      * @return string
      */
@@ -87,7 +116,7 @@ public function export()
         $customerCollection = $exportCustomer->filterEntityCollection($customerCollection);
 
         // Get customer default addresses column name to customer attribute mapping array.
-        $defaultAddressMap = Mage_ImportExport_Model_Import_Entity_Customer_Address::getDefaultAddressAttrMapping();
+        $defaultAddressMap = self::getDefaultAddressAttributeMapping();
         $customerCollection->addAttributeToSelect($defaultAddressMap);
 
         $customers = $customerCollection->getItems();
diff --git a/app/code/core/Mage/ImportExport/Model/Import.php b/app/code/core/Mage/ImportExport/Model/Import.php
index bb57c009e75d4..5eabcfaa08c17 100644
--- a/app/code/core/Mage/ImportExport/Model/Import.php
+++ b/app/code/core/Mage/ImportExport/Model/Import.php
@@ -30,16 +30,21 @@
  * @category    Mage
  * @package     Mage_ImportExport
  * @author      Magento Core Team <core@magentocommerce.com>
+ *
+ * @method string getEntitySubtype() getEntitySubtype()
+ * @method string getBehavior() getBehavior()
  */
 class Mage_ImportExport_Model_Import extends Mage_ImportExport_Model_Abstract
 {
-    /**
-     * Key in config with entities.
+    /**#@+
+     * Config keys
      */
-    const CONFIG_KEY_ENTITIES  = 'global/importexport/import_entities';
+    const CONFIG_KEY_ENTITIES          = 'global/importexport/import_entities';
+    const CONFIG_KEY_CUSTOMER_ENTITIES = 'global/importexport/import_customer_entities';
+    /**#@-*/
 
     /**
-     * Import behavior.
+     * Import behavior
      */
     const BEHAVIOR_APPEND  = 'append';
     const BEHAVIOR_REPLACE = 'replace';
@@ -83,36 +88,72 @@ class Mage_ImportExport_Model_Import extends Mage_ImportExport_Model_Abstract
      * Create instance of entity adapter and returns it.
      *
      * @throws Mage_Core_Exception
-     * @return Mage_ImportExport_Model_Import_Entity_Abstract
+     * @return Mage_ImportExport_Model_Import_Entity_Abstract|Mage_ImportExport_Model_Import_Entity_V2_Abstract
      */
     protected function _getEntityAdapter()
     {
         if (!$this->_entityAdapter) {
-            $validTypes = Mage_ImportExport_Model_Config::getModels(self::CONFIG_KEY_ENTITIES);
+            $entityTypes = Mage_ImportExport_Model_Config::getModels(self::CONFIG_KEY_ENTITIES);
+            $customerEntityTypes = Mage_ImportExport_Model_Config::getModels(self::CONFIG_KEY_CUSTOMER_ENTITIES);
+
+            $entitySubtype = $this->getEntitySubtype();
+            if (!empty($entitySubtype)) {
+                if (isset($customerEntityTypes[$entitySubtype])) {
+                    try {
+                        $this->_entityAdapter = Mage::getModel($customerEntityTypes[$entitySubtype]['model']);
+                    } catch (Exception $e) {
+                        Mage::logException($e);
+                        Mage::throwException(
+                            Mage::helper('Mage_ImportExport_Helper_Data')->__('Invalid entity model')
+                        );
+                    }
+                    if (!$this->_entityAdapter instanceof Mage_ImportExport_Model_Import_Entity_V2_Abstract) {
+                        Mage::throwException(
+                            Mage::helper('Mage_ImportExport_Helper_Data')
+                                ->__('Entity adapter object must be an instance of %s',
+                                    'Mage_ImportExport_Model_Import_Entity_V2_Abstract'
+                                )
+                        );
+                    }
 
-            if (isset($validTypes[$this->getEntity()])) {
+                    // check for entity codes integrity
+                    if ($this->getEntitySubtype() != $this->_entityAdapter->getEntityTypeCode()) {
+                        Mage::throwException(
+                            Mage::helper('Mage_ImportExport_Helper_Data')
+                                ->__('Input entity code is not equal to entity adapter code')
+                        );
+                    }
+                } else {
+                    Mage::throwException(Mage::helper('Mage_ImportExport_Helper_Data')->__('Invalid entity'));
+                }
+            } elseif (isset($entityTypes[$this->getEntity()])) {
                 try {
-                    $this->_entityAdapter = Mage::getModel($validTypes[$this->getEntity()]['model']);
+                    $this->_entityAdapter = Mage::getModel($entityTypes[$this->getEntity()]['model']);
                 } catch (Exception $e) {
                     Mage::logException($e);
                     Mage::throwException(
                         Mage::helper('Mage_ImportExport_Helper_Data')->__('Invalid entity model')
                     );
                 }
-                if (!($this->_entityAdapter instanceof Mage_ImportExport_Model_Import_Entity_Abstract)) {
+                if (!$this->_entityAdapter instanceof Mage_ImportExport_Model_Import_Entity_Abstract) {
+                    Mage::throwException(
+                        Mage::helper('Mage_ImportExport_Helper_Data')
+                            ->__('Entity adapter object must be an instance of %s',
+                                'Mage_ImportExport_Model_Import_Entity_Abstract'
+                            )
+                    );
+                }
+
+                // check for entity codes integrity
+                if ($this->getEntity() != $this->_entityAdapter->getEntityTypeCode()) {
                     Mage::throwException(
-                        Mage::helper('Mage_ImportExport_Helper_Data')->__('Entity adapter object must be an instance of Mage_ImportExport_Model_Import_Entity_Abstract')
+                        Mage::helper('Mage_ImportExport_Helper_Data')
+                            ->__('Input entity code is not equal to entity adapter code')
                     );
                 }
             } else {
                 Mage::throwException(Mage::helper('Mage_ImportExport_Helper_Data')->__('Invalid entity'));
             }
-            // check for entity codes integrity
-            if ($this->getEntity() != $this->_entityAdapter->getEntityTypeCode()) {
-                Mage::throwException(
-                    Mage::helper('Mage_ImportExport_Helper_Data')->__('Input entity code is not equal to entity adapter code')
-                );
-            }
             $this->_entityAdapter->setParameters($this->getData());
         }
         return $this->_entityAdapter;
@@ -141,16 +182,20 @@ public function getOperationResultMessages($validationResult)
         if ($this->getProcessedRowsCount()) {
             if (!$validationResult) {
                 if ($this->getProcessedRowsCount() == $this->getInvalidRowsCount()) {
-                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('File is totally invalid. Please fix errors and re-upload file');
+                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                        ->__('File is totally invalid. Please fix errors and re-upload file');
                 } elseif ($this->getErrorsCount() >= $this->getErrorsLimit()) {
-                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('Errors limit (%d) reached. Please fix errors and re-upload file',
-                        $this->getErrorsLimit()
-                    );
+                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                        ->__('Errors limit (%d) reached. Please fix errors and re-upload file',
+                            $this->getErrorsLimit()
+                        );
                 } else {
                     if ($this->isImportAllowed()) {
-                        $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('Please fix errors and re-upload file');
+                        $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                            ->__('Please fix errors and re-upload file');
                     } else {
-                        $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('File is partially valid, but import is not possible');
+                        $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                            ->__('File is partially valid, but import is not possible');
                     }
                 }
                 // errors info
@@ -162,19 +207,22 @@ public function getOperationResultMessages($validationResult)
                 }
             } else {
                 if ($this->isImportAllowed()) {
-                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('Validation finished successfully');
+                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                        ->__('Validation finished successfully');
                 } else {
-                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('File is valid, but import is not possible');
+                    $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                        ->__('File is valid, but import is not possible');
                 }
             }
             $notices = $this->getNotices();
             if (is_array($notices)) {
                 $messages = array_merge($messages, $notices);
             }
-            $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d',
-                $this->getProcessedRowsCount(), $this->getProcessedEntitiesCount(),
-                $this->getInvalidRowsCount(), $this->getErrorsCount()
-            );
+            $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')
+                ->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d',
+                    $this->getProcessedRowsCount(), $this->getProcessedEntitiesCount(),
+                    $this->getInvalidRowsCount(), $this->getErrorsCount()
+                );
         } else {
             $messages[] = Mage::helper('Mage_ImportExport_Helper_Data')->__('File does not contain data.');
         }
@@ -322,19 +370,35 @@ public static function getWorkingDir()
      */
     public function importSource()
     {
+        $entitySubtype = self::getDataSourceModel()->getUniqueColumnData('entity_subtype');
         $this->setData(array(
-            'entity'   => self::getDataSourceModel()->getEntityTypeCode(),
-            'behavior' => self::getDataSourceModel()->getBehavior()
+            'entity'         => self::getDataSourceModel()->getEntityTypeCode(),
+            'behavior'       => self::getDataSourceModel()->getBehavior(),
+            'entity_subtype' => $entitySubtype
         ));
-        $this->addLogComment(Mage::helper('Mage_ImportExport_Helper_Data')->__('Begin import of "%s" with "%s" behavior', $this->getEntity(), $this->getBehavior()));
+
+        $this->addLogComment(
+            Mage::helper('Mage_ImportExport_Helper_Data')
+                ->__('Begin import of "%s" "%s" with "%s" behavior',
+                    $this->getEntity(),
+                    $entitySubtype,
+                    $this->getBehavior()
+                )
+        );
+
         $result = $this->_getEntityAdapter()->importData();
+
         $this->addLogComment(array(
-            Mage::helper('Mage_ImportExport_Helper_Data')->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d',
-                $this->getProcessedRowsCount(), $this->getProcessedEntitiesCount(),
-                $this->getInvalidRowsCount(), $this->getErrorsCount()
-            ),
+            Mage::helper('Mage_ImportExport_Helper_Data')
+                ->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d',
+                    $this->getProcessedRowsCount(),
+                    $this->getProcessedEntitiesCount(),
+                    $this->getInvalidRowsCount(),
+                    $this->getErrorsCount()
+                ),
             Mage::helper('Mage_ImportExport_Helper_Data')->__('Import has been done successfuly.')
         ));
+
         return $result;
     }
 
@@ -355,6 +419,7 @@ public function isImportAllowed()
      */
     public function expandSource()
     {
+        /** @var $writer Mage_ImportExport_Model_Export_Adapter_Csv */
         $writer  = Mage::getModel('Mage_ImportExport_Model_Export_Adapter_Csv', self::getWorkingDir() . "big0.csv");
         $regExps = array('last' => '/(.*?)(\d+)$/', 'middle' => '/(.*?)(\d+)(.*)$/');
         $colReg  = array(
@@ -406,6 +471,7 @@ public function expandSource()
     public function uploadSource()
     {
         $entity    = $this->getEntity();
+        /** @var $uploader Mage_Core_Model_File_Uploader */
         $uploader  = Mage::getModel('Mage_Core_Model_File_Uploader', self::FIELD_NAME_SOURCE_FILE);
         $uploader->skipDbProcessing(true);
         $result    = $uploader->save(self::getWorkingDir());
@@ -420,7 +486,7 @@ public function uploadSource()
 
         $sourceFile .= '.' . $extension;
 
-        if(strtolower($uploadedFile) != strtolower($sourceFile)) {
+        if (strtolower($uploadedFile) != strtolower($sourceFile)) {
             if (file_exists($sourceFile)) {
                 unlink($sourceFile);
             }
@@ -482,4 +548,3 @@ public function invalidateIndex()
         return $this;
     }
 }
-
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php
index 5bf6590da91f8..44c5c96a1aa66 100644
--- a/app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php
@@ -664,32 +664,46 @@ public function setSource(Mage_ImportExport_Model_Import_Adapter_Abstract $sourc
     public function validateData()
     {
         if (!$this->_dataValidated) {
-            // does all permanent columns exists?
-            if (($colsAbsent = array_diff($this->_permanentAttributes, $this->_getSource()->getColNames()))) {
+            /** @var $helper Mage_ImportExport_Helper_Data */
+            $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+
+            // do all permanent columns exist?
+            if ($absentColumns = array_diff($this->_permanentAttributes, $this->getSource()->getColNames())) {
                 Mage::throwException(
-                    Mage::helper('Mage_ImportExport_Helper_Data')->__('Can not find required columns: %s', implode(', ', $colsAbsent))
+                    $helper->__('Can not find required columns: %s', implode(', ', $absentColumns))
                 );
             }
 
-            // initialize validation related attributes
-            $this->_errors = array();
-            $this->_invalidRows = array();
-
             // check attribute columns names validity
-            $invalidColumns = array();
-
-            foreach ($this->_getSource()->getColNames() as $colName) {
-                if (!preg_match('/^[a-z][a-z0-9_]*$/', $colName) && !$this->isAttributeParticular($colName)) {
-                    $invalidColumns[] = $colName;
+            $columnNumber       = 0;
+            $emptyHeaderColumns = array();
+            $invalidColumns     = array();
+            foreach ($this->getSource()->getColNames() as $columnName) {
+                $columnNumber++;
+                if (!$this->isAttributeParticular($columnName)) {
+                    if (trim($columnName) == '') {
+                        $emptyHeaderColumns[] = $columnNumber;
+                    } elseif (!preg_match('/^[a-z][a-z0-9_]*$/', $columnName)) {
+                        $invalidColumns[] = $columnName;
+                    }
                 }
             }
+
+            if ($emptyHeaderColumns) {
+                Mage::throwException(
+                    $helper->__('Columns number: "%s" have empty headers', implode('", "', $emptyHeaderColumns))
+                );
+            }
             if ($invalidColumns) {
                 Mage::throwException(
-                    Mage::helper('Mage_ImportExport_Helper_Data')->__('Column names: "%s" are invalid', implode('", "', $invalidColumns))
+                    $helper->__('Column names: "%s" are invalid', implode('", "', $invalidColumns))
                 );
             }
-            $this->_saveValidatedBunches();
 
+            // initialize validation related attributes
+            $this->_errors = array();
+            $this->_invalidRows = array();
+            $this->_saveValidatedBunches();
             $this->_dataValidated = true;
         }
         return $this;
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Abstract.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Abstract.php
new file mode 100644
index 0000000000000..be3b9e9328db5
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Abstract.php
@@ -0,0 +1,661 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Import entity abstract model
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+abstract class Mage_ImportExport_Model_Import_Entity_V2_Abstract
+{
+    /**#@+
+     * Database constants
+     */
+    const DB_MAX_PACKET_COEFFICIENT = 900000;
+    const DB_MAX_PACKET_DATA        = 1048576;
+    const DB_MAX_VARCHAR_LENGTH     = 256;
+    const DB_MAX_TEXT_LENGTH        = 65536;
+    /**#@-*/
+
+    /**
+     * DB connection
+     *
+     * @var Varien_Db_Adapter_Interface
+     */
+    protected $_connection;
+
+    /**
+     * Has data process validation done?
+     *
+     * @var bool
+     */
+    protected $_dataValidated = false;
+
+    /**
+     * DB data source model
+     *
+     * @var Mage_ImportExport_Model_Resource_Import_Data
+     */
+    protected $_dataSourceModel;
+
+    /**
+     * Error codes with arrays of corresponding row numbers
+     *
+     * @var array
+     */
+    protected $_errors = array();
+
+    /**
+     * Error counter
+     *
+     * @var int
+     */
+    protected $_errorsCount = 0;
+
+    /**
+     * Limit of errors after which pre-processing will exit
+     *
+     * @var int
+     */
+    protected $_errorsLimit = 100;
+
+    /**
+     * Flag to disable import
+     *
+     * @var bool
+     */
+    protected $_importAllowed = true;
+
+    /**
+     * Array of invalid rows numbers
+     *
+     * @var array
+     */
+    protected $_invalidRows = array();
+
+    /**
+     * Validation failure message template definitions
+     *
+     * @var array
+     */
+    protected $_messageTemplates = array();
+
+    /**
+     * Notice messages
+     *
+     * @var array
+     */
+    protected $_notices = array();
+
+    /**
+     * Entity model parameters
+     *
+     * @var array
+     */
+    protected $_parameters = array();
+
+    /**
+     * Column names that holds values with particular meaning
+     *
+     * @var array
+     */
+    protected $_particularAttributes = array();
+
+    /**
+     * Permanent entity columns
+     *
+     * @var array
+     */
+    protected $_permanentAttributes = array();
+
+    /**
+     * Number of entities processed by validation
+     *
+     * @var int
+     */
+    protected $_processedEntitiesCount = 0;
+
+    /**
+     * Number of rows processed by validation
+     *
+     * @var int
+     */
+    protected $_processedRowsCount = 0;
+
+    /**
+     * Rows which will be skipped during import
+     *
+     * [Row number 1] => true,
+     * ...
+     * [Row number N] => true
+     *
+     * @var array
+     */
+    protected $_skippedRows = array();
+
+    /**
+     * Array of numbers of validated rows as keys and boolean TRUE as values
+     *
+     * @var array
+     */
+    protected $_validatedRows = array();
+
+    /**
+     * Source model
+     *
+     * @var Mage_ImportExport_Model_Import_Adapter_Abstract
+     */
+    protected $_source;
+
+    /**
+     * Array of unique attributes
+     *
+     * @var array
+     */
+    protected $_uniqueAttributes = array();
+
+    /**
+     * List of available behaviors
+     *
+     * @var array
+     */
+    protected $_availableBehaviors = array();
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->_dataSourceModel = Mage_ImportExport_Model_Import::getDataSourceModel();
+        /** @var $coreResourceModel Mage_Core_Model_Resource */
+        $coreResourceModel = Mage::getSingleton('Mage_Core_Model_Resource');
+        $this->_connection = $coreResourceModel->getConnection('write');
+
+        $this->_availableBehaviors = array(
+            Mage_ImportExport_Model_Import::BEHAVIOR_APPEND,
+            Mage_ImportExport_Model_Import::BEHAVIOR_REPLACE,
+            Mage_ImportExport_Model_Import::BEHAVIOR_DELETE,
+        );
+    }
+
+    /**
+     * Import data rows
+     *
+     * @abstract
+     * @return boolean
+     */
+    abstract protected function _importData();
+
+    /**
+     * Imported entity type code getter
+     *
+     * @abstract
+     * @return string
+     */
+    abstract public function getEntityTypeCode();
+
+    /**
+     * Imported entity type code getter
+     *
+     * @return string
+     */
+    public function getEntitySubtype()
+    {
+        return !empty($this->_parameters['entity_subtype']) ? $this->_parameters['entity_subtype'] : null;
+    }
+
+    /**
+     * Change row data before saving in DB table
+     *
+     * @param array $rowData
+     * @return array
+     */
+    protected function _prepareRowForDb(array $rowData)
+    {
+        /**
+         * Convert all empty strings to null values, as
+         * a) we don't use empty string in DB
+         * b) empty strings instead of numeric values will product errors in Sql Server
+         */
+        foreach ($rowData as $key => $val) {
+            if ($val === '') {
+                $rowData[$key] = null;
+            }
+        }
+        return $rowData;
+    }
+
+    /**
+     * Validate data rows and save bunches to DB
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    protected function _saveValidatedBunches()
+    {
+        $source            = $this->getSource();
+        $processedDataSize = 0;
+        $bunchRows         = array();
+        $startNewBunch     = false;
+        $nextRowBackup     = array();
+
+        /** @var $resourceHelper Mage_ImportExport_Model_Resource_Helper_Mysql4 */
+        $resourceHelper = Mage::getResourceHelper('Mage_ImportExport');
+        /** @var $dataHelper  Mage_ImportExport_Helper_Data */
+        $dataHelper = Mage::helper('Mage_ImportExport_Helper_Data');
+        $bunchSize = $dataHelper->getBunchSize();
+
+        $source->rewind();
+        $this->_dataSourceModel->cleanBunches();
+
+        while ($source->valid() || $bunchRows) {
+            if ($startNewBunch || !$source->valid()) {
+                $this->_dataSourceModel->saveBunch(
+                    $this->getEntityTypeCode(),
+                    $this->getBehavior(),
+                    $bunchRows,
+                    $this->getEntitySubtype()
+                );
+
+                $bunchRows         = $nextRowBackup;
+                $processedDataSize = strlen(serialize($bunchRows));
+                $startNewBunch     = false;
+                $nextRowBackup     = array();
+            }
+            if ($source->valid()) {
+                // errors limit check
+                if ($this->_errorsCount >= $this->_errorsLimit) {
+                    return $this;
+                }
+                $rowData = $source->current();
+                // add row to bunch for save
+                if ($this->validateRow($rowData, $source->key())) {
+                    $rowData = $this->_prepareRowForDb($rowData);
+                    $rowSize = strlen(Mage::helper('Mage_Core_Helper_Data')->jsonEncode($rowData));
+
+                    $isBunchSizeExceeded = ($bunchSize > 0 && count($bunchRows) >= $bunchSize);
+
+                    if (($processedDataSize + $rowSize) >= $resourceHelper->getMaxDataSize() || $isBunchSizeExceeded) {
+                        $startNewBunch = true;
+                        $nextRowBackup = array($source->key() => $rowData);
+                    } else {
+                        $bunchRows[$source->key()] = $rowData;
+                        $processedDataSize += $rowSize;
+                    }
+                }
+                $this->_processedRowsCount++;
+                $source->next();
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Add error with corresponding current data source row number
+     *
+     * @param string $errorCode Error code or simply column name
+     * @param int $errorRowNum Row number
+     * @param string $columnName OPTIONAL Column name
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    public function addRowError($errorCode, $errorRowNum, $columnName = null)
+    {
+        $this->_errors[$errorCode][] = array($errorRowNum + 1, $columnName); // one added for human readability
+        $this->_invalidRows[$errorRowNum] = true;
+        $this->_errorsCount++;
+
+        return $this;
+    }
+
+    /**
+     * Add message template for specific error code from outside
+     *
+     * @param string $errorCode Error code
+     * @param string $message Message template
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    public function addMessageTemplate($errorCode, $message)
+    {
+        $this->_messageTemplates[$errorCode] = $message;
+
+        return $this;
+    }
+
+    /**
+     * Import behavior getter
+     *
+     * @return string
+     */
+    public function getBehavior()
+    {
+        if (isset($this->_parameters['behavior'])
+            && in_array($this->_parameters['behavior'], $this->_availableBehaviors)
+        ) {
+            return $this->_parameters['behavior'];
+        }
+        return Mage_ImportExport_Model_Import::getDefaultBehavior();
+    }
+
+    /**
+     * Returns error information grouped by error types and translated (if possible)
+     *
+     * @return array
+     */
+    public function getErrorMessages()
+    {
+        $translator = Mage::helper('Mage_ImportExport_Helper_Data');
+        $messages   = array();
+
+        foreach ($this->_errors as $errorCode => $errorRows) {
+            if (isset($this->_messageTemplates[$errorCode])) {
+                $errorCode = $translator->__($this->_messageTemplates[$errorCode]);
+            }
+            foreach ($errorRows as $errorRowData) {
+                $key = $errorRowData[1] ? sprintf($errorCode, $errorRowData[1]) : $errorCode;
+                $messages[$key][] = $errorRowData[0];
+            }
+        }
+        return $messages;
+    }
+
+    /**
+     * Returns error counter value
+     *
+     * @return int
+     */
+    public function getErrorsCount()
+    {
+        return $this->_errorsCount;
+    }
+
+    /**
+     * Returns error limit value
+     *
+     * @return int
+     */
+    public function getErrorsLimit()
+    {
+        return $this->_errorsLimit;
+    }
+
+    /**
+     * Returns invalid rows count
+     *
+     * @return int
+     */
+    public function getInvalidRowsCount()
+    {
+        return count($this->_invalidRows);
+    }
+
+    /**
+     * Returns model notices
+     *
+     * @return array
+     */
+    public function getNotices()
+    {
+        return $this->_notices;
+    }
+
+    /**
+     * Returns number of checked entities
+     *
+     * @return int
+     */
+    public function getProcessedEntitiesCount()
+    {
+        return $this->_processedEntitiesCount;
+    }
+
+    /**
+     * Returns number of checked rows
+     *
+     * @return int
+     */
+    public function getProcessedRowsCount()
+    {
+        return $this->_processedRowsCount;
+    }
+
+    /**
+     * Source object getter
+     *
+     * @throws Exception
+     * @return Mage_ImportExport_Model_Import_Adapter_Abstract
+     */
+    public function getSource()
+    {
+        if (!$this->_source) {
+            Mage::throwException(Mage::helper('Mage_ImportExport_Helper_Data')->__('Source is not set'));
+        }
+        return $this->_source;
+    }
+
+    /**
+     * Import process start
+     *
+     * @return bool Result of operation
+     */
+    public function importData()
+    {
+        return $this->_importData();
+    }
+
+    /**
+     * Is attribute contains particular data (not plain entity attribute)
+     *
+     * @param string $attrCode
+     * @return bool
+     */
+    public function isAttributeParticular($attrCode)
+    {
+        return in_array($attrCode, $this->_particularAttributes);
+    }
+
+    /**
+     * Check one attribute can be overridden in child
+     *
+     * @param string $attributeCode Attribute code
+     * @param array $attributeParams Attribute params
+     * @param array $rowData Row data
+     * @param int $rowNumber
+     * @return boolean
+     */
+    public function isAttributeValid($attributeCode, array $attributeParams, array $rowData, $rowNumber)
+    {
+        /** @var $stringHelper Mage_Core_Helper_String */
+        $stringHelper = Mage::helper('Mage_Core_Helper_String');
+
+        switch ($attributeParams['type']) {
+            case 'varchar':
+                $value = $stringHelper->cleanString($rowData[$attributeCode]);
+                $valid = $stringHelper->strlen($value) < self::DB_MAX_VARCHAR_LENGTH;
+                break;
+            case 'decimal':
+                $value = trim($rowData[$attributeCode]);
+                $valid = ((float)$value == $value) && is_numeric($value);
+                break;
+            case 'select':
+            case 'multiselect':
+                $valid = isset($attributeParams['options'][strtolower($rowData[$attributeCode])]);
+                break;
+            case 'int':
+                $value = trim($rowData[$attributeCode]);
+                $valid = ((int)$value == $value) && is_numeric($value);
+                break;
+            case 'datetime':
+                $value = trim($rowData[$attributeCode]);
+                $valid = strtotime($value) !== false
+                    || preg_match('/^\d{2}.\d{2}.\d{2,4}(?:\s+\d{1,2}.\d{1,2}(?:.\d{1,2})?)?$/', $value);
+                break;
+            case 'text':
+                $value = $stringHelper->cleanString($rowData[$attributeCode]);
+                $valid = $stringHelper->strlen($value) < self::DB_MAX_TEXT_LENGTH;
+                break;
+            default:
+                $valid = true;
+                break;
+        }
+
+        /** @var $dataHelper Mage_ImportExport_Helper_Data */
+        $dataHelper = Mage::helper('Mage_ImportExport_Helper_Data');
+
+        if (!$valid) {
+            $this->addRowError($dataHelper->__("Invalid value for '%s'"), $rowNumber, $attributeCode);
+        } elseif (!empty($attributeParams['is_unique'])) {
+            if (isset($this->_uniqueAttributes[$attributeCode][$rowData[$attributeCode]])) {
+                $this->addRowError($dataHelper->__("Duplicate Unique Attribute for '%s'"), $rowNumber, $attributeCode);
+                return false;
+            }
+            $this->_uniqueAttributes[$attributeCode][$rowData[$attributeCode]] = true;
+        }
+        return (bool) $valid;
+    }
+
+    /**
+     * Check that is all of data valid
+     *
+     * @return bool
+     */
+    public function isDataValid()
+    {
+        $this->validateData();
+        return 0 == $this->_errorsCount;
+    }
+
+    /**
+     * Import possibility getter
+     *
+     * @return bool
+     */
+    public function isImportAllowed()
+    {
+        return $this->_importAllowed;
+    }
+
+    /**
+     * Returns TRUE if row is valid and not in skipped rows array
+     *
+     * @param array $rowData
+     * @param int $rowNumber
+     * @return bool
+     */
+    public function isRowAllowedToImport(array $rowData, $rowNumber)
+    {
+        return $this->validateRow($rowData, $rowNumber) && !isset($this->_skippedRows[$rowNumber]);
+    }
+
+    /**
+     * Validate data row
+     *
+     * @param array $rowData
+     * @param int $rowNumber
+     * @return boolean
+     */
+    abstract public function validateRow(array $rowData, $rowNumber);
+
+    /**
+     * Set data from outside to change behavior
+     *
+     * @param array $parameters
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    public function setParameters(array $parameters)
+    {
+        $this->_parameters = $parameters;
+        return $this;
+    }
+
+    /**
+     * Source model setter
+     *
+     * @param Mage_ImportExport_Model_Import_Adapter_Abstract $source
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    public function setSource(Mage_ImportExport_Model_Import_Adapter_Abstract $source)
+    {
+        $this->_source = $source;
+        $this->_dataValidated = false;
+
+        return $this;
+    }
+
+    /**
+     * Validate data
+     *
+     * @throws Exception
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    public function validateData()
+    {
+        if (!$this->_dataValidated) {
+            /** @var $helper Mage_ImportExport_Helper_Data */
+            $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+
+            // do all permanent columns exist?
+            if ($absentColumns = array_diff($this->_permanentAttributes, $this->getSource()->getColNames())) {
+                Mage::throwException(
+                    $helper->__('Can not find required columns: %s', implode(', ', $absentColumns))
+                );
+            }
+
+            // check attribute columns names validity
+            $columnNumber       = 0;
+            $emptyHeaderColumns = array();
+            $invalidColumns     = array();
+            foreach ($this->getSource()->getColNames() as $columnName) {
+                $columnNumber++;
+                if (!$this->isAttributeParticular($columnName)) {
+                    if (trim($columnName) == '') {
+                        $emptyHeaderColumns[] = $columnNumber;
+                    } elseif (!preg_match('/^[a-z][a-z0-9_]*$/', $columnName)) {
+                        $invalidColumns[] = $columnName;
+                    }
+                }
+            }
+
+            if ($emptyHeaderColumns) {
+                Mage::throwException(
+                    $helper->__('Columns number: "%s" have empty headers', implode('", "', $emptyHeaderColumns))
+                );
+            }
+            if ($invalidColumns) {
+                Mage::throwException(
+                    $helper->__('Column names: "%s" are invalid', implode('", "', $invalidColumns))
+                );
+            }
+
+            // initialize validation related attributes
+            $this->_errors = array();
+            $this->_invalidRows = array();
+            $this->_saveValidatedBunches();
+            $this->_dataValidated = true;
+        }
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Abstract.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Abstract.php
new file mode 100644
index 0000000000000..0b98b3c65338a
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Abstract.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Import EAV entity abstract model
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+abstract class Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+    extends Mage_ImportExport_Model_Import_Entity_V2_Abstract
+{
+    /**
+     * Entity type id
+     *
+     * @var int
+     */
+    protected $_entityTypeId;
+
+    /**
+     * Attributes with index (not label) value
+     *
+     * @var array
+     */
+    protected $_indexValueAttributes = array();
+
+    /**
+     * Website code-to-ID
+     *
+     * @var array
+     */
+    protected $_websiteCodeToId = array();
+
+    /**
+     * All stores code-ID pairs.
+     *
+     * @var array
+     */
+    protected $_storeCodeToId = array();
+
+    /**
+     * Entity attributes parameters
+     *
+     *  [attr_code_1] => array(
+     *      'options' => array(),
+     *      'type' => 'text', 'price', 'textarea', 'select', etc.
+     *      'id' => ..
+     *  ),
+     *  ...
+     *
+     * @var array
+     */
+    protected $_attributes = array();
+
+    /**
+     * Initialize website values
+     *
+     * @param bool $withDefault
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+     */
+    protected function _initWebsites($withDefault = false)
+    {
+        /** @var $website Mage_Core_Model_Website */
+        foreach (Mage::app()->getWebsites($withDefault) as $website) {
+            $this->_websiteCodeToId[$website->getCode()] = $website->getId();
+        }
+        return $this;
+    }
+
+    /**
+     * Initialize stores data
+     *
+     * @param bool $withDefault
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+     */
+    protected function _initStores($withDefault = false)
+    {
+        /** @var $store Mage_Core_Model_Store */
+        foreach (Mage::app()->getStores($withDefault) as $store) {
+            $this->_storeCodeToId[$store->getCode()] = $store->getId();
+        }
+        return $this;
+    }
+
+    /**
+     * Initialize entity attributes
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+     */
+    protected function _initAttributes()
+    {
+        $collection = $this->_getAttributeCollection();
+        /** @var $attribute Mage_Eav_Model_Attribute */
+        foreach ($collection as $attribute) {
+            $this->_attributes[$attribute->getAttributeCode()] = array(
+                'id'          => $attribute->getId(),
+                'code'        => $attribute->getAttributeCode(),
+                'table'       => $attribute->getBackend()->getTable(),
+                'is_required' => $attribute->getIsRequired(),
+                'is_static'   => $attribute->isStatic(),
+                'rules'       => $attribute->getValidateRules() ? unserialize($attribute->getValidateRules()) : null,
+                'type'        => Mage_ImportExport_Model_Import::getAttributeType($attribute),
+                'options'     => $this->getAttributeOptions($attribute)
+            );
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve entity attribute EAV collection
+     *
+     * @abstract
+     * @return Mage_Eav_Model_Resource_Attribute_Collection
+     */
+    abstract protected function _getAttributeCollection();
+
+    /**
+     * Entity type ID getter
+     *
+     * @return int
+     */
+    public function getEntityTypeId()
+    {
+        if ($this->_entityTypeId == null) {
+            /** @var $eavConfig Mage_Eav_Model_Config */
+            $eavConfig = Mage::getSingleton('Mage_Eav_Model_Config');
+            $entityType = $eavConfig->getEntityType($this->getEntityTypeCode());
+            $this->_entityTypeId = $entityType->getEntityTypeId();
+        }
+
+        return $this->_entityTypeId;
+    }
+
+    /**
+     * Returns attributes all values in label-value or value-value pairs form. Labels are lower-cased
+     *
+     * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
+     * @param array $indexAttributes OPTIONAL Additional attribute codes with index values.
+     * @return array
+     */
+    public function getAttributeOptions(Mage_Eav_Model_Entity_Attribute_Abstract $attribute,
+        array $indexAttributes = array()
+    ) {
+        $options = array();
+
+        if ($attribute->usesSource()) {
+            // merge global entity index value attributes
+            $indexAttributes = array_merge($indexAttributes, $this->_indexValueAttributes);
+
+            // should attribute has index (option value) instead of a label?
+            $index = in_array($attribute->getAttributeCode(), $indexAttributes) ? 'value' : 'label';
+
+            // only default (admin) store values used
+            $attribute->setStoreId(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID);
+
+            try {
+                foreach ($attribute->getSource()->getAllOptions(false) as $option) {
+                    $value = is_array($option['value']) ? $option['value'] : array($option);
+                    foreach ($value as $innerOption) {
+                        if (strlen($innerOption['value'])) { // skip ' -- Please Select -- ' option
+                            $options[strtolower($innerOption[$index])] = $innerOption['value'];
+                        }
+                    }
+                }
+            } catch (Exception $e) {
+                // ignore exceptions connected with source models
+            }
+        }
+        return $options;
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer.php
new file mode 100644
index 0000000000000..b1eafbab1900e
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer.php
@@ -0,0 +1,362 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Import entity customer model
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer
+    extends Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract
+{
+    /**#@+
+     * Permanent column names
+     *
+     * Names that begins with underscore is not an attribute. This name convention is for
+     * to avoid interference with same attribute name.
+     */
+    const COLUMN_EMAIL   = 'email';
+    const COLUMN_STORE   = '_store';
+    /**#@-*/
+
+    /**#@+
+     * Error codes
+     */
+    const ERROR_DUPLICATE_EMAIL_SITE = 'duplicateEmailSite';
+    const ERROR_ROW_IS_ORPHAN        = 'rowIsOrphan';
+    const ERROR_INVALID_STORE        = 'invalidStore';
+    const ERROR_EMAIL_SITE_NOT_FOUND = 'emailSiteNotFound';
+    const ERROR_PASSWORD_LENGTH      = 'passwordLength';
+    /**#@-*/
+
+    /**
+     * Minimum password length
+     */
+    const MIN_PASSWORD_LENGTH = 6;
+
+    /**
+     * Default customer group
+     */
+    const DEFAULT_GROUP_ID = 1;
+
+    /**
+     * Customers information from import file
+     *
+     * @var array
+     */
+    protected $_newCustomers = array();
+
+    /**
+     * Array of attribute codes which will be ignored in validation and import procedures.
+     * For example, when entity attribute has own validation and import procedures
+     * or just to deny this attribute processing.
+     *
+     * @var array
+     */
+    protected $_ignoredAttributes = array('website_id', 'store_id');
+
+    /**
+     * Customer entity DB table name.
+     *
+     * @var string
+     */
+    protected $_entityTable;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_particularAttributes[] = self::COLUMN_WEBSITE;
+        $this->_particularAttributes[] = self::COLUMN_STORE;
+        $this->_permanentAttributes[]  = self::COLUMN_EMAIL;
+        $this->_permanentAttributes[]  = self::COLUMN_WEBSITE;
+        $this->_indexValueAttributes[] = 'group_id';
+
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+
+        $this->addMessageTemplate(self::ERROR_DUPLICATE_EMAIL_SITE, $helper->__('E-mail is duplicated in import file'));
+        $this->addMessageTemplate(self::ERROR_ROW_IS_ORPHAN,
+            $helper->__('Orphan rows that will be skipped due default row errors')
+        );
+        $this->addMessageTemplate(self::ERROR_INVALID_STORE,
+            $helper->__('Invalid value in Store column (store does not exists?)')
+        );
+        $this->addMessageTemplate(self::ERROR_EMAIL_SITE_NOT_FOUND,
+            $helper->__('E-mail and website combination is not found')
+        );
+        $this->addMessageTemplate(self::ERROR_PASSWORD_LENGTH, $helper->__('Invalid password length'));
+
+        $this->_initStores(true)
+            ->_initAttributes();
+
+        /** @var $customerResource Mage_Customer_Model_Resource_Customer */
+        $customerResource = Mage::getModel('Mage_Customer_Model_Customer')->getResource();
+        $this->_entityTable = $customerResource->getEntityTable();
+    }
+
+    /**
+     * Gather and save information about customer entities.
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_Customer
+     */
+    protected function _saveCustomers()
+    {
+        /** @var $resource Mage_Customer_Model_Customer */
+        $resource = Mage::getModel('Mage_Customer_Model_Customer');
+
+        $passwordAttribute = $resource->getAttribute('password_hash');
+        $passwordAttributeId = $passwordAttribute->getId();
+        $passwordStorageTable = $passwordAttribute->getBackend()->getTable();
+
+        $dateTimeFormat = Varien_Date::convertZendToStrftime(Varien_Date::DATETIME_INTERNAL_FORMAT, true, true);
+
+        $nextEntityId = Mage::getResourceHelper('Mage_ImportExport')->getNextAutoincrement($this->_entityTable);
+
+        while ($bunch = $this->_dataSourceModel->getNextBunch()) {
+            $entitiesToCreate = array();
+            $entitiesToUpdate = array();
+            $attributes   = array();
+
+            foreach ($bunch as $rowNumber => $rowData) {
+                if (!$this->validateRow($rowData, $rowNumber)) {
+                    continue;
+                }
+
+                // entity table data
+                $entityRow = array(
+                    'group_id'   => empty($rowData['group_id'])
+                        ? self::DEFAULT_GROUP_ID : $rowData['group_id'],
+
+                    'store_id'   => empty($rowData[self::COLUMN_STORE])
+                        ? 0 : $this->_storeCodeToId[$rowData[self::COLUMN_STORE]],
+
+                    'created_at' => empty($rowData['created_at'])
+                        ? now() : gmstrftime($dateTimeFormat, strtotime($rowData['created_at'])),
+
+                    'updated_at' => now()
+                );
+
+                $emailInLowercase = strtolower($rowData[self::COLUMN_EMAIL]);
+                if ($entityId = $this->_getCustomerId($emailInLowercase, $rowData[self::COLUMN_WEBSITE])) { // edit
+                    $entityRow['entity_id'] = $entityId;
+                    $entitiesToUpdate[] = $entityRow;
+                } else { // create
+                    $entityId = $nextEntityId++;
+                    $entityRow['entity_id'] = $entityId;
+                    $entityRow['entity_type_id'] = $this->getEntityTypeId();
+                    $entityRow['attribute_set_id'] = 0;
+                    $entityRow['website_id'] = $this->_websiteCodeToId[$rowData[self::COLUMN_WEBSITE]];
+                    $entityRow['email'] = $emailInLowercase;
+                    $entityRow['is_active'] = 1;
+                    $entitiesToCreate[] = $entityRow;
+
+                    $this->_newCustomers[$emailInLowercase][$rowData[self::COLUMN_WEBSITE]] = $entityId;
+                }
+
+                // attribute values
+                foreach (array_intersect_key($rowData, $this->_attributes) as $attributeCode => $value) {
+                    if (!$this->_attributes[$attributeCode]['is_static'] && strlen($value)) {
+                        /** @var $attribute Mage_Customer_Model_Attribute */
+                        $attribute = $resource->getAttribute($attributeCode);
+                        $backendModel = $attribute->getBackendModel();
+                        $attributeParameters = $this->_attributes[$attributeCode];
+
+                        if ('select' == $attributeParameters['type']) {
+                            $value = $attributeParameters['options'][strtolower($value)];
+                        } elseif ('datetime' == $attributeParameters['type']) {
+                            $value = gmstrftime($dateTimeFormat, strtotime($value));
+                        } elseif ($backendModel) {
+                            $attribute->getBackend()->beforeSave($resource->setData($attributeCode, $value));
+                            $value = $resource->getData($attributeCode);
+                        }
+                        $attributes[$attribute->getBackend()->getTable()][$entityId][$attributeParameters['id']]
+                            = $value;
+
+                        // restore 'backend_model' to avoid default setting
+                        $attribute->setBackendModel($backendModel);
+                    }
+                }
+
+                // password change/set
+                if (isset($rowData['password']) && strlen($rowData['password'])) {
+                    $attributes[$passwordStorageTable][$entityId][$passwordAttributeId]
+                        = $resource->hashPassword($rowData['password']);
+                }
+            }
+
+            $this->_saveCustomerEntity($entitiesToCreate, $entitiesToUpdate)
+                ->_saveCustomerAttributes($attributes);
+        }
+        return $this;
+    }
+
+    /**
+     * Update and insert data in entity table.
+     *
+     * @param array $entitiesToCreate Rows for insert
+     * @param array $entitiesToUpdate Rows for update
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer
+     */
+    protected function _saveCustomerEntity(array $entitiesToCreate, array $entitiesToUpdate)
+    {
+        if ($entitiesToCreate) {
+            $this->_connection->insertMultiple($this->_entityTable, $entitiesToCreate);
+        }
+
+        if ($entitiesToUpdate) {
+            $this->_connection->insertOnDuplicate(
+                $this->_entityTable,
+                $entitiesToUpdate,
+                array('group_id', 'store_id', 'updated_at', 'created_at')
+            );
+        }
+
+        return $this;
+    }
+
+    /**
+     * Save customer attributes.
+     *
+     * @param array $attributesData
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer
+     */
+    protected function _saveCustomerAttributes(array $attributesData)
+    {
+        foreach ($attributesData as $tableName => $data) {
+            $tableData = array();
+
+            foreach ($data as $customerId => $attrData) {
+                foreach ($attrData as $attributeId => $value) {
+                    $tableData[] = array(
+                        'entity_id'      => $customerId,
+                        'entity_type_id' => $this->getEntityTypeId(),
+                        'attribute_id'   => $attributeId,
+                        'value'          => $value
+                    );
+                }
+            }
+            $this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
+        }
+        return $this;
+    }
+
+    /**
+     * Import data rows
+     *
+     * @return boolean
+     */
+    protected function _importData()
+    {
+        $this->_saveCustomers();
+
+        return true;
+    }
+
+    /**
+     * EAV entity type code getter
+     *
+     * @abstract
+     * @return string
+     */
+    public function getEntityTypeCode()
+    {
+        return $this->_getAttributeCollection()->getEntityTypeCode();
+    }
+
+    /**
+     * Retrieve customer attribute EAV collection
+     *
+     * @return Mage_Customer_Model_Resource_Attribute_Collection
+     */
+    protected function _getAttributeCollection()
+    {
+        /** @var $collection Mage_Customer_Model_Resource_Attribute_Collection */
+        $collection = Mage::getResourceModel('Mage_Customer_Model_Resource_Attribute_Collection');
+        $collection->addSystemHiddenFilterWithPasswordHash();
+        return $collection;
+    }
+
+    /**
+     * Validate data row
+     *
+     * @param array $rowData
+     * @param int $rowNumber
+     * @return boolean
+     */
+    public function validateRow(array $rowData, $rowNumber)
+    {
+        if (isset($this->_validatedRows[$rowNumber])) { // check that row is already validated
+            return !isset($this->_invalidRows[$rowNumber]);
+        }
+        $this->_validatedRows[$rowNumber] = true;
+
+        $this->_processedEntitiesCount++;
+        $email   = strtolower($rowData[self::COLUMN_EMAIL]);
+        $website = $rowData[self::COLUMN_WEBSITE];
+
+        if (!Zend_Validate::is($email, 'EmailAddress')) {
+            $this->addRowError(self::ERROR_INVALID_EMAIL, $rowNumber);
+        } elseif (!isset($this->_websiteCodeToId[$website])) {
+            $this->addRowError(self::ERROR_INVALID_WEBSITE, $rowNumber);
+        } else {
+            if (isset($this->_newCustomers[strtolower($rowData[self::COLUMN_EMAIL])][$website])) {
+                $this->addRowError(self::ERROR_DUPLICATE_EMAIL_SITE, $rowNumber);
+            }
+            $this->_newCustomers[$email][$website] = false;
+
+            if (!empty($rowData[self::COLUMN_STORE]) && !isset($this->_storeCodeToId[$rowData[self::COLUMN_STORE]])) {
+                $this->addRowError(self::ERROR_INVALID_STORE, $rowNumber);
+            }
+            // check password
+            /** @var $stringHelper Mage_Core_Helper_String */
+            $stringHelper = Mage::helper('Mage_Core_Helper_String');
+            if (isset($rowData['password']) && strlen($rowData['password'])
+                && $stringHelper->strlen($rowData['password']) < self::MIN_PASSWORD_LENGTH
+            ) {
+                $this->addRowError(self::ERROR_PASSWORD_LENGTH, $rowNumber);
+            }
+            // check simple attributes
+            foreach ($this->_attributes as $attributeCode => $attributeParams) {
+                if (in_array($attributeCode, $this->_ignoredAttributes)) {
+                    continue;
+                }
+                if (isset($rowData[$attributeCode]) && strlen($rowData[$attributeCode])) {
+                    $this->isAttributeValid($attributeCode, $attributeParams, $rowData, $rowNumber);
+                } elseif ($attributeParams['is_required'] && !$this->_getCustomerId($email, $website)) {
+                    $this->addRowError(self::ERROR_VALUE_IS_REQUIRED, $rowNumber, $attributeCode);
+                }
+            }
+        }
+
+        return !isset($this->_invalidRows[$rowNumber]);
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Abstract.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Abstract.php
new file mode 100644
index 0000000000000..811f233b82144
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Abstract.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Import entity abstract customer model
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+abstract class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract
+    extends Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+{
+    /**#@+
+     * Permanent column names
+     *
+     * Names that begins with underscore is not an attribute. This name convention is for
+     * to avoid interference with same attribute name.
+     */
+    const COLUMN_WEBSITE = '_website';
+    /**#@-*/
+
+    /**#@+
+     * Error codes
+     */
+    const ERROR_WEBSITE_IS_EMPTY   = 'websiteIsEmpty';
+    const ERROR_EMAIL_IS_EMPTY     = 'emailIsEmpty';
+    const ERROR_INVALID_WEBSITE    = 'invalidWebsite';
+    const ERROR_INVALID_EMAIL      = 'invalidEmail';
+    const ERROR_VALUE_IS_REQUIRED  = 'valueIsRequired';
+    const ERROR_CUSTOMER_NOT_FOUND = 'customerNotFound';
+    /**#@-*/
+
+    /**
+     * Existing customers information. In form of:
+     *
+     * [customer e-mail] => array(
+     *    [website id 1] => customer_id 1,
+     *    [website id 2] => customer_id 2,
+     *           ...       =>     ...      ,
+     *    [website id n] => customer_id n,
+     * )
+     *
+     * @var array
+     */
+    protected $_customers = array();
+
+    /**
+     * Array of attribute codes which will be ignored in validation and import procedures.
+     * For example, when entity attribute has own validation and import procedures
+     * or just to deny this attribute processing.
+     *
+     * @var array
+     */
+    protected $_ignoredAttributes = array('website_id', 'store_id', 'default_billing', 'default_shipping');
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+
+        $this->addMessageTemplate(self::ERROR_WEBSITE_IS_EMPTY, $helper->__('Website is not specified'));
+        $this->addMessageTemplate(self::ERROR_EMAIL_IS_EMPTY, $helper->__('E-mail is not specified'));
+        $this->addMessageTemplate(self::ERROR_INVALID_WEBSITE,
+            $helper->__('Invalid value in Website column (website does not exists?)')
+        );
+        $this->addMessageTemplate(self::ERROR_INVALID_EMAIL, $helper->__('E-mail is invalid'));
+        $this->addMessageTemplate(self::ERROR_VALUE_IS_REQUIRED,
+            $helper->__("Required attribute '%s' has an empty value")
+        );
+        $this->addMessageTemplate(self::ERROR_CUSTOMER_NOT_FOUND,
+            $helper->__("Customer with such email and website code doesn't exist")
+        );
+
+        $this->_initCustomers()
+            ->_initWebsites(true);
+    }
+
+    /**
+     * Initialize existent customers data
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract
+     */
+    protected function _initCustomers()
+    {
+        $collection = $this->_getCustomerCollection();
+        /** @var $customer Mage_Customer_Model_Customer */
+        foreach ($collection->getItems() as $customer) {
+            $email = strtolower($customer->getEmail());
+            if (!isset($this->_customers[$email])) {
+                $this->_customers[$email] = array();
+            }
+            $this->_customers[$email][$customer->getWebsiteId()] = $customer->getId();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get customer collection
+     *
+     * @return Mage_Customer_Model_Resource_Customer_Collection
+     */
+    protected function _getCustomerCollection()
+    {
+        /** @var $collection Mage_Customer_Model_Resource_Customer_Collection */
+        $collection = Mage::getResourceModel('Mage_Customer_Model_Resource_Customer_Collection');
+        return $collection;
+    }
+
+    /**
+     * Get customer id if customer is present in database
+     *
+     * @param string $email
+     * @param string $websiteCode
+     * @return bool|int
+     */
+    protected function _getCustomerId($email, $websiteCode)
+    {
+        $email = strtolower(trim($email));
+        if (isset($this->_websiteCodeToId[$websiteCode])) {
+            $websiteId = $this->_websiteCodeToId[$websiteCode];
+            if (isset($this->_customers[$email][$websiteId])) {
+                return $this->_customers[$email][$websiteId];
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Address.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Address.php
new file mode 100644
index 0000000000000..948d42e044a12
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/Address.php
@@ -0,0 +1,504 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Import entity customer address model
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+    extends Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract
+{
+    /**#@+
+     * Permanent column names
+     *
+     * Names that begins with underscore is not an attribute.
+     * This name convention is for to avoid interference with same attribute name.
+     */
+    const COLUMN_EMAIL      = '_email';
+    const COLUMN_ADDRESS_ID = '_entity_id';
+    /**#@-*/
+
+    /**#@+
+     * Required column names
+     */
+    const COLUMN_REGION     = 'region';
+    const COLUMN_COUNTRY_ID = 'country_id';
+    /**#@-*/
+
+    /**#@+
+     * Particular columns that contains of customer default addresses
+     */
+    const COLUMN_DEFAULT_BILLING  = '_address_default_billing_';
+    const COLUMN_DEFAULT_SHIPPING = '_address_default_shipping_';
+    /**#@-*/
+
+    /**#@+
+     * Error codes
+     */
+    const ERROR_ADDRESS_ID_IS_EMPTY = 'addressIdIsEmpty';
+    const ERROR_INVALID_REGION      = 'invalidRegion';
+    /**#@-*/
+
+    /**
+     * Default addresses column names to appropriate customer attribute code
+     *
+     * @var array
+     */
+    protected static $_defaultAddressAttributeMapping = array(
+        self::COLUMN_DEFAULT_BILLING  => 'default_billing',
+        self::COLUMN_DEFAULT_SHIPPING => 'default_shipping'
+    );
+
+    /**
+     * Permanent entity columns
+     *
+     * @var array
+     */
+    protected $_permanentAttributes = array(self::COLUMN_WEBSITE, self::COLUMN_EMAIL, self::COLUMN_ADDRESS_ID);
+
+    /**
+     * Existing addresses
+     *
+     * [customer ID] => array(
+     *     address ID 1,
+     *     address ID 2,
+     *     ...
+     *     address ID N
+     * )
+     *
+     * @var array
+     */
+    protected $_addresses = array();
+
+    /**
+     * Attributes with index (not label) value
+     *
+     * @var array
+     */
+    protected $_indexValueAttributes = array(self::COLUMN_COUNTRY_ID);
+
+    /**
+     * Customer entity DB table name
+     *
+     * @var string
+     */
+    protected $_entityTable;
+
+    /**
+     * Countries and regions
+     *
+     * array(
+     *   [country_id_lowercased_1] => array(
+     *     [region_code_lowercased_1]         => region_id_1,
+     *     [region_default_name_lowercased_1] => region_id_1,
+     *     ...,
+     *     [region_code_lowercased_n]         => region_id_n,
+     *     [region_default_name_lowercased_n] => region_id_n
+     *   ),
+     *   ...
+     * )
+     *
+     * @var array
+     */
+    protected $_countryRegions = array();
+
+    /**
+     * Region ID to region default name pairs
+     *
+     * @var array
+     */
+    protected $_regions = array();
+
+    /**
+     * Column names that holds values with particular meaning
+     *
+     * @var array
+     */
+    protected $_particularAttributes = array(
+        self::COLUMN_WEBSITE,
+        self::COLUMN_EMAIL,
+        self::COLUMN_ADDRESS_ID,
+        self::COLUMN_DEFAULT_BILLING,
+        self::COLUMN_DEFAULT_SHIPPING
+    );
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_entityTable = Mage::getModel('Mage_Customer_Model_Address')->getResource()->getEntityTable();
+
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+        $this->addMessageTemplate(self::ERROR_ADDRESS_ID_IS_EMPTY,
+            $helper->__('Customer address id column is not specified')
+        );
+        $this->addMessageTemplate(self::ERROR_INVALID_REGION, $helper->__('Region is invalid'));
+
+        $this->_initAttributes();
+        $this->_initAddresses()
+            ->_initCountryRegions();
+    }
+
+    /**
+     * Initialize existent addresses data
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected function _initAddresses()
+    {
+        /** @var $address Mage_Customer_Model_Address */
+        foreach (Mage::getResourceModel('Mage_Customer_Model_Resource_Address_Collection') as $address) {
+            $customerId = $address->getParentId();
+            if (!isset($this->_addresses[$customerId])) {
+                $this->_addresses[$customerId] = array();
+            }
+            $addressId = $address->getId();
+            if (!in_array($addressId, $this->_addresses[$customerId])) {
+                $this->_addresses[$customerId][] = $addressId;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get region collection
+     *
+     * @return Mage_Customer_Model_Resource_Customer_Collection
+     */
+    protected function _getRegionCollection()
+    {
+        /** @var $collection Mage_Directory_Model_Resource_Region_Collection */
+        $collection = Mage::getResourceModel('Mage_Directory_Model_Resource_Region_Collection');
+        return $collection;
+    }
+
+    /**
+     * Initialize country regions hash for clever recognition
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected function _initCountryRegions()
+    {
+        $collection = $this->_getRegionCollection();
+        /** @var $region Mage_Directory_Model_Region */
+        foreach ($collection->getItems() as $region) {
+            $countryNormalized = strtolower($region->getCountryId());
+            $regionCode = strtolower($region->getCode());
+            $regionName = strtolower($region->getDefaultName());
+            $this->_countryRegions[$countryNormalized][$regionCode] = $region->getId();
+            $this->_countryRegions[$countryNormalized][$regionName] = $region->getId();
+            $this->_regions[$region->getId()] = $region->getDefaultName();
+        }
+        return $this;
+    }
+
+    /**
+     * Import data rows
+     *
+     * @abstract
+     * @return boolean
+     */
+    protected function _importData()
+    {
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer       = Mage::getModel('Mage_Customer_Model_Customer');
+        $dateTimeFormat = Varien_Date::convertZendToStrftime(Varien_Date::DATETIME_INTERNAL_FORMAT, true, true);
+        $addressModel   = Mage::getModel('Mage_Customer_Model_Address');
+        $table          = $addressModel->getResource()->getEntityTable();
+        $nextEntityId   = Mage::getResourceHelper('Mage_ImportExport')->getNextAutoincrement($table);
+
+        /** @var $regionConfig Mage_Eav_Model_Config */
+        $regionConfig        = Mage::getSingleton('Mage_Eav_Model_Config');
+        /** @var $regionIdAttribute Mage_Customer_Model_Attribute */
+        $regionIdAttribute   = $regionConfig->getAttribute($this->getEntityTypeCode(), 'region_id');
+        $regionIdTable       = $regionIdAttribute->getBackend()->getTable();
+        $regionIdAttributeId = $regionIdAttribute->getId();
+
+        while ($bunch = $this->_dataSourceModel->getNextBunch()) {
+            $entityRows = array();
+            $attributes = array();
+            $defaults   = array(); // customer default addresses (billing/shipping) data
+
+            foreach ($bunch as $rowNumber => $rowData) {
+                // check row data
+                if (!$this->validateRow($rowData, $rowNumber)) {
+                    continue;
+                }
+
+                $email = strtolower($rowData[self::COLUMN_EMAIL]);
+                $websiteId = $this->_websiteCodeToId[$rowData[self::COLUMN_WEBSITE]];
+                $customerId = $this->_customers[$email][$websiteId];
+
+                // get address attributes
+                $addressAttributes = array();
+                foreach ($this->_attributes as $attributeAlias => $attributeParams) {
+                    if (isset($rowData[$attributeAlias]) && strlen($rowData[$attributeAlias])) {
+                        if ('select' == $attributeParams['type']) {
+                            $value = $attributeParams['options'][strtolower($rowData[$attributeAlias])];
+                        } elseif ('datetime' == $attributeParams['type']) {
+                            $value = gmstrftime($dateTimeFormat, strtotime($rowData[$attributeAlias]));
+                        } else {
+                            $value = $rowData[$attributeAlias];
+                        }
+                        $addressAttributes[$attributeParams['id']] = $value;
+                    }
+                }
+
+                // get address id
+                if (isset($this->_addresses[$customerId])
+                    && in_array($rowData[self::COLUMN_ADDRESS_ID], $this->_addresses[$customerId])
+                ) {
+                    $addressId = $rowData[self::COLUMN_ADDRESS_ID];
+                } else {
+                    $addressId = $nextEntityId++;
+                }
+
+                // entity table data
+                $entityRows[] = array(
+                    'entity_id'      => $addressId,
+                    'entity_type_id' => $this->getEntityTypeId(),
+                    'parent_id'      => $customerId,
+                    'created_at'     => now(),
+                    'updated_at'     => now()
+                );
+
+                // attribute values
+                foreach ($this->_attributes as $attributeParams) {
+                    if (isset($addressAttributes[$attributeParams['id']])) {
+                        $attributes[$attributeParams['table']][$addressId][$attributeParams['id']]
+                            = $addressAttributes[$attributeParams['id']];
+                    }
+                }
+
+                // customer default addresses
+                foreach (self::getDefaultAddressAttributeMapping() as $columnName => $attributeCode) {
+                    if (!empty($rowData[$columnName])) {
+                        /** @var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
+                        $attribute = $customer->getAttribute($attributeCode);
+                        $defaults[$attribute->getBackend()->getTable()][$customerId][$attribute->getId()] = $addressId;
+                    }
+                }
+
+                // let's try to find region ID
+                if (!empty($rowData[self::COLUMN_REGION])) {
+                    $countryNormalized = strtolower($rowData[self::COLUMN_COUNTRY_ID]);
+                    $regionNormalized  = strtolower($rowData[self::COLUMN_REGION]);
+
+                    if (isset($this->_countryRegions[$countryNormalized][$regionNormalized])) {
+                        $regionId = $this->_countryRegions[$countryNormalized][$regionNormalized];
+                        $attributes[$regionIdTable][$addressId][$regionIdAttributeId] = $regionId;
+                        $tableName = $this->_attributes[self::COLUMN_REGION]['table'];
+                        $regionColumnNameId = $this->_attributes[self::COLUMN_REGION]['id'];
+                        $attributes[$tableName][$addressId][$regionColumnNameId] = $this->_regions[$regionId];
+                    }
+                }
+            }
+
+            $this->_saveAddressEntities($entityRows)
+                ->_saveAddressAttributes($attributes)
+                ->_saveCustomerDefaults($defaults);
+        }
+        return true;
+    }
+
+    /**
+     * Update and insert data in entity table
+     *
+     * @param array $entityRows Rows for insert
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected function _saveAddressEntities(array $entityRows)
+    {
+        if ($entityRows) {
+            $this->_connection->insertOnDuplicate($this->_entityTable, $entityRows, array('updated_at'));
+        }
+        return $this;
+    }
+
+    /**
+     * Save customer address attributes
+     *
+     * @param array $attributesData
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected function _saveAddressAttributes(array $attributesData)
+    {
+        foreach ($attributesData as $tableName => $data) {
+            $tableData = array();
+            foreach ($data as $addressId => $attributeData) {
+                foreach ($attributeData as $attributeId => $value) {
+                    $tableData[] = array(
+                        'entity_id'      => $addressId,
+                        'entity_type_id' => $this->getEntityTypeId(),
+                        'attribute_id'   => $attributeId,
+                        'value'          => $value
+                    );
+                }
+            }
+            $this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
+        }
+        return $this;
+    }
+
+    /**
+     * Save customer default addresses
+     *
+     * @param array $defaults
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected function _saveCustomerDefaults(array $defaults)
+    {
+        /** @var $entity Mage_Customer_Model_Customer */
+        $entity = Mage::getModel('Mage_Customer_Model_Customer');
+        $entityTypeId = $entity->getEntityTypeId();
+
+        foreach ($defaults as $tableName => $data) {
+            $tableData = array();
+            foreach ($data as $customerId => $attributeData) {
+                foreach ($attributeData as $attributeId => $value) {
+                    $tableData[] = array(
+                        'entity_id'      => $customerId,
+                        'entity_type_id' => $entityTypeId,
+                        'attribute_id'   => $attributeId,
+                        'value'          => $value
+                    );
+                }
+            }
+            $this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
+        }
+        return $this;
+    }
+
+    /**
+     * EAV entity type code getter
+     *
+     * @abstract
+     * @return string
+     */
+    public function getEntityTypeCode()
+    {
+        return 'customer_address';
+    }
+
+    /**
+     * Customer default addresses column name to customer attribute mapping array
+     *
+     * @static
+     * @return array
+     */
+    public static function getDefaultAddressAttributeMapping()
+    {
+        return self::$_defaultAddressAttributeMapping;
+    }
+
+    /**
+     * Validate data row
+     *
+     * @param array $rowData
+     * @param int $rowNumber
+     * @return boolean
+     */
+    public function validateRow(array $rowData, $rowNumber)
+    {
+        if (isset($this->_validatedRows[$rowNumber])) { // check that row is already validated
+            return !isset($this->_invalidRows[$rowNumber]);
+        }
+        $this->_validatedRows[$rowNumber] = true;
+        $this->_processedEntitiesCount++;
+
+        if (empty($rowData[self::COLUMN_WEBSITE])) {
+            $this->addRowError(self::ERROR_WEBSITE_IS_EMPTY, $rowNumber, self::COLUMN_WEBSITE);
+        } elseif (empty($rowData[self::COLUMN_EMAIL])) {
+            $this->addRowError(self::ERROR_EMAIL_IS_EMPTY, $rowNumber, self::COLUMN_EMAIL);
+        } else {
+            $email   = strtolower($rowData[self::COLUMN_EMAIL]);
+            $website = $rowData[self::COLUMN_WEBSITE];
+            $addressId  = $rowData[self::COLUMN_ADDRESS_ID];
+
+            if (!Zend_Validate::is($email, 'EmailAddress')) {
+                $this->addRowError(self::ERROR_INVALID_EMAIL, $rowNumber, self::COLUMN_EMAIL);
+            } elseif (!isset($this->_websiteCodeToId[$website])) {
+                $this->addRowError(self::ERROR_INVALID_WEBSITE, $rowNumber, self::COLUMN_WEBSITE);
+            } elseif (!$this->_getCustomerId($email, $website)) {
+                $this->addRowError(self::ERROR_CUSTOMER_NOT_FOUND, $rowNumber);
+            } else {
+                $websiteId  = $this->_websiteCodeToId[$rowData[self::COLUMN_WEBSITE]];
+                $customerId = $this->_customers[$email][$websiteId];
+
+                // check simple attributes
+                foreach ($this->_attributes as $attributeCode => $attributeParams) {
+                    if (in_array($attributeCode, $this->_ignoredAttributes)) {
+                        continue;
+                    }
+                    if (isset($rowData[$attributeCode]) && strlen($rowData[$attributeCode])) {
+                        $this->isAttributeValid($attributeCode, $attributeParams, $rowData, $rowNumber);
+                    } elseif ($attributeParams['is_required'] && (!isset($this->_addresses[$customerId])
+                        || !in_array($addressId, $this->_addresses[$customerId]))
+                    ) {
+                        $this->addRowError(self::ERROR_VALUE_IS_REQUIRED, $rowNumber, $attributeCode);
+                    }
+                }
+
+                if (isset($rowData[self::COLUMN_COUNTRY_ID]) && isset($rowData[self::COLUMN_REGION])) {
+                    $countryRegions = isset($this->_countryRegions[strtolower($rowData[self::COLUMN_COUNTRY_ID])])
+                        ? $this->_countryRegions[strtolower($rowData[self::COLUMN_COUNTRY_ID])]
+                        : array();
+
+                    if (!empty($rowData[self::COLUMN_REGION])
+                        && !empty($countryRegions)
+                        && !isset($countryRegions[strtolower($rowData[self::COLUMN_REGION])])
+                    ) {
+                        $this->addRowError(self::ERROR_INVALID_REGION, $rowNumber, self::COLUMN_REGION);
+                    }
+                }
+            }
+        }
+
+        return !isset($this->_invalidRows[$rowNumber]);
+    }
+
+    /**
+     * Retrieve entity attribute EAV collection
+     *
+     * @return Mage_Eav_Model_Resource_Attribute_Collection
+     */
+    protected function _getAttributeCollection()
+    {
+        /** @var $addressCollection Mage_Customer_Model_Resource_Address_Attribute_Collection */
+        $addressCollection = Mage::getResourceModel('Mage_Customer_Model_Resource_Address_Attribute_Collection');
+        $addressCollection->addSystemHiddenFilter()
+            ->addExcludeHiddenFrontendFilter();
+        return $addressCollection;
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Resource/Import/Data.php b/app/code/core/Mage/ImportExport/Model/Resource/Import/Data.php
index 721d8dda9f3fd..5decb5c4a6a8e 100644
--- a/app/code/core/Mage/ImportExport/Model/Resource/Import/Data.php
+++ b/app/code/core/Mage/ImportExport/Model/Resource/Import/Data.php
@@ -86,39 +86,45 @@ public function cleanBunches()
     /**
      * Return behavior from import data table.
      *
-     * @throws Exception
      * @return string
      */
     public function getBehavior()
     {
-        $adapter = $this->_getReadAdapter();
-        $behaviors = array_unique($adapter->fetchCol(
-            $adapter->select()
-                ->from($this->getMainTable(), array('behavior'))
-        ));
-        if (count($behaviors) != 1) {
-            Mage::throwException(Mage::helper('Mage_ImportExport_Helper_Data')->__('Error in data structure: behaviors are mixed'));
-        }
-        return $behaviors[0];
+        return $this->getUniqueColumnData('behavior');
     }
 
     /**
      * Return entity type code from import data table.
      *
-     * @throws Exception
      * @return string
      */
     public function getEntityTypeCode()
+    {
+        return $this->getUniqueColumnData('entity');
+    }
+
+    /**
+     * Return request data from import data table
+     *
+     * @throws Mage_Core_Exception
+     *
+     * @param string $code parameter name
+     * @return string
+     */
+    public function getUniqueColumnData($code)
     {
         $adapter = $this->_getReadAdapter();
-        $entityCodes = array_unique($adapter->fetchCol(
+        $values = array_unique($adapter->fetchCol(
             $adapter->select()
-                ->from($this->getMainTable(), array('entity'))
+                ->from($this->getMainTable(), array($code))
         ));
-        if (count($entityCodes) != 1) {
-            Mage::throwException(Mage::helper('Mage_ImportExport_Helper_Data')->__('Error in data structure: entity codes are mixed'));
+
+        if (count($values) != 1) {
+            Mage::throwException(
+                Mage::helper('Mage_ImportExport_Helper_Data')->__('Error in data structure: %s values are mixed', $code)
+            );
         }
-        return $entityCodes[0];
+        return $values[0];
     }
 
     /**
@@ -149,13 +155,19 @@ public function getNextBunch()
      * @param string $entity
      * @param string $behavior
      * @param array $data
+     * @param string|null $entitySubtype
      * @return int
      */
-    public function saveBunch($entity, $behavior, array $data)
+    public function saveBunch($entity, $behavior, array $data, $entitySubtype = null)
     {
         return $this->_getWriteAdapter()->insert(
             $this->getMainTable(),
-            array('behavior' => $behavior, 'entity' => $entity, 'data' => Mage::helper('Mage_Core_Helper_Data')->jsonEncode($data))
+            array(
+                'behavior'       => $behavior,
+                'entity'         => $entity,
+                'entity_subtype' => $entitySubtype,
+                'data'           => Mage::helper('Mage_Core_Helper_Data')->jsonEncode($data)
+            )
         );
     }
 }
diff --git a/app/code/core/Mage/ImportExport/Model/Source/Export/Format/Version.php b/app/code/core/Mage/ImportExport/Model/Source/Format/Version.php
similarity index 81%
rename from app/code/core/Mage/ImportExport/Model/Source/Export/Format/Version.php
rename to app/code/core/Mage/ImportExport/Model/Source/Format/Version.php
index 4f789c0aa474f..8995952a0a561 100644
--- a/app/code/core/Mage/ImportExport/Model/Source/Export/Format/Version.php
+++ b/app/code/core/Mage/ImportExport/Model/Source/Format/Version.php
@@ -25,23 +25,24 @@
  */
 
 /**
- * Source model of export format versions
+ * Source model of import/export format versions
  *
  * @category    Mage
  * @package     Mage_ImportExport
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_ImportExport_Model_Source_Export_Format_Version
+
+class Mage_ImportExport_Model_Source_Format_Version
 {
     /**#@+
-     * Export versions
+     * Import versions
      */
-    const EXPORT_VERSION_1 = 1;
-    const EXPORT_VERSION_2 = 2;
+    const VERSION_1 = 1;
+    const VERSION_2 = 2;
     /**#@-*/
 
     /**
-     * Prepare and return array of available export version file formats
+     * Prepare and return array of available version file formats
      *
      * @return array
      */
@@ -66,7 +67,7 @@ public function toOptionArray()
     }
 
     /**
-     * Get possible export format versions
+     * Get possible format versions
      *
      * @return array
      */
@@ -75,8 +76,8 @@ public function toArray()
         $helper = Mage::helper('Mage_ImportExport_Helper_Data');
 
         return array(
-            self::EXPORT_VERSION_1 => $helper->__('Magento 1.7 format'),
-            self::EXPORT_VERSION_2 => $helper->__('Magento 2.0 format'),
+            self::VERSION_1 => $helper->__('Magento 1.7 format'),
+            self::VERSION_2 => $helper->__('Magento 2.0 format'),
         );
     }
 }
diff --git a/app/code/core/Mage/ImportExport/Model/Source/Import/Behavior.php b/app/code/core/Mage/ImportExport/Model/Source/Import/Behavior.php
index 4459c24a577a8..ec826155c4cd8 100644
--- a/app/code/core/Mage/ImportExport/Model/Source/Import/Behavior.php
+++ b/app/code/core/Mage/ImportExport/Model/Source/Import/Behavior.php
@@ -43,6 +43,10 @@ public function toOptionArray()
         $helper = Mage::helper('Mage_ImportExport_Helper_Data');
 
         return array(
+            array(
+                'value' => '',
+                'label' => $helper->__('-- Please Select --')
+            ),
             array(
                 'value' => Mage_ImportExport_Model_Import::BEHAVIOR_APPEND,
                 'label' => $helper->__('Append Complex Data')
diff --git a/app/code/core/Mage/ImportExport/Model/Source/Import/Customer/Entity.php b/app/code/core/Mage/ImportExport/Model/Source/Import/Customer/Entity.php
new file mode 100644
index 0000000000000..2d9a9d88d24c9
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/Model/Source/Import/Customer/Entity.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Source import customer entity model (the same as for export)
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_ImportExport_Model_Source_Import_Customer_Entity
+{
+    /**
+     * Prepare and return array of import customer entities ids and their names
+     *
+     * @return array
+     */
+    public function toOptionArray()
+    {
+        return Mage_ImportExport_Model_Config::getModelsComboOptions(
+            Mage_ImportExport_Model_Import::CONFIG_KEY_CUSTOMER_ENTITIES
+        );
+    }
+}
diff --git a/app/code/core/Mage/ImportExport/Model/Source/Import/Entity.php b/app/code/core/Mage/ImportExport/Model/Source/Import/Entity.php
index 1396aaf09b4d8..dec677d94cdc4 100644
--- a/app/code/core/Mage/ImportExport/Model/Source/Import/Entity.php
+++ b/app/code/core/Mage/ImportExport/Model/Source/Import/Entity.php
@@ -40,13 +40,8 @@ class Mage_ImportExport_Model_Source_Import_Entity
      */
     public function toOptionArray()
     {
-        $options = array();
-        $entities = Mage_ImportExport_Model_Import::CONFIG_KEY_ENTITIES;
-        $comboOptions = Mage_ImportExport_Model_Config::getModelsComboOptions($entities);
-
-        foreach ($comboOptions as $option) {
-           $options[] = $option;
-        }
-        return $options;
+        return Mage_ImportExport_Model_Config::getModelsComboOptions(
+            Mage_ImportExport_Model_Import::CONFIG_KEY_ENTITIES, true
+        );
     }
 }
diff --git a/app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php b/app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php
index 476c57524be20..1f2cc3bbf5490 100644
--- a/app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php
+++ b/app/code/core/Mage/ImportExport/controllers/Adminhtml/ExportController.php
@@ -53,7 +53,7 @@ protected function _initAction()
     {
         $this->_title($this->__('Import/Export'))
             ->loadLayout()
-            ->_setActiveMenu('system/importexport');
+            ->_setActiveMenu('Mage_ImportExport::system_convert_export');
 
         return $this;
     }
diff --git a/app/code/core/Mage/ImportExport/controllers/Adminhtml/ImportController.php b/app/code/core/Mage/ImportExport/controllers/Adminhtml/ImportController.php
index 2b6787282a768..c3284de20fa6a 100644
--- a/app/code/core/Mage/ImportExport/controllers/Adminhtml/ImportController.php
+++ b/app/code/core/Mage/ImportExport/controllers/Adminhtml/ImportController.php
@@ -53,7 +53,7 @@ protected function _initAction()
     {
         $this->_title($this->__('Import/Export'))
             ->loadLayout()
-            ->_setActiveMenu('system/importexport');
+            ->_setActiveMenu('Mage_ImportExport::system_convert_import');
 
         return $this;
     }
@@ -121,7 +121,7 @@ public function startAction()
     }
 
     /**
-     * Validate uploaded files action.
+     * Validate uploaded files action
      *
      * @return void
      */
@@ -139,6 +139,10 @@ public function validateAction()
                     Mage_ImportExport_Model_Import::FIELD_NAME_IMG_ARCHIVE_FILE)
                 );
 
+            if (!empty($data['customer_entity'])) {
+                $data['entity_subtype'] = $data['customer_entity'];
+            }
+
             try {
                 /** @var $import Mage_ImportExport_Model_Import */
                 $import = Mage::getModel('Mage_ImportExport_Model_Import');
@@ -154,7 +158,9 @@ public function validateAction()
                             );
                         } elseif ($import->getErrorsCount() >= $import->getErrorsLimit()) {
                             $resultBlock->addNotice(
-                                $this->__('Errors limit (%d) reached. Please fix errors and re-upload file', $import->getErrorsLimit())
+                                $this->__('Errors limit (%d) reached. Please fix errors and re-upload file',
+                                    $import->getErrorsLimit()
+                                )
                             );
                         } else {
                             if ($import->isImportAllowed()) {
@@ -185,7 +191,12 @@ public function validateAction()
                         }
                     }
                     $resultBlock->addNotice($import->getNotices());
-                    $resultBlock->addNotice($this->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d', $import->getProcessedRowsCount(), $import->getProcessedEntitiesCount(), $import->getInvalidRowsCount(), $import->getErrorsCount()));
+                    $resultBlock->addNotice(
+                        $this->__('Checked rows: %d, checked entities: %d, invalid rows: %d, total errors: %d',
+                            $import->getProcessedRowsCount(), $import->getProcessedEntitiesCount(),
+                            $import->getInvalidRowsCount(), $import->getErrorsCount()
+                        )
+                    );
                 }
             } catch (Exception $e) {
                 $resultBlock->addNotice($this->__('Please fix errors and re-upload file'))
diff --git a/app/code/core/Mage/ImportExport/etc/adminhtml.xml b/app/code/core/Mage/ImportExport/etc/adminhtml.xml
index bd47e5fe2681e..51d33a0c95d04 100644
--- a/app/code/core/Mage/ImportExport/etc/adminhtml.xml
+++ b/app/code/core/Mage/ImportExport/etc/adminhtml.xml
@@ -26,26 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <convert translate="title">
-                    <children>
-                        <import translate="title" module="Mage_ImportExport">
-                            <title>Import</title>
-                            <action>adminhtml/import</action>
-                            <sort_order>10</sort_order>
-                        </import>
-                        <export translate="title" module="Mage_ImportExport">
-                            <title>Export</title>
-                            <action>adminhtml/export</action>
-                            <sort_order>20</sort_order>
-                        </export>
-                    </children>
-                </convert>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/ImportExport/etc/adminhtml/menu.xml b/app/code/core/Mage/ImportExport/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..cba1090c9528c
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/etc/adminhtml/menu.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_ImportExport::system_convert_import" title="Import" module="Mage_ImportExport" sortOrder="10" parent="Mage_Adminhtml::system_convert" action="adminhtml/import" />
+        <add id="Mage_ImportExport::system_convert_export" title="Export" module="Mage_ImportExport" sortOrder="20" parent="Mage_Adminhtml::system_convert" action="adminhtml/export" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/ImportExport/etc/config.xml b/app/code/core/Mage/ImportExport/etc/config.xml
index de968597f6e5c..9660a8b4e4060 100644
--- a/app/code/core/Mage/ImportExport/etc/config.xml
+++ b/app/code/core/Mage/ImportExport/etc/config.xml
@@ -28,7 +28,7 @@
 <config>
     <modules>
         <Mage_ImportExport>
-            <version>1.6.0.2</version>
+            <version>1.6.0.3</version>
         </Mage_ImportExport>
     </modules>
     <global>
@@ -61,6 +61,16 @@
                     <label>Customers</label>
                 </customer>
             </export_entities>
+            <import_customer_entities>
+                <customer translate="label">
+                    <model_token>Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer</model_token>
+                    <label>Customers Main File</label>
+                </customer>
+                <customer_address translate="label">
+                    <model_token>Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address</model_token>
+                    <label>Customer Addresses</label>
+                </customer_address>
+            </import_customer_entities>
             <export_customer_entities>
                 <customer translate="label">
                     <model_token>Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer</model_token>
diff --git a/app/code/core/Mage/ImportExport/sql/importexport_setup/upgrade-1.6.0.2-1.6.0.3.php b/app/code/core/Mage/ImportExport/sql/importexport_setup/upgrade-1.6.0.2-1.6.0.3.php
new file mode 100644
index 0000000000000..cba8852b21342
--- /dev/null
+++ b/app/code/core/Mage/ImportExport/sql/importexport_setup/upgrade-1.6.0.2-1.6.0.3.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $installer Mage_ImportExport_Model_Resource_Setup */
+$installer = $this;
+
+$installer->getConnection()->addColumn(
+    $installer->getTable('importexport_importdata'), 'entity_subtype',
+    array(
+        'TYPE'    => Varien_Db_Ddl_Table::TYPE_TEXT,
+        'LENGTH'  => 50,
+        'COMMENT' => 'Defines entity subtype to have ability import entity data partially'
+    )
+);
diff --git a/app/code/core/Mage/ImportExport/view/adminhtml/export/form/before.phtml b/app/code/core/Mage/ImportExport/view/adminhtml/export/form/before.phtml
index 331ced49c2c28..19018a863f388 100644
--- a/app/code/core/Mage/ImportExport/view/adminhtml/export/form/before.phtml
+++ b/app/code/core/Mage/ImportExport/view/adminhtml/export/form/before.phtml
@@ -25,7 +25,7 @@
  */
 ?>
 <?php
-    $exportVersionTwo = (int) Mage_ImportExport_Model_Source_Export_Format_Version::EXPORT_VERSION_2;
+    $exportVersionTwo = (int) Mage_ImportExport_Model_Source_Format_Version::VERSION_2;
 ?>
 <script type="text/javascript">
 //<![CDATA[
@@ -75,13 +75,13 @@
     {
         if ($('file_format_version') && $F('file_format_version')) {
             switch ($F('file_format_version')) {
-                case '<?php echo Mage_ImportExport_Model_Source_Export_Format_Version::EXPORT_VERSION_1 ?>':
+                case '<?php echo Mage_ImportExport_Model_Source_Format_Version::VERSION_1 ?>':
                     $('head-customer_entity_fieldset').hide();
                     $('customer_entity_fieldset').hide();
                     $('customer_entity').selectedIndex = 0;
                     this.getFilter();
                     break;
-                case '<?php echo Mage_ImportExport_Model_Source_Export_Format_Version::EXPORT_VERSION_2 ?>':
+                case '<?php echo Mage_ImportExport_Model_Source_Format_Version::VERSION_2 ?>':
                     this.getCustomerFilter();
                     $('head-customer_entity_fieldset').show();
                     $('customer_entity_fieldset').show();
diff --git a/app/code/core/Mage/ImportExport/view/adminhtml/import/form/after.phtml b/app/code/core/Mage/ImportExport/view/adminhtml/import/form/after.phtml
index e8b8329fb2565..132c2bd9401e3 100644
--- a/app/code/core/Mage/ImportExport/view/adminhtml/import/form/after.phtml
+++ b/app/code/core/Mage/ImportExport/view/adminhtml/import/form/after.phtml
@@ -26,7 +26,16 @@
 ?>
 <div class="entry-edit" id="import_validation_container" style="display:none;">
     <div class="entry-edit-head">
-        <h4 class="icon-head head-edit-form fieldset-legend" id="import_validation_container_header"><?php echo $this->__('Validation Results'); ?></h4>
+        <h4 class="icon-head head-edit-form fieldset-legend"
+            id="import_validation_container_header"><?php echo $this->__('Validation Results'); ?></h4>
     </div>
     <div id="import_validation_messages" class="fieldset "><!-- --></div>
 </div>
+<script type="text/javascript">
+//<![CDATA[
+    $('entity').selectedIndex = 0; // forced resetting entity selector after page refresh
+    $('behavior').selectedIndex = 0; // forced resetting behavior selector after page refresh
+    $('file_format_version').selectedIndex = 0; // forced resetting file format version selector after page refresh
+    $('customer_entity').selectedIndex = 0; // forced resetting customer entity selector after page refresh
+//]]>
+</script>
diff --git a/app/code/core/Mage/ImportExport/view/adminhtml/import/form/before.phtml b/app/code/core/Mage/ImportExport/view/adminhtml/import/form/before.phtml
index 80a5973c8a779..f5a382691108c 100644
--- a/app/code/core/Mage/ImportExport/view/adminhtml/import/form/before.phtml
+++ b/app/code/core/Mage/ImportExport/view/adminhtml/import/form/before.phtml
@@ -33,6 +33,131 @@
      */
     varienForm.prototype.ifrElemName = 'import_post_target_frame';
 
+    /**
+     * Handle value change in entity type selector
+     *
+     * @return void
+     */
+    varienForm.prototype.handleEntityTypeSelector = function()
+    {
+        if ($('entity') && $F('entity')) {
+            $('head-import_format_version_fieldset').hide();
+            $('import_format_version_fieldset').hide();
+            $('file_format_version').selectedIndex = 0;
+            $('head-customer_entity_fieldset').hide();
+            $('customer_entity_fieldset').hide();
+            $('customer_entity').disable();
+            $('customer_entity').selectedIndex = 0;
+            $('head-upload_file_fieldset').hide();
+            $('upload_file_fieldset').hide();
+            this.showAllBehaviours();
+
+            switch ($F('entity')) {
+                case 'customer':
+                    $('head-import_format_version_fieldset').show();
+                    $('import_format_version_fieldset').show();
+                    $('file_format_version').addClassName('required-entry');
+                    break;
+                case 'catalog_product':
+                    $('head-upload_file_fieldset').show();
+                    $('upload_file_fieldset').show();
+                    $('file_format_version').removeClassName('required-entry');
+                    break;
+                default:
+                    break;
+            }
+        } else {
+            $('head-import_format_version_fieldset').hide();
+            $('import_format_version_fieldset').hide();
+            $('file_format_version').selectedIndex = 0;
+            $('head-customer_entity_fieldset').hide();
+            $('customer_entity_fieldset').hide();
+            $('customer_entity').disable();
+            $('customer_entity').selectedIndex = 0;
+            $('head-upload_file_fieldset').hide();
+            $('upload_file_fieldset').hide();
+            this.showAllBehaviours();
+        }
+    };
+
+    /**
+     * Handle value change in import format version selector
+     *
+     * @return void
+     */
+    varienForm.prototype.handleImportFormatVersionSelector = function()
+    {
+        if ($('file_format_version') && $F('file_format_version')) {
+            var allowedBehaviours = [];
+            <?php
+                $importVersion = array(
+                    1 => Mage_ImportExport_Model_Source_Format_Version::VERSION_1,
+                    2 => Mage_ImportExport_Model_Source_Format_Version::VERSION_2,
+                );
+            ?>
+            switch ($F('file_format_version')) {
+                case '<?php echo $importVersion[1] ?>':
+                    $('head-customer_entity_fieldset').hide();
+                    $('customer_entity_fieldset').hide();
+                    $('customer_entity').disable();
+                    $('customer_entity').selectedIndex = 0;
+                    allowedBehaviours = <?php echo $this->getJsAllowedCustomerBehaviours($importVersion[1]) ?>;
+                    break;
+                case '<?php echo $importVersion[2] ?>':
+                    $('head-customer_entity_fieldset').show();
+                    $('customer_entity_fieldset').show();
+                    $('customer_entity').enable();
+                    allowedBehaviours = <?php echo $this->getJsAllowedCustomerBehaviours($importVersion[2]) ?>;
+                    break;
+                default:
+                    break;
+            }
+
+            // hide not allowed behaviours
+            if ($('behavior')) {
+                var behaviourLength = $('behavior').length;
+                var behaviourOptions = $('behavior').options;
+
+                for (var i = 0; i < behaviourLength; i++) {
+                    if (allowedBehaviours.include(behaviourOptions[i].value)) {
+                        behaviourOptions[i].show();
+                    } else if (behaviourOptions[i].value != '') {
+                        behaviourOptions[i].hide();
+                        if (behaviourOptions[i].selected) {
+                            $('behavior').selectedIndex = 0;
+                        }
+                    }
+                }
+            }
+
+            $('head-upload_file_fieldset').show();
+            $('upload_file_fieldset').show();
+        } else {
+            $('head-customer_entity_fieldset').hide();
+            $('customer_entity_fieldset').hide();
+            $('customer_entity').disable();
+            $('customer_entity').selectedIndex = 0;
+            $('head-upload_file_fieldset').hide();
+            $('upload_file_fieldset').hide();
+        }
+    };
+
+    /**
+     * Show all available behaviours
+     *
+     * @return void
+     */
+    varienForm.prototype.showAllBehaviours = function()
+    {
+        if ($('behavior')) {
+            var behaviourLength = $('behavior').length;
+            var behaviourOptions = $('behavior').options;
+            for (var i = 0; i < behaviourLength; i++) {
+                behaviourOptions[i].show();
+            }
+        }
+    };
+
     /**
      * Post form data to dynamic iframe.
      *
@@ -45,7 +170,8 @@
             // create dynamic frame
             if (!$(this.ifrElemName)) {
                 $('html-body').insert({
-                    bottom:'<iframe name="' + this.ifrElemName + '" id="' + this.ifrElemName + '" style="display:none;"/>'
+                    bottom:'<iframe name="' + this.ifrElemName + '" id="' + this.ifrElemName
+                        + '" style="display:none;"/>'
                 });
             }
 
@@ -55,7 +181,7 @@
             var oldTarget   = formElem.target;
             var oldAction   = formElem.action;
 
-            Element.clonePosition(loadingMask, $$('#html-body .wrapper')[0], {offsetLeft:-2})
+            Element.clonePosition(loadingMask, $$('#html-body .wrapper')[0], {offsetLeft:-2});
             toggleSelectsUnderBlock(loadingMask, false);
             loadingMask.show();
             setLoaderPosition();
diff --git a/app/code/core/Mage/ImportExport/view/adminhtml/layout.xml b/app/code/core/Mage/ImportExport/view/adminhtml/layout.xml
index 3ef6b2768ccd6..b7daeb35b2d11 100644
--- a/app/code/core/Mage/ImportExport/view/adminhtml/layout.xml
+++ b/app/code/core/Mage/ImportExport/view/adminhtml/layout.xml
@@ -28,7 +28,7 @@
 <layout>
     <adminhtml_import_index>
         <reference name="content">
-            <block type="Mage_Adminhtml_Block_Template" template="Mage_ImportExport::import/form/before.phtml" name="import.form.before" alias="form_before"/>
+            <block type="Mage_ImportExport_Block_Adminhtml_Import_Before" template="Mage_ImportExport::import/form/before.phtml" name="import.form.before" alias="form_before"/>
             <block type="Mage_ImportExport_Block_Adminhtml_Import_Edit" name="import.form.container"/>
             <block type="Mage_Adminhtml_Block_Template" template="Mage_ImportExport::import/form/after.phtml" name="import.form.after" alias="form_after"/>
         </reference>
diff --git a/app/code/core/Mage/Index/controllers/Adminhtml/ProcessController.php b/app/code/core/Mage/Index/controllers/Adminhtml/ProcessController.php
index 277299ac3ffbe..b4d47c07a7d12 100644
--- a/app/code/core/Mage/Index/controllers/Adminhtml/ProcessController.php
+++ b/app/code/core/Mage/Index/controllers/Adminhtml/ProcessController.php
@@ -51,7 +51,7 @@ public function listAction()
         $this->_title($this->__('System'))->_title($this->__('Index Management'));
 
         $this->loadLayout();
-        $this->_setActiveMenu('system/index');
+        $this->_setActiveMenu('Mage_Index::system_index');
         $this->_addContent($this->getLayout()->createBlock('Mage_Index_Block_Adminhtml_Process'));
         $this->renderLayout();
     }
diff --git a/app/code/core/Mage/Index/etc/adminhtml.xml b/app/code/core/Mage/Index/etc/adminhtml.xml
index 9f93bebfb69a2..60a8b933d5094 100644
--- a/app/code/core/Mage/Index/etc/adminhtml.xml
+++ b/app/code/core/Mage/Index/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <index translate="title" module="Mage_Index">
-                    <title>Index Management</title>
-                    <action>adminhtml/process/list</action>
-                    <sort_order>92</sort_order>
-                </index>
-            </children>
-        </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Index/etc/adminhtml/menu.xml b/app/code/core/Mage/Index/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..55b25fa706411
--- /dev/null
+++ b/app/code/core/Mage/Index/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Index
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Index::system_index" title="Index Management" module="Mage_Index" sortOrder="92" parent="Mage_Adminhtml::system" action="adminhtml/process/list" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Install/Model/Installer/Console.php b/app/code/core/Mage/Install/Model/Installer/Console.php
index ef2ea28b12b42..7b2d88a0e8091 100644
--- a/app/code/core/Mage/Install/Model/Installer/Console.php
+++ b/app/code/core/Mage/Install/Model/Installer/Console.php
@@ -358,17 +358,16 @@ public function uninstall()
             return false;
         }
         $dbConfig = Mage::getConfig()->getResourceConnectionConfig(Mage_Core_Model_Resource::DEFAULT_SETUP_RESOURCE);
-        if ($dbConfig->model != 'mysql4') {
-            $this->addError('Database uninstall is supported for the MySQL only.');
+        $modelName = 'Mage_Install_Model_Installer_Db_' . ucfirst($dbConfig->model);
+
+        if (!Magento_Autoload::getInstance()->classExists($modelName)) {
+            $this->addError('Database uninstall is not supported for the ' . ucfirst($dbConfig->model) . '.');
             return false;
         }
 
-        /* Cleanup database */
-        $resourceModel = new Mage_Core_Model_Resource;
-        $dbConnection = $resourceModel->getConnection(Mage_Core_Model_Resource::DEFAULT_SETUP_RESOURCE);
-        $dbConnection->query("DROP DATABASE `$dbConfig->dbname`");
-        $dbConnection->query("CREATE DATABASE `$dbConfig->dbname`");
-
+        /** @var $resourceModel Mage_Install_Model_Installer_Db_Abstract */
+        $resourceModel = Mage::getModel($modelName);
+        $resourceModel->cleanUpDatabase($dbConfig);
 
         /* Remove temporary directories */
         $configOptions = Mage::app()->getConfig()->getOptions();
@@ -378,7 +377,6 @@ public function uninstall()
             $configOptions->getExportDir(),
             $configOptions->getLogDir(),
             $configOptions->getVarDir() . '/report',
-            $configOptions->getMediaDir() . '/skin',
         );
         foreach ($dirsToRemove as $dir) {
             Varien_Io_File::rmdirRecursive($dir);
diff --git a/app/code/core/Mage/Install/Model/Installer/Db/Abstract.php b/app/code/core/Mage/Install/Model/Installer/Db/Abstract.php
index 9b8fdc09c7344..3b92665d556c6 100644
--- a/app/code/core/Mage/Install/Model/Installer/Db/Abstract.php
+++ b/app/code/core/Mage/Install/Model/Installer/Db/Abstract.php
@@ -155,4 +155,12 @@ public function getRequiredExtensions()
         }
         return $extensions;
     }
+
+    /**
+     * Clean database
+     *
+     * @param SimpleXMLElement $config
+     * @return Mage_Install_Model_Installer_Db_Abstract
+     */
+    abstract public function cleanUpDatabase(SimpleXMLElement $config);
 }
diff --git a/app/code/core/Mage/Install/Model/Installer/Db/Mysql4.php b/app/code/core/Mage/Install/Model/Installer/Db/Mysql4.php
index bc482b5d0ff55..cd00031611fa2 100644
--- a/app/code/core/Mage/Install/Model/Installer/Db/Mysql4.php
+++ b/app/code/core/Mage/Install/Model/Installer/Db/Mysql4.php
@@ -62,4 +62,22 @@ public function supportEngine()
             ->fetchPairs('SHOW VARIABLES');
         return (!isset($variables['have_innodb']) || $variables['have_innodb'] != 'YES') ? false : true;
     }
+
+    /**
+     * Clean database
+     *
+     * @param SimpleXMLElement $config
+     * @return Mage_Install_Model_Installer_Db_Abstract
+     */
+    public function cleanUpDatabase(SimpleXMLElement $config)
+    {
+        $resourceModel = new Mage_Core_Model_Resource();
+        $connection = $resourceModel->getConnection(Mage_Core_Model_Resource::DEFAULT_SETUP_RESOURCE);
+        $dbName = $config->dbname;
+
+        $connection->query('DROP DATABASE IF EXISTS ' . $dbName);
+        $connection->query('CREATE DATABASE ' . $dbName);
+
+        return $this;
+    }
 }
diff --git a/app/code/core/Mage/Newsletter/etc/adminhtml.xml b/app/code/core/Mage/Newsletter/etc/adminhtml.xml
index e0cf764ca7cce..307a014ec748e 100644
--- a/app/code/core/Mage/Newsletter/etc/adminhtml.xml
+++ b/app/code/core/Mage/Newsletter/etc/adminhtml.xml
@@ -26,30 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <newsletter translate="title" module="Mage_Newsletter">
-            <title>Newsletter</title>
-            <sort_order>60</sort_order>
-            <children>
-                <template translate="title" module="Mage_Newsletter">
-                    <title>Newsletter Templates</title>
-                    <action>adminhtml/newsletter_template/</action>
-                </template>
-                <queue translate="title" module="Mage_Newsletter">
-                    <title>Newsletter Queue</title>
-                    <action>adminhtml/newsletter_queue/</action>
-                </queue>
-                <subscriber translate="title" module="Mage_Newsletter">
-                    <title>Newsletter Subscribers</title>
-                    <action>adminhtml/newsletter_subscriber/</action>
-                </subscriber>
-                <problem translate="title" module="Mage_Newsletter">
-                    <title>Newsletter Problem Reports</title>
-                    <action>adminhtml/newsletter_problem/</action>
-                </problem>
-            </children>
-        </newsletter>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Newsletter/etc/adminhtml/menu.xml b/app/code/core/Mage/Newsletter/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..526556d05648d
--- /dev/null
+++ b/app/code/core/Mage/Newsletter/etc/adminhtml/menu.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Newsletter
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Newsletter::newsletter" title="Newsletter" module="Mage_Newsletter" sortOrder="60" />
+        <add id="Mage_Newsletter::newsletter_template" title="Newsletter Templates" module="Mage_Newsletter" parent="Mage_Newsletter::newsletter" action="adminhtml/newsletter_template/" />
+        <add id="Mage_Newsletter::newsletter_queue" title="Newsletter Queue" module="Mage_Newsletter" parent="Mage_Newsletter::newsletter" action="adminhtml/newsletter_queue/" />
+        <add id="Mage_Newsletter::newsletter_subscriber" title="Newsletter Subscribers" module="Mage_Newsletter" parent="Mage_Newsletter::newsletter" action="adminhtml/newsletter_subscriber/" />
+        <add id="Mage_Newsletter::newsletter_problem" title="Newsletter Problem Reports" module="Mage_Newsletter" parent="Mage_Newsletter::newsletter" action="adminhtml/newsletter_problem/" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
index 2e011be4af65e..8121597945f5c 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
@@ -35,6 +35,18 @@
  */
 class Mage_Oauth_Adminhtml_Oauth_Admin_TokenController extends Mage_Adminhtml_Controller_Action
 {
+    /**
+     * Perform layout initialization actions
+     *
+     * @return Mage_Oauth_Adminhtml_Oauth_ConsumerController
+     */
+    protected function  _initAction()
+    {
+        $this->loadLayout()
+            ->_setActiveMenu('Mage_Oauth::system_api_oauth_admin_token');
+        return $this;
+    }
+
     /**
      * Init titles
      *
@@ -54,7 +66,7 @@ public function preDispatch()
      */
     public function indexAction()
     {
-        $this->loadLayout();
+        $this->_initAction();
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
index 9578b8b7b4af2..fa4ee1cb315f2 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
@@ -52,7 +52,7 @@ public function preDispatch()
      */
     public function indexAction()
     {
-        $this->loadLayout()->_setActiveMenu('system/oauth');
+        $this->loadLayout()->_setActiveMenu('Mage_Oauth::system_api_oauth_authorized_tokens');
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
index 57d9846e6ddbf..6bf614d2c7c25 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
@@ -33,6 +33,17 @@
  */
 class Mage_Oauth_Adminhtml_Oauth_ConsumerController extends Mage_Adminhtml_Controller_Action
 {
+    /**
+     * Perform layout initialization actions
+     *
+     * @return Mage_Oauth_Adminhtml_Oauth_ConsumerController
+     */
+    protected function  _initAction()
+    {
+        $this->loadLayout()
+            ->_setActiveMenu('Mage_Oauth::system_api_oauth_consumer');
+        return $this;
+    }
     /**
      * Unset unused data from request
      * Skip getting "key" and "secret" because its generated from server side only
@@ -69,7 +80,7 @@ public function preDispatch()
      */
     public function indexAction()
     {
-        $this->loadLayout();
+        $this->_initAction();
         $this->renderLayout();
     }
 
@@ -104,7 +115,7 @@ public function newAction()
 
         Mage::register('current_consumer', $model);
 
-        $this->loadLayout();
+        $this->_initAction();
         $this->renderLayout();
     }
 
@@ -134,7 +145,7 @@ public function editAction()
         $model->addData($this->_filter($this->getRequest()->getParams()));
         Mage::register('current_consumer', $model);
 
-        $this->loadLayout();
+        $this->_initAction();
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Oauth/etc/adminhtml.xml b/app/code/core/Mage/Oauth/etc/adminhtml.xml
index aece3c3a0462e..804ae7dfc2025 100644
--- a/app/code/core/Mage/Oauth/etc/adminhtml.xml
+++ b/app/code/core/Mage/Oauth/etc/adminhtml.xml
@@ -72,29 +72,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <system>
-            <children>
-                <api>
-                    <children>
-                        <oauth_consumer translate="title" module="Mage_Oauth">
-                            <title>REST - OAuth Consumers</title>
-                            <sort_order>50</sort_order>
-                            <action>adminhtml/oauth_consumer</action>
-                        </oauth_consumer>
-                        <oauth_authorized_tokens translate="title" module="Mage_Oauth">
-                            <title>REST - OAuth Authorized Tokens</title>
-                            <sort_order>60</sort_order>
-                            <action>adminhtml/oauth_authorizedTokens</action>
-                        </oauth_authorized_tokens>
-                        <oauth_admin_token translate="title" module="Mage_Oauth">
-                            <title>REST - My Apps</title>
-                            <sort_order>70</sort_order>
-                            <action>adminhtml/oauth_admin_token</action>
-                        </oauth_admin_token>
-                    </children>
-                </api>
-            </children>
-        </system>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml b/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..9f3d6d855061a
--- /dev/null
+++ b/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Oauth
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Oauth::system_api_oauth_consumer" title="REST - OAuth Consumers" module="Mage_Oauth" sortOrder="50" parent="Mage_Api::system_api" action="adminhtml/oauth_consumer" />
+        <add id="Mage_Oauth::system_api_oauth_authorized_tokens" title="REST - OAuth Authorized Tokens" module="Mage_Oauth" sortOrder="60" parent="Mage_Api::system_api" action="adminhtml/oauth_authorizedTokens" />
+        <add id="Mage_Oauth::system_api_oauth_admin_token" title="REST - My Apps" module="Mage_Oauth" sortOrder="70" parent="Mage_Api::system_api" action="adminhtml/oauth_admin_token" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php b/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
index 1427a087077d1..8e26881c931a4 100644
--- a/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
+++ b/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
@@ -115,7 +115,7 @@ protected function _initAction()
     {
         $this->_title($this->__('Reports'))->_title($this->__('Sales'))->_title($this->__('PayPal Settlement Reports'));
         $this->loadLayout()
-            ->_setActiveMenu('report/sales')
+            ->_setActiveMenu('Mage_Paypal::report_salesroot_paypal_settlement_reports')
             ->_addBreadcrumb(Mage::helper('Mage_Paypal_Helper_Data')->__('Reports'), Mage::helper('Mage_Paypal_Helper_Data')->__('Reports'))
             ->_addBreadcrumb(Mage::helper('Mage_Paypal_Helper_Data')->__('Sales'), Mage::helper('Mage_Paypal_Helper_Data')->__('Sales'))
             ->_addBreadcrumb(Mage::helper('Mage_Paypal_Helper_Data')->__('PayPal Settlement Reports'), Mage::helper('Mage_Paypal_Helper_Data')->__('PayPal Settlement Reports'));
diff --git a/app/code/core/Mage/Paypal/etc/adminhtml.xml b/app/code/core/Mage/Paypal/etc/adminhtml.xml
index d5b67ed94ae0c..afe7cbb44dd85 100644
--- a/app/code/core/Mage/Paypal/etc/adminhtml.xml
+++ b/app/code/core/Mage/Paypal/etc/adminhtml.xml
@@ -26,21 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <report>
-            <children>
-                <salesroot translate="title">
-                    <children>
-                        <paypal_settlement_reports translate="title">
-                            <title>PayPal Settlement Reports</title>
-                            <action>adminhtml/paypal_reports</action>
-                            <sort_order>100</sort_order>
-                        </paypal_settlement_reports>
-                    </children>
-                </salesroot>
-            </children>
-        </report>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Paypal/etc/adminhtml/menu.xml b/app/code/core/Mage/Paypal/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..8a302c5242286
--- /dev/null
+++ b/app/code/core/Mage/Paypal/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Paypal
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Paypal::report_salesroot_paypal_settlement_reports" title="PayPal Settlement Reports" module="Mage_Paypal" sortOrder="100" parent="Mage_Reports::report_salesroot" action="adminhtml/paypal_reports" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Persistent/view/frontend/checkout/onepage/login.phtml b/app/code/core/Mage/Persistent/view/frontend/checkout/onepage/login.phtml
index 6e9e703c64616..66c96a55d8706 100644
--- a/app/code/core/Mage/Persistent/view/frontend/checkout/onepage/login.phtml
+++ b/app/code/core/Mage/Persistent/view/frontend/checkout/onepage/login.phtml
@@ -87,7 +87,7 @@
                         <input type="password" class="input-text required-entry" id="login-password" name="login[password]" />
                     </div>
                 </li>
-                <?php echo $this->getChildHtml('form.additional.info'); ?>
+                <?php echo $this->getChildHtml('login.form.additional.info'); ?>
                 <?php echo $this->getChildHtml('persistent.remember.me'); ?>
             </ul>
             <input name="context" type="hidden" value="checkout" />
diff --git a/app/code/core/Mage/Poll/etc/adminhtml.xml b/app/code/core/Mage/Poll/etc/adminhtml.xml
index 0a1bbc1e82e2c..b992439786eab 100644
--- a/app/code/core/Mage/Poll/etc/adminhtml.xml
+++ b/app/code/core/Mage/Poll/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <cms>
-            <children>
-                <poll translate="title" module="Mage_Poll">
-                    <title>Polls</title>
-                    <action>adminhtml/poll</action>
-                    <sort_order>20</sort_order>
-                </poll>
-            </children>
-         </cms>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Poll/etc/adminhtml/menu.xml b/app/code/core/Mage/Poll/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..9a939fa72e617
--- /dev/null
+++ b/app/code/core/Mage/Poll/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Poll
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Poll::cms_poll" title="Polls" module="Mage_Poll" sortOrder="20" parent="Mage_Cms::cms" action="adminhtml/poll" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Reports/Model/Resource/Product/Ordered/Collection.php b/app/code/core/Mage/Reports/Model/Resource/Product/Ordered/Collection.php
deleted file mode 100755
index 698ea3653ade2..0000000000000
--- a/app/code/core/Mage/Reports/Model/Resource/Product/Ordered/Collection.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_Reports
- * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Products Ordered (Bestsellers) Report collection
- *
- * @category    Mage
- * @package     Mage_Reports
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Reports_Model_Resource_Product_Ordered_Collection extends Mage_Reports_Model_Resource_Product_Collection
-{
-    /**
-     * Join fields
-     *
-     * @param int $from
-     * @param int $to
-     * @return Mage_Reports_Model_Resource_Product_Ordered_Collection
-     */
-    protected function _joinFields($from = '', $to = '')
-    {
-        $this->addAttributeToSelect('*')
-            ->addOrderedQty($from, $to)
-            ->setOrder('ordered_qty', self::SORT_ORDER_DESC);
-
-        return $this;
-    }
-
-    /**
-     * Enter description here ...
-     *
-     * @param int $from
-     * @param int $to
-     * @return Mage_Reports_Model_Resource_Product_Ordered_Collection
-     */
-    public function setDateRange($from, $to)
-    {
-        $this->_reset()
-            ->_joinFields($from, $to);
-        return $this;
-    }
-
-    /**
-     * Set store ids
-     *
-     * @param array s$storeIds
-     * @return Mage_Reports_Model_Resource_Product_Ordered_Collection
-     */
-    public function setStoreIds($storeIds)
-    {
-        $storeId = array_pop($storeIds);
-        $this->setStoreId($storeId);
-        $this->addStoreFilter($storeId);
-        return $this;
-    }
-}
diff --git a/app/code/core/Mage/Reports/Model/Resource/Product/Viewed/Collection.php b/app/code/core/Mage/Reports/Model/Resource/Product/Viewed/Collection.php
deleted file mode 100755
index d6ec47e4e7779..0000000000000
--- a/app/code/core/Mage/Reports/Model/Resource/Product/Viewed/Collection.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_Reports
- * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Products Most Viewed Report collection
- *
- * @category    Mage
- * @package     Mage_Reports
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Reports_Model_Resource_Product_Viewed_Collection extends Mage_Reports_Model_Resource_Product_Collection
-{
-    /**
-     * List of store ids for the current collection will be filtered by
-     *
-     * @var array
-     */
-    protected $_storeIds = array();
-
-    /**
-     * Join fields
-     *
-     * @param string $from
-     * @param string $to
-     * @return Mage_Reports_Model_Resource_Product_Viewed_Collection
-     */
-    protected function _joinFields($from = '', $to = '')
-    {
-        $this->addAttributeToSelect('*')
-            ->addViewsCount($from, $to);
-        return $this;
-    }
-
-    /**
-     * Set date range
-     *
-     * @param string $from
-     * @param string $to
-     * @return Mage_Reports_Model_Resource_Product_Viewed_Collection
-     */
-    public function setDateRange($from, $to)
-    {
-        $this->_reset()
-            ->_joinFields($from, $to);
-        return $this;
-    }
-
-    /**
-     * Set store ids
-     *
-     * @param array $storeIds
-     * @return Mage_Reports_Model_Resource_Product_Viewed_Collection
-     */
-    public function setStoreIds($storeIds)
-    {
-        $storeId = array_pop($storeIds);
-        $this->setStoreId($storeId);
-        $this->addStoreFilter($storeId);
-        $this->addStoreIds($storeId);
-        return $this;
-    }
-
-    /**
-     * Add store ids to filter 'report_event' data by store
-     *
-     * @param array|int $storeIds
-     * @return Mage_Reports_Model_Resource_Product_Viewed_Collection
-     */
-    public function addStoreIds($storeIds)
-    {
-        if (is_array($storeIds)) {
-            $this->_storeIds = array_merge($this->_storeIds, $storeIds);
-        } else {
-            $this->_storeIds[] = $storeIds;
-        }
-        return $this;
-    }
-
-    /**
-     * Apply store filter
-     *
-     * @return Mage_Reports_Model_Resource_Product_Viewed_Collection
-     */
-    protected function _applyStoreIds()
-    {
-        $this->getSelect()->where('store_id IN(?)', $this->_storeIds);
-        return $this;
-    }
-
-    /**
-     * Apply filters
-     *
-     * @return Mage_Catalog_Model_Resource_Product_Collection
-     */
-    protected function _beforeLoad()
-    {
-        $this->_applyStoreIds();
-        return parent::_beforeLoad();
-    }
-}
diff --git a/app/code/core/Mage/Reports/etc/adminhtml.xml b/app/code/core/Mage/Reports/etc/adminhtml.xml
index b7a4327a98226..257fc571b1928 100644
--- a/app/code/core/Mage/Reports/etc/adminhtml.xml
+++ b/app/code/core/Mage/Reports/etc/adminhtml.xml
@@ -26,112 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <report translate="title" module="Mage_Reports">
-            <title>Reports</title>
-            <sort_order>80</sort_order>
-            <children>
-                <salesroot translate="title" module="Mage_Reports">
-                    <title>Sales</title>
-                    <sort_order>10</sort_order>
-                    <children>
-                        <sales translate="title" module="Mage_Reports">
-                            <title>Orders</title>
-                            <action>adminhtml/report_sales/sales</action>
-                        </sales>
-                        <tax translate="title" module="Mage_Reports">
-                            <title>Tax</title>
-                            <action>adminhtml/report_sales/tax</action>
-                        </tax>
-                        <invoiced translate="title" module="Mage_Reports">
-                            <title>Invoiced</title>
-                            <action>adminhtml/report_sales/invoiced</action>
-                        </invoiced>
-                        <shipping translate="title" module="Mage_Reports">
-                            <title>Shipping</title>
-                            <action>adminhtml/report_sales/shipping</action>
-                        </shipping>
-                        <refunded translate="title" module="Mage_Reports">
-                            <title>Refunds</title>
-                            <action>adminhtml/report_sales/refunded</action>
-                        </refunded>
-                         <coupons translate="title" module="Mage_Reports">
-                            <title>Coupons</title>
-                            <action>adminhtml/report_sales/coupons</action>
-                        </coupons>
-                    </children>
-                </salesroot>
-                <shopcart translate="title" module="Mage_Reports">
-                    <title>Shopping Cart</title>
-                    <sort_order>20</sort_order>
-                    <children>
-                        <product translate="title" module="Mage_Reports">
-                            <title>Products in carts</title>
-                            <action>adminhtml/report_shopcart/product</action>
-                        </product>
-                        <abandoned translate="title" module="Mage_Reports">
-                            <title>Abandoned carts</title>
-                            <action>adminhtml/report_shopcart/abandoned</action>
-                        </abandoned>
-                        <!--<customer translate="title" module="Mage_Reports">
-                            <title>Customers</title>
-                            <action>adminhtml/report_shopcart/customer</action>
-                        </customer>-->
-                    </children>
-                </shopcart>
-                <products translate="title" module="Mage_Reports">
-                    <title>Products</title>
-                    <sort_order>30</sort_order>
-                    <children>
-                        <bestsellers translate="title" module="Mage_Reports">
-                            <title>Bestsellers</title>
-                            <action>adminhtml/report_sales/bestsellers</action>
-                        </bestsellers>
-                        <sold translate="title" module="Mage_Reports">
-                            <title>Products Ordered</title>
-                            <action>adminhtml/report_product/sold</action>
-                        </sold>
-                        <viewed translate="title" module="Mage_Reports">
-                            <title>Most Viewed</title>
-                            <action>adminhtml/report_product/viewed</action>
-                        </viewed>
-                        <lowstock translate="title" module="Mage_Reports">
-                            <title>Low stock</title>
-                            <action>adminhtml/report_product/lowstock</action>
-                        </lowstock>
-                    </children>
-                </products>
-                <customers translate="title" module="Mage_Reports">
-                    <title>Customers</title>
-                    <sort_order>40</sort_order>
-                    <children>
-                        <accounts translate="title" module="Mage_Reports">
-                            <title>New Accounts</title>
-                            <action>adminhtml/report_customer/accounts</action>
-                        </accounts>
-                        <totals translate="title" module="Mage_Reports">
-                            <title>Customers by orders total</title>
-                            <action>adminhtml/report_customer/totals</action>
-                        </totals>
-                        <orders translate="title" module="Mage_Reports">
-                            <title>Customers by number of orders</title>
-                            <action>adminhtml/report_customer/orders</action>
-                        </orders>
-                    </children>
-                </customers>
-                <search translate="title" module="Mage_Reports">
-                    <title>Search Terms</title>
-                    <sort_order>60</sort_order>
-                    <action>adminhtml/report/search</action>
-                </search>
-                <statistics translate="title" module="Mage_Reports">
-                    <sort_order>65535</sort_order>
-                    <title>Refresh Statistics</title>
-                    <action>adminhtml/report_statistics</action>
-                </statistics>
-            </children>
-        </report>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Reports/etc/adminhtml/menu.xml b/app/code/core/Mage/Reports/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..923bbb3da39ab
--- /dev/null
+++ b/app/code/core/Mage/Reports/etc/adminhtml/menu.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Reports
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Reports::report" title="Reports" module="Mage_Reports" sortOrder="80" />
+        <add id="Mage_Reports::report_salesroot" title="Sales" module="Mage_Reports" sortOrder="10" parent="Mage_Reports::report" />
+        <add id="Mage_Reports::report_salesroot_sales" title="Orders" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/sales" />
+        <add id="Mage_Reports::report_salesroot_tax" title="Tax" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/tax" />
+        <add id="Mage_Reports::report_salesroot_invoiced" title="Invoiced" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/invoiced" />
+        <add id="Mage_Reports::report_salesroot_shipping" title="Shipping" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/shipping" />
+        <add id="Mage_Reports::report_salesroot_refunded" title="Refunds" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/refunded" />
+        <add id="Mage_Reports::report_salesroot_coupons" title="Coupons" module="Mage_Reports" parent="Mage_Reports::report_salesroot" action="adminhtml/report_sales/coupons" />
+        <add id="Mage_Reports::report_shopcart" title="Shopping Cart" module="Mage_Reports" sortOrder="20" parent="Mage_Reports::report" />
+        <add id="Mage_Reports::report_shopcart_product" title="Products in carts" module="Mage_Reports" parent="Mage_Reports::report_shopcart" action="adminhtml/report_shopcart/product" />
+        <add id="Mage_Reports::report_shopcart_abandoned" title="Abandoned carts" module="Mage_Reports" parent="Mage_Reports::report_shopcart" action="adminhtml/report_shopcart/abandoned" />
+        <add id="Mage_Reports::report_products" title="Products" module="Mage_Reports" sortOrder="30" parent="Mage_Reports::report" />
+        <add id="Mage_Reports::report_products_bestsellers" title="Bestsellers" module="Mage_Reports" parent="Mage_Reports::report_products" action="adminhtml/report_sales/bestsellers" />
+        <add id="Mage_Reports::report_products_sold" title="Products Ordered" module="Mage_Reports" parent="Mage_Reports::report_products" action="adminhtml/report_product/sold" />
+        <add id="Mage_Reports::report_products_viewed" title="Most Viewed" module="Mage_Reports" parent="Mage_Reports::report_products" action="adminhtml/report_product/viewed" />
+        <add id="Mage_Reports::report_products_lowstock" title="Low stock" module="Mage_Reports" parent="Mage_Reports::report_products" action="adminhtml/report_product/lowstock" />
+        <add id="Mage_Reports::report_customers" title="Customers" module="Mage_Reports" sortOrder="40" parent="Mage_Reports::report" />
+        <add id="Mage_Reports::report_customers_accounts" title="New Accounts" module="Mage_Reports" parent="Mage_Reports::report_customers" action="adminhtml/report_customer/accounts" />
+        <add id="Mage_Reports::report_customers_totals" title="Customers by orders total" module="Mage_Reports" parent="Mage_Reports::report_customers" action="adminhtml/report_customer/totals" />
+        <add id="Mage_Reports::report_customers_orders" title="Customers by number of orders" module="Mage_Reports" parent="Mage_Reports::report_customers" action="adminhtml/report_customer/orders" />
+        <add id="Mage_Reports::report_search" title="Search Terms" module="Mage_Reports" sortOrder="60" parent="Mage_Reports::report" action="adminhtml/report/search" />
+        <add id="Mage_Reports::report_statistics" title="Refresh Statistics" module="Mage_Reports" sortOrder="65535" parent="Mage_Reports::report" action="adminhtml/report_statistics" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Review/etc/adminhtml.xml b/app/code/core/Mage/Review/etc/adminhtml.xml
index 37899f53e7013..f8d75366d527a 100644
--- a/app/code/core/Mage/Review/etc/adminhtml.xml
+++ b/app/code/core/Mage/Review/etc/adminhtml.xml
@@ -26,53 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog>
-            <children>
-                <reviews_ratings translate="title" module="Mage_Review">
-                    <title>Reviews and Ratings</title>
-                    <children>
-                        <reviews translate="title" module="Mage_Review">
-                            <title>Customer Reviews</title>
-                            <children>
-                                <pending translate="title" module="Mage_Review">
-                                    <title>Pending Reviews</title>
-                                    <action>adminhtml/catalog_product_review/pending/</action>
-                                </pending>
-                                <all translate="title" module="Mage_Review">
-                                    <title>All Reviews</title>
-                                    <action>adminhtml/catalog_product_review/</action>
-                                </all>
-                            </children>
-                        </reviews>
-                        <ratings translate="title" module="Mage_Review">
-                            <title>Manage Ratings</title>
-                            <action>adminhtml/rating/</action>
-                        </ratings>
-                    </children>
-                    <sort_order>50</sort_order>
-                </reviews_ratings>
-            </children>
-         </catalog>
-        <report>
-            <children>
-                <review translate="title" module="Mage_Reports">
-                    <title>Reviews</title>
-                    <sort_order>55</sort_order>
-                    <children>
-                        <customer translate="title" module="Mage_Review">
-                            <title>Customers Reviews</title>
-                            <action>adminhtml/report_review/customer</action>
-                        </customer>
-                        <product translate="title" module="Mage_Review">
-                            <title>Products Reviews</title>
-                            <action>adminhtml/report_review/product</action>
-                        </product>
-                    </children>
-                </review>
-            </children>
-        </report>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Review/etc/adminhtml/menu.xml b/app/code/core/Mage/Review/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..95bed523a119c
--- /dev/null
+++ b/app/code/core/Mage/Review/etc/adminhtml/menu.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Review
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Review::catalog_reviews_ratings" title="Reviews and Ratings" module="Mage_Review" sortOrder="50" parent="Mage_Catalog::catalog" />
+        <add id="Mage_Review::catalog_reviews_ratings_reviews" title="Customer Reviews" module="Mage_Review" parent="Mage_Review::catalog_reviews_ratings" />
+        <add id="Mage_Review::catalog_reviews_ratings_ratings" title="Manage Ratings" module="Mage_Review" parent="Mage_Review::catalog_reviews_ratings" action="adminhtml/rating/" />
+        <add id="Mage_Review::catalog_reviews_ratings_reviews_pending" title="Pending Reviews" module="Mage_Review" parent="Mage_Review::catalog_reviews_ratings_reviews" action="adminhtml/catalog_product_review/pending/" />
+        <add id="Mage_Review::catalog_reviews_ratings_reviews_all" title="All Reviews" module="Mage_Review" parent="Mage_Review::catalog_reviews_ratings_reviews" action="adminhtml/catalog_product_review/" />
+        <add id="Mage_Review::report_review" title="Reviews" module="Mage_Reports" sortOrder="55" parent="Mage_Reports::report" />
+        <add id="Mage_Review::report_review_customer" title="Customers Reviews" module="Mage_Review" parent="Mage_Review::report_review" action="adminhtml/report_review/customer" />
+        <add id="Mage_Review::report_review_product" title="Products Reviews" module="Mage_Review" parent="Mage_Review::report_review" action="adminhtml/report_review/product" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Sales/etc/adminhtml.xml b/app/code/core/Mage/Sales/etc/adminhtml.xml
index f3ca64d888184..7ddd80ecf206e 100644
--- a/app/code/core/Mage/Sales/etc/adminhtml.xml
+++ b/app/code/core/Mage/Sales/etc/adminhtml.xml
@@ -26,59 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <sales translate="title" module="Mage_Sales">
-            <title>Sales</title>
-            <sort_order>20</sort_order>
-            <depends><module>Mage_Sales</module></depends>
-            <children>
-                <order translate="title" module="Mage_Sales">
-                    <title>Orders</title>
-                    <action>adminhtml/sales_order</action>
-                    <sort_order>10</sort_order>
-                </order>
-                <invoice translate="title" module="Mage_Sales">
-                    <title>Invoices</title>
-                    <action>adminhtml/sales_invoice</action>
-                    <sort_order>20</sort_order>
-                </invoice>
-                <shipment translate="title" module="Mage_Sales">
-                    <title>Shipments</title>
-                    <action>adminhtml/sales_shipment</action>
-                    <sort_order>30</sort_order>
-                </shipment>
-                <creditmemo translate="title" module="Mage_Sales">
-                    <title>Credit Memos</title>
-                    <action>adminhtml/sales_creditmemo</action>
-                    <sort_order>40</sort_order>
-                </creditmemo>
-                <transactions translate="title" module="Mage_Sales">
-                    <title>Transactions</title>
-                    <action>adminhtml/sales_transactions</action>
-                    <sort_order>50</sort_order>
-                </transactions>
-                <recurring_profile translate="title" module="Mage_Sales">
-                    <title>Recurring Profiles (beta)</title>
-                    <action>adminhtml/sales_recurring_profile</action>
-                    <sort_order>60</sort_order>
-                </recurring_profile>
-                <billing_agreement translate="title" module="Mage_Sales">
-                    <title>Billing Agreements</title>
-                    <action>adminhtml/sales_billing_agreement</action>
-                    <sort_order>70</sort_order>
-                </billing_agreement>
-            </children>
-         </sales>
-         <system>
-            <children>
-                <order_statuses translate="title" module="Mage_Sales">
-                    <title>Order Statuses</title>
-                    <action>adminhtml/sales_order_status</action>
-                    <sort_order>105</sort_order>
-                </order_statuses>
-            </children>
-         </system>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Sales/etc/adminhtml/menu.xml b/app/code/core/Mage/Sales/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..c7ff48acc425a
--- /dev/null
+++ b/app/code/core/Mage/Sales/etc/adminhtml/menu.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Sales::sales" title="Sales" module="Mage_Sales" sortOrder="20" dependsOnModule="Mage_Sales" />
+        <add id="Mage_Sales::sales_order" title="Orders" module="Mage_Sales" sortOrder="10" parent="Mage_Sales::sales" action="adminhtml/sales_order" />
+        <add id="Mage_Sales::sales_invoice" title="Invoices" module="Mage_Sales" sortOrder="20" parent="Mage_Sales::sales" action="adminhtml/sales_invoice" />
+        <add id="Mage_Sales::sales_shipment" title="Shipments" module="Mage_Sales" sortOrder="30" parent="Mage_Sales::sales" action="adminhtml/sales_shipment" />
+        <add id="Mage_Sales::sales_creditmemo" title="Credit Memos" module="Mage_Sales" sortOrder="40" parent="Mage_Sales::sales" action="adminhtml/sales_creditmemo" />
+        <add id="Mage_Sales::sales_transactions" title="Transactions" module="Mage_Sales" sortOrder="50" parent="Mage_Sales::sales" action="adminhtml/sales_transactions" />
+        <add id="Mage_Sales::sales_recurring_profile" title="Recurring Profiles (beta)" module="Mage_Sales" sortOrder="60" parent="Mage_Sales::sales" action="adminhtml/sales_recurring_profile" />
+        <add id="Mage_Sales::sales_billing_agreement" title="Billing Agreements" module="Mage_Sales" sortOrder="70" parent="Mage_Sales::sales" action="adminhtml/sales_billing_agreement" />
+        <add id="Mage_Sales::system_order_statuses" title="Order Statuses" module="Mage_Sales" sortOrder="105" parent="Mage_Adminhtml::system" action="adminhtml/sales_order_status" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/SalesRule/etc/adminhtml.xml b/app/code/core/Mage/SalesRule/etc/adminhtml.xml
index f96ad409caf72..79a0484a12f11 100644
--- a/app/code/core/Mage/SalesRule/etc/adminhtml.xml
+++ b/app/code/core/Mage/SalesRule/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-         <promo>
-            <children>
-                <quote translate="title" module="Mage_SalesRule">
-                    <title>Shopping Cart Price Rules</title>
-                    <action>adminhtml/promo_quote/</action>
-                    <depends><module>Mage_Sales</module></depends>
-                </quote>
-            </children>
-         </promo>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/SalesRule/etc/adminhtml/menu.xml b/app/code/core/Mage/SalesRule/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..ad3e13f20b399
--- /dev/null
+++ b/app/code/core/Mage/SalesRule/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_SalesRule
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_SalesRule::promo_quote" title="Shopping Cart Price Rules" module="Mage_SalesRule" parent="Mage_CatalogRule::promo" action="adminhtml/promo_quote/" dependsOnModule="Mage_Sales" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Sitemap/etc/adminhtml.xml b/app/code/core/Mage/Sitemap/etc/adminhtml.xml
index 5ac192cfe977e..f4343f8c42c83 100644
--- a/app/code/core/Mage/Sitemap/etc/adminhtml.xml
+++ b/app/code/core/Mage/Sitemap/etc/adminhtml.xml
@@ -26,17 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog>
-            <children>
-                <sitemap translate="title" module="Mage_Sitemap">
-                    <title>Google Sitemap</title>
-                    <sort_order>180</sort_order>
-                    <action>adminhtml/sitemap/</action>
-                </sitemap>
-            </children>
-        </catalog>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Sitemap/etc/adminhtml/menu.xml b/app/code/core/Mage/Sitemap/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..dbd771f5008a3
--- /dev/null
+++ b/app/code/core/Mage/Sitemap/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sitemap
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Sitemap::catalog_sitemap" title="Google Sitemap" module="Mage_Sitemap" sortOrder="180" parent="Mage_Catalog::catalog" action="adminhtml/sitemap/" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Tag/etc/adminhtml.xml b/app/code/core/Mage/Tag/etc/adminhtml.xml
index 49a587f6b31ec..ac52acafd8543 100644
--- a/app/code/core/Mage/Tag/etc/adminhtml.xml
+++ b/app/code/core/Mage/Tag/etc/adminhtml.xml
@@ -26,52 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <catalog>
-            <children>
-                <tag translate="title" module="Mage_Tag">
-                    <title>Tags</title>
-                    <children>
-                        <!--
-                            childrens should be in the order (All Tags, Pending Tags)
-                            for correct menu building in "None Secret Key" mode
-                        -->
-                        <all translate="title" module="Mage_Tag">
-                            <title>All Tags</title>
-                            <action>adminhtml/tag/index</action>
-                        </all>
-                        <pending translate="title" module="Mage_Tag">
-                            <title>Pending Tags</title>
-                            <action>adminhtml/tag/pending</action>
-                        </pending>
-                    </children>
-                    <sort_order>60</sort_order>
-                </tag>
-             </children>
-        </catalog>
-        <report translate="title" module="Mage_Reports">
-            <children>
-                <tags translate="title" module="Mage_Tag">
-                    <title>Tags</title>
-                    <sort_order>50</sort_order>
-                    <children>
-                        <customer translate="title" module="Mage_Tag">
-                            <title>Customers</title>
-                            <action>adminhtml/report_tag/customer</action>
-                        </customer>
-                        <product translate="title" module="Mage_Tag">
-                            <title>Products</title>
-                            <action>adminhtml/report_tag/product</action>
-                        </product>
-                        <popular translate="title" module="Mage_Tag">
-                            <title>Popular</title>
-                            <action>adminhtml/report_tag/popular</action>
-                        </popular>
-                    </children>
-                </tags>
-            </children>
-        </report>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Tag/etc/adminhtml/menu.xml b/app/code/core/Mage/Tag/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..540c436caa6e6
--- /dev/null
+++ b/app/code/core/Mage/Tag/etc/adminhtml/menu.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Tag
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Tag::catalog_tag" title="Tags" module="Mage_Tag" sortOrder="60" parent="Mage_Catalog::catalog" />
+        <add id="Mage_Tag::catalog_tag_all" title="All Tags" module="Mage_Tag" parent="Mage_Tag::catalog_tag" action="adminhtml/tag/index" />
+        <add id="Mage_Tag::catalog_tag_pending" title="Pending Tags" module="Mage_Tag" parent="Mage_Tag::catalog_tag" action="adminhtml/tag/pending" />
+        <add id="Mage_Tag::report_tags" title="Tags" module="Mage_Tag" sortOrder="50" parent="Mage_Reports::report" />
+        <add id="Mage_Tag::report_tags_customer" title="Customers" module="Mage_Tag" parent="Mage_Tag::report_tags" action="adminhtml/report_tag/customer" />
+        <add id="Mage_Tag::report_tags_product" title="Products" module="Mage_Tag" parent="Mage_Tag::report_tags" action="adminhtml/report_tag/product" />
+        <add id="Mage_Tag::report_tags_popular" title="Popular" module="Mage_Tag" parent="Mage_Tag::report_tags" action="adminhtml/report_tag/popular" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Tax/etc/adminhtml.xml b/app/code/core/Mage/Tax/etc/adminhtml.xml
index a97a637ce67c2..c3403379e6889 100644
--- a/app/code/core/Mage/Tax/etc/adminhtml.xml
+++ b/app/code/core/Mage/Tax/etc/adminhtml.xml
@@ -26,38 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <sales>
-            <children>
-                <tax translate="title" module="Mage_Tax">
-                    <title>Tax</title>
-                    <sort_order>500</sort_order>
-                    <children>
-                        <rules translate="title" module="Mage_Tax">
-                            <title>Manage Tax Rules</title>
-                            <action>adminhtml/tax_rule</action>
-                        </rules>
-                        <rates translate="title" module="Mage_Tax">
-                            <title>Manage Tax Zones &amp; Rates</title>
-                            <action>adminhtml/tax_rate</action>
-                        </rates>
-                        <import_export translate="title" module="Mage_Tax">
-                            <title>Import / Export Tax Rates</title>
-                            <action>adminhtml/tax_rate/importExport</action>
-                        </import_export>
-                        <classes_customer translate="title" module="Mage_Tax">
-                            <title>Customer Tax Classes</title>
-                            <action>adminhtml/tax_class_customer</action>
-                        </classes_customer>
-                        <classes_product translate="title" module="Mage_Tax">
-                            <title>Product Tax Classes</title>
-                            <action>adminhtml/tax_class_product</action>
-                        </classes_product>
-                    </children>
-                </tax>
-            </children>
-        </sales>
-    </menu>
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/Tax/etc/adminhtml/menu.xml b/app/code/core/Mage/Tax/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..45c01318879ed
--- /dev/null
+++ b/app/code/core/Mage/Tax/etc/adminhtml/menu.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Tax
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Tax::sales_tax" title="Tax" module="Mage_Tax" sortOrder="500" parent="Mage_Sales::sales" />
+        <add id="Mage_Tax::sales_tax_rules" title="Manage Tax Rules" module="Mage_Tax" parent="Mage_Tax::sales_tax" action="adminhtml/tax_rule" />
+        <add id="Mage_Tax::sales_tax_rates" title="Manage Tax Zones &amp; Rates" module="Mage_Tax" parent="Mage_Tax::sales_tax" action="adminhtml/tax_rate" />
+        <add id="Mage_Tax::sales_tax_import_export" title="Import / Export Tax Rates" module="Mage_Tax" parent="Mage_Tax::sales_tax" action="adminhtml/tax_rate/importExport" />
+        <add id="Mage_Tax::sales_tax_classes_customer" title="Customer Tax Classes" module="Mage_Tax" parent="Mage_Tax::sales_tax" action="adminhtml/tax_class_customer" />
+        <add id="Mage_Tax::sales_tax_classes_product" title="Product Tax Classes" module="Mage_Tax" parent="Mage_Tax::sales_tax" action="adminhtml/tax_class_product" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/User/controllers/Adminhtml/User/RoleController.php b/app/code/core/Mage/User/controllers/Adminhtml/User/RoleController.php
index df13f2a593fd8..041f4651c6195 100644
--- a/app/code/core/Mage/User/controllers/Adminhtml/User/RoleController.php
+++ b/app/code/core/Mage/User/controllers/Adminhtml/User/RoleController.php
@@ -42,7 +42,7 @@ class Mage_User_Adminhtml_User_RoleController extends Mage_Backend_Controller_Ac
     protected function _initAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('system/acl');
+        $this->_setActiveMenu('Mage_User::system_acl_roles');
         $this->_addBreadcrumb($this->__('System'), $this->__('System'));
         $this->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'));
         $this->_addBreadcrumb($this->__('Roles'), $this->__('Roles'));
diff --git a/app/code/core/Mage/User/controllers/Adminhtml/UserController.php b/app/code/core/Mage/User/controllers/Adminhtml/UserController.php
index 46fc915c04297..8a219f7181f04 100644
--- a/app/code/core/Mage/User/controllers/Adminhtml/UserController.php
+++ b/app/code/core/Mage/User/controllers/Adminhtml/UserController.php
@@ -29,7 +29,7 @@ class Mage_User_Adminhtml_UserController extends Mage_Backend_Controller_ActionA
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('system/acl')
+            ->_setActiveMenu('Mage_User::system_acl_users')
             ->_addBreadcrumb($this->__('System'), $this->__('System'))
             ->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'))
             ->_addBreadcrumb($this->__('Users'), $this->__('Users'))
diff --git a/app/code/core/Mage/User/etc/adminhtml.xml b/app/code/core/Mage/User/etc/adminhtml.xml
index 6643bfe6fcd29..2bd53767de4db 100644
--- a/app/code/core/Mage/User/etc/adminhtml.xml
+++ b/app/code/core/Mage/User/etc/adminhtml.xml
@@ -26,27 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <system>
-            <children>
-                <acl translate="title" module="Mage_User">
-                    <title>Permissions</title>
-                    <sort_order>70</sort_order>
-                    <children>
-                        <users translate="title">
-                            <title>Users</title>
-                            <action>adminhtml/user</action>
-                        </users>
-                        <roles translate="title">
-                            <title>Roles</title>
-                            <action>adminhtml/user_role</action>
-                        </roles>
-                    </children>
-                </acl>
-            </children>
-        </system>
-    </menu>
-
     <acl>
         <resources>
             <admin>
diff --git a/app/code/core/Mage/User/etc/adminhtml/menu.xml b/app/code/core/Mage/User/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..51a2b19a44c17
--- /dev/null
+++ b/app/code/core/Mage/User/etc/adminhtml/menu.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_User
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_User::system_acl" title="Permissions" module="Mage_User" sortOrder="70" parent="Mage_Adminhtml::system" />
+        <add id="Mage_User::system_acl_users" title="Users" module="Mage_User" parent="Mage_User::system_acl" action="adminhtml/user" />
+        <add id="Mage_User::system_acl_roles" title="Roles" module="Mage_User" parent="Mage_User::system_acl" action="adminhtml/user_role" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php b/app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php
index 74938d0e520ef..b33603ce0407f 100644
--- a/app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php
+++ b/app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php
@@ -51,7 +51,7 @@ protected function _getSession()
     protected function _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('cms/widgets')
+            ->_setActiveMenu('Mage_Widget::cms_widget_instance')
             ->_addBreadcrumb(Mage::helper('Mage_Widget_Helper_Data')->__('CMS'),
                 Mage::helper('Mage_Widget_Helper_Data')->__('CMS'))
             ->_addBreadcrumb(Mage::helper('Mage_Widget_Helper_Data')->__('Manage Widget Instances'),
diff --git a/app/code/core/Mage/Widget/etc/adminhtml.xml b/app/code/core/Mage/Widget/etc/adminhtml.xml
index fec21459c7dbc..fbe413f42b72f 100644
--- a/app/code/core/Mage/Widget/etc/adminhtml.xml
+++ b/app/code/core/Mage/Widget/etc/adminhtml.xml
@@ -42,15 +42,4 @@
             </admin>
         </resources>
     </acl>
-    <menu>
-        <cms>
-            <children>
-                <widget_instance translate="title" module="Mage_Widget">
-                    <title>Widgets</title>
-                    <sort_order>15</sort_order>
-                    <action>adminhtml/widget_instance</action>
-                </widget_instance>
-            </children>
-        </cms>
-    </menu>
 </config>
diff --git a/app/code/core/Mage/Widget/etc/adminhtml/menu.xml b/app/code/core/Mage/Widget/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..5f68b0a238a26
--- /dev/null
+++ b/app/code/core/Mage/Widget/etc/adminhtml/menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Widget
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Widget::cms_widget_instance" title="Widgets" module="Mage_Widget" sortOrder="15" parent="Mage_Cms::cms" action="adminhtml/widget_instance" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php b/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php
index b31778c3ce059..204bddad2947a 100644
--- a/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php
+++ b/app/code/core/Mage/XmlConnect/controllers/Adminhtml/MobileController.php
@@ -88,7 +88,7 @@ protected function _restoreSessionFilesFormData($data)
     public function indexAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/mobile');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_mobile');
         $this->renderLayout();
     }
 
@@ -101,7 +101,7 @@ public function newAction()
     {
         Mage::getSingleton('Mage_Adminhtml_Model_Session')->setData('new_application', true);
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/mobile');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_mobile');
         $this->renderLayout();
     }
 
@@ -130,7 +130,7 @@ public function submissionAction()
             }
 
             $this->loadLayout();
-            $this->_setActiveMenu('xmlconnect/mobile');
+            $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_mobile');
             $this->renderLayout();
         } catch (Mage_Core_Exception $e) {
             $this->_getSession()->addError($e->getMessage());
@@ -190,7 +190,7 @@ public function editAction()
             $app->setDevtype($deviceTitle);
             $app->loadSubmit();
             $this->loadLayout();
-            $this->_setActiveMenu('xmlconnect/mobile');
+            $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_mobile');
             $this->renderLayout();
         } catch (Mage_Core_Exception $e) {
             $this->_getSession()->addError($e->getMessage());
@@ -786,7 +786,7 @@ protected function _isAllowed()
     public function historyAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/history');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_history');
         $this->renderLayout();
     }
 
@@ -798,7 +798,7 @@ public function historyAction()
     public function gridAction()
     {
         $this->loadLayout(false);
-        $this->_setActiveMenu('xmlconnect/mobile');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_mobile');
         $this->renderLayout();
     }
 
@@ -957,7 +957,7 @@ protected function _initTemplate($paramName = 'id')
     public function queueAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/queue');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_queue');
         $this->renderLayout();
     }
 
@@ -1223,7 +1223,7 @@ protected function _getQueueMessageParams(Mage_XmlConnect_Model_Queue $message)
     public function templateAction()
     {
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/template');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_templates');
         $this->renderLayout();
     }
 
@@ -1254,7 +1254,7 @@ public function editTemplateAction()
         }
 
         $this->loadLayout();
-        $this->_setActiveMenu('xmlconnect/templates');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_templates');
         $this->renderLayout();
     }
 
@@ -1344,7 +1344,7 @@ public function queueMessageAction()
         );
         $this->_addBreadcrumb($title, $title);
 
-        $this->_setActiveMenu('xmlconnect/queue');
+        $this->_setActiveMenu('Mage_XmlConnect::xmlconnect_queue');
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/XmlConnect/etc/adminhtml.xml b/app/code/core/Mage/XmlConnect/etc/adminhtml.xml
index 2ae741a420537..924f7d04351f3 100644
--- a/app/code/core/Mage/XmlConnect/etc/adminhtml.xml
+++ b/app/code/core/Mage/XmlConnect/etc/adminhtml.xml
@@ -26,34 +26,6 @@
  */
 -->
 <config>
-    <menu>
-        <xmlconnect translate="title" module="Mage_XmlConnect">
-            <title>Mobile</title>
-            <sort_order>35</sort_order>
-            <children>
-                <mobile translate="title" module="Mage_XmlConnect">
-                    <title>Manage Apps</title>
-                    <sort_order>10</sort_order>
-                    <action>adminhtml/mobile</action>
-                </mobile>
-                <history translate="title" module="Mage_XmlConnect">
-                    <title>Submission History</title>
-                    <sort_order>20</sort_order>
-                    <action>adminhtml/mobile/history</action>
-                </history>
-                <templates translate="title" module="Mage_XmlConnect">
-                    <title>Message Templates</title>
-                    <sort_order>30</sort_order>
-                    <action>adminhtml/mobile/template</action>
-                </templates>
-                <queue translate="title" module="Mage_XmlConnect">
-                    <title>Message Queue</title>
-                    <sort_order>40</sort_order>
-                    <action>adminhtml/mobile/queue</action>
-                </queue>
-            </children>
-        </xmlconnect>
-    </menu>
     <acl>
         <resources>
             <admin translate="title" module="Mage_XmlConnect">
diff --git a/app/code/core/Mage/XmlConnect/etc/adminhtml/menu.xml b/app/code/core/Mage/XmlConnect/etc/adminhtml/menu.xml
new file mode 100644
index 0000000000000..542582c94e2f7
--- /dev/null
+++ b/app/code/core/Mage/XmlConnect/etc/adminhtml/menu.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_XmlConnect
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_XmlConnect::xmlconnect" title="Mobile" module="Mage_XmlConnect" sortOrder="35" />
+        <add id="Mage_XmlConnect::xmlconnect_mobile" title="Manage Apps" module="Mage_XmlConnect" sortOrder="10" parent="Mage_XmlConnect::xmlconnect" action="adminhtml/mobile" />
+        <add id="Mage_XmlConnect::xmlconnect_history" title="Submission History" module="Mage_XmlConnect" sortOrder="20" parent="Mage_XmlConnect::xmlconnect" action="adminhtml/mobile/history" />
+        <add id="Mage_XmlConnect::xmlconnect_templates" title="Message Templates" module="Mage_XmlConnect" sortOrder="30" parent="Mage_XmlConnect::xmlconnect" action="adminhtml/mobile/template" />
+        <add id="Mage_XmlConnect::xmlconnect_queue" title="Message Queue" module="Mage_XmlConnect" sortOrder="40" parent="Mage_XmlConnect::xmlconnect" action="adminhtml/mobile/queue" />
+    </menu>
+</config>
diff --git a/app/design/frontend/default/iphone/Mage_Persistent/checkout/onepage/login.phtml b/app/design/frontend/default/iphone/Mage_Persistent/checkout/onepage/login.phtml
index e9c1446a2ac9e..496b4e04ccdcd 100644
--- a/app/design/frontend/default/iphone/Mage_Persistent/checkout/onepage/login.phtml
+++ b/app/design/frontend/default/iphone/Mage_Persistent/checkout/onepage/login.phtml
@@ -52,7 +52,7 @@
                         <input type="password" class="input-text required-entry" id="login-password" name="login[password]" />
                     </div>
                 </li>
-                <?php echo $this->getChildHtml('form.additional.info'); ?>
+                <?php echo $this->getChildHtml('login.form.additional.info'); ?>
                 <?php echo $this->getChildHtml('persistent.remember.me'); ?>
                 <li class="note">
                     <a href="<?php echo $this->getUrl('customer/account/forgotpassword') ?>" class="f-left"><?php echo $this->__('Forgot your password?') ?></a>
diff --git a/app/etc/modules/Mage_Captcha.xml b/app/etc/modules/Mage_Captcha.xml
index ef84e715540e5..af5586df97a5a 100755
--- a/app/etc/modules/Mage_Captcha.xml
+++ b/app/etc/modules/Mage_Captcha.xml
@@ -32,6 +32,7 @@
             <codePool>core</codePool>
             <depends>
                 <Mage_Customer />
+                <Mage_Checkout />
                 <Mage_Adminhtml />
             </depends>
         </Mage_Captcha>
diff --git a/dev/tests/integration/framework/Magento/Test/Bootstrap.php b/dev/tests/integration/framework/Magento/Test/Bootstrap.php
index 3ba6f13e547cd..249eca8d2c12b 100644
--- a/dev/tests/integration/framework/Magento/Test/Bootstrap.php
+++ b/dev/tests/integration/framework/Magento/Test/Bootstrap.php
@@ -308,6 +308,12 @@ public function getAppOptions()
      */
     protected function _resetApp()
     {
+        /** @var $layout Mage_Core_Model_Layout */
+        $layout = Mage::registry('_singleton/Mage_Core_Model_Layout');
+        if ($layout) {
+            /* Force to cleanup circular references */
+            $layout->__destruct();
+        }
         Mage::reset();
         Varien_Data_Form::setElementRenderer(null);
         Varien_Data_Form::setFieldsetRenderer(null);
diff --git a/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php b/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
index b29bce1183c32..950d585c1c7f9 100644
--- a/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
+++ b/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
@@ -72,6 +72,12 @@ protected function setUp()
         $this->_runOptions['response']  = $this->getResponse();
     }
 
+    protected function tearDown()
+    {
+        $this->_request = null;
+        $this->_response = null;
+    }
+
     /**
      * Run request
      *
diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php
index 537e24cd8f67c..77a3eb23443d9 100644
--- a/dev/tests/integration/framework/bootstrap.php
+++ b/dev/tests/integration/framework/bootstrap.php
@@ -114,7 +114,7 @@
     $localXmlFile,
     $globalEtcFiles,
     $moduleEtcFiles,
-     'etc/integration-tests-config.xml',
+    'etc/integration-tests-config.xml',
     $testsTmpDir,
     $cleanupAction,
     $developerMode
diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist
index 1c67347fe389d..54740502f97b2 100644
--- a/dev/tests/integration/phpunit.xml.dist
+++ b/dev/tests/integration/phpunit.xml.dist
@@ -31,6 +31,7 @@
     <testsuites>
         <testsuite name="Magento Integration Tests">
             <directory suffix="Test.php">testsuite</directory>
+            <exclude>testsuite/integrity</exclude>
         </testsuite>
     </testsuites>
      <!-- Code coverage filters -->
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Customer/Edit/Tab/View/AccordionTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Customer/Edit/Tab/View/AccordionTest.php
index dc7355c0cd857..9a527e327edaf 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Customer/Edit/Tab/View/AccordionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Customer/Edit/Tab/View/AccordionTest.php
@@ -41,6 +41,11 @@ protected function setUp()
         $this->_block = $layout->createBlock('Mage_Adminhtml_Block_Customer_Edit_Tab_View_Accordion');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Customer/_files/customer.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Dashboard/GraphTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Dashboard/GraphTest.php
index 1f38967302d65..63abdbc2204b2 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Dashboard/GraphTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Dashboard/GraphTest.php
@@ -38,6 +38,11 @@ protected function setUp()
         $this->_block->setDataHelperName('Mage_Adminhtml_Helper_Dashboard_Order');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetChartUrl()
     {
         $this->assertStringStartsWith('http://chart.apis.google.com/chart', $this->_block->getChartUrl());
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeaderTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeaderTest.php
index 986337833a625..c5c35edc17b6f 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeaderTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeaderTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_block = new Mage_Adminhtml_Block_Page_Header;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetHomeLink()
     {
         $expected = Mage::helper('Mage_Backend_Helper_Data')->getHomePageUrl();
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Report/Sales/Bestsellers/GridTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Report/Sales/Bestsellers/GridTest.php
index 9d5b2755a32a6..50bfa21e3ee64 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Report/Sales/Bestsellers/GridTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Report/Sales/Bestsellers/GridTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_Adminhtml_Block_Report_Sales_Bestsellers_Grid;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetResourceCollectionName()
     {
         $collectionName = $this->_block->getResourceCollectionName();
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Controller/ActionTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Controller/ActionTest.php
index a615167a29620..2c6d0f6f7cc8c 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Controller/ActionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Controller/ActionTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstruct()
     {
         $this->assertInstanceOf('Mage_Backend_Controller_ActionAbstract', $this->_model);
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Model/Sales/Order/CreateTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Model/Sales/Order/CreateTest.php
index e00d792896391..7fbe9453358d7 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Model/Sales/Order/CreateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Model/Sales/Order/CreateTest.php
@@ -39,6 +39,11 @@ public function setUp()
         $this->_model = new Mage_Adminhtml_Model_Sales_Order_Create();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Downloadable/_files/product.php
      * @magentoDataFixture Mage/Downloadable/_files/order_with_downloadable_product.php
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php
new file mode 100644
index 0000000000000..40ca1a1578c88
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Adminhtml
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test Mage_Adminhtml_Model_System_Config_Source_Admin_Page
+ */
+class Mage_Adminhtml_Model_System_Config_Source_Admin_PageTest extends Mage_Adminhtml_Utility_Controller
+{
+    public function testToOptionArray()
+    {
+        $this->dispatch('admin/system_config/edit/section/admin');
+
+        $dom = new DomDocument();
+        $dom->loadHTML($this->getResponse()->getBody());
+        $select = $dom->getElementById('admin_startup_menu_item_id');
+
+        $this->assertNotEmpty($select, 'Startup Page select missed');
+        $options = $select->getElementsByTagName('option');
+        $optionsCount = $options->length;
+
+        $this->assertGreaterThan(98, $optionsCount, 'Paucity count of menu items in the list');
+
+        $this->assertEquals('Dashboard', $options->item(0)->nodeValue, 'First element is not Dashboard');
+        $this->assertContains('Configuration', $options->item($optionsCount - 1)->nodeValue);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Utility/Controller.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Utility/Controller.php
index 954b17e906a24..d52265f34c504 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Utility/Controller.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Utility/Controller.php
@@ -56,6 +56,9 @@ protected function setUp()
     protected function tearDown()
     {
         $this->_auth->logout();
+        $this->_auth = null;
+        $this->_session = null;
+
         Mage::getSingleton('Mage_Backend_Model_Url')->turnOnSecretKey();
 
         parent::tearDown();
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Backend/Block/TemplateTest.php
index cb81900c00c20..dc8b0c06e1de0 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Block/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/TemplateTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_block = new Mage_Backend_Block_Template;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @covers Mage_Backend_Block_Template::getFormKey
      */
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Controller/Router/DefaultTest.php b/dev/tests/integration/testsuite/Mage/Backend/Controller/Router/DefaultTest.php
index a5649ccc7ef70..bbedcf0bef262 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Controller/Router/DefaultTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Controller/Router/DefaultTest.php
@@ -39,7 +39,12 @@ protected function setUp()
             'base_controller' => 'Mage_Backend_Controller_ActionAbstract'
         );
         $this->_model = new Mage_Backend_Controller_Router_Default($options);
-        $this->_model->setFront(Mage::app()->getFrontController());
+        $this->_model->setFront(new Mage_Core_Controller_Varien_Front());
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
     }
 
     /**
@@ -61,8 +66,9 @@ public function testFetchDefault()
             'controller' => 'index',
             'action' => 'index'
         );
+        $this->assertEmpty($this->_model->getFront()->getDefault());
         $this->_model->fetchDefault();
-        $this->assertEquals($default, Mage::app()->getFrontController()->getDefault());
+        $this->assertEquals($default, $this->_model->getFront()->getDefault());
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Backend/Helper/DataTest.php
index 383211ae2ffa8..18f79f5d3f07f 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Helper/DataTest.php
@@ -40,6 +40,16 @@ class Mage_Backend_Helper_DataTest extends PHPUnit_Framework_TestCase
      */
     protected $_auth;
 
+    protected function setUp()
+    {
+        $this->_helper = Mage::helper('Mage_Backend_Helper_Data');
+    }
+
+    protected function tearDown()
+    {
+        $this->_helper = null;
+        $this->_auth = null;
+    }
 
     /**
      * Performs user login
@@ -60,12 +70,6 @@ protected function _logout()
         Mage::getSingleton('Mage_Backend_Model_Url')->turnOnSecretKey();
     }
 
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->_helper = Mage::helper('Mage_Backend_Helper_Data');
-    }
-
     /**
      * @covers Mage_Backend_Helper_Data::getPageHelpUrl
      * @covers Mage_Backend_Helper_Data::setPageHelpUrl
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/Auth/SessionTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/Auth/SessionTest.php
index 5d1b6e20d4e71..ece0a121444e0 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Model/Auth/SessionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/Auth/SessionTest.php
@@ -39,7 +39,7 @@ class Mage_Backend_Model_Auth_SessionTest extends PHPUnit_Framework_TestCase
      * @var Mage_Backend_Model_Auth_Session
      */
     protected $_model;
-    
+
     public function setUp()
     {
         $this->_auth  = new Mage_Backend_Model_Auth();
@@ -47,6 +47,11 @@ public function setUp()
         $this->_auth->setAuthStorage($this->_model);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Disabled form security in order to prevent exit from the app
      * @magentoConfigFixture current_store admin/security/session_lifetime 100
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/AuthTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/AuthTest.php
index 49792feb20940..5a64297fd3860 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Model/AuthTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/AuthTest.php
@@ -42,6 +42,11 @@ public function setUp()
         $this->_model = new Mage_Backend_Model_Auth();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @expectedException Mage_Backend_Model_Auth_Exception
      */
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/MenuTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/MenuTest.php
new file mode 100644
index 0000000000000..d1ae170c39ec1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/MenuTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_Backend_Model_Auth.
+ *
+ * @group module:Mage_Backend
+ */
+class Mage_Backend_Model_MenuTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new Mage_Backend_Model_Auth();
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testMenuItemManipulation()
+    {
+        /* @var $menu Mage_Backend_Model_Menu */
+        $menu = Mage::getSingleton('Mage_Backend_Model_Menu_Config')->getMenu();
+        /* @var $itemFactory Mage_Backend_Model_Menu_Item_Factory */
+        $itemFactory = Mage::getModel('Mage_Backend_Model_Menu_Item_Factory');
+
+        // Add new item in top level
+        $menu->add($itemFactory->createFromArray(array(
+            'id' => 'Mage_Backend::system2',
+            'title' => 'Extended System',
+            'module' => 'Mage_Backend',
+        )));
+
+         //Add submenu
+        $menu->add($itemFactory->createFromArray(array(
+            'id' => 'Mage_Backend::system2_acl',
+            'title' => 'Acl',
+            'module' => 'Mage_Backend',
+            'action' => 'admin/backend/acl/index'
+        )), 'Mage_Backend::system2');
+
+        // Modify existing menu item
+        $menu->get('Mage_Backend::system2')->setTitle('Base system')
+            ->setAction('admin/backend/system/base'); // remove dependency from config
+
+        // Change sort order
+        $menu->reorder('Mage_Backend::system', 40);
+
+        // Remove menu item
+        $menu->remove('Mage_Backend::catalog_attribute');
+
+        // Move menu item
+        $menu->move('Mage_Catalog::catalog_products', 'Mage_Backend::system2');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/ObserverTest.php
index 5763c7e5a1b33..90c74085354d8 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/ObserverTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Backend_Model_Observer();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testActionPreDispatchAdminNotLogged()
     {
         $this->markTestSkipped('Skipped because of authentication process moved into base controller.');
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/UrlTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/UrlTest.php
index 9cfbbed6fbef6..a7a4148f1d0cb 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Model/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/UrlTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_Backend_Model_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @covers Mage_Backend_Model_Url::getSecure
      */
diff --git a/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/AuthControllerTest.php b/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/AuthControllerTest.php
index e21e9e0dc506a..797440aeac16a 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/AuthControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/AuthControllerTest.php
@@ -41,10 +41,12 @@ class Mage_Backend_Adminhtml_AuthControllerTest extends Magento_Test_TestCase_Co
      */
     protected $_auth;
 
-    /**
-     * @var Mage_User_Model_User
-     */
-    protected static $_newUser;
+    protected function tearDown()
+    {
+        $this->_session = null;
+        $this->_auth = null;
+        parent::tearDown();
+    }
 
     /**
      * Performs user login
@@ -176,24 +178,6 @@ public function testIncorrectLogin($params)
         $this->assertContains('Invalid User Name or Password', $this->getResponse()->getBody());
     }
 
-    public static function userDataFixture()
-    {
-        self::$_newUser = new Mage_User_Model_User;
-        self::$_newUser->setFirstname('admin_role')
-            ->setUsername('test2')
-            ->setPassword(Magento_Test_Bootstrap::ADMIN_PASSWORD)
-            ->setIsActive(1)
-            ->save();
-
-        self::$_newUser = new Mage_User_Model_User;
-        self::$_newUser->setFirstname('admin_role')
-            ->setUsername('test3')
-            ->setPassword(Magento_Test_Bootstrap::ADMIN_PASSWORD)
-            ->setIsActive(0)
-            ->setRoleId(1)
-            ->save();
-    }
-
     public function incorrectLoginDataProvider()
     {
         return array(
diff --git a/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/IndexControllerTest.php b/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/IndexControllerTest.php
index a0070b8733cd1..b2a172ce340b5 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/IndexControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/controllers/Adminhtml/IndexControllerTest.php
@@ -36,6 +36,12 @@ class Mage_Backend_Adminhtml_IndexControllerTest extends Magento_Test_TestCase_C
      */
     protected $_auth;
 
+    protected function tearDown()
+    {
+        $this->_auth = null;
+        parent::tearDown();
+    }
+
     /**
      * Performs user login
      */
diff --git a/dev/tests/integration/testsuite/Mage/Bundle/Model/ProductTest.php b/dev/tests/integration/testsuite/Mage/Bundle/Model/ProductTest.php
index a30109d818b62..0135bc640757b 100644
--- a/dev/tests/integration/testsuite/Mage/Bundle/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/Bundle/Model/ProductTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_BUNDLE);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetTypeId()
     {
         $this->assertEquals(Mage_Catalog_Model_Product_Type::TYPE_BUNDLE, $this->_model->getTypeId());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/AbstractTest.php
index c5bdc714d3908..7f374365e88b4 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/AbstractTest.php
@@ -56,6 +56,12 @@ protected function setUp()
         $this->_block->setProduct($this->_product);
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_product = null;
+    }
+
     public function testGetAddToCartUrl()
     {
         $url = $this->_block->getAddToCartUrl($this->_product);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ListTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ListTest.php
index eee91dfbd1e45..68573aee64f6d 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ListTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ListTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_block = new Mage_Catalog_Block_Product_List;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetLayer()
     {
         $this->assertInstanceOf('Mage_Catalog_Model_Layer', $this->_block->getLayer());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php
index fc302833bcd03..3e60514602cf3 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_block = new Mage_Catalog_Block_Product_New;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetCacheKeyInfo()
     {
         $info = $this->_block->getCacheKeyInfo();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ViewTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ViewTest.php
index 3d91f38be0bcc..e1816ccdee903 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ViewTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/ViewTest.php
@@ -52,6 +52,12 @@ protected function setUp()
         Mage::register('product', $this->_product);
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_product = null;
+    }
+
     public function testSetLayout()
     {
         $layout = new Mage_Core_Model_Layout();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Category/FlatTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Category/FlatTest.php
index 759102133b062..064f492a5b38d 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Category/FlatTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Category/FlatTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Category_Flat;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testIsEnabledDefault()
     {
         $this->assertFalse($this->_helper->isEnabled());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/CategoryTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/CategoryTest.php
index 790b5918b2d45..8a932c6c0b4a7 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/CategoryTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Category;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/categories.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/DataTest.php
index 5dd7bfd980c74..f6d61b9617451 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/DataTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Data;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/categories.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/ImageTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/ImageTest.php
index 6e4c763543ff8..e6dc672d8b907 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/ImageTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/ImageTest.php
@@ -95,6 +95,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Image;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * init()
      * __toString()
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/MapTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/MapTest.php
index 0092e98e57ad3..dab5858cec395 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/MapTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/MapTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Map;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetCategoryUrl()
     {
         $this->assertStringEndsWith('/catalog/seo_sitemap/category/', $this->_helper->getCategoryUrl());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/OutputTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/OutputTest.php
index 940ad034d41b7..38b2c6f1719b7 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/OutputTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/OutputTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Output;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * addHandler()
      * getHandlers()
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/CompareTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/CompareTest.php
index 69ad82b7d63fe..41b30bf0d2c46 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/CompareTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/CompareTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Product_Compare;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/two_products.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/FlatTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/FlatTest.php
index e379dd0c02677..b79a093910de3 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/FlatTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/FlatTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Product_Flat;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetFlag()
     {
         $flag = $this->_helper->getFlag();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/UrlTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/UrlTest.php
index 2dd12cdca19d9..597e5dc56f64e 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/UrlTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Product_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetConvertTable()
     {
         $convertTable = $this->_helper->getConvertTable();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/ViewTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/ViewTest.php
index 73afe033a192b..9225bf777314f 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/ViewTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/Product/ViewTest.php
@@ -55,6 +55,8 @@ protected function setUp()
     protected function tearDown()
     {
         Mage::getSingleton('Mage_Catalog_Model_Session')->unsLastViewedProductId();
+        $this->_controller = null;
+        $this->_helper = null;
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Helper/ProductTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Helper/ProductTest.php
index a19e52b4b1403..f021608fc8ef9 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Helper/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Helper/ProductTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_Catalog_Helper_Product;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/products.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/AbstractTest.php
index 25973e307d2c7..ad15c1f6c3e85 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/AbstractTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $collectionProperty->setValue($this->_model, 'Mage_Catalog_Model_Resource_Product_Collection');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @covers Mage_Catalog_Model_Abstract::lockAttribute
      * @covers Mage_Catalog_Model_Abstract::unlockAttribute
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php
index b33d3a09ef488..dc5736cf589a6 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php
@@ -41,6 +41,11 @@ protected function setUp()
         Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testCRUD()
     {
         // @codingStandardsIgnoreStart
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
index 416ffafdf91f7..b94563d72f099 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
@@ -43,6 +43,11 @@ protected function setUp()
         Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testLevel()
     {
         $default = $this->_model->level();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php
index 53868ae9da765..359802982fe3a 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Category_Attribute_Api;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testItems()
     {
         $attributes = $this->_model->items();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/CategoryImageTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/CategoryImageTest.php
index aa5bf5490ca57..7626e1690d80b 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/CategoryImageTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/CategoryImageTest.php
@@ -55,8 +55,13 @@ public static function setUpBeforeClass()
     public static function tearDownAfterClass()
     {
         Mage::app()->getStore()->setConfig('dev/log/active', self::$_oldLogActive);
+        self::$_oldLogActive = null;
+
         Mage::app()->getStore()->setConfig('dev/log/exception_file', self::$_oldExceptionFile);
+        self::$_oldExceptionFile = null;
+
         Mage::getConfig()->setNode('global/log/core/writer_model', self::$_oldWriterModel);
+        self::$_oldWriterModel = null;
 
         Stub_Mage_Catalog_Model_CategoryTest_Zend_Log_Writer_Stream::$exceptions = array();
 
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTest.php
index de74019931b8f..fec6b0aef762f 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTest.php
@@ -44,6 +44,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Category();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetUrlInstance()
     {
         $instance = $this->_model->getUrlInstance();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTreeTest.php
index f83bdcc48c4fb..35e96f329e633 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTreeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTreeTest.php
@@ -44,6 +44,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Category();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testMove()
     {
         $this->_model->load(7);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/DesignTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/DesignTest.php
index 1737bfcc0c615..f1a35322c92b1 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/DesignTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/DesignTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Design();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testApplyCustomDesign()
     {
         $this->_model->applyCustomDesign('package/theme/skin');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/AttributeTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/AttributeTest.php
index b85149a708cee..c8a64f1db2e0c 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/AttributeTest.php
@@ -61,6 +61,11 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testApplyInvalid()
     {
         $this->assertEmpty($this->_model->getLayer()->getState()->getFilters());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/CategoryTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/CategoryTest.php
index 4f6cdbde871fb..4e44679101475 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/CategoryTest.php
@@ -54,6 +54,12 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_category = null;
+    }
+
     public function testGetResetValue()
     {
         $this->assertNull($this->_model->getResetValue());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/DecimalTest.php
index b4bbb9f98cfcb..af3a54bc6a7e6 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/DecimalTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/DecimalTest.php
@@ -55,6 +55,11 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testApplyNothing()
     {
         $this->assertEmpty($this->_model->getData('range'));
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/ItemTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/ItemTest.php
index cf68a851e1c25..e402536de154b 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/ItemTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/ItemTest.php
@@ -43,6 +43,11 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetFilter()
     {
         $filter = $this->_model->getFilter();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
index 0ff09274d9671..68f3802a97dde 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
@@ -44,6 +44,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Layer_Filter_Price_Algorithm();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Prepare price filter model
      *
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php
index 6c70c97292866..dcc3058dca5b5 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php
@@ -63,6 +63,13 @@ protected function setUp()
             ->setAttributeModel(new Varien_Object(array('attribute_code' => 'price')));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_layer = null;
+        $this->_filter = null;
+    }
+
     /**
      * @dataProvider pricesSegmentationDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/PriceTest.php
index 146b12bfafd2f..9bdbaf543fbda 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/PriceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/PriceTest.php
@@ -49,6 +49,11 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoConfigFixture current_store catalog/layered_navigation/price_range_calculation auto
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/LayerTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/LayerTest.php
index 69007d705b58d..dfbec778db2e0 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/LayerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/LayerTest.php
@@ -43,6 +43,11 @@ protected function setUp()
         $this->_model->setCurrentCategory(4);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetStateKey()
     {
         $this->assertEquals('STORE_1_CAT_4_CUSTGROUP_0', $this->_model->getStateKey());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
index 93f2eed1e5411..c6fb76a10d1d6 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Attribute_Api;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testItems()
     {
         $items = $this->_model->items(4); /* default product attribute set after installation */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
index db5575f182a26..0161ebaf0c4c2 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
@@ -74,6 +74,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testAfterLoad()
     {
         $product = new Mage_Catalog_Model_Product();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/PriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/PriceTest.php
index 1325c3964796e..cb713699523f8 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/PriceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/PriceTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetScopeDefault()
     {
         /* validate result of setAttribute */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php
index 48934bf7f89f0..b82d99ad05c0c 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php
@@ -45,6 +45,10 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
 
     public function testValidate()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
index 75fb6abcdc484..456c3c85ca054 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
@@ -53,6 +53,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Attribute_Media_Api;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public static function setUpBeforeClass()
     {
         self::$_fixtureDir = realpath(__DIR__ . '/../../../../_files');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php
index ebded4b43f36e..0a9c3022e2153 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @expectedException Mage_Api_Exception
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php
index 98c9a0abc3d89..144f92211b5aa 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Attribute_Tierprice_Api;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testInfo()
     {
         $info = $this->_model->info(1);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php
index 4888cbb003b10..f595a3aa91655 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = $this->getMockForAbstractClass('Mage_Catalog_Model_Product_Type_Abstract');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetRelationInfo()
     {
         $info = $this->_model->getRelationInfo();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/Configurable/AttributeTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/Configurable/AttributeTest.php
index ed6e4b1b717aa..0dec8fec6c5dc 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/Configurable/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/Configurable/AttributeTest.php
@@ -37,6 +37,10 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Type_Configurable_Attribute;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
     public function testAddPrice()
     {
         $this->assertEmpty($this->_model->getPrices());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
index fda199a8d03aa..3ad7031baaf2b 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
@@ -50,6 +50,11 @@ protected function setUp()
         $this->_product->setTypeInstance($this->_model);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetRelationInfo()
     {
         $info = $this->_model->getRelationInfo();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/PriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/PriceTest.php
index 656ef135a7c9b..7e6866d8e0a51 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/PriceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/PriceTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Type_Price;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetPrice()
     {
         $this->assertEquals('test', $this->_model->getPrice(new Varien_Object(array('price' => 'test'))));
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/UrlTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/UrlTest.php
index 00cdf288a0111..94fa5c5d0a3c2 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/UrlTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetUrlInstance()
     {
         $instance = $this->_model->getUrlInstance();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductExternalTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductExternalTest.php
index ced953e460e36..8c5cf739520a8 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductExternalTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductExternalTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetStoreId()
     {
         $this->assertEquals(Mage::app()->getStore()->getId(), $this->_model->getStoreId());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductGettersTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductGettersTest.php
index 4cc5bbf18fa54..356460b78523e 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductGettersTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductGettersTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetResourceCollection()
     {
         $collection = $this->_model->getResourceCollection();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductPriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductPriceTest.php
index 248925efa51bc..8d0e4be4980ea 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductPriceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductPriceTest.php
@@ -44,6 +44,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetPrice()
     {
         $this->assertEmpty($this->_model->getPrice());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductTest.php
index 2ab89df5da459..09af384decc03 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/ProductTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Product;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public static function tearDownAfterClass()
     {
         $config = Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Eav/AttributeTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Eav/AttributeTest.php
index 061a06343f860..30119de167f08 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Eav/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Eav/AttributeTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model= new Mage_Catalog_Model_Resource_Eav_Attribute();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testCRUD()
     {
         $this->_model->setAttributeCode('test')
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/CollectionTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/CollectionTest.php
index 922caf8b782dc..14171abcd60fd 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/CollectionTest.php
@@ -41,6 +41,11 @@ protected function setUp()
         $this->_collection = new Mage_Catalog_Model_Resource_Product_Collection;
     }
 
+    protected function tearDown()
+    {
+        $this->_collection = null;
+    }
+
     /**
      * @dataProvider setOrderDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/UrlTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/UrlTest.php
index e41e26415bc90..a2542fbc9b529 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/UrlTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Resource_Url();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/Model/Resource/_files/url_rewrites.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/UrlTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/UrlTest.php
index 56015dd907da3..fd49e2f7afeeb 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/UrlTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_Catalog_Model_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Retrieve loaded url rewrite
      *
diff --git a/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/ItemTest.php b/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/ItemTest.php
index 06affbcc92600..f1435b9e44c96 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/ItemTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/ItemTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_CatalogInventory_Model_Stock_Item;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Simple product with stock item
      */
diff --git a/dev/tests/integration/testsuite/Mage/CatalogRule/Model/RuleTest.php b/dev/tests/integration/testsuite/Mage/CatalogRule/Model/RuleTest.php
index 2f293daa42be8..318cdc3257e4a 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogRule/Model/RuleTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogRule/Model/RuleTest.php
@@ -40,12 +40,9 @@ protected function setUp()
         $this->_object = new Mage_CatalogRule_Model_Rule();
     }
 
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
     protected function tearDown()
     {
+        $this->_object = null;
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/Advanced/ResultTest.php b/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/Advanced/ResultTest.php
index 6f62e461848f7..76e7a61ecc4df 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/Advanced/ResultTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/Advanced/ResultTest.php
@@ -43,6 +43,12 @@ protected function setUp()
         $this->_block = $this->_layout->createBlock('Mage_CatalogSearch_Block_Advanced_Result', 'block');
     }
 
+    protected function tearDown()
+    {
+        $this->_layout = null;
+        $this->_block = null;
+    }
+
     /**
      * @magentoAppIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/TermTest.php b/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/TermTest.php
index 014fb4f7ca2f3..566590911dfbc 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/TermTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogSearch/Block/TermTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_CatalogSearch_Block_Term;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetSearchUrl()
     {
         $query = uniqid();
diff --git a/dev/tests/integration/testsuite/Mage/CatalogSearch/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/CatalogSearch/Helper/DataTest.php
index 046c515b4fe4f..e811d3ebdc20d 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogSearch/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogSearch/Helper/DataTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_CatalogSearch_Helper_Data;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetResultUrl()
     {
         $this->assertStringEndsWith('/catalogsearch/result/', $this->_helper->getResultUrl());
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Block/Cart/Item/RendererTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Block/Cart/Item/RendererTest.php
index 4137742064898..53fc2104e3ffb 100644
--- a/dev/tests/integration/testsuite/Mage/Checkout/Block/Cart/Item/RendererTest.php
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Block/Cart/Item/RendererTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_block->setItem($item);
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testThumbnail()
     {
         $size = $this->_block->getThumbnailSize();
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Block/Onepage/Payment/MethodsTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Block/Onepage/Payment/MethodsTest.php
index b8b4f6915bd04..34039502755dd 100644
--- a/dev/tests/integration/testsuite/Mage/Checkout/Block/Onepage/Payment/MethodsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Block/Onepage/Payment/MethodsTest.php
@@ -42,6 +42,11 @@ protected function setUp()
             ->createBlock('Mage_Checkout_Block_Onepage_Payment_Methods');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetMethodTitleAndMethodLabelAfterHtml()
     {
         $expectedTitle = 'Free Method';
diff --git a/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/ConfigTest.php
index 4cab585acd316..9f14a2f70f4fd 100644
--- a/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/ConfigTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Cms_Model_Wysiwyg_Config;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Tests that config returns valid config array in it
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
index 41b103797aa13..169671ad5de7d 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
@@ -46,6 +46,12 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_layout = null;
+    }
+
     public function testGetRequest()
     {
         $this->assertInstanceOf('Mage_Core_Controller_Request_Http', $this->_block->getRequest());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/FlushTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/FlushTest.php
index 05f6f7ff8db94..41de3b7966813 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/FlushTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/FlushTest.php
@@ -43,6 +43,12 @@ protected function setUp()
         $this->_block = $this->_layout->createBlock('Mage_Core_Block_Flush');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_layout = null;
+    }
+
     public function testToHtml()
     {
         $children = array(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
index 12b30c3813ad3..4802d6ea0ee3f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_Core_Block_Template;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testConstruct()
     {
         $block = new Mage_Core_Block_Template(array('template' => 'value'));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/Text/ListTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/Text/ListTest.php
index 4d58a4cf77935..efd898c7400f4 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/Text/ListTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/Text/ListTest.php
@@ -43,6 +43,12 @@ protected function setUp()
         $this->_block = $this->_layout->createBlock('Mage_Core_Block_Text_List');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_layout = null;
+    }
+
     public function testToHtml()
     {
         $children = array(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/TextTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/TextTest.php
index 7aa8be03e1d4a..6a9a1351ba6bb 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/TextTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/TextTest.php
@@ -42,7 +42,6 @@ public function tearDown()
         $this->_block = null;
     }
 
-
     public function testSetGetText()
     {
         $this->_block->setText('text');
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
index 5779e9c0b40fb..f613a19690b19 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Controller_Request_Http();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetOriginalPathInfo()
     {
         $this->assertEmpty($this->_model->getOriginalPathInfo());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
index 63ac4d88f252d..f928ba72c0060 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testHasAction()
     {
         $this->assertFalse($this->_model->hasAction('test'));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/FrontTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/FrontTest.php
index 25c5c2a0e5ac2..2abb99a7c2718 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/FrontTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/FrontTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Controller_Varien_Front;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetGetDefault()
     {
         $this->_model->setDefault('test', 'value');
@@ -63,8 +68,10 @@ public function testGetResponse()
     public function testAddGetRouter()
     {
         $router = new Mage_Core_Controller_Varien_Router_Default();
+        $this->assertNull($router->getFront());
         $this->_model->addRouter('test', $router);
-        $this->assertEquals($router, $this->_model->getRouter('test'));
+        $this->assertSame($this->_model, $router->getFront());
+        $this->assertSame($router, $this->_model->getRouter('test'));
         $this->assertEmpty($this->_model->getRouter('tt'));
     }
 
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/AbstractTest.php
new file mode 100644
index 0000000000000..d69c0355ac879
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/AbstractTest.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Core_Controller_Varien_Router_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Core_Controller_Varien_Router_Abstract
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = $this->getMockForAbstractClass('Mage_Core_Controller_Varien_Router_Abstract');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testGetSetFront()
+    {
+        $expected = new Mage_Core_Controller_Varien_Front();
+        $this->assertNull($this->_model->getFront());
+        $this->_model->setFront($expected);
+        $this->assertSame($expected, $this->_model->getFront());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/BaseTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/BaseTest.php
index 0976be7d269ac..82b4a6010dbdb 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/BaseTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/Router/BaseTest.php
@@ -39,7 +39,12 @@ protected function setUp()
             'base_controller' => 'Mage_Core_Controller_Front_Action'
         );
         $this->_model = new Mage_Core_Controller_Varien_Router_Base($options);
-        $this->_model->setFront(Mage::app()->getFrontController());
+        $this->_model->setFront(new Mage_Core_Controller_Varien_Front());
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
     }
 
     /**
@@ -79,8 +84,9 @@ public function testFetchDefault()
             'controller' => 'index',
             'action' => 'index'
         );
+        $this->assertEmpty($this->_model->getFront()->getDefault());
         $this->_model->fetchDefault();
-        $this->assertEquals($default, Mage::app()->getFrontController()->getDefault());
+        $this->assertEquals($default, $this->_model->getFront()->getDefault());
     }
 
     public function testMatch()
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/AbstractTest.php
index bcc1a72000596..8c9c457fba7a3 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/AbstractTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         ;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @covers Mage_Core_Helper_Abstract::isModuleEnabled
      * @covers Mage_Core_Helper_Abstract::isModuleOutputEnabled
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/DataTest.php
index e5c49e3078631..341a46dae9082 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/DataTest.php
@@ -55,6 +55,11 @@ public function setUp()
         $this->_dateTime->setTimezone(new DateTimeZone(self::DATE_TIMEZONE));
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetEncryptor()
     {
         $this->assertInstanceOf('Mage_Core_Model_Encryption', $this->_helper->getEncryptor());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/HttpTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/HttpTest.php
index 9b902a2487764..b0aa9be5bcd18 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/HttpTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/HttpTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_helper = new Mage_Core_Helper_Http;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetRemoteAddrHeaders()
     {
         $this->assertEquals(array(), $this->_helper->getRemoteAddrHeaders());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/JsTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/JsTest.php
index ac4280e03e6c7..79c21acfceee4 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/JsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/JsTest.php
@@ -39,6 +39,11 @@ public function setUp()
         $this->_helper = new Mage_Core_Helper_Js();
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetTranslateJson()
     {
         $this->assertNotNull(json_decode($this->_helper->getTranslateJson()));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/StringTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/StringTest.php
index c99759510723f..c4d61eafa5f68 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/StringTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/StringTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_helper = new Mage_Core_Helper_String;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @covers Mage_Core_Helper_String::truncate
      * @covers Mage_Core_Helper_String::strlen
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/Url/RewriteTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/Url/RewriteTest.php
index 445ef1f644beb..c84f33a102e27 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/Url/RewriteTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/Url/RewriteTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_helper = new Mage_Core_Helper_Url_Rewrite();
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @dataProvider requestPathDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Helper/UrlTest.php b/dev/tests/integration/testsuite/Mage/Core/Helper/UrlTest.php
index 3e38cf232c3df..16c90255944dd 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Helper/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Helper/UrlTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_helper = new Mage_Core_Helper_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testGetCurrentUrl()
     {
         $_SERVER['HTTP_HOST'] = 'example.com';
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
index 47546cb30a515..a6d8e2be63da1 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
@@ -34,7 +34,12 @@ class Mage_Core_Model_App_AreaTest extends PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->_model = new Mage_Core_Model_App_Area('frontend', new Mage_Core_Model_App);
+        $this->_model = new Mage_Core_Model_App_Area('frontend');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
     }
 
     /**
@@ -60,7 +65,7 @@ public function testInitDesign()
      */
     public function testDetectDesignGlobalConfig()
     {
-        $model = new Mage_Core_Model_App_Area('adminhtml', new Mage_Core_Model_App);
+        $model = new Mage_Core_Model_App_Area('adminhtml');
         $model->detectDesign();
         $this->assertEquals('default/default/default', Mage::getDesign()->getDesignTheme());
     }
@@ -110,7 +115,7 @@ public function testDetectDesignDesignChange()
     public function testDetectDesignNonFrontend()
     {
         $_SERVER['HTTP_USER_AGENT'] = 'Mozilla Firefox';
-        $model = new Mage_Core_Model_App_Area('install', new Mage_Core_Model_App);
+        $model = new Mage_Core_Model_App_Area('install');
         $model->detectDesign(new Zend_Controller_Request_Http);
         $this->assertNotEquals('default/modern/default', Mage::getDesign()->getDesignTheme());
         $this->assertNotEquals('default/default/blue', Mage::getDesign()->getDesignTheme());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
index 4d99e909fd74f..2c996be2fe9d7 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
@@ -53,6 +53,12 @@ protected function setUp()
         $this->_mageModel   = Mage::app();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_mageModel = null;
+    }
+
     public function testInit()
     {
         $this->assertNull($this->_model->getConfig());
@@ -117,11 +123,21 @@ public function errorHandler()
 
     /**
      * @magentoAppIsolation enabled
+     * @magentoConfigFixture current_store general/locale/code de_DE
      */
-    public function testLoadGetArea()
+    public function testLoadArea()
     {
+        $translator = Mage::app()->getTranslator();
+        $this->assertEmpty($translator->getConfig(Mage_Core_Model_Translate::CONFIG_KEY_LOCALE));
         $this->_model->loadArea('frontend');
-        $this->assertSame($this->_model, $this->_model->getArea('frontend')->getApplication());
+        $this->assertEquals('de_DE', $translator->getConfig(Mage_Core_Model_Translate::CONFIG_KEY_LOCALE));
+    }
+
+    public function testGetArea()
+    {
+        $area = $this->_model->getArea('frontend');
+        $this->assertInstanceOf('Mage_Core_Model_App_Area', $area);
+        $this->assertSame($area, $this->_model->getArea('frontend'));
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/CacheTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/CacheTest.php
index 40f3b108c4484..4959e062b8496 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/CacheTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/CacheTest.php
@@ -44,6 +44,7 @@ public function tearDown()
     {
         /* Cleanup all cached data */
         $this->_model->flush();
+        $this->_model = null;
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Config/DataTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Config/DataTest.php
index 7ded13377c8e1..2e02394320861 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Config/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Config/DataTest.php
@@ -47,6 +47,11 @@ public static function tearDownAfterClass()
         self::_refreshConfiguration();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Remove cached configuration and reinitialize the application
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Config/ElementTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Config/ElementTest.php
index ba2961f99a206..bafb7c71df9c8 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Config/ElementTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Config/ElementTest.php
@@ -60,6 +60,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testIs()
     {
         $element = $this->_model->is_test;
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
index afaefaa2f6890..78fb73f75878f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
@@ -57,6 +57,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Config_Options;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstruct()
     {
         $data = $this->_model->getData();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
index f531401386b55..580a56adf8c96 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
@@ -49,6 +49,11 @@ public function setUp()
         $this->_model->init(self::$_options);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @dataProvider classNameRewriteDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
index 460890b609944..fa8a523e4c8b8 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
@@ -187,7 +187,6 @@ public function testLoadModulesConfiguration()
     {
         $config = $this->_createModel(true)->loadModulesConfiguration('adminhtml.xml');
         $this->assertInstanceOf('Mage_Core_Model_Config_Base', $config);
-        $this->assertInstanceOf('Mage_Core_Model_Config_Element', $config->getNode('menu'));
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $config->getNode('acl'));
     }
 
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/Backend/ExceptionsTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/Backend/ExceptionsTest.php
index 7ed04a2b55b6d..6ca549eb05600 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/Backend/ExceptionsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/Backend/ExceptionsTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model->setPath('design/theme/ua_regexp');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Basic test, checks that saved value contains all required entries and is saved as an array
      * @magentoDbIsolation enabled
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
index 6a8c726dad4ad..a00344088fc84 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
@@ -48,6 +48,11 @@ protected function setUp()
         $this->_model->setDesignTheme('test/default/default', 'frontend');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetFilename()
     {
         $expected = '%s/frontend/test/default/Mage_Catalog/theme_template.phtml';
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
index b8b2702401476..b63071588af13 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
@@ -65,6 +65,7 @@ protected function setUp()
     protected function tearDown()
     {
         Varien_Io_File::rmdirRecursive(self::$_skinPublicDir);
+        $this->_model = null;
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
index aa712fa585e10..0b8d860de1654 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
@@ -66,6 +66,7 @@ protected function tearDown()
     {
         Varien_Io_File::rmdirRecursive(self::$_skinPublicDir);
         Varien_Io_File::rmdirRecursive(self::$_fixtureTmpDir);
+        $this->_model = null;
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
index 679a152da558c..88611c8c47f1b 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
@@ -61,6 +61,11 @@ protected function setUp()
         $this->_model->setDesignTheme('test/default/default', 'frontend');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetGetArea()
     {
         $this->assertEquals(Mage_Core_Model_Design_Package::DEFAULT_AREA, $this->_model->getArea());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/Source/DesignTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/Source/DesignTest.php
index eac2921b6934c..55133d6a60712 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/Source/DesignTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/Source/DesignTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Design_Source_Design;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetAllOptionsSorting()
     {
         $fixture = array(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/DesignTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/DesignTest.php
index 1b3423f11f596..f1d591411d47c 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/DesignTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/DesignTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Design();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testLoadChange()
     {
         $this->_model->loadChange(1);
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
index 146ba02762f48..6a5a1c1ca3824 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Email_Template_Filter;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * Isolation level has been raised in order to flush themes configuration in-memory cache
      *
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
index d93f5cfdb4431..68ca60ad7d4d4 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
@@ -47,6 +47,12 @@ protected function setUp()
         $this->_model->setSenderName('sender')->setSenderEmail('sender@example.com')->setTemplateSubject('Subject');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_mail = null;
+    }
+
     /**
      * Return a disposable Zend_Mail instance
      *
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/EncryptionTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/EncryptionTest.php
index c08e6b64af115..d8ec96bf3aaeb 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/EncryptionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/EncryptionTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Encryption();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testEncryptDecrypt()
     {
         $this->assertEquals('', $this->_model->decrypt($this->_model->encrypt('')));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/DataTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/DataTest.php
index 0d16a936e841f..b03551ae08e0d 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/DataTest.php
@@ -32,6 +32,11 @@ class Mage_Core_Model_Layout_DataTest extends PHPUnit_Framework_TestCase
      */
     protected $_model;
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstructor()
     {
         $this->_model = new Mage_Core_Model_Layout_Data();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/ElementTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/ElementTest.php
index 1780ce46d5ef6..f05c5f17c4d97 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/ElementTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/ElementTest.php
@@ -32,6 +32,11 @@ class Mage_Core_Model_Layout_ElementTest extends PHPUnit_Framework_TestCase
      */
     protected $_model;
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testPrepare()
     {
         $this->_model = new Mage_Core_Model_Layout_Element(__DIR__ . '/../_files/_layout_update.xml', 0, true);
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/UpdateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/UpdateTest.php
index 3f5ae51346bcc..87d52fb6d97c0 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/UpdateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/UpdateTest.php
@@ -49,6 +49,11 @@ protected function setUp()
         ));
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetElementClass()
     {
         $this->assertEquals('Mage_Core_Model_Layout_Element', $this->_model->getElementClass());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
index d41f5e04c722a..eeed0d0ba6c6e 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
@@ -51,6 +51,11 @@ protected function setUp()
         $this->_layout->getUpdate()->load('layout_test_handle_extra');
     }
 
+    protected function tearDown()
+    {
+        $this->_layout = null;
+    }
+
     /**
      * @param array $inputArguments
      * @param string $expectedArea
@@ -87,6 +92,14 @@ public function testConstructorWrongStructure()
         new Mage_Core_Model_Layout(array('structure' => false));
     }
 
+    public function testDestructor()
+    {
+        $this->_layout->addBlock('Mage_Core_Block_Text', 'test');
+        $this->assertNotEmpty($this->_layout->getAllBlocks());
+        $this->_layout->__destruct();
+        $this->assertEmpty($this->_layout->getAllBlocks());
+    }
+
     public function testGetUpdate()
     {
         $this->assertInstanceOf('Mage_Core_Model_Layout_Update', $this->_layout->getUpdate());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/CacheTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/CacheTest.php
index b0be05d1b2ae6..4c85b66b7d9c0 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/CacheTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/CacheTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Cache();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoConfigFixture global/resources/db/table_prefix prefix_
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/ConfigTest.php
index 513873a03d701..6e4251bec7111 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/ConfigTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Config();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSaveDeleteConfig()
     {
         $connection = $this->_model->getReadConnection();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Db/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Db/AbstractTest.php
index ec0d61c9907dc..006f3e556c38b 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Db/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Db/AbstractTest.php
@@ -37,6 +37,12 @@ public function setUp()
         $this->_model = $this->getMockForAbstractClass('Mage_Core_Model_Resource_Db_Abstract');
     }
 
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstruct()
     {
         $resourceProperty = new ReflectionProperty(get_class($this->_model), '_resources');
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Entity/TableTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Entity/TableTest.php
index 19e3d6c634608..56cddcbad11c0 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Entity/TableTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Entity/TableTest.php
@@ -43,6 +43,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Resource_Entity_Table($config);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetTable()
     {
         $this->assertEquals('test_table', $this->_model->getTable());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Helper/Mysql4Test.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Helper/Mysql4Test.php
index 31e22beec6aaf..dd63d823811cb 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Helper/Mysql4Test.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Helper/Mysql4Test.php
@@ -47,6 +47,12 @@ protected function setUp()
         $this->_select = $collection->getSelect();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_select = null;
+    }
+
     public function testCastField()
     {
         $this->assertEquals('test', $this->_model->castField('test'));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/IteratorTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/IteratorTest.php
index 7990a6eccb1ab..a2fc20b966314 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/IteratorTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/IteratorTest.php
@@ -44,6 +44,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Iterator();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testWalk()
     {
         $collection = new Mage_Core_Model_Resource_Store_Collection();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/LayoutTest.php
index 1344d20ecbada..298b8bc8cd2c8 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/LayoutTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Layout();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testFetchUpdatesByHandle()
     {
         $this->assertEmpty($this->_model->fetchUpdatesByHandle('test', array('test' => 'test')));
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SessionTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SessionTest.php
index fd90fa2e27060..cf6fa3720c339 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SessionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SessionTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Session();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testHasConnection()
     {
         $this->assertTrue($this->_model->hasConnection());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SetupTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SetupTest.php
index ac9e0d766a2df..d50869e44f52f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SetupTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/SetupTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Setup('default_setup');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetTable()
     {
         $this->_model->setTable('test_name', 'test_real_name');
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Store/CollectionTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Store/CollectionTest.php
index 22d2fee947df4..c314dddfc7d43 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Store/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/Store/CollectionTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_collection = new Mage_Core_Model_Resource_Store_Collection();
     }
 
+    protected function tearDown()
+    {
+        $this->_collection = null;
+    }
+
     public function testSetGetLoadDefault()
     {
         $this->assertFalse($this->_collection->getLoadDefault());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/TransactionTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/TransactionTest.php
index 85080f72ba4bd..4851ab54de257 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Resource/TransactionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Resource/TransactionTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource_Transaction();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSaveDelete()
     {
         $first  = new Mage_Core_Model_Store_Group();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ResourceMysqlTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ResourceMysqlTest.php
index b99a9d3a88a40..e3bce620804cd 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ResourceMysqlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ResourceMysqlTest.php
@@ -40,6 +40,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetConnectionTypeInstance()
     {
         $this->assertInstanceOf(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ResourceTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ResourceTest.php
index 69297d7885df2..8efc300fdae87 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ResourceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ResourceTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Resource();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoConfigFixture global/resources/db/table_prefix prefix_
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Session/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Session/AbstractTest.php
index a52548553f225..083b0ccdde85f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Session/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Session/AbstractTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = $this->getMockForAbstractClass('Mage_Core_Model_Session_Abstract');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetCookie()
     {
         $cookie = $this->_model->getCookie();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
index f84a13e3dda48..93778eefaae78 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
@@ -40,6 +40,11 @@ public function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @dataProvider loadDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/ExprTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/ExprTest.php
index f3edc608e5a66..2b6df3a82b727 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/ExprTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/ExprTest.php
@@ -40,6 +40,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Translate_Expr($this->_expectedText, $this->_expectedModule);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstructor()
     {
         $this->assertEquals($this->_expectedText, $this->_model->getText());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/InlineTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/InlineTest.php
index f5fc386f58501..33f999ac905ed 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/InlineTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/InlineTest.php
@@ -47,6 +47,10 @@ public function setUp()
         Mage::app()->getStore($this->_storeId)->setConfig('dev/translate_inline/active', true);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
 
     public function testIsAllowed()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/StringTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/StringTest.php
index 3628bb55d256e..a4a9d1ff77dd3 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Translate/StringTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Translate/StringTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Core_Model_Translate_String();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testConstructor()
     {
         $this->assertInstanceOf('Mage_Core_Model_Resource_Translate_String', $this->_model->getResource());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
index ced908bfc889e..dfe4712b0a7e2 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
@@ -48,6 +48,11 @@ public function setUp()
         $this->_model->init('frontend');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetModulesConfig()
     {
         /** @var $modulesConfig Mage_Core_Model_Config_Element */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Url/RewriteTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Url/RewriteTest.php
index 842401641ee28..bb40c78a09f7d 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Url/RewriteTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Url/RewriteTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Url_Rewrite;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testLoadByRequestPath()
     {
         $this->_model->setStoreId(Mage::app()->getDefaultStoreView()->getId())
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/UrlTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/UrlTest.php
index 5de9ca5aab676..948a869345f64 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/UrlTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/UrlTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Url;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testParseUrl()
     {
         $url = 'http://user:password@www.example.com:80/manual/3.5/?one=1&two=2#skeleton-generator.test';
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Variable/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Variable/ConfigTest.php
index 29f51470496cd..26521cb22d1bf 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Variable/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Variable/ConfigTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Core_Model_Variable_Config;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetWysiwygJsPluginSrc()
     {
         $src = $this->_model->getWysiwygJsPluginSrc();
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/WebsiteTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/WebsiteTest.php
index b962a4b0ed2b5..12b8c12a8128c 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/WebsiteTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/WebsiteTest.php
@@ -38,6 +38,11 @@ public function setUp()
         $this->_model->load(1);
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testLoad()
     {
         /* Test loading by id */
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/_layout_update.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/_layout_update.xml
index 07051ea2ac061..f21276ffb0ebf 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/_layout_update.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/_layout_update.xml
@@ -44,7 +44,7 @@
          <block type="Mage_Core_Block_Html_Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
       </block>
       <block type="Mage_Adminhtml_Block_Page_Header" name="header" as="header" ignore="1"/>
-      <block type="Mage_Adminhtml_Block_Page_Menu" name="menu" as="menu" ignore="1"/>
+      <block type="Mage_Backend_Block_Menu" name="menu" as="menu" ignore="1"/>
       <block type="Mage_Core_Block_Text_List" name="notifications" as="notifications">
          <block type="Mage_Adminhtml_Block_Notification_Baseurl" name="notification_baseurl" as="notification_baseurl" template="notification/baseurl.phtml"/>
          <block type="Mage_Adminhtml_Block_Cache_Notifications" name="cache_notifications" template="system/cache/notifications.phtml"/>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
index b60af132d35b0..a09588ee4dd13 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
@@ -39,7 +39,7 @@
             </block>
 
             <block type="Mage_Adminhtml_Block_Page_Header" name="header" as="header"/>
-            <block type="Mage_Adminhtml_Block_Page_Menu" name="menu" as="menu"/>
+            <block type="Mage_Backend_Block_Menu" name="menu" as="menu"/>
             <block type="Mage_Core_Block_Text_List" name="notifications" as="notifications">
                 <block type="Mage_Adminhtml_Block_Notification_Baseurl" name="notification_baseurl" as="notification_baseurl" template="notification/baseurl.phtml"/>
                 <block type="Mage_Adminhtml_Block_Cache_Notifications" name="cache_notifications" template="system/cache/notifications.phtml"/>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Utility/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Core/Utility/LayoutTest.php
index 69656e14150e7..fcc7d92f67db8 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Utility/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Utility/LayoutTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_utility = new Mage_Core_Utility_Layout($this);
     }
 
+    protected function tearDown()
+    {
+        $this->_utility = null;
+    }
+
     /**
      * Assert that the actual layout update instance represents the expected layout update file
      *
diff --git a/dev/tests/integration/testsuite/Mage/Cron/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Cron/Model/ObserverTest.php
index e34db28fea5b9..0e9ea5946de03 100644
--- a/dev/tests/integration/testsuite/Mage/Cron/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Cron/Model/ObserverTest.php
@@ -38,6 +38,11 @@ public function setUp()
         $this->_model->dispatch('this argument is not used');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testDispatchScheduled()
     {
         $collection = new Mage_Cron_Model_Resource_Schedule_Collection;
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Block/Account/LinkTest.php b/dev/tests/integration/testsuite/Mage/Customer/Block/Account/LinkTest.php
index f3817502d13a4..98def6c339835 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/Block/Account/LinkTest.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/Block/Account/LinkTest.php
@@ -46,6 +46,12 @@ public function setUp()
         $this->_links = $layout->getBlock('links');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_links = null;
+    }
+
     public function testAddAccountLink()
     {
         $this->assertEmpty($this->_links->getLinks());
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Block/Account/NavigationTest.php b/dev/tests/integration/testsuite/Mage/Customer/Block/Account/NavigationTest.php
new file mode 100644
index 0000000000000..70ba02ebbb9a4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Customer/Block/Account/NavigationTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Customer_Block_Account_NavigationTest extends PHPUnit_Framework_TestCase
+{
+    public function testAddRemoveLink()
+    {
+        $block = new Mage_Customer_Block_Account_Navigation;
+        $this->assertSame(array(), $block->getLinks());
+        $this->assertSame($block, $block->addLink('Name', 'some/path/index', 'Label', array('parameter' => 'value')));
+        $links = $block->getLinks();
+        $this->assertArrayHasKey('Name', $links);
+        $this->assertInstanceOf('Varien_Object', $links['Name']);
+        $this->assertSame(array(
+                'name' => 'Name', 'path' => 'some/path/index', 'label' => 'Label',
+                'url' => 'http://localhost/index.php/some/path/index/parameter/value/'
+            ), $links['Name']->getData()
+        );
+        $block->removeLink('nonexistent');
+        $this->assertSame($links, $block->getLinks());
+        $block->removeLink('Name');
+        $this->assertSame(array(), $block->getLinks());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ConfigTest.php
index 18bb468ccab77..ef27d910841ae 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ConfigTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model= new Mage_Customer_Model_Address_Config();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoAppIsolation enabled
      * @magentoDataFixture Mage/Customer/_files/address_formats.php
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/FormTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/FormTest.php
index ff383b3927657..10fa8646bce42 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/Model/FormTest.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/FormTest.php
@@ -38,6 +38,11 @@ protected function setUp()
         $this->_model->setFormCode('customer_account_create');
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetAttributes()
     {
         $attributes = $this->_model->getAttributes();
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/GroupTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/GroupTest.php
index aa8a7bd6b75b6..406e0cee8e8c6 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/Model/GroupTest.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/GroupTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model= new Mage_Customer_Model_Group();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testCRUD()
     {
         $this->_model->setCustomerGroupCode('test');
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/BreadcrumbsTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/BreadcrumbsTest.php
index c265c19034fa9..4fd34cd7866bf 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/BreadcrumbsTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/BreadcrumbsTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_block->setLayout($layoutUtility->getLayoutFromFixture($pageTypesFixture));
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * Set the current route/controller/action
      *
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/ExitTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/ExitTest.php
index 32410fffd949b..5934f5974f478 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/ExitTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/ExitTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_DesignEditor_Block_Toolbar_Exit(array('template' => 'toolbar/exit.phtml'));
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetExitUrl()
     {
         $expected = 'http://localhost/index.php/admin/system_design_editor/exit/';
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/HandlesHierarchyTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/HandlesHierarchyTest.php
index baeb1a0499984..42b196a1fb53f 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/HandlesHierarchyTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/HandlesHierarchyTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_block->setLayout($layoutUtility->getLayoutFromFixture($pageTypesFixture));
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testRenderHierarchy()
     {
         $expected = __DIR__ . '/_files/_handles_hierarchy.html';
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/SkinTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/SkinTest.php
index 95b0379e4993e..632a74605cd30 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/SkinTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/Toolbar/SkinTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_block = new Mage_DesignEditor_Block_Toolbar_Skin();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetOptions()
     {
         Mage::getConfig()->getOptions()->setDesignDir(__DIR__ . '/../../../Core/Model/Design/Source/_files/design');
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/ToolbarTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/ToolbarTest.php
index 169be8f976fca..3a9c95e4ff0a7 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Block/ToolbarTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Block/ToolbarTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * Isolation has been raised because block pollutes the registry
      *
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Model/ObserverTest.php
index 617885059debd..3aefbd7d9fff3 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Model/ObserverTest.php
@@ -48,6 +48,11 @@ protected function setUp()
         $this->_eventObserver->setEvent(new Varien_Event(array('layout' => Mage::app()->getLayout())));
     }
 
+    protected function tearDown()
+    {
+        $this->_observer = null;
+    }
+
     /**
      * @magentoAppIsolation enabled
      * @magentoDataFixture Mage/DesignEditor/_files/design_editor_active.php
diff --git a/dev/tests/integration/testsuite/Mage/DesignEditor/Model/SessionTest.php b/dev/tests/integration/testsuite/Mage/DesignEditor/Model/SessionTest.php
index 24ee10ad0f0a7..9406daa36bed9 100644
--- a/dev/tests/integration/testsuite/Mage/DesignEditor/Model/SessionTest.php
+++ b/dev/tests/integration/testsuite/Mage/DesignEditor/Model/SessionTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_model = new Mage_DesignEditor_Model_Session();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testIsDesignEditorActiveFalse()
     {
         $this->assertFalse($this->_model->isDesignEditorActive());
diff --git a/dev/tests/integration/testsuite/Mage/Eav/Model/Resource/Entity/Attribute/CollectionTest.php b/dev/tests/integration/testsuite/Mage/Eav/Model/Resource/Entity/Attribute/CollectionTest.php
index 73beccd7284f8..c2cc89f1175e9 100644
--- a/dev/tests/integration/testsuite/Mage/Eav/Model/Resource/Entity/Attribute/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Eav/Model/Resource/Entity/Attribute/CollectionTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Eav_Model_Resource_Entity_Attribute_Collection();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetAttributeSetExcludeFilter()
     {
         $collection = new Mage_Eav_Model_Resource_Entity_Attribute_Collection();
diff --git a/dev/tests/integration/testsuite/Mage/GiftMessage/Block/Message/InlineTest.php b/dev/tests/integration/testsuite/Mage/GiftMessage/Block/Message/InlineTest.php
index 7b1480b3eac72..50faf090f363a 100644
--- a/dev/tests/integration/testsuite/Mage/GiftMessage/Block/Message/InlineTest.php
+++ b/dev/tests/integration/testsuite/Mage/GiftMessage/Block/Message/InlineTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_GiftMessage_Block_Message_Inline();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/product_with_image.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Block/Adminhtml/Import/Edit/FormTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Block/Adminhtml/Import/Edit/FormTest.php
new file mode 100644
index 0000000000000..febdccee42fc7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Block/Adminhtml/Import/Edit/FormTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Tests for block Mage_ImportExport_Block_Adminhtml_Import_Edit_FormTest
+ */
+class Mage_ImportExport_Block_Adminhtml_Import_Edit_FormTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test content of form after _prepareForm
+     */
+    public function testPrepareForm()
+    {
+        $formBlock = new Mage_ImportExport_Block_Adminhtml_Import_Edit_Form();
+        $prepareForm = new ReflectionMethod(
+            'Mage_ImportExport_Block_Adminhtml_Import_Edit_Form',
+            '_prepareForm'
+        );
+        $prepareForm->setAccessible(true);
+        $prepareForm->invoke($formBlock);
+
+        // check form
+        $form = $formBlock->getForm();
+        $this->assertInstanceOf('Varien_Data_Form', $form, 'Incorrect import form class.');
+        $this->assertTrue($form->getUseContainer(), 'Form should use container.');
+
+        // check form fieldsets
+        $formFieldsetIds = array(
+            'base_fieldset',
+            'import_format_version_fieldset',
+            'customer_entity_fieldset',
+            'upload_file_fieldset'
+        );
+        $formFieldsets = array();
+        $formElements = $form->getElements();
+        foreach ($formElements as $element) {
+            /** @var $element Varien_Data_Form_Element_Abstract */
+            if (in_array($element->getId(), $formFieldsetIds)) {
+                $formFieldsets[] = $element;
+            }
+        }
+        $this->assertCount(count($formFieldsetIds), $formFieldsets);
+        foreach ($formFieldsets as $fieldset) {
+            $this->assertInstanceOf('Varien_Data_Form_Element_Fieldset', $fieldset, 'Incorrect fieldset class.');
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
index 78d66899411a0..c2c4d5b61ab46 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
@@ -72,6 +72,7 @@ protected function tearDown()
         ini_set('display_errors', $this->_oldDisplayErrors);
         error_reporting($this->_oldErrorLevel);
         Mage::setIsDeveloperMode($this->_oldIsDeveloperMode);
+        $this->_model = null;
 
         parent::tearDown();
     }
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/AbstractTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/AbstractTest.php
index 3e1077ae620de..e3bb3b486953f 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/AbstractTest.php
@@ -109,10 +109,12 @@ public function testGetExportAttrCodes()
     /**
      * Test for method filterEntityCollection()
      *
-     * @magentoDataFixture Mage/ImportExport/_files/customers.php
+     * magentoDataFixture Mage/ImportExport/_files/customers.php
      */
     public function testFilterEntityCollection()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $createdAtDate = '2013-01-01';
         /**
          * Change created_at date of first customer for future filter test.
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/AddressTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/AddressTest.php
index 021f2c787f5bb..7d18295dd303c 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/AddressTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/Customer/AddressTest.php
@@ -29,7 +29,7 @@
  * Test for customer address export model V2
  *
  * @group module:Mage_ImportExport
- * @magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+ * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
  */
 class Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_AddressTest extends PHPUnit_Framework_TestCase
 {
@@ -69,6 +69,8 @@ protected function tearDown()
      */
     public function testExport()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $websiteCode = Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address::COL_WEBSITE;
         $emailCode = Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address::COL_EMAIL;
         $entityIdCode = Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address::COL_ADDRESS_ID;
@@ -152,6 +154,8 @@ public function getGenderFilterValueDataProvider()
      */
     public function testExportWithFilter($genderFilterValue)
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $entityIdCode = Mage_ImportExport_Model_Export_Entity_V2_Eav_Customer_Address::COL_ADDRESS_ID;
 
         $this->_model->setWriter(new Mage_ImportExport_Model_Export_Adapter_Csv());
@@ -184,6 +188,8 @@ public function testExportWithFilter($genderFilterValue)
      */
     public function testGetEntityTypeCode()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->assertEquals('customer_address', $this->_model->getEntityTypeCode());
     }
 
@@ -192,6 +198,8 @@ public function testGetEntityTypeCode()
      */
     public function testGetAttributeCollection()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->assertInstanceOf('Mage_Customer_Model_Resource_Address_Attribute_Collection',
             $this->_model->getAttributeCollection()
         );
@@ -227,4 +235,14 @@ protected function _csvToArray($content, $entityId = null)
 
         return $data;
     }
+
+    /**
+     * Test filename getter. Filename must be set in constructor.
+     */
+    public function testGetFileName()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->assertEquals($this->_model->getEntityTypeCode(), $this->_model->getFileName());
+    }
 }
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/CustomerTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/CustomerTest.php
index 71ed192f7b9e1..1f5f5de00dfcd 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/V2/Eav/CustomerTest.php
@@ -52,10 +52,12 @@ protected function tearDown()
     /**
      * Test export method
      *
-     * @magentoDataFixture Mage/ImportExport/_files/customers.php
+     * magentoDataFixture Mage/ImportExport/_files/customers.php
      */
     public function testExport()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $expectedAttributes = array();
         /** @var $collection Mage_Customer_Model_Resource_Attribute_Collection */
         $collection = Mage::getResourceModel('Mage_Customer_Model_Resource_Attribute_Collection');
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/CustomerTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/CustomerTest.php
index 217e53da2a3ca..42b9cc56241f8 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/CustomerTest.php
@@ -27,7 +27,7 @@
 
 /**
  * @group module:Mage_ImportExport
- * @magentoDataFixture Mage/ImportExport/_files/customers.php
+ * magentoDataFixture Mage/ImportExport/_files/customers.php
  */
 class Mage_ImportExport_Model_Import_Entity_CustomerTest extends PHPUnit_Framework_TestCase
 {
@@ -87,8 +87,16 @@ protected function setUp()
         );
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_modelDelete = null;
+    }
+
     public function testValidateRowDuplicateEmail()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertFalse($this->_errorWas);
 
@@ -106,6 +114,8 @@ public function testValidateRowDuplicateEmail()
 
     public function testValidateRowInvalidEmail()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_customerData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL] = 'wrong_email@format';
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertTrue($this->_errorWas);
@@ -116,6 +126,8 @@ public function testValidateRowInvalidEmail()
 
     public function testValidateRowInvalidWebsite()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_customerData[Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE] = 'not_existing_web_site';
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertTrue($this->_errorWas);
@@ -126,6 +138,8 @@ public function testValidateRowInvalidWebsite()
 
     public function testValidateRowInvalidStore()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_customerData[Mage_ImportExport_Model_Import_Entity_Customer::COL_STORE] = 'not_existing_web_store';
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertTrue($this->_errorWas);
@@ -136,6 +150,8 @@ public function testValidateRowInvalidStore()
 
     public function testValidateRowPasswordLengthIncorrect()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_customerData['password'] = '12345';
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertTrue($this->_errorWas);
@@ -146,6 +162,8 @@ public function testValidateRowPasswordLengthIncorrect()
 
     public function testValidateRowPasswordLengthCorrect()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_customerData['password'] = '1234567890';
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertFalse($this->_errorWas);
@@ -153,6 +171,8 @@ public function testValidateRowPasswordLengthCorrect()
 
     public function testValidateRowAttributeRequired()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         unset($this->_customerData['firstname']);
         unset($this->_customerData['lastname']);
         unset($this->_customerData['group_id']);
@@ -172,6 +192,8 @@ public function testValidateRowAttributeRequired()
 
     public function testValidateRowDelete()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_modelDelete->expects($this->any())
             ->method('getBehavior')
             ->will($this->returnValue(Mage_ImportExport_Model_Import::BEHAVIOR_DELETE));
@@ -189,6 +211,8 @@ public function testValidateRowDelete()
 
     public function testScopeAddressFirst()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $customerAddressData = array(
             Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL => '',
             Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE => '',
@@ -203,6 +227,8 @@ public function testScopeAddressFirst()
 
     public function testMultipleCustomerAddress()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $this->_model->validateRow($this->_customerData, 0);
         $this->assertFalse($this->_errorWas);
 
@@ -213,6 +239,8 @@ public function testMultipleCustomerAddress()
 
     public function testMultipleCustomerAddressOrphan()
     {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
         $errorWas = false;
         $errors = array();
         $checkException = function ($errorCode, $errorRowNum, $colName = null) use (&$errorWas, &$errors) {
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php
new file mode 100644
index 0000000000000..97645e437fb77
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test for method _saveValidatedBunches()
+     */
+    public function testSaveValidatedBunches()
+    {
+        $source = new Mage_ImportExport_Model_Import_Adapter_Csv(__DIR__ . '/_files/customers_for_validation_test.csv');
+        $expected = $source->current();
+        /** @var $model Mage_ImportExport_Model_Import_Entity_V2_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $model = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Abstract');
+        $model->expects($this->any())
+            ->method('validateRow')
+            ->will($this->returnValue(true));
+        $model->expects($this->any())
+            ->method('getEntityTypeCode')
+            ->will($this->returnValue('customer'));
+
+        $model->setSource($source);
+
+        $method = new ReflectionMethod($model, '_saveValidatedBunches');
+        $method->setAccessible(true);
+        $method->invoke($model);
+
+        $dataSourceModel = Mage_ImportExport_Model_Import::getDataSourceModel();
+        $this->assertCount(1, $dataSourceModel->getIterator());
+
+        $bunch = $dataSourceModel->getNextBunch();
+        $this->assertEquals($expected, $bunch[0]);
+
+        //Delete created bunch from DB
+        $dataSourceModel->cleanBunches();
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerImportTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerImportTest.php
new file mode 100644
index 0000000000000..652d254651684
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerImportTest.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Tests for customer V2 import model
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_CustomerImportTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Model object which used for tests
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = new Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer();
+    }
+
+    protected function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Test importData() method
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::_importData
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::_saveCustomers
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::_saveCustomerEntity
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::_saveCustomerAttributes
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer.php
+     */
+    public function testImportData()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // 3 customers will be imported.
+        // 1 of this customers is already exist, but its first and last name were changed in file
+        $expectAddedCustomers = 2;
+        $source = new Mage_ImportExport_Model_Import_Adapter_Csv(__DIR__ . '/_files/customers_to_import.csv');
+
+        /** @var $customersCollection Mage_Customer_Model_Resource_Customer_Collection */
+        $customersCollection = Mage::getResourceModel('Mage_Customer_Model_Resource_Customer_Collection');
+        $customersCollection->addAttributeToSelect('firstname', 'inner')
+            ->addAttributeToSelect('lastname', 'inner');
+
+        $existCustomersCount = count($customersCollection->load());
+
+        $customersCollection->resetData();
+        $customersCollection->clear();
+
+        $this->_model->setSource($source)
+            ->isDataValid();
+
+        $this->_model->importData();
+
+        $customers = $customersCollection->getItems();
+
+        $addedCustomers = count($customers) - $existCustomersCount;
+
+        $this->assertEquals($expectAddedCustomers, $addedCustomers, 'Added unexpected amount of customers');
+
+        $existingCustomer = Mage::registry('_fixture/Mage_ImportExport_Customer');
+
+        $updatedCustomer = $customers[$existingCustomer->getId()];
+
+        $this->assertNotEquals(
+            $existingCustomer->getFirstname(),
+            $updatedCustomer->getFirstname(),
+            'Firstname must be changed'
+        );
+
+        $this->assertNotEquals(
+            $existingCustomer->getLastname(),
+            $updatedCustomer->getLastname(),
+            'Lastname must be changed'
+        );
+    }
+
+    /**
+     * Test entity type code value
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::getAttributeCollection
+     */
+    public function testGetEntityTypeCode()
+    {
+        $this->assertEquals('customer', $this->_model->getEntityTypeCode());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerValidateTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerValidateTest.php
new file mode 100644
index 0000000000000..7d04e0673b610
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/CustomerValidateTest.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test for class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer which covers validation logic
+ *
+ * magentoDataFixture Mage/ImportExport/_files/customers.php
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_CustomerValidateTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Model object which used for tests
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    /**
+     * Customer data
+     *
+     * @var array
+     */
+    protected $_customerData;
+
+    /**
+     * Create all necessary data for tests
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = new Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer();
+
+        $propertyAccessor = new ReflectionProperty($this->_model, '_messageTemplates');
+        $propertyAccessor->setAccessible(true);
+        $propertyAccessor->setValue($this->_model, array());
+
+        $this->_customerData = array(
+            'firstname' => 'Firstname',
+            'lastname' => 'Lastname',
+            'group_id' => 1,
+            Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_EMAIL => 'customer@example.com',
+            Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_WEBSITE => 'base',
+            Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_STORE => 'default',
+            'store_id' => 1,
+            'website_id' => 1,
+            'password' => 'password',
+        );
+    }
+
+    /**
+     * Unset created data during tests
+     */
+    protected function tearDown()
+    {
+        unset($this->_model, $this->_customerData);
+        parent::tearDown();
+    }
+
+    /**
+     * Test which check duplicated data validation
+     */
+    public function testValidateRowDuplicateEmail()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(0, $this->_model->getErrorsCount());
+
+        $this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_EMAIL] =
+            strtoupper($this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_EMAIL]);
+        $this->_model->validateRow($this->_customerData, 1);
+        $this->assertEquals(1, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_DUPLICATE_EMAIL_SITE,
+            $this->_model->getErrorMessages());
+    }
+
+    /**
+     * Test which check validation of customer email
+     */
+    public function testValidateRowInvalidEmail()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_EMAIL]
+            = 'wrong_email@format';
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(1, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_INVALID_EMAIL,
+            $this->_model->getErrorMessages()
+        );
+    }
+
+    /**
+     * Test which check validation of website data
+     */
+    public function testValidateRowInvalidWebsite()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_WEBSITE]
+            = 'not_existing_web_site';
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(1, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_INVALID_WEBSITE,
+            $this->_model->getErrorMessages()
+        );
+    }
+
+    /**
+     * Test which check validation of store data
+     */
+    public function testValidateRowInvalidStore()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_STORE]
+            = 'not_existing_web_store';
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(1, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_INVALID_STORE,
+            $this->_model->getErrorMessages()
+        );
+    }
+
+    /**
+     * Test which check validation of password length - incorrect case
+     */
+    public function testValidateRowPasswordLengthIncorrect()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_customerData['password'] = '12345';
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(1, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_PASSWORD_LENGTH,
+            $this->_model->getErrorMessages()
+        );
+    }
+
+    /**
+     * Test which check validation of password length - correct case
+     */
+    public function testValidateRowPasswordLengthCorrect()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $this->_customerData['password'] = '1234567890';
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(0, $this->_model->getErrorsCount());
+    }
+
+    /**
+     * Test which check validation of required fields
+     */
+    public function testValidateRowAttributeRequired()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        unset($this->_customerData['firstname']);
+        unset($this->_customerData['lastname']);
+        unset($this->_customerData['group_id']);
+
+        $this->_model->validateRow($this->_customerData, 0);
+        $this->assertEquals(0, $this->_model->getErrorsCount());
+
+        $this->_customerData[Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::COLUMN_EMAIL]
+            = 'new.customer@example.com';
+        $this->_model->validateRow($this->_customerData, 1);
+        $this->assertGreaterThan(0, $this->_model->getErrorsCount());
+        $this->assertArrayHasKey(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer::ERROR_VALUE_IS_REQUIRED,
+            $this->_model->getErrorMessages()
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php
new file mode 100644
index 0000000000000..2ff9b08888825
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Model object which used for tests
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    /**
+     * Create all necessary data for tests
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+        $this->_model = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract', array(),
+            '', false);
+    }
+
+    /**
+     * Unset created data during test
+     */
+    protected function tearDown()
+    {
+        unset($this->_model);
+        parent::tearDown();
+    }
+
+    /**
+     * Test for method getAttributeOptions()
+     */
+    public function testGetAttributeOptions()
+    {
+        $indexAttributeCode = 'gender';
+
+        /** @var $attributeCollection Mage_Customer_Model_Resource_Attribute_Collection */
+        $attributeCollection = Mage::getResourceModel('Mage_Customer_Model_Resource_Attribute_Collection');
+        $attributeCollection->addFieldToFilter(
+            'attribute_code',
+            array(
+                'in' => array($indexAttributeCode, 'group_id')
+            )
+        );
+        /** @var $attribute Mage_Customer_Model_Attribute */
+        foreach ($attributeCollection as $attribute) {
+            $index = ($attribute->getAttributeCode() == $indexAttributeCode) ? 'value' : 'label';
+            $expectedOptions = array();
+            foreach ($attribute->getSource()->getAllOptions(false) as $option) {
+                $expectedOptions[strtolower($option[$index])] = $option['value'];
+            }
+
+            $actualOptions = $this->_model->getAttributeOptions($attribute, array($indexAttributeCode));
+            $this->assertSame($expectedOptions, $actualOptions);
+        }
+    }
+
+    /**
+     * Test for method _initWebsites()
+     */
+    public function testInitWebsitesWithoutBaseWebsite()
+    {
+        $method = new ReflectionMethod($this->_model, '_initWebsites');
+        $method->setAccessible(true);
+        $method->invoke($this->_model);
+        $this->assertAttributeSame($this->_getWebsites(), '_websiteCodeToId', $this->_model);
+    }
+
+    /**
+     * Test for method _initWebsites()
+     */
+    public function testInitWebsitesWithBaseWebsite()
+    {
+        $method = new ReflectionMethod($this->_model, '_initWebsites');
+        $method->setAccessible(true);
+        $method->invoke($this->_model, true);
+        $this->assertAttributeSame($this->_getWebsites(true), '_websiteCodeToId', $this->_model);
+    }
+
+    /**
+     * Get websites data for tests
+     *
+     * @param bool $withDefault
+     * @return array
+     */
+    protected function _getWebsites($withDefault = false)
+    {
+        $websites = array();
+        /** @var $website Mage_Core_Model_Website */
+        foreach (Mage::app()->getWebsites($withDefault) as $website) {
+            $websites[$website->getCode()] = $website->getId();
+        }
+        return $websites;
+    }
+
+    /**
+     * Test for method _initStores()
+     */
+    public function testInitStoresWithoutBaseStore()
+    {
+        $method = new ReflectionMethod($this->_model, '_initStores');
+        $method->setAccessible(true);
+        $method->invoke($this->_model);
+        $this->assertAttributeSame($this->_getStores(), '_storeCodeToId', $this->_model);
+    }
+
+    /**
+     * Test for method _initStores()
+     */
+    public function testInitStoresWithBaseStore()
+    {
+        $method = new ReflectionMethod($this->_model, '_initStores');
+        $method->setAccessible(true);
+        $method->invoke($this->_model, true);
+        $this->assertAttributeSame($this->_getStores(true), '_storeCodeToId', $this->_model);
+    }
+
+    /**
+     * Get stores data for tests
+     *
+     * @param bool $withDefault
+     * @return array
+     */
+    protected function _getStores($withDefault = false)
+    {
+        $stores = array();
+        /** @var $store Mage_Core_Model_Store */
+        foreach (Mage::app()->getStores($withDefault) as $store) {
+            $stores[$store->getCode()] = $store->getId();
+        }
+        return $stores;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php
new file mode 100644
index 0000000000000..5ba7281272ee8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php
@@ -0,0 +1,440 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tested class name
+     *
+     * @var string
+     */
+    protected $_testClassName = 'Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address';
+
+    /**
+     * Fixture key from fixture
+     *
+     * @var string
+     */
+    protected $_fixtureKey = '_fixture/Mage_ImportExport_Customers_Array';
+
+    /**
+     * Address entity adapter instance
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     */
+    protected $_entityAdapter;
+
+    /**
+     * Init new instance of address entity adapter
+     */
+    public function setUp()
+    {
+        parent::setUp();
+        $this->_entityAdapter = Mage::getModel($this->_testClassName);
+    }
+
+    /**
+     * Unset entity adapter
+     */
+    public function tearDown()
+    {
+        unset($this->_entityAdapter);
+        parent::tearDown();
+    }
+
+    /**
+     * Test constructor
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     */
+    public function testConstruct()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // check entity table
+        $this->assertAttributeInternalType('string', '_entityTable', $this->_entityAdapter,
+            'Entity table must be a string.');
+        $this->assertAttributeNotEmpty('_entityTable', $this->_entityAdapter, 'Entity table must not be empty');
+
+        // check message templates
+        $this->assertAttributeInternalType('array', '_messageTemplates', $this->_entityAdapter,
+            'Templates must be an array.');
+        $this->assertAttributeNotEmpty('_messageTemplates', $this->_entityAdapter, 'Templates must not be empty');
+
+        // check attributes
+        $this->assertAttributeInternalType('array', '_attributes', $this->_entityAdapter,
+            'Attributes must be an array.');
+        $this->assertAttributeNotEmpty('_attributes', $this->_entityAdapter, 'Attributes must not be empty');
+
+        // check addresses
+        $this->assertAttributeInternalType('array', '_addresses', $this->_entityAdapter,
+            'Addresses must be an array.');
+        $this->assertAttributeNotEmpty('_addresses', $this->_entityAdapter, 'Addresses must not be empty');
+
+        // check country regions and regions
+        $this->assertAttributeInternalType('array', '_countryRegions', $this->_entityAdapter,
+            'Country regions must be an array.');
+        $this->assertAttributeNotEmpty('_countryRegions', $this->_entityAdapter, 'Country regions must not be empty');
+
+        $this->assertAttributeInternalType('array', '_regions', $this->_entityAdapter,
+            'Regions must be an array.');
+        $this->assertAttributeNotEmpty('_regions', $this->_entityAdapter, 'Regions must not be empty');
+    }
+
+    /**
+     * Test _initAddresses
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_initAddresses
+     */
+    public function testInitAddresses()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // get addressed from fixture
+        $customers = Mage::registry($this->_fixtureKey);
+        $correctAddresses = array();
+        /** @var $customer Mage_Customer_Model_Customer */
+        foreach ($customers as $customer) {
+            $correctAddresses[$customer->getId()] = array();
+            /** @var $address Mage_Customer_Model_Address */
+            foreach ($customer->getAddressesCollection() as $address) {
+                $correctAddresses[$customer->getId()][] = $address->getId();
+            }
+        }
+
+        // invoke _initAddresses
+        $initAddresses = new ReflectionMethod($this->_testClassName, '_initAddresses');
+        $initAddresses->setAccessible(true);
+        $initAddresses->invoke($this->_entityAdapter);
+
+        // check addresses
+        $this->assertAttributeInternalType('array', '_addresses', $this->_entityAdapter,
+            'Addresses must be an array.');
+        $this->assertAttributeNotEmpty('_addresses', $this->_entityAdapter, 'Addresses must not be empty');
+
+        $addressesReflection = new ReflectionProperty($this->_testClassName, '_addresses');
+        $addressesReflection->setAccessible(true);
+        $testAddresses = $addressesReflection->getValue($this->_entityAdapter);
+
+        $correctCustomerIds = array_keys($correctAddresses);
+        $testCustomerIds = array_keys($testAddresses);
+        sort($correctCustomerIds);
+        sort($testCustomerIds);
+        $this->assertEquals($correctCustomerIds, $testCustomerIds, 'Incorrect customer IDs in addresses array.');
+
+        foreach ($correctCustomerIds as $customerId) {
+            $this->assertInternalType('array', $correctAddresses[$customerId], 'Addresses must be an array.');
+            $correctAddressIds = $correctAddresses[$customerId];
+            $testAddressIds = $testAddresses[$customerId];
+            sort($correctAddressIds);
+            sort($testAddressIds);
+            $this->assertEquals($correctAddressIds, $testAddressIds, 'Incorrect addresses IDs.');
+        }
+    }
+
+    /**
+     * Test _saveAddressEntity
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_saveAddressEntities
+     */
+    public function testSaveAddressEntities()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // invoke _saveAddressEntities
+        list($customerId, $addressId) = $this->_addTestAddress($this->_entityAdapter);
+
+        // check DB
+        $testAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $testAddress->load($addressId);
+        $this->assertEquals($addressId, $testAddress->getId(), 'Incorrect address ID.');
+        $this->assertEquals($customerId, $testAddress->getParentId(), 'Incorrect address customer ID.');
+    }
+
+    /**
+     * Add new test address for existing customer
+     *
+     * @param Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address $entityAdapter
+     * @return array (customerID, addressID)
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     */
+    protected function _addTestAddress(Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address $entityAdapter)
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        $customers = Mage::registry($this->_fixtureKey);
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = reset($customers);
+        $customerId = $customer->getId();
+
+        /** @var $addressModel Mage_Customer_Model_Address */
+        $addressModel = Mage::getModel('Mage_Customer_Model_Address');
+        $tableName    = $addressModel->getResource()->getEntityTable();
+        $addressId    = Mage::getResourceHelper('Mage_ImportExport')->getNextAutoincrement($tableName);
+
+        $entityData = array(
+            'entity_id'      => $addressId,
+            'entity_type_id' => $addressModel->getEntityTypeId(),
+            'parent_id'      => $customerId,
+            'created_at'     => now(),
+            'updated_at'     => now()
+        );
+
+        // invoke _saveAddressEntities
+        $saveAddressEntities = new ReflectionMethod($this->_testClassName, '_saveAddressEntities');
+        $saveAddressEntities->setAccessible(true);
+        $saveAddressEntities->invoke($entityAdapter, $entityData);
+
+        return array($customerId, $addressId);
+    }
+
+    /**
+     * Test _saveAddressAttributes
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_saveAddressAttributes
+     */
+    public function testSaveAddressAttributes()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // get attributes list
+        $attributesReflection = new ReflectionProperty($this->_testClassName, '_attributes');
+        $attributesReflection->setAccessible(true);
+        $attributes = $attributesReflection->getValue($this->_entityAdapter);
+
+        // get some attribute
+        $attributeName = 'city';
+        $this->assertArrayHasKey($attributeName, $attributes, 'Key "' . $attributeName . '" should be an attribute.');
+        $attributeParams = $attributes[$attributeName];
+        $this->assertArrayHasKey('id', $attributeParams, 'Attribute must have an ID.');
+        $this->assertArrayHasKey('table', $attributeParams, 'Attribute must have a table.');
+
+        // create new address with attributes
+        $data = $this->_addTestAddress($this->_entityAdapter);
+        $addressId = $data[1];
+        $attributeId = $attributeParams['id'];
+        $attributeTable = $attributeParams['table'];
+        $attributeValue = 'Test City';
+
+        $attributeArray = array();
+        $attributeArray[$attributeTable][$addressId][$attributeId] = $attributeValue;
+
+        // invoke _saveAddressAttributes
+        $saveAttributes = new ReflectionMethod($this->_testClassName, '_saveAddressAttributes');
+        $saveAttributes->setAccessible(true);
+        $saveAttributes->invoke($this->_entityAdapter, $attributeArray);
+
+        // check DB
+        /** @var $testAddress Mage_Customer_Model_Address */
+        $testAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $testAddress->load($addressId);
+        $this->assertEquals($addressId, $testAddress->getId(), 'Incorrect address ID.');
+        $this->assertEquals($attributeValue, $testAddress->getData($attributeName), 'There is no attribute value.');
+    }
+
+    /**
+     * Test _saveCustomerDefaults
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customer_with_addresses.php
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_saveCustomerDefaults
+     */
+    public function testSaveCustomerDefaults()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // get not default address
+        $customers = Mage::registry($this->_fixtureKey);
+        /** @var $notDefaultAddress Mage_Customer_Model_Address */
+        $notDefaultAddress = null;
+        /** @var $addressCustomer Mage_Customer_Model_Customer */
+        $addressCustomer = null;
+        /** @var $customer Mage_Customer_Model_Customer */
+        foreach ($customers as $customer) {
+            /** @var $address Mage_Customer_Model_Address */
+            foreach ($customer->getAddressesCollection() as $address) {
+                if (!$customer->getDefaultBillingAddress() && !$customer->getDefaultShippingAddress()) {
+                    $notDefaultAddress = $address;
+                    $addressCustomer = $customer;
+                    break;
+                }
+                if ($notDefaultAddress) {
+                    break;
+                }
+            }
+        }
+        $this->assertNotNull($notDefaultAddress, 'Not default address must exists.');
+        $this->assertNotNull($addressCustomer, 'Not default address customer must exists.');
+
+        $addressId  = $notDefaultAddress->getId();
+        $customerId = $addressCustomer->getId();
+
+        // set customer defaults
+        $defaults = array();
+        foreach (Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::getDefaultAddressAttributeMapping()
+            as $attributeCode) {
+            /** @var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
+            $attribute = $addressCustomer->getAttribute($attributeCode);
+            $attributeTable = $attribute->getBackend()->getTable();
+            $attributeId = $attribute->getId();
+            $defaults[$attributeTable][$customerId][$attributeId] = $addressId;
+        }
+
+        // invoke _saveCustomerDefaults
+        $saveDefaults = new ReflectionMethod($this->_testClassName, '_saveCustomerDefaults');
+        $saveDefaults->setAccessible(true);
+        $saveDefaults->invoke($this->_entityAdapter, $defaults);
+
+        // check DB
+        /** @var $testCustomer Mage_Customer_Model_Customer */
+        $testCustomer = Mage::getModel('Mage_Customer_Model_Customer');
+        $testCustomer->load($customerId);
+        $this->assertEquals($customerId, $testCustomer->getId(), 'Customer must exists.');
+        $this->assertNotNull($testCustomer->getDefaultBillingAddress(), 'Default billing address must exists.');
+        $this->assertNotNull($testCustomer->getDefaultShippingAddress(), 'Default shipping address must exists.');
+        $this->assertEquals(
+            $addressId,
+            $testCustomer->getDefaultBillingAddress()->getId(),
+            'Incorrect default billing address.'
+        );
+        $this->assertEquals(
+            $addressId,
+            $testCustomer->getDefaultShippingAddress()->getId(),
+            'Incorrect default shipping address.'
+        );
+    }
+
+    /**
+     * Test attribute collection getter
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_getAttributeCollection
+     */
+    public function testGetAttributeCollection()
+    {
+        $getCollection = new ReflectionMethod($this->_testClassName, '_getAttributeCollection');
+        $getCollection->setAccessible(true);
+        $collection = $getCollection->invoke($this->_entityAdapter);
+        $this->assertInstanceOf(
+            'Mage_Customer_Model_Resource_Address_Attribute_Collection',
+            $collection,
+            'Incorrect attribute collection class.'
+        );
+    }
+
+    /**
+     * Test import data method
+     *
+     * magentoDataFixture Mage/ImportExport/_files/customers_for_address_import.php
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_importData
+     */
+    public function testImportData()
+    {
+        $this->markTestIncomplete('BUG MAGETWO-1953');
+
+        // set fixture CSV file
+        $sourceFile = __DIR__ . '/../../_files/address_import.csv';
+        $result = $this->_entityAdapter
+            ->setSource(Mage_ImportExport_Model_Import_Adapter::findAdapterFor($sourceFile))
+            ->isDataValid();
+        $this->assertFalse($result, 'Validation result must be false.');
+
+        // fixture registry keys
+        $fixtureCustomer = '_fixture/Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest_Customer';
+        $fixtureCsv      = '_fixture/Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest_Csv';
+
+        // get customer
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = Mage::registry($fixtureCustomer);
+        $customerId = $customer->getId();
+
+        // get csv fixture data
+        $csvData = Mage::registry($fixtureCsv);
+
+        // import data
+        $this->_entityAdapter->importData();
+
+        // form attribute list
+        $keyAttribute = 'postcode';
+        $requiredAttributes[] = array($keyAttribute);
+        foreach (array('update', 'remove') as $action) {
+            foreach ($csvData[$action] as $attributes) {
+                $requiredAttributes = array_merge($requiredAttributes, array_keys($attributes));
+            }
+        }
+
+        // get addresses
+        /** @var $addressCollection Mage_Customer_Model_Resource_Address_Collection */
+        $addressCollection = Mage::getResourceModel('Mage_Customer_Model_Resource_Address_Collection');
+        $addressCollection->addAttributeToSelect($requiredAttributes);
+        $addresses = array();
+        /** @var $address Mage_Customer_Model_Address */
+        foreach ($addressCollection as $address) {
+            $addresses[$address->getData($keyAttribute)] = $address;
+        }
+
+        // is addresses exists
+        $this->assertArrayHasKey($csvData['address']['update'], $addresses, 'Address must exist.');
+        $this->assertArrayHasKey($csvData['address']['new'], $addresses, 'Address must exist.');
+        $this->assertArrayNotHasKey($csvData['address']['no_customer'], $addresses, 'Address must not exist.');
+        $this->assertArrayHasKey($csvData['address']['new_no_address_id'], $addresses, 'Address must exist.');
+
+        // is updated address fields have new values
+        $updatedAddressId = $csvData['address']['update'];
+        /** @var $updatedAddress Mage_Customer_Model_Address */
+        $updatedAddress = $addresses[$updatedAddressId];
+        $updatedData = $csvData['update'][$updatedAddressId];
+        foreach ($updatedData as $fieldName => $fieldValue) {
+            $this->assertEquals($fieldValue, $updatedAddress->getData($fieldName));
+        }
+
+        // are removed data fields have old values
+        $removedData = $csvData['remove'][$updatedAddressId];
+        foreach ($removedData as $fieldName => $fieldValue) {
+            $this->assertEquals($fieldValue, $updatedAddress->getData($fieldName));
+        }
+
+        // are default billing/shipping addresses have new value
+        $customer = Mage::getModel('Mage_Customer_Model_Customer');
+        $customer->load($customerId);
+        $defaultsData = $csvData['default'];
+        $this->assertEquals(
+            $defaultsData['billing'],
+            $customer->getDefaultBillingAddress()->getData($keyAttribute),
+            'Incorrect default billing address'
+        );
+        $this->assertEquals(
+            $defaultsData['shipping'],
+            $customer->getDefaultShippingAddress()->getData($keyAttribute),
+            'Incorrect default shipping address'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/address_import.csv b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/address_import.csv
new file mode 100644
index 0000000000000..76fbbc72911e6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/address_import.csv
@@ -0,0 +1,5 @@
+"_website","_email","_entity_id","city","company","country_id","fax","firstname","lastname","middlename","postcode","prefix","region","region_id","street","suffix","telephone","vat_id","vat_is_valid","vat_request_date","vat_request_id","vat_request_success","_address_default_billing_","_address_default_shipping_"
+"admin","BetsyParker@example.com",1,,,"US",,"Katy","Parker","T.",19107,,,,"1079 Rocky Road",,"215-629-9720",,,,,,,1
+"admin","BetsyParker@example.com",3,"Phoenix",,"US",,"Brad","Brown","H.",85034,,"Arizona",4,"4225 Martha Street",,"928-707-1577",,,,,,1,
+"admin","JenniferCJackson@teleworm.us",4,"Tampa",,"US",,"Jennifer ","Jackson","C.",33602,,"Florida",18,"1192 Maryland Avenue",,"727-555-0854",,,,,,,
+"admin","BetsyParker@example.com",,"Tallahassee",,"US",,"William ","Compton","M.",32301,,"Florida",18,"1973 Drainer Avenue",,"850-590-7403",,,,,,,
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_for_validation_test.csv b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_for_validation_test.csv
new file mode 100644
index 0000000000000..3cad25683fde3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_for_validation_test.csv
@@ -0,0 +1,3 @@
+email,_website,_store,attr_pylwhnacmivoekxo,attr_qpygb,confirmation,created_at,created_in,default_billing,default_shipping,disable_auto_group_change,dob,firstname,gender,group_id,irinkin,iriyes,lastname,middlename,password_hash,prefix,reward_update_notification,reward_warning_notification,rp_token,rp_token_created_at,store_id,suffix,taxvat,textiri,website_id,zagogulina,password
+qwerty@example.ru,base,admin,,,,"2012-06-15 07:58:23",,11,,0,,qwerty,,1,,,qwerty,,,,1,1,,,0,,,,1,,
+ziza@example.com,base,admin,,,,"2012-06-14 07:43:00",Admin,12,,0,,Irina1,,1,111,,Glazunova1,,e02484cbed89b7eeb5fb6abb437424c70e805b4d4e6ef91ae1bf07d79bc7938b:xi,,1,1,,,0,,,,1,No,
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_to_import.csv b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_to_import.csv
new file mode 100644
index 0000000000000..5b9d02293b451
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/V2/_files/customers_to_import.csv
@@ -0,0 +1,4 @@
+email,_website,_store,confirmation,created_at,created_in,default_billing,default_shipping,disable_auto_group_change,dob,firstname,gender,group_id,lastname,middlename,password_hash,prefix,reward_update_notification,reward_warning_notification,rp_token,rp_token_created_at,store_id,suffix,taxvat,website_id,password
+AnthonyANealy@magento.com,base,admin,,05-06-12 15:53,Admin,1,1,0,,Anthony,Male,1,Nealy,A.,6a9c9bfb2ba88a6ad2a64e7402df44a763e0c48cd21d7af9e7e796cd4677ee28:RF,,1,1,,,0,,,1,
+LoriBBanks@magento.com,admin,admin,,05-06-12 15:59,Admin,3,3,0,,Lori,Female,1,Banks,B.,7ad6dbdc83d3e9f598825dc58b84678c7351e4281f6bc2b277a32dcd88b9756b:pz,,1,1,,,0,,,0,
+CharlesTAlston@teleworm.us,base,admin,,05-06-12 16:13,Admin,4,4,0,,Jhon,Female,1,Doe,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,1,1,,,0,,,2,
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/ImportTest.php
new file mode 100644
index 0000000000000..fbc4cbbb019ad
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/ImportTest.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Tests for Import model
+ *
+ * @magentoDataFixture Mage/ImportExport/_files/import_data.php
+ */
+class Mage_ImportExport_Model_ImportTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Model object which used for tests
+     *
+     * @var Mage_ImportExport_Model_Import
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = new Mage_ImportExport_Model_Import();
+    }
+
+    protected function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Test import from import data storage.
+     * Covers _getEntityAdapter() in case when entity adapter was successfully returned
+     *
+     * @covers Mage_ImportExport_Model_Import::_getEntityAdapter
+     */
+    public function testImportSource()
+    {
+        $this->markTestIncomplete('MAGETWO-1953');
+
+        /** @var $customersCollection Mage_Customer_Model_Resource_Customer_Collection */
+        $customersCollection = Mage::getResourceModel('Mage_Customer_Model_Resource_Customer_Collection');
+
+        $existCustomersCount = count($customersCollection->load());
+
+        $customersCollection->resetData();
+        $customersCollection->clear();
+
+        $this->_model->importSource();
+
+        $customers = $customersCollection->getItems();
+
+        $addedCustomers = count($customers) - $existCustomersCount;
+
+        $this->assertGreaterThan($existCustomersCount, $addedCustomers);
+    }
+
+    /**
+     * Test _getEntityAdapter() through validateSource() method in case when entity was not set
+     *
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Entity is unknown
+     */
+    public function testGetEntityAdapterEntityIsNotSet()
+    {
+        $this->_model->validateSource('');
+    }
+
+    /**
+     * Test _getEntityAdapter() through validateSource() method
+     * in case when not valid customer entity subtype was passed
+     *
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Invalid entity
+     */
+    public function testGetEntityAdapterInvalidCustomerSubtype()
+    {
+        $this->_model->setEntitySubtype(microtime());
+
+        $this->_model->validateSource('');
+    }
+
+    /**
+     * Test _getEntityAdapter() through validateSource() method
+     * in case when not valid customer entity model was set in config
+     *
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Invalid entity model
+     *
+     * @magentoConfigFixture global/importexport/import_customer_entities/customer_address/model_token Varien_Image
+     *
+     */
+    public function testGetEntityAdapterInvalidCustomerEntityModel()
+    {
+        $addressesImport = new Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address();
+
+        $this->_model->setEntitySubtype($addressesImport->getEntityTypeCode());
+
+        $this->_model->validateSource('');
+    }
+
+    // @codingStandardsIgnoreStart
+    /**
+     * Test _getEntityAdapter() through validateSource() method
+     * in case when in config was set customer entity model which not
+     * extends Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+     *
+     * @magentoConfigFixture global/importexport/import_customer_entities/customer_address/model_token Mage_ImportExport_Model_Import_Entity_Customer
+     *
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Entity adapter object must be an instance of Mage_ImportExport_Model_Import_Entity_V2_Abstract
+     */
+    // @codingStandardsIgnoreEnd
+    public function testGetEntityAdapterInvalidCustomerEntityObject()
+    {
+        $addressesImport = new Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address();
+
+        $this->_model->setEntitySubtype($addressesImport->getEntityTypeCode());
+
+        $this->_model->validateSource('');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Resource/Import/DataTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Resource/Import/DataTest.php
new file mode 100644
index 0000000000000..caea234f9e065
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Resource/Import/DataTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     <package-name>
+ * @subpackage  <subpackage-name>
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test Import Data resource model
+ *
+ * @magentoDataFixture Mage/ImportExport/_files/import_data.php
+ */
+class Mage_ImportExport_Model_Resource_Import_DataTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_ImportExport_Model_Resource_Import_Data
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = new Mage_ImportExport_Model_Resource_Import_Data();
+    }
+
+    protected function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Test getUniqueColumnData() in case when in data stored in requested column is unique
+     */
+    public function testGetUniqueColumnData()
+    {
+        $expectedBunches = Mage::registry('_fixture/Mage_ImportExport_Import_Data');
+
+        $this->assertEquals($expectedBunches[0]['entity'], $this->_model->getUniqueColumnData('entity'));
+    }
+
+    /**
+     * Test getUniqueColumnData() in case when in data stored in requested column is NOT unique
+     *
+     * @expectedException Mage_Core_Exception
+     */
+    public function testGetUniqueColumnDataException()
+    {
+        $this->_model->getUniqueColumnData('data');
+    }
+
+    /**
+     * Test successful getBehavior()
+     */
+    public function testGetBehavior()
+    {
+        $expectedBunches = Mage::registry('_fixture/Mage_ImportExport_Import_Data');
+
+        $this->assertEquals($expectedBunches[0]['behavior'], $this->_model->getBehavior());
+    }
+
+    /**
+     * Test successful getEntityTypeCode()
+     */
+    public function testGetEntityTypeCode()
+    {
+        $expectedBunches = Mage::registry('_fixture/Mage_ImportExport_Import_Data');
+
+        $this->assertEquals($expectedBunches[0]['entity'], $this->_model->getEntityTypeCode());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer.php b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer.php
new file mode 100644
index 0000000000000..56d6dbad2e876
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/*
+//Create customer
+$customer = new Mage_Customer_Model_Customer();
+$customer->setWebsiteId(1)
+    ->setEntityId(1)
+    ->setEntityTypeId(1)
+    ->setAttributeSetId(0)
+    ->setEmail('CharlesTAlston@teleworm.us')
+    ->setPassword('password')
+    ->setGroupId(1)
+    ->setStoreId(1)
+    ->setIsActive(1)
+    ->setFirstname('Charles')
+    ->setLastname('Alston')
+    ->setGender(2);
+$customer->isObjectNew(true);
+
+// Create address
+$address = new Mage_Customer_Model_Address();
+//  default_billing and default_shipping information would not be saved, it is needed only for simple check
+$address->addData(array(
+    'firstname'         => 'Charles',
+    'lastname'          => 'Alston',
+    'street'            => '3781 Neuport Lane',
+    'city'              => 'Panola',
+    'country_id'        => 'US',
+    'region_id'         => '51',
+    'postcode'          => '30058',
+    'telephone'         => '770-322-3514',
+    'default_billing'   => 1,
+    'default_shipping'  => 1,
+));
+
+// Assign customer and address
+$customer->addAddress($address);
+$customer->save();
+
+// Mark last address as default billing and default shipping for current customer
+$customer->setDefaultBilling($address->getId());
+$customer->setDefaultShipping($address->getId());
+$customer->save();
+
+Mage::unregister('_fixture/Mage_ImportExport_Customer');
+Mage::register('_fixture/Mage_ImportExport_Customer', $customer);
+*/
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer_with_addresses.php b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer_with_addresses.php
index c8f12789b90ed..d6f7460dc77f0 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer_with_addresses.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customer_with_addresses.php
@@ -24,7 +24,7 @@
  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
+/*
 $customers = array();
 
 //Create customer
@@ -162,3 +162,4 @@
 
 Mage::unregister('_fixture/Mage_ImportExport_Customers_Array');
 Mage::register('_fixture/Mage_ImportExport_Customers_Array', $customers);
+*/
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers.php b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers.php
index 15feac1a3796e..3eef189208627 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers.php
@@ -24,7 +24,7 @@
  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
+/*
 $customers = array();
 
 $customer = new Mage_Customer_Model_Customer();
@@ -83,3 +83,4 @@
 $customers[] = $customer;
 
 Mage::register('_fixture/Mage_ImportExport_Customer_Collection', $customers);
+*/
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers_for_address_import.php b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers_for_address_import.php
new file mode 100644
index 0000000000000..5d898ffd5f002
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/_files/customers_for_address_import.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/*
+//Create customer
+$customer = new Mage_Customer_Model_Customer();
+$customer
+    ->setWebsiteId(0)
+    ->setEntityId(1)
+    ->setEntityTypeId(1)
+    ->setAttributeSetId(0)
+    ->setEmail('BetsyParker@example.com')
+    ->setPassword('password')
+    ->setGroupId(0)
+    ->setStoreId(0)
+    ->setIsActive(1)
+    ->setFirstname('Betsy')
+    ->setLastname('Parker')
+    ->setGender(2);
+$customer->save();
+
+// Create and set addresses
+$addressFirst = new Mage_Customer_Model_Address();
+$addressFirst->addData(array(
+    'entity_id'         => 1,
+    'firstname'         => 'Betsy',
+    'lastname'          => 'Parker',
+    'street'            => '1079 Rocky Road',
+    'city'              => 'Philadelphia',
+    'country_id'        => 'US',
+    'region_id'         => '51',
+    'postcode'          => '19107',
+    'telephone'         => '215-629-9720',
+));
+$customer->addAddress($addressFirst);
+$customer->setDefaultBilling($addressFirst->getId());
+
+$addressSecond = new Mage_Customer_Model_Address();
+$addressSecond->addData(array(
+    'entity_id'         => 2,
+    'firstname'         => 'Anthony',
+    'lastname'          => 'Nealy',
+    'street'            => '3176 Cambridge Court',
+    'city'              => 'Fayetteville',
+    'country_id'        => 'US',
+    'region_id'         => '5',
+    'postcode'          => '72701',
+    'telephone'         => '479-899-9849',
+));
+$customer->addAddress($addressSecond);
+$customer->setDefaultShipping($addressSecond->getId());
+
+$customer->save();
+
+$fixtureKey = '_fixture/Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest_Customer';
+Mage::unregister($fixtureKey);
+Mage::register($fixtureKey, $customer);
+
+// important data from address_import.csv (postcode is key)
+$csvData = array(
+    'address' => array( // address records
+        'update'            => '19107',  // address with updates
+        'new'               => '85034',  // new address
+        'no_customer'       => '33602',  // there is no customer with this primary key (email+website)
+        'new_no_address_id' => '32301',  // new address without address id
+    ),
+    'update'  => array( // this data is changed in CSV file
+        '19107' => array(
+            'firstname'  => 'Katy',
+            'middlename' => 'T.',
+        ),
+    ),
+    'remove'  => array( // this data is not set in CSV file
+        '19107' => array(
+            'city'   => 'Philadelphia',
+            'region' => 'Pennsylvania',
+        ),
+    ),
+    'default' => array( // new default billing/shipping addresses
+        'billing'  => '85034',
+        'shipping' => '19107',
+    ),
+);
+
+$fixtureKey = '_fixture/Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest_Csv';
+Mage::unregister($fixtureKey);
+Mage::register($fixtureKey, $csvData);
+*/
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/_files/import_data.php b/dev/tests/integration/testsuite/Mage/ImportExport/_files/import_data.php
new file mode 100644
index 0000000000000..004baef40d63e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/_files/import_data.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$bunches = array(
+    0 => array(
+        'entity'         => 'customer',
+        'entity_subtype' => 'customer',
+        'behavior'       => 'append',
+        'data'           => array(
+            0 =>
+            array(
+                'email'                       => 'AnthonyANealy@magento.com',
+                '_website'                    => 'base',
+                '_store'                      => 'admin',
+                'confirmation'                => NULL,
+                'created_at'                  => '05-06-12 15:53',
+                'created_in'                  => 'Admin',
+                'default_billing'             => '1',
+                'default_shipping'            => '1',
+                'disable_auto_group_change'   => '0',
+                'dob'                         => '13-06-84',
+                'firstname'                   => 'Anthony',
+                'gender'                      => 'Male',
+                'group_id'                    => '1',
+                'lastname'                    => 'Nealy',
+                'middlename'                  => 'A.',
+                'password_hash'               => '6a9c9bfb2ba88a6ad2a64e7402df44a763e0c48cd21d7af9e7e796cd4677ee28:RF',
+                'prefix'                      => NULL,
+                'reward_update_notification'  => '1',
+                'reward_warning_notification' => '1',
+                'rp_token'                    => NULL,
+                'rp_token_created_at'         => NULL,
+                'store_id'                    => '0',
+                'suffix'                      => NULL,
+                'taxvat'                      => NULL,
+                'website_id'                  => '1',
+                'password'                    => NULL,
+            ),
+            1 =>
+            array(
+                'email'                       => 'LoriBBanks@magento.com',
+                '_website'                    => 'admin',
+                '_store'                      => 'admin',
+                'confirmation'                => NULL,
+                'created_at'                  => '05-06-12 15:59',
+                'created_in'                  => 'Admin',
+                'default_billing'             => '3',
+                'default_shipping'            => '3',
+                'disable_auto_group_change'   => '0',
+                'dob'                         => NULL,
+                'firstname'                   => 'Lori',
+                'gender'                      => 'Female',
+                'group_id'                    => '1',
+                'lastname'                    => 'Banks',
+                'middlename'                  => NULL,
+                'password_hash'               => '7ad6dbdc83d3e9f598825dc58b84678c7351e4281f6bc2b277a32dcd88b9756b:pz',
+                'prefix'                      => NULL,
+                'reward_update_notification'  => '1',
+                'reward_warning_notification' => '1',
+                'rp_token'                    => NULL,
+                'rp_token_created_at'         => NULL,
+                'store_id'                    => '0',
+                'suffix'                      => NULL,
+                'taxvat'                      => NULL,
+                'website_id'                  => '0',
+                'password'                    => NULL,
+            ),
+        )
+
+    ),
+    1 => array(
+        'entity'         => 'customer',
+        'entity_subtype' => 'customer',
+        'behavior'       => 'append',
+        'data'           => array(
+            0 =>
+            array(
+                'email'                       => 'BetsyHParker@magento.com',
+                '_website'                    => 'base',
+                '_store'                      => 'admin',
+                'confirmation'                => NULL,
+                'created_at'                  => '05-06-12 16:13',
+                'created_in'                  => 'Admin',
+                'default_billing'             => '4',
+                'default_shipping'            => '4',
+                'disable_auto_group_change'   => '0',
+                'dob'                         => NULL,
+                'firstname'                   => 'Betsy',
+                'gender'                      => 'Female',
+                'group_id'                    => '1',
+                'lastname'                    => 'Parker',
+                'middlename'                  => 'H.',
+                'password_hash'               => '145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1',
+                'prefix'                      => NULL,
+                'reward_update_notification'  => '1',
+                'reward_warning_notification' => '1',
+                'rp_token'                    => NULL,
+                'rp_token_created_at'         => NULL,
+                'store_id'                    => '0',
+                'suffix'                      => NULL,
+                'taxvat'                      => NULL,
+                'website_id'                  => '2',
+                'password'                    => NULL,
+            ),
+        )
+
+    )
+);
+
+$importDataResource = new Mage_ImportExport_Model_Resource_Import_Data();
+
+foreach ($bunches as $bunch) {
+    $importDataResource->saveBunch($bunch['entity'], $bunch['behavior'], $bunch['data'], $bunch['entity_subtype']);
+}
+
+Mage::unregister('_fixture/Mage_ImportExport_Import_Data');
+Mage::register('_fixture/Mage_ImportExport_Import_Data', $bunches);
diff --git a/dev/tests/integration/testsuite/Mage/Log/Model/Resource/ShellTest.php b/dev/tests/integration/testsuite/Mage/Log/Model/Resource/ShellTest.php
index 7dfc84b5c4896..fa1095b9c996a 100644
--- a/dev/tests/integration/testsuite/Mage/Log/Model/Resource/ShellTest.php
+++ b/dev/tests/integration/testsuite/Mage/Log/Model/Resource/ShellTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Log_Model_Resource_Shell;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetTablesInfo()
     {
         $tables = $this->_model->getTablesInfo();
diff --git a/dev/tests/integration/testsuite/Mage/Newsletter/Model/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Newsletter/Model/TemplateTest.php
index e7d2e9ceb3552..7d01b8914aa12 100644
--- a/dev/tests/integration/testsuite/Mage/Newsletter/Model/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Newsletter/Model/TemplateTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_Newsletter_Model_Template;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function getProcessedTemplateDataProvider()
     {
         return array(
diff --git a/dev/tests/integration/testsuite/Mage/Page/Block/Html/BreadcrumbsTest.php b/dev/tests/integration/testsuite/Mage/Page/Block/Html/BreadcrumbsTest.php
index 22ca031a7608d..399053503782e 100644
--- a/dev/tests/integration/testsuite/Mage/Page/Block/Html/BreadcrumbsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Page/Block/Html/BreadcrumbsTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_Page_Block_Html_Breadcrumbs();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testAddCrumb()
     {
         $this->assertEmpty($this->_block->toHtml());
diff --git a/dev/tests/integration/testsuite/Mage/Page/Block/Html/HeadTest.php b/dev/tests/integration/testsuite/Mage/Page/Block/Html/HeadTest.php
index d65e2e97fc12b..9cea3ac083a19 100644
--- a/dev/tests/integration/testsuite/Mage/Page/Block/Html/HeadTest.php
+++ b/dev/tests/integration/testsuite/Mage/Page/Block/Html/HeadTest.php
@@ -42,6 +42,11 @@ protected function setUp()
         $this->_block = new Mage_Page_Block_Html_Head;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testAddCss()
     {
         $this->assertEmpty($this->_block->getItems());
diff --git a/dev/tests/integration/testsuite/Mage/PageCache/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/PageCache/Helper/DataTest.php
index 035b03755ea5c..9a0f97db8f292 100644
--- a/dev/tests/integration/testsuite/Mage/PageCache/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/PageCache/Helper/DataTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_helper = new Mage_PageCache_Helper_Data;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     public function testSetNoCacheCookie()
     {
         /** @var $cookie Mage_Core_Model_Cookie */
diff --git a/dev/tests/integration/testsuite/Mage/PageCache/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/PageCache/Model/ObserverTest.php
index 41ea35c6614c1..d6eaa0190665c 100644
--- a/dev/tests/integration/testsuite/Mage/PageCache/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/PageCache/Model/ObserverTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_observer = new Mage_PageCache_Model_Observer;
     }
 
+    protected function tearDown()
+    {
+        $this->_observer = null;
+    }
+
     /**
      * @magentoConfigFixture current_store system/external_page_cache/enabled 1
      */
diff --git a/dev/tests/integration/testsuite/Mage/Paypal/Model/IpnTest.php b/dev/tests/integration/testsuite/Mage/Paypal/Model/IpnTest.php
index dd92be39e9a17..2cc7e1e2c80df 100644
--- a/dev/tests/integration/testsuite/Mage/Paypal/Model/IpnTest.php
+++ b/dev/tests/integration/testsuite/Mage/Paypal/Model/IpnTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Paypal_Model_Ipn();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @param string $currencyCode
      * @dataProvider currencyProvider
diff --git a/dev/tests/integration/testsuite/Mage/ProductAlert/Block/Email/StockTest.php b/dev/tests/integration/testsuite/Mage/ProductAlert/Block/Email/StockTest.php
index 6121b8b74dd42..5848144452def 100644
--- a/dev/tests/integration/testsuite/Mage/ProductAlert/Block/Email/StockTest.php
+++ b/dev/tests/integration/testsuite/Mage/ProductAlert/Block/Email/StockTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_ProductAlert_Block_Email_Stock();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/product_with_image.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/CommentsTest.php b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/CommentsTest.php
index 528a6685948d6..3695fa6629b3e 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/CommentsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/CommentsTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_block = new Mage_Sales_Block_Order_Comments;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @param mixed $commentedEntity
      * @param string $expectedClass
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Creditmemo/ItemsTest.php b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Creditmemo/ItemsTest.php
index 28909d7346058..4684e0e390365 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Creditmemo/ItemsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Creditmemo/ItemsTest.php
@@ -50,6 +50,14 @@ public function setUp()
         $this->_creditmemo = new Mage_Sales_Model_Order_Creditmemo;
     }
 
+
+    protected function tearDown()
+    {
+        $this->_layout = null;
+        $this->_block = null;
+        $this->_creditmemo = null;
+    }
+
     public function testGetTotalsHtml()
     {
         $childBlock = $this->_layout->addBlock('Mage_Core_Block_Text', 'creditmemo_totals', 'block');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Invoice/ItemsTest.php b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Invoice/ItemsTest.php
index c460234213136..159e4b3f3360d 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Invoice/ItemsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Block/Order/Invoice/ItemsTest.php
@@ -50,6 +50,13 @@ public function setUp()
         $this->_invoice = new Mage_Sales_Model_Order_Invoice;
     }
 
+    protected function tearDown()
+    {
+        $this->_layout = null;
+        $this->_block = null;
+        $this->_invoice = null;
+    }
+
     public function testGetInvoiceTotalsHtml()
     {
         $childBlock = $this->_layout->addBlock('Mage_Core_Block_Text', 'invoice_totals', 'block');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Block/Recurring/Profile/ViewTest.php b/dev/tests/integration/testsuite/Mage/Sales/Block/Recurring/Profile/ViewTest.php
index 85ffb72b2a729..44261dfea305e 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Block/Recurring/Profile/ViewTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Block/Recurring/Profile/ViewTest.php
@@ -55,6 +55,9 @@ public function setUp()
     public function tearDown()
     {
         Mage::unregister('current_recurring_profile');
+        $this->_profile = null;
+        $this->_block = null;
+        $this->_layout = null;
     }
 
     public function testPrepareAddressInfo()
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/TrackTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/TrackTest.php
index e1439f23c3865..05a686c4b4f1a 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/TrackTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/TrackTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Sales_Model_Order_Shipment_Track();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetGetNumber()
     {
         $this->assertNull($this->_model->getNumber());
diff --git a/dev/tests/integration/testsuite/Mage/Shipping/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Shipping/Helper/DataTest.php
index f3c8de733f567..83a5b61cd3d4b 100644
--- a/dev/tests/integration/testsuite/Mage/Shipping/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Shipping/Helper/DataTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_helper = new Mage_Shipping_Helper_Data;
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @param string $modelName
      * @param string $getIdMethod
diff --git a/dev/tests/integration/testsuite/Mage/Tag/Block/Customer/ViewTest.php b/dev/tests/integration/testsuite/Mage/Tag/Block/Customer/ViewTest.php
index 9c1c9b4319cc2..ec1e92df35261 100644
--- a/dev/tests/integration/testsuite/Mage/Tag/Block/Customer/ViewTest.php
+++ b/dev/tests/integration/testsuite/Mage/Tag/Block/Customer/ViewTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_Tag_Block_Customer_View();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetMode()
     {
         $layout = new Mage_Core_Model_Layout;
diff --git a/dev/tests/integration/testsuite/Mage/Tag/Block/Product/ResultTest.php b/dev/tests/integration/testsuite/Mage/Tag/Block/Product/ResultTest.php
index c3737ebc3df70..34b61c6ea65e2 100644
--- a/dev/tests/integration/testsuite/Mage/Tag/Block/Product/ResultTest.php
+++ b/dev/tests/integration/testsuite/Mage/Tag/Block/Product/ResultTest.php
@@ -58,6 +58,13 @@ protected function setUp()
         $this->_layout->addBlock($this->_child, 'search_result_list', 'test');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_layout = null;
+        $this->_child = null;
+    }
+
     public function testSetListOrders()
     {
         $this->assertEmpty($this->_child->getData('available_orders'));
diff --git a/dev/tests/integration/testsuite/Mage/Tag/Model/TagTest.php b/dev/tests/integration/testsuite/Mage/Tag/Model/TagTest.php
index 7559590fc0d09..e8a2396722e02 100644
--- a/dev/tests/integration/testsuite/Mage/Tag/Model/TagTest.php
+++ b/dev/tests/integration/testsuite/Mage/Tag/Model/TagTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model= new Mage_Tag_Model_Tag();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoAppIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Mage/User/Block/Role/Grid/UserTest.php b/dev/tests/integration/testsuite/Mage/User/Block/Role/Grid/UserTest.php
index 7e50dc9843c1f..686928b4fa6fe 100644
--- a/dev/tests/integration/testsuite/Mage/User/Block/Role/Grid/UserTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Block/Role/Grid/UserTest.php
@@ -41,6 +41,11 @@ public function setUp()
         $this->_block = $layout->createBlock('Mage_User_Block_Role_Grid_User');
     }
 
+    protected function tearDown()
+    {
+        $this->_block= null;
+    }
+
     public function testPreparedCollection()
     {
         $this->_block->toHtml();
diff --git a/dev/tests/integration/testsuite/Mage/User/Block/Role/GridTest.php b/dev/tests/integration/testsuite/Mage/User/Block/Role/GridTest.php
index 4125a1291c05e..0bdd9ee35ac71 100644
--- a/dev/tests/integration/testsuite/Mage/User/Block/Role/GridTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Block/Role/GridTest.php
@@ -41,6 +41,11 @@ public function setUp()
         $this->_block = $layout->createBlock('Mage_User_Block_Role_Grid');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testPreparedCollection()
     {
         $this->_block->toHtml();
diff --git a/dev/tests/integration/testsuite/Mage/User/Block/Role/Tab/EditTest.php b/dev/tests/integration/testsuite/Mage/User/Block/Role/Tab/EditTest.php
index 7eaf2ca2399fc..239b500385917 100644
--- a/dev/tests/integration/testsuite/Mage/User/Block/Role/Tab/EditTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Block/Role/Tab/EditTest.php
@@ -44,6 +44,11 @@ public function setUp()
         $this->_block = new Mage_User_Block_Role_Tab_Edit();
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testConstructor()
     {
         $this->assertNotEmpty($this->_block->getSelectedResources());
diff --git a/dev/tests/integration/testsuite/Mage/User/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/User/Helper/DataTest.php
index e6f75d5c1da2d..236da69fae70f 100644
--- a/dev/tests/integration/testsuite/Mage/User/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Helper/DataTest.php
@@ -41,6 +41,11 @@ protected function setUp()
         $this->_helper = Mage::helper('Mage_User_Helper_Data');
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * Test generate unique token for reset password confirmation link
      *
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/CollectionTest.php b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/CollectionTest.php
index 0f1835512e811..d2e652f7359d7 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/CollectionTest.php
@@ -39,6 +39,11 @@ protected function setUp()
         $this->_collection = new Mage_User_Model_Resource_Role_Collection();
     }
 
+    protected function tearDown()
+    {
+        $this->_collection = null;
+    }
+
     public function testSetUserFilter()
     {
         $user = new Mage_User_Model_User;
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/User/CollectionTest.php b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/User/CollectionTest.php
index a5f0b2ef0a89c..13329a92c7abc 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/User/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Role/User/CollectionTest.php
@@ -39,6 +39,11 @@ protected function setUp()
         $this->_collection = new Mage_User_Model_Resource_Role_User_Collection();
     }
 
+    protected function tearDown()
+    {
+        $this->_collection = null;
+    }
+
     public function testSelectQueryInitialized()
     {
         $this->assertContains('user_id > 0', $this->_collection->getSelect()->__toString());
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Rules/CollectionTest.php b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Rules/CollectionTest.php
index b17419c242dd2..edf40c4b5b961 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/Resource/Rules/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/Resource/Rules/CollectionTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_collection = new Mage_User_Model_Resource_Rules_Collection();
     }
 
+    protected function tearDown()
+    {
+        $this->_collection = null;
+    }
+
     public function testGetByRoles()
     {
         $user = new Mage_User_Model_User;
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/RoleTest.php b/dev/tests/integration/testsuite/Mage/User/Model/RoleTest.php
index 5f9d5c24a7d80..0bccaed9e427a 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/RoleTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/RoleTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_User_Model_Role();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetUsersCollection()
     {
         $this->assertInstanceOf('Mage_User_Model_Resource_Role_User_Collection', $this->_model->getUsersCollection());
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/RulesTest.php b/dev/tests/integration/testsuite/Mage/User/Model/RulesTest.php
index 26b5d96187816..47988298db374 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/RulesTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/RulesTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_model = new Mage_User_Model_Rules;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoDbIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Mage/User/Model/UserTest.php b/dev/tests/integration/testsuite/Mage/User/Model/UserTest.php
index 96f4354da106f..0930701e80b55 100644
--- a/dev/tests/integration/testsuite/Mage/User/Model/UserTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/Model/UserTest.php
@@ -45,6 +45,11 @@ protected function setUp()
         $this->_model = new Mage_User_Model_User;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoDbIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Mage/User/controllers/Adminhtml/AuthControllerTest.php b/dev/tests/integration/testsuite/Mage/User/controllers/Adminhtml/AuthControllerTest.php
index 19f9c31c241af..1e25b437a2fac 100644
--- a/dev/tests/integration/testsuite/Mage/User/controllers/Adminhtml/AuthControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/User/controllers/Adminhtml/AuthControllerTest.php
@@ -37,6 +37,13 @@ class Mage_User_Adminhtml_AuthControllerTest extends Magento_Test_TestCase_Contr
      */
     protected $_auth;
 
+
+    protected function tearDown()
+    {
+        $this->_auth = null;
+        parent::tearDown();
+    }
+
     protected  function _login()
     {
         Mage::getSingleton('Mage_Backend_Model_Url')->turnOffSecretKey();
diff --git a/dev/tests/integration/testsuite/Mage/Weee/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Weee/Model/ObserverTest.php
index 432066ae3182f..e45636cc59d6a 100644
--- a/dev/tests/integration/testsuite/Mage/Weee/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Weee/Model/ObserverTest.php
@@ -37,6 +37,11 @@ public function setUp()
         $this->_model = new Mage_Weee_Model_Observer();
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * @magentoConfigFixture current_store tax/weee/enable 1
      * @magentoDataFixture Mage/Weee/_files/product_with_fpt.php
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
index 4b796da96ccb9..5bf09b025d317 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Mage_Widget_Block_Adminhtml_Widget_Instance_Edit_Chooser_Container;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testSetGetAllowedContainers()
     {
         $this->assertEmpty($this->_block->getAllowedContainers());
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/LayoutTest.php
index 4edb02cbdf5f5..4c7de463fa15c 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/LayoutTest.php
@@ -53,6 +53,11 @@ protected function setUp()
         ;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testToHtml()
     {
         $this->assertXmlStringEqualsXmlFile(__DIR__ . '/_files/page_types_select.html', $this->_block->toHtml());
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Tab/Main/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Tab/Main/LayoutTest.php
index d69c5d33c15e0..ea466e75807b7 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Tab/Main/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Block/Adminhtml/Widget/Instance/Edit/Tab/Main/LayoutTest.php
@@ -40,6 +40,11 @@ protected function setUp()
         $this->_block->setLayout(Mage::app()->getLayout());
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testGetLayoutsChooser()
     {
         $actualHtml = $this->_block->getLayoutsChooser();
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/ConfigTest.php
index b358a9aa2415a..6f935066f575c 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/ConfigTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Widget_Model_Widget_Config;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     /**
      * App isolation is enabled, because we change current area and design
      *
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/InstanceTest.php b/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/InstanceTest.php
index 0423ba3bb52d9..e0429fa09246d 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/InstanceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Model/Widget/InstanceTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Widget_Model_Widget_Instance;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testSetGetType()
     {
         $this->assertEmpty($this->_model->getType());
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php b/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
index 113a650072d49..0262197f054c2 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_model = new Mage_Widget_Model_Widget;
     }
 
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
     public function testGetWidgetsArray()
     {
         $declaredWidgets = $this->_model->getWidgetsArray();
diff --git a/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
index cef1cc3bcdf40..7a3ff85534d45 100644
--- a/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = $this->getMockForAbstractClass('Mage_Wishlist_Block_Abstract');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     /**
      * @magentoDataFixture Mage/Catalog/_files/product_with_image.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Wishlist/Block/Customer/Wishlist/Item/ColumnTest.php b/dev/tests/integration/testsuite/Mage/Wishlist/Block/Customer/Wishlist/Item/ColumnTest.php
index 249b3b6dd1134..df60bea9f581e 100644
--- a/dev/tests/integration/testsuite/Mage/Wishlist/Block/Customer/Wishlist/Item/ColumnTest.php
+++ b/dev/tests/integration/testsuite/Mage/Wishlist/Block/Customer/Wishlist/Item/ColumnTest.php
@@ -45,6 +45,12 @@ protected function setUp()
 
     }
 
+    protected function tearDown()
+    {
+        $this->_layout = null;
+        $this->_block = null;
+    }
+
     public function testToHtml()
     {
         $item = new StdClass;
diff --git a/dev/tests/integration/testsuite/Mage/XmlConnect/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/XmlConnect/Helper/DataTest.php
index 52cbccf3d1998..3579f18a57f6b 100644
--- a/dev/tests/integration/testsuite/Mage/XmlConnect/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/XmlConnect/Helper/DataTest.php
@@ -38,6 +38,11 @@ protected function setUp()
         Mage::getDesign()->setDesignTheme('default/default/default', 'adminhtml');
     }
 
+    protected function tearDown()
+    {
+        $this->_helper = null;
+    }
+
     /**
      * @dataProvider getDefaultDesignTabsDataProvider
      */
diff --git a/dev/tests/integration/testsuite/Phoenix/Moneybookers/Block/FormTest.php b/dev/tests/integration/testsuite/Phoenix/Moneybookers/Block/FormTest.php
index 7e8f71abbc808..323e0a8b697d3 100644
--- a/dev/tests/integration/testsuite/Phoenix/Moneybookers/Block/FormTest.php
+++ b/dev/tests/integration/testsuite/Phoenix/Moneybookers/Block/FormTest.php
@@ -37,6 +37,11 @@ protected function setUp()
         $this->_block = new Phoenix_Moneybookers_Block_Form;
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+    }
+
     public function testConstruct()
     {
         $this->assertStringEndsWith('form.phtml', $this->_block->getTemplate());
diff --git a/dev/tests/integration/testsuite/Varien/Db/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Varien/Db/Adapter/InterfaceTest.php
index e05bb1fced3d6..3b7153a2da5db 100644
--- a/dev/tests/integration/testsuite/Varien/Db/Adapter/InterfaceTest.php
+++ b/dev/tests/integration/testsuite/Varien/Db/Adapter/InterfaceTest.php
@@ -74,6 +74,7 @@ protected function tearDown()
     {
         $this->_connection->dropTable($this->_tableName);
         $this->_connection->resetDdlCache($this->_tableName);
+        $this->_connection = null;
     }
 
     protected function assertPreConditions()
diff --git a/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php b/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
index 40a7d40331a1b..22f791fc944e3 100644
--- a/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
+++ b/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
@@ -37,6 +37,12 @@ class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
      */
     protected $_connection = null;
 
+
+    protected function tearDown()
+    {
+        $this->_connection = null;
+    }
+
     /**
      * Test lost connection re-initializing
      *
diff --git a/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
index 680963010eb71..75e051240f2bd 100644
--- a/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
+++ b/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
@@ -33,8 +33,8 @@ class Varien_Image_Adapter_InterfaceTest extends PHPUnit_Framework_TestCase
      * @var array
      */
     protected $_adapters = array(
-        'Varien_Image_Adapter_Gd2',
-        'Varien_Image_Adapter_ImageMagick'
+        Varien_Image_Adapter::ADAPTER_GD2,
+        Varien_Image_Adapter::ADAPTER_IM
     );
 
     /**
@@ -48,7 +48,7 @@ protected function _prepareData($data)
         $result   = array();
         foreach ($this->_adapters as $adapter) {
             foreach ($data as $row) {
-                $row[] = new $adapter;
+                $row[] = Varien_Image_Adapter::factory($adapter);
                 $result[] = $row;
             }
         }
@@ -151,7 +151,7 @@ public function adaptersDataProvider()
     {
         $data = array();
         foreach ($this->_adapters as $adapter) {
-            $data[] = array(new $adapter);
+            $data[] = array(Varien_Image_Adapter::factory($adapter));
         }
         return $data;
     }
diff --git a/dev/tests/integration/testsuite/integrity/modular/MenuConfigFilesTest.php b/dev/tests/integration/testsuite/integrity/modular/MenuConfigFilesTest.php
new file mode 100644
index 0000000000000..e18d8a001c853
--- /dev/null
+++ b/dev/tests/integration/testsuite/integrity/modular/MenuConfigFilesTest.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * @group integrity
+ */
+class Integrity_Modular_MenuConfigFilesTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Configuration menu file list
+     * @var array
+     */
+    protected $_fileList = array();
+
+    /**
+     * Mage_Backend_Model_Config_Menu
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = $this->getMockForAbstractClass(
+            'Mage_Backend_Model_Menu_Config_Menu',
+            array(),
+            '',
+            false
+        );
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_fileList = null;
+    }
+
+    /**
+     * Get Configuration File List
+     * @return array
+     */
+    protected function _getConfigurationFileList()
+    {
+        if (empty($this->_fileList)) {
+            foreach (glob(Mage::getBaseDir('app') . '/*/*/*/*/etc/adminhtml/menu.xml') as $file) {
+                $this->_fileList[$file] = $file;
+            }
+        }
+        return $this->_fileList;
+    }
+
+    /**
+     * Perform test whether a configuration file is valid
+     *
+     * @param string $file
+     * @throws PHPUnit_Framework_AssertionFailedError if file is invalid
+     */
+    protected function _validateConfigFile($file)
+    {
+
+        $schemaFile = $this->_model->getSchemaFile();
+        $domConfig = new Magento_Config_Dom(file_get_contents($file));
+        $result = $domConfig->validate($schemaFile, $errors);
+        $message = "Invalid XML-file: {$file}\n";
+        foreach ($errors as $error) {
+            $message .= "{$error->message} Line: {$error->line}\n";
+        }
+        $this->assertTrue($result, $message);
+    }
+
+    /**
+     * Test each menu configuration file
+     * @param string $file
+     * @dataProvider menuConfigFileDataProvider
+     */
+    public function testMenuConfigFile($file)
+    {
+        $this->_validateConfigFile($file);
+    }
+
+    /**
+     * @return array
+     */
+    public function menuConfigFileDataProvider()
+    {
+        $output = array();
+        $list = $this->_getConfigurationFileList();
+        foreach ($list as $file) {
+            $output[$file] = array($file);
+        }
+        return $output;
+    }
+
+    /**
+     * Test merged menu configuration
+     */
+    public function testMergedConfig()
+    {
+        $model = new Mage_Backend_Model_Menu_Config_Menu($this->_getConfigurationFileList());
+        try {
+            $this->assertInstanceOf('Mage_Backend_Model_Menu_Config_Menu', $model->validate());
+        } catch (Magento_Exception $e) {
+            $this->fail($e->getMessage());
+        }
+    }
+}
diff --git a/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
index 033cb5aa2cb5a..a7f5fdafad2ad 100644
--- a/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
+++ b/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
@@ -143,6 +143,11 @@ protected function _testObsoleteMethodArguments($content)
             'Backwards-incompatible change: method getUsedProductIds($product)'
             . ' must be invoked with one and only one argument - product model object'
         );
+
+        $this->_assertNotRegExp('#->_setActiveMenu\([\'"]([\w\d/_]+)[\'"]\)#Ui', $content,
+            'Backwards-incompatible change: method _setActiveMenu()'
+            . ' must be invoked with menu item identifier than xpath for menu item'
+        );
     }
 
     /**
diff --git a/dev/tests/static/testsuite/Legacy/ObsoleteMenuTest.php b/dev/tests/static/testsuite/Legacy/ObsoleteMenuTest.php
new file mode 100644
index 0000000000000..4eead2367ec10
--- /dev/null
+++ b/dev/tests/static/testsuite/Legacy/ObsoleteMenuTest.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    tests
+ * @package     static
+ * @subpackage  Legacy
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Legacy tests to find obsolete menu declaration
+ */
+class Legacy_ObsoleteMenuTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @param string $menuFile
+     * @dataProvider menuFilesDataProvider
+     */
+    public function testMenuDeclaration($menuFile)
+    {
+        $menuXml = simplexml_load_file($menuFile);
+        $xpath = '/config/menu/*[boolean(./children) or boolean(./title) or boolean(./action)]';
+        $this->assertEmpty(
+            $menuXml->xpath($xpath),
+            'Obsolete menu structure detected in file ' . $menuFile . '.'
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function menuFilesDataProvider()
+    {
+        return Utility_Files::init()->getConfigFiles();
+    }
+}
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
index a3e66d8f8e45b..eeeb1c1068c81 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
@@ -51,6 +51,7 @@
     'Mage_Adminhtml_Block_Api_Edituser',
     'Mage_Adminhtml_Block_Api_Tab_Userroles',
     'Mage_Adminhtml_Block_Catalog',
+    'Mage_Adminhtml_Block_Page_Menu' => array('suggestion' => 'Mage_Backend_Block_Menu'),
     'Mage_Adminhtml_Block_Permissions_User',
     'Mage_Adminhtml_Block_Permissions_User_Grid',
     'Mage_Adminhtml_Block_Permissions_User_Edit',
@@ -123,6 +124,10 @@
     'Mage_ProductAlert_Block_Stock',
     'Mage_Reports_Model_Resource_Coupons_Collection',
     'Mage_Reports_Model_Resource_Invoiced_Collection',
+    'Mage_Reports_Model_Resource_Product_Ordered_Collection',
+    'Mage_Reports_Model_Resource_Product_Viewed_Collection' => array(
+        'suggestion' => 'Mage_Reports_Model_Resource_Report_Product_Viewed_Collection'
+    ),
     'Mage_Reports_Model_Resource_Refunded_Collection',
     'Mage_Reports_Model_Resource_Shipping_Collection',
     'Mage_Rss_Model_Observer',
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
index 2467d2e265fb7..c15cb774f1058 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
@@ -222,6 +222,7 @@
     'getLocaleBaseDir' => array('class_scope' => 'Mage_Core_Model_Design_Package'),
     'getMail' => array('class_scope' => 'Mage_Newsletter_Model_Template'),
     'getMaxQueryLenght',
+    'getMenuItemLabel' => array('class_scope' => 'Mage_Admin_Model_Config'),
     'getMergedCssUrl',
     'getMergedJsUrl',
     'getMinQueryLenght',
diff --git a/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php b/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
index 2b13aa68cf23a..b30e9694d0917 100644
--- a/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
+++ b/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
@@ -161,8 +161,8 @@ protected function _assertTotalErrorsAndWarnings($report, $expected)
         if (!$elements) {
             return;
         }
-        $numErrorsActual = count($report->xpath('/checkstyle/file/error[@severity="error"]'));
-        $numWarningsActual = count($report->xpath('/checkstyle/file/error[@severity="warning"]'));
+
+        list($numErrorsActual, $numWarningsActual) = $this->_calculateCountErrors($report);
 
         $element = $elements[0];
         $attributes = $element->attributes();
@@ -184,6 +184,21 @@ protected function _assertTotalErrorsAndWarnings($report, $expected)
         }
     }
 
+    /**
+     * Calculate count errors and warnings
+     *
+     * @param SimpleXMLElement $report
+     * @return array
+     */
+    protected function _calculateCountErrors($report)
+    {
+        $errorNode = $report->xpath('/checkstyle/file/error[@severity="error"]') ?: array();
+        $warningNode = $report->xpath('/checkstyle/file/error[@severity="warning"]') ?: array();
+        $numErrorsActual = count($errorNode);
+        $numWarningsActual = count($warningNode);
+        return array($numErrorsActual, $numWarningsActual);
+    }
+
     /**
      * Assert that errors correspond to expected errors
      *
diff --git a/dev/tests/unit/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php b/dev/tests/unit/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php
new file mode 100644
index 0000000000000..c446d2ecf75ff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Adminhtml/Model/System/Config/Source/Admin/PageTest.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Adminhtml
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_Adminhtml_Model_System_Config_Source_Admin_Page
+ */
+
+class Mage_Adminhtml_Model_System_Config_Source_Admin_PageTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menuModel;
+
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menuSubModel;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_factoryMock;
+
+    /**
+     * @var Mage_Adminhtml_Model_System_Config_Source_Admin_Page
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $logger = $this->getMock('Mage_Backend_Model_Menu_Logger');
+        $this->_menuModel = new Mage_Backend_Model_Menu(array('logger' => $logger));
+        $this->_menuSubModel = new Mage_Backend_Model_Menu(array('logger' => $logger));
+
+        $this->_factoryMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+
+        $item1 = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $item1->expects($this->any())->method('getId')->will($this->returnValue('item1'));
+        $item1->expects($this->any())->method('getTitle')->will($this->returnValue('Item 1'));
+        $item1->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+        $item1->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
+        $item1->expects($this->any())->method('getAction')->will($this->returnValue('adminhtml/item1'));
+        $item1->expects($this->any())->method('getChildren')->will($this->returnValue($this->_menuSubModel));
+        $item1->expects($this->any())->method('hasChildren')->will($this->returnValue(true));
+        $this->_menuModel->add($item1);
+
+        $item2 = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $item2->expects($this->any())->method('getId')->will($this->returnValue('item2'));
+        $item2->expects($this->any())->method('getTitle')->will($this->returnValue('Item 2'));
+        $item2->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+        $item2->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
+        $item2->expects($this->any())->method('getAction')->will($this->returnValue('adminhtml/item2'));
+        $item2->expects($this->any())->method('hasChildren')->will($this->returnValue(false));
+        $this->_menuSubModel->add($item2);
+
+        $this->_model = new Mage_Adminhtml_Model_System_Config_Source_Admin_Page(
+            array(
+                'menu' => $this->_menuModel,
+                'objectFactory' => $this->_factoryMock,
+            )
+        );
+    }
+
+    public function testToOptionArray()
+    {
+        $this->_factoryMock
+            ->expects($this->at(0))
+            ->method('getModelInstance')
+            ->with(
+            $this->equalTo('Mage_Backend_Model_Menu_Filter_Iterator'),
+            $this->equalTo($this->_menuModel->getIterator())
+            )->will($this->returnValue(new Mage_Backend_Model_Menu_Filter_Iterator($this->_menuModel->getIterator())));
+
+        $this->_factoryMock
+            ->expects($this->at(1))
+            ->method('getModelInstance')
+            ->with(
+                $this->equalTo('Mage_Backend_Model_Menu_Filter_Iterator'),
+                $this->equalTo($this->_menuSubModel->getIterator())
+            )->will($this->returnValue(
+                new Mage_Backend_Model_Menu_Filter_Iterator($this->_menuSubModel->getIterator())
+            )
+        );
+
+        $nonEscapableNbspChar = html_entity_decode('&#160;', ENT_NOQUOTES, 'UTF-8');
+        $paddingString = str_repeat($nonEscapableNbspChar, 4);
+
+        $expected = array(
+            array(
+                'label' => 'Item 1',
+                'value' => 'item1',
+            ),
+            array(
+                'label' => $paddingString . 'Item 2',
+                'value' => 'item2',
+            ),
+        );
+        $this->assertEquals($expected, $this->_model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/AddTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/AddTest.php
new file mode 100644
index 0000000000000..fd6743dba9dd5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/AddTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Builder_Command_AddTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Builder_Command_Add
+     */
+    protected $_model;
+
+    protected $_params = array(
+        'id' => 'item', 'title' => 'item', 'module' => 'Mage_Backend', 'parent' => 'parent'
+    );
+
+    public function setUp()
+    {
+        $this->_model = new Mage_Backend_Model_Menu_Builder_Command_Add($this->_params);
+    }
+
+    public function testExecuteFillsEmptyItemWithData()
+    {
+        $params = $this->_model->execute(array());
+        $this->assertEquals($this->_params, $params);
+    }
+
+    public function testExecuteDoesntRewriteDataInFilledItem()
+    {
+        $params = $this->_model->execute(array('title' => 'newitem'));
+        $this->_params['title'] =  'newitem';
+        $this->assertEquals($this->_params, $params);
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testChainWithAnotherAddCommandTrowsException()
+    {
+        $this->_model->chain(new Mage_Backend_Model_Menu_Builder_Command_Add($this->_params));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/RemoveTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/RemoveTest.php
new file mode 100644
index 0000000000000..82306b79d3b4f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/RemoveTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Builder_Command_RemoveTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Builder_Command_Remove
+     */
+    protected $_model;
+
+    protected $_params = array(
+        'id' => 'item'
+    );
+
+    public function setUp()
+    {
+        $this->_model = new Mage_Backend_Model_Menu_Builder_Command_Remove($this->_params);
+    }
+
+    public function testExecuteMarksItemAsRemoved()
+    {
+        $params = $this->_model->execute(array());
+        $this->_params['removed'] = true;
+        $this->assertEquals($this->_params, $params);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/UpdateTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/UpdateTest.php
new file mode 100644
index 0000000000000..03439b999e841
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/Command/UpdateTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Builder_Command_UpdateTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Builder_Command_Update
+     */
+    protected $_model;
+
+    protected $_params = array(
+        'id' => 'item', 'title' => 'item', 'module' => 'Mage_Backend', 'parent' => 'parent'
+    );
+
+    public function setUp()
+    {
+        $this->_model = new Mage_Backend_Model_Menu_Builder_Command_Update($this->_params);
+    }
+
+    public function testExecuteFillsEmptyItemWithData()
+    {
+        $params = $this->_model->execute(array());
+        $this->assertEquals($this->_params, $params);
+    }
+
+    public function testExecuteRewritesDataInFilledItem()
+    {
+        $params = $this->_model->execute(array('title' => 'newitem'));
+        $this->assertEquals($this->_params, $params);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/CommandAbstractTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/CommandAbstractTest.php
new file mode 100644
index 0000000000000..5a5b42268f6a1
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Builder/CommandAbstractTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Item_Builder_CommandAbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Builder_CommandAbstract
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = $this->getMockForAbstractClass(
+            'Mage_Backend_Model_Menu_Builder_CommandAbstract',
+            array(array('id' => 'item'))
+        );
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorRequiresObligatoryParams()
+    {
+        $this->getMockForAbstractClass('Mage_Backend_Model_Menu_Builder_CommandAbstract');
+    }
+
+    public function testChainAddsNewCommandAsNextInChain()
+    {
+        $command1 = $this->getMock('Mage_Backend_Model_Menu_Builder_Command_Update', array(), array(array('id' => 1)));
+        $command2 = $this->getMock('Mage_Backend_Model_Menu_Builder_Command_Remove', array(), array(array('id' => 1)));
+        $command1->expects($this->once())->method('chain')->with($this->equalTo($command2));
+
+        $this->_model->chain($command1);
+        $this->_model->chain($command2);
+    }
+
+    public function testExecuteCallsNextCommandInChain()
+    {
+        $itemParams = array();
+        $this->_model->expects($this->once())
+            ->method('_execute')
+            ->with($this->equalTo($itemParams))
+            ->will($this->returnValue($itemParams));
+
+        $command1 = $this->getMock('Mage_Backend_Model_Menu_Builder_Command_Update', array(), array(array('id' => 1)));
+        $command1->expects($this->once())
+            ->method('execute')
+            ->with($this->equalTo($itemParams))
+            ->will($this->returnValue($itemParams));
+
+        $this->_model->chain($command1);
+        $this->assertEquals($itemParams, $this->_model->execute($itemParams));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/BuilderTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/BuilderTest.php
new file mode 100644
index 0000000000000..581fce4cb4924
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/BuilderTest.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+class Mage_Backend_Model_Menu_BuilderTest extends PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var Mage_Backend_Model_Menu_Builder
+     */
+    protected  $_model;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_menuMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_factoryMock;
+
+    public function setUp()
+    {
+        $this->_factoryMock = $this->getMock("Mage_Backend_Model_Menu_Item_Factory", array(), array(), '', false);
+        $this->_menuMock = $this->getMock('Mage_Backend_Model_Menu', array(),
+            array(array('logger' => $this->getMock('Mage_Backend_Model_Menu_Logger'))));
+
+        $this->_model = new Mage_Backend_Model_Menu_Builder(array(
+            'itemFactory' => $this->_factoryMock,
+            'menu' => $this->_menuMock
+        ));
+    }
+
+    public function testProcessCommand()
+    {
+        $command = $this->getMock('Mage_Backend_Model_Menu_Builder_Command_Add', array(), array(), '', false);
+        $command->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $command2 = $this->getMock('Mage_Backend_Model_Menu_Builder_Command_Update', array(), array(), '', false);
+        $command2->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $command->expects($this->once())
+            ->method('chain')
+            ->with($this->equalTo($command2));
+        $this->_model->processCommand($command);
+        $this->_model->processCommand($command2);
+    }
+
+    public function testGetResultBuildsTreeStructure()
+    {
+        $item1 = $this->getMock("Mage_Backend_Model_Menu_Item", array(), array(), '', false);
+        $item1->expects($this->once())->method('getChildren')->will($this->returnValue($this->_menuMock));
+        $this->_factoryMock->expects($this->any())->method('createFromArray')->will($this->returnValue($item1));
+
+        $item2 = $this->getMock("Mage_Backend_Model_Menu_Item", array(), array(), '', false);
+        $this->_factoryMock->expects($this->at(1))->method('createFromArray')->will($this->returnValue($item2));
+
+        $this->_menuMock->expects($this->at(0))
+            ->method('add')
+            ->with(
+            $this->isInstanceOf('Mage_Backend_Model_Menu_Item'),
+            $this->equalTo(null),
+            $this->equalTo(2)
+        );
+
+        $this->_menuMock->expects($this->at(1))
+            ->method('add')
+            ->with(
+            $this->isInstanceOf('Mage_Backend_Model_Menu_Item'),
+            $this->equalTo(null),
+            $this->equalTo(4)
+        );
+
+        $this->_model->processCommand(
+            new Mage_Backend_Model_Menu_Builder_Command_Add(
+                array('id' => 'item1', 'title' => 'Item 1', 'module' => 'Mage_Backend', 'sortOrder' => 2)
+            )
+        );
+        $this->_model->processCommand(
+            new Mage_Backend_Model_Menu_Builder_Command_Add(
+                array(
+                    'id' => 'item2', 'parent' => 'item1', 'title' => 'two',
+                    'module' => 'Mage_Backend', 'sortOrder' => 4
+                )
+            )
+        );
+
+        $this->_model->getResult();
+    }
+
+    public function testGetResultSkipsRemovedItems()
+    {
+        $this->_model->processCommand(new Mage_Backend_Model_Menu_Builder_Command_Add(array(
+                'id' => 1,
+                'title' => 'Item 1',
+                'module' => 'Mage_Backend'
+            )
+        ));
+        $this->_model->processCommand(
+            new Mage_Backend_Model_Menu_Builder_Command_Remove(
+                array('id' => 1,)
+            )
+        );
+
+        $this->_menuMock->expects($this->never())
+            ->method('addChild');
+
+        $this->_model->getResult();
+    }
+
+    /**
+     * @expectedException OutOfRangeException
+     */
+    public function testGetResultSkipItemsWithInvalidParent()
+    {
+        $item1 = $this->getMock("Mage_Backend_Model_Menu_Item", array(), array(), '', false);
+        $this->_factoryMock->expects($this->any())->method('createFromArray')
+            ->will($this->returnValue($item1));
+
+        $this->_model->processCommand(new Mage_Backend_Model_Menu_Builder_Command_Add(array(
+                'id' => 'item1',
+                'parent' => 'not_exists',
+                'title' => 'Item 1',
+                'module' => 'Mage_Backend'
+            )
+        ));
+
+        $this->_model->getResult();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Config/MenuTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Config/MenuTest.php
new file mode 100644
index 0000000000000..44a50c3863a7e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Config/MenuTest.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_Backend_Model_Url
+ */
+class Mage_Backend_Model_Config_MenuTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test existence of xsd file
+     */
+    public function testGetSchemaFile()
+    {
+        $model = $this->getMockForAbstractClass(
+            'Mage_Backend_Model_Menu_Config_Menu',
+            array(),
+            '',
+            false
+        );
+        $actual = $model->getSchemaFile();
+        $this->assertFileExists($actual, 'XSD file [' . $actual . '] not exist');
+    }
+
+    /**
+     * Test output data type of method getMergedConfig
+     */
+    public function testGetMergedConfigDataType()
+    {
+        $model = $this->getMockForAbstractClass(
+            'Mage_Backend_Model_Menu_Config_Menu',
+            array(),
+            '',
+            false
+        );
+        $this->assertInstanceOf('DOMDocument', $model->getMergedConfig(), 'Invalid output type');
+    }
+
+    /**
+     * Test output data type of method getMergedConfig
+     */
+    public function testGetMergedConfig()
+    {
+        $basePath = realpath(__DIR__)  . '/../../_files/';
+
+        $expectedFile = $basePath . 'menu_merged.xml';
+        $files = array(
+            $basePath . 'menu_1.xml',
+            $basePath . 'menu_2.xml',
+        );
+        $model = new Mage_Backend_Model_Menu_Config_Menu($files);
+        $actual = $model->getMergedConfig();
+        $actual->preserveWhiteSpace = false;
+
+        $this->assertInstanceOf('DOMDocument', $actual, 'Invalid output type');
+        $expected = new DOMDocument();
+        $expected->preserveWhiteSpace = false;
+        $expected->load($expectedFile);
+        $this->assertEqualXMLStructure(
+            $expected->documentElement,
+            $actual->documentElement,
+            true,
+            'Incorrect document structure'
+        );
+        $this->assertEquals($expected, $actual, 'Incorrect configuration merge');
+    }
+
+    /**
+     * Test validation of invalid files
+     * @expectedException Magento_Exception
+     */
+    public function testValidateInvalidConfig()
+    {
+        $basePath = realpath(__DIR__)  . '/../_files/';
+        $files = array(
+            $basePath . 'menu_1.xml',
+            $basePath . 'menu_1.xml',
+        );
+        $model = new Mage_Backend_Model_Menu_Config_Menu($files);
+        $model->validate();
+    }
+
+    /**
+     * Test validation of valid files
+     */
+    public function testValidateValidConfig()
+    {
+        $basePath = realpath(__DIR__)  . '/../../_files/';
+        $files = array(
+            $basePath . 'menu_1.xml',
+            $basePath . 'menu_2.xml',
+        );
+        $model = new Mage_Backend_Model_Menu_Config_Menu($files);
+        try {
+            $this->assertInstanceOf('Mage_Backend_Model_Menu_Config_Menu', $model->validate());
+        } catch (Magento_Exception $e) {
+            $this->fail($e->getMessage());
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ConfigTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ConfigTest.php
new file mode 100644
index 0000000000000..6df98c2f5d477
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ConfigTest.php
@@ -0,0 +1,283 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+class Mage_Backend_Model_Menu_ConfigTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Core_Mode_Config
+     */
+    protected $_appConfigMock;
+
+    /**
+     * @var Mage_Core_Model_Cache
+     */
+    protected $_cacheInstanceMock;
+
+    /**
+     * @var DOMDocument
+     */
+    protected $_domDocumentMock;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Director_Dom
+     */
+    protected $_directorDomMock;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Config_Menu
+     */
+    protected $_configMenuMock;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Builder
+     */
+    protected $_builderMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_eventManagerMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_itemFactoryMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_logger;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Config
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_appConfigMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $this->_appConfigMock->expects($this->any())
+            ->method('getModelInstance')
+            ->will($this->returnCallback(array($this, 'getModelInstance')));
+
+        $this->_cacheInstanceMock = $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false);
+
+        $this->_directorDomMock = $this->getMock('Mage_Backend_Model_Menu_Director_Dom', array(), array(), '', false);
+
+        $this->_builderMock = $this->getMock('Mage_Backend_Model_Menu_Builder', array(), array(), '', false);
+
+        $this->_configMenuMock = $this->getMock('Mage_Backend_Model_Menu_Config_Menu', array(), array(), '', false);
+
+        $this->_domDocumentMock = $this->getMock('DOMDocument', array(), array(), '', false);
+
+        $this->_eventManagerMock = $this->getMock('Mage_Core_Model_Event_Manager');
+
+        $this->_logger = $this->getMock('Mage_Backend_Model_Menu_Logger');
+
+        $this->_model = new Mage_Backend_Model_Menu_Config(array(
+            'appConfig' => $this->_appConfigMock,
+            'cache' => $this->_cacheInstanceMock,
+            'eventManager' => $this->_eventManagerMock,
+            'menuBuilder' => $this->_builderMock,
+            'logger' => $this->_logger
+        ));
+    }
+
+    public function testGetMenuConfigurationFiles()
+    {
+        $this->_appConfigMock->expects($this->any())
+            ->method('getModuleConfigurationFiles')
+            ->will($this->returnValue(array(
+                realpath(__DIR__) . '/../_files/menu_1.xml',
+                realpath(__DIR__) . '/../_files/menu_2.xml'
+            )
+        ));
+        $this->assertNotEmpty($this->_model->getMenuConfigurationFiles());
+    }
+
+    /**
+     * @covers Mage_Backend_Model_Menu_Config::getMenu
+     */
+    public function testGetMenuWhenEnabledCache()
+    {
+        $xmlString = '<?xml version="1.0" encoding="utf-8"?><config><menu></menu></config>';
+
+        $this->_cacheInstanceMock->expects($this->any())
+            ->method('canUse')
+            ->with($this->equalTo('config'))
+            ->will($this->returnValue(true));
+
+        $this->_cacheInstanceMock->expects($this->exactly(1))
+            ->method('load')
+            ->will($this->returnValue($xmlString));
+
+        $this->_directorDomMock->expects($this->exactly(1))
+            ->method('buildMenu')
+            ->with($this->isInstanceOf('Mage_Backend_Model_Menu_Builder'));
+
+        $this->_builderMock->expects($this->exactly(1))
+            ->method('getResult')
+            ->will($this->returnValue($this->getMock('Mage_Backend_Model_Menu', array(), array(), '', false)));
+
+        $this->_model->getMenu();
+
+        /*
+         * Recall the same method to ensure that built menu cached in local protected property
+         */
+        $this->_model->getMenu();
+    }
+
+    /**
+     * @covers Mage_Backend_Model_Menu_Config::getMenu
+     */
+    public function testGetMenuWhenDisabledCache()
+    {
+        $this->_cacheInstanceMock->expects($this->any())
+            ->method('canUse')
+            ->will($this->returnValue(false));
+
+        $this->_configMenuMock->expects($this->exactly(1))
+            ->method('getMergedConfig')
+            ->will($this->returnValue($this->_domDocumentMock));
+
+        $this->_domDocumentMock->expects($this->exactly(1))
+            ->method('saveXML')
+            ->will($this->returnValue('<?xml version="1.0" encoding="utf-8"?><config><menu></menu></config>'));
+
+        $this->_model->getMenu();
+    }
+
+    /**
+     * @covers Mage_Backend_Model_Menu_Config::getMenu
+     */
+    public function testGetMenuWhenCacheEnabledAndCleaned()
+    {
+        $xmlString = '<?xml version="1.0" encoding="utf-8"?><config><menu></menu></config>';
+
+        $this->_appConfigMock->expects($this->any())
+            ->method('getModelInstance')
+            ->will($this->returnCallback(array($this, 'getModelInstance')));
+
+        $this->_cacheInstanceMock->expects($this->any())
+            ->method('canUse')
+            ->will($this->returnValue(true));
+
+        $this->_cacheInstanceMock->expects($this->exactly(1))
+            ->method('load')
+            ->will($this->returnValue(null));
+
+        $this->_domDocumentMock->expects($this->exactly(1))
+            ->method('saveXML')
+            ->will($this->returnValue('<?xml version="1.0" encoding="utf-8"?><config><menu></menu></config>'));
+
+        $this->_configMenuMock->expects($this->exactly(1))
+            ->method('getMergedConfig')
+            ->will($this->returnValue($this->_domDocumentMock));
+
+        $this->_cacheInstanceMock->expects($this->exactly(1))
+            ->method('save')
+            ->with($this->equalTo($xmlString));
+
+        $this->_model->getMenu();
+    }
+
+    public function testGetMenuTriggersEventOnlyOnceAfterMenuIsCreated()
+    {
+        $menuMock = new Varien_Object();
+        $this->_eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with($this->equalTo('backend_menu_load_after'), $this->equalTo(array('menu' => $menuMock)));
+
+        $this->_builderMock->expects($this->once())
+            ->method('getResult')
+            ->will($this->returnValue($menuMock));
+
+        $this->_configMenuMock->expects($this->once())
+            ->method('getMergedConfig')
+            ->will($this->returnValue($this->_domDocumentMock));
+
+        $this->_model->getMenu();
+        $this->_model->getMenu();
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testGetMenuInvalidArgumentExceptionLogged()
+    {
+        $this->_configMenuMock->expects($this->any())
+            ->method('getMergedConfig')
+            ->will($this->returnValue($this->_domDocumentMock));
+
+        $this->_logger->expects($this->exactly(1))->method('logException')
+            ->with($this->isInstanceOf('InvalidArgumentException'));
+
+        $this->_builderMock->expects($this->exactly(1))
+            ->method('getResult')
+            ->will($this->throwException(new InvalidArgumentException()));
+
+        $this->_model->getMenu();
+    }
+
+    public function testGetMenuGenericExceptionIsNotLogged()
+    {
+        $this->_configMenuMock->expects($this->any())
+            ->method('getMergedConfig')
+            ->will($this->returnValue($this->_domDocumentMock));
+
+        $this->_logger->expects($this->never())->method('logException');
+
+        $this->_builderMock->expects($this->exactly(1))
+            ->method('getResult')
+            ->will($this->throwException(new Exception()));
+        try {
+            $this->_model->getMenu();
+        } catch (Exception $e) {
+            return;
+        }
+        $this->fail("Generic Exception was not throwed");
+    }
+
+    /**
+     * Callback method for mock object Mage_Core_Model_Config object
+     *
+     * @param mixed $model
+     * @param mixed $arguments
+     * @return PHPUnit_Framework_MockObject_MockObject
+     */
+    public function getModelInstance($model, $arguments)
+    {
+        if ($model == 'Mage_Backend_Model_Menu_Director_Dom') {
+            return $this->_directorDomMock;
+        } elseif ($model == 'Mage_Backend_Model_Menu_Config_Menu') {
+            return $this->_configMenuMock;
+        } else {
+            return $this->getMock($model, array(), $arguments, '', false);
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Director/DomTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Director/DomTest.php
new file mode 100644
index 0000000000000..dd19360f288fa
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Director/DomTest.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_Backend_Model_Menu_Director_Dom
+ */
+class Mage_Backend_Model_Menu_Director_DomTest extends PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var Mage_Backend_Model_Menu_Director_Dom
+     */
+    protected $_model;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_loggerMock;
+
+    public function setUp()
+    {
+        $basePath = realpath(__DIR__)  . '/../../_files/';
+        $path = $basePath . 'menu_merged.xml';
+        $domDocument = new DOMDocument();
+        $domDocument->load($path);
+
+        $mockCommand = $this->getMockForAbstractClass(
+            'Mage_Backend_Model_Menu_Builder_CommandAbstract',
+            array(),
+            '',
+            false,
+            true,
+            true,
+            array('getId')
+        );
+
+        $factory = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $factory->expects($this->any())->method('getModelInstance')->will($this->returnValue($mockCommand));
+
+        $this->_loggerMock = $this->getMock('Mage_Backend_Model_Menu_Logger', array('log'));
+
+        $this->_model = new Mage_Backend_Model_Menu_Director_Dom(
+            array(
+                'config' => $domDocument,
+                'factory' => $factory,
+                'logger' => $this->_loggerMock
+            )
+        );
+    }
+
+    /**
+     * Test __construct if required param missed
+     * @expectedException InvalidArgumentException
+     */
+    public function testInvalidConstructorException()
+    {
+        new Mage_Backend_Model_Menu_Director_Dom();
+    }
+
+    /**
+     * Test __construct if config is no instance of DOMDocument
+     * @expectedException InvalidArgumentException
+     */
+    public function testInvalidConfigInstanceConstructorException()
+    {
+        $object = $this->getMock('StdClass');
+        new Mage_Backend_Model_Menu_Director_Dom(array('config' => $object, 'factory' => $object));
+    }
+
+    /**
+     * Test __construct
+     *
+     * @expectedException InvalidArgumentException
+     */
+    public function testMissingLoggerInstanceException()
+    {
+        $domDocument = $this->getMock('DOMDocument');
+        $factory = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $logger = null;
+        $model = new Mage_Backend_Model_Menu_Director_Dom(
+            array(
+                'config' => $domDocument,
+                'factory' => $factory,
+                'logger' => $logger
+            )
+        );
+
+        unset($model);
+    }
+
+    /**
+     * Test __construct
+     *
+     * @expectedException InvalidArgumentException
+     */
+    public function testInvalidLoggerInstanceException()
+    {
+        $domDocument = $this->getMock('DOMDocument');
+        $factory = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $logger = $this->getMock('StdClass');
+        $model = new Mage_Backend_Model_Menu_Director_Dom(
+            array(
+                'config' => $domDocument,
+                'factory' => $factory,
+                'logger' => $logger
+            )
+        );
+
+        unset($model);
+    }
+
+    /**
+     * Test __construct if config is instance of DOMDocument
+     */
+    public function testValidConfigInstanceConstructor()
+    {
+        $domDocument = $this->getMock('DOMDocument');
+        $factory = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $logger = $this->getMock('Mage_Backend_Model_Menu_Logger');
+        $model = new Mage_Backend_Model_Menu_Director_Dom(
+            array(
+                'config' => $domDocument,
+                'factory' => $factory,
+                'logger' => $logger
+            )
+        );
+        unset($model);
+    }
+
+    /**
+     * Test data extracted from DOMDocument
+     */
+    public function testExtractData()
+    {
+        $basePath = realpath(__DIR__)  . '/../../_files/';
+        $expectedData = include ($basePath . 'menu_merged.php');
+        $this->assertEquals($expectedData, $this->_model->getExtractedData(), 'Invalid extracted data');
+    }
+
+    /**
+     * Test command method with valid builder
+     */
+    public function testCommandWithValidBuilder()
+    {
+        $builder = $this->getMock('Mage_Backend_Model_Menu_Builder', array('processCommand'), array(), '', false);
+        $builder->expects($this->exactly(8))->method('processCommand');
+        $this->assertInstanceOf('Mage_Backend_Model_Menu_DirectorAbstract', $this->_model->buildMenu($builder));
+    }
+
+    public function testCommandLogging()
+    {
+        $this->_loggerMock->expects($this->exactly(4))->method('log');
+        $builder = $this->getMock('Mage_Backend_Model_Menu_Builder', array(), array(), '', false);
+        $this->_model->buildMenu($builder);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Filter/IteratorTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Filter/IteratorTest.php
new file mode 100644
index 0000000000000..4fd883ca1b6ff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Filter/IteratorTest.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Filter_IteratorTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_menuModel;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Filter_Iterator
+     */
+    protected $_filterIteratorModel;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Item[]
+     */
+    protected $_items = array();
+
+    public function setUp()
+    {
+        $this->_items['item1'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item1']->expects($this->any())->method('getId')->will($this->returnValue('item1'));
+        $this->_items['item1']->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
+        $this->_items['item1']->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+
+        $this->_items['item2'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item2']->expects($this->any())->method('getId')->will($this->returnValue('item2'));
+        $this->_items['item2']->expects($this->any())->method('isDisabled')->will($this->returnValue(true));
+        $this->_items['item2']->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+
+        $this->_items['item3'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item3']->expects($this->any())->method('getId')->will($this->returnValue('item3'));
+        $this->_items['item3']->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
+        $this->_items['item3']->expects($this->any())->method('isAllowed')->will($this->returnValue(false));
+
+        $loggerMock = $this->getMock('Mage_Backend_Model_Menu_Logger');
+
+        $this->_menuModel = new Mage_Backend_Model_Menu(array('logger' => $loggerMock));
+        $this->_filterIteratorModel = new Mage_Backend_Model_Menu_Filter_Iterator($this->_menuModel->getIterator());
+    }
+
+
+    public function testLoopWithAllItemsDisabledDoesntIterate()
+    {
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $items = array();
+        foreach ($this->_filterIteratorModel as $item) {
+            $items[] = $item;
+        }
+        $this->assertCount(0, $items);
+    }
+
+    public function testLoopIteratesOnlyValidItems()
+    {
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_menuModel->add($this->_items['item1']);
+
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $items = array();
+        foreach ($this->_filterIteratorModel as $item) {
+            $items[] = $item;
+        }
+        $this->assertCount(1, $items);
+    }
+
+    public function testLoopIteratesDosntIterateDisabledItems()
+    {
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_menuModel->add($this->_items['item1']);
+        $this->_menuModel->add($this->_items['item2']);
+
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $items = array();
+        foreach ($this->_filterIteratorModel as $item) {
+            $items[] = $item;
+        }
+        $this->assertCount(1, $items);
+    }
+
+    public function testLoopIteratesDosntIterateNotAllowedItems()
+    {
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_menuModel->add($this->_items['item1']);
+        $this->_menuModel->add($this->_items['item3']);
+
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $items = array();
+        foreach ($this->_filterIteratorModel as $item) {
+            $items[] = $item;
+        }
+        $this->assertCount(1, $items);
+    }
+
+    public function testLoopIteratesMixedItems()
+    {
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_menuModel->add($this->_items['item1']);
+        $this->_menuModel->add($this->_items['item2']);
+        $this->_menuModel->add($this->_items['item3']);
+
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_menuModel->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $items = array();
+        foreach ($this->_filterIteratorModel as $item) {
+            $items[] = $item;
+        }
+        $this->assertCount(1, $items);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/FactoryTest.php
new file mode 100644
index 0000000000000..3f56d06924a29
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/FactoryTest.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Item_FactoryTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Item_Factory
+     */
+    protected $_model;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectFactoryMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_factoryMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_urlModelMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_aclMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject[]
+     */
+    protected $_helpers = array();
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_appConfigMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeConfigMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_itemValidatorMock;
+
+    /**
+     * Constructor params
+     *
+     * @var array
+     */
+    protected $_params = array();
+
+    public function setUp()
+    {
+        $this->_aclMock = $this->getMock('Mage_Backend_Model_Auth_Session', array(), array(), '', false);
+        $this->_objectFactoryMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $this->_factoryMock = $this->getMock('Mage_Backend_Model_Menu_Factory');
+        $this->_helpers = array(
+            'Mage_Backend_Helper_Data' => $this->getMock('Mage_Backend_Helper_Data'),
+            'Mage_User_Helper_Data' => $this->getMock('Mage_User_Helper_Data')
+        );
+        $this->_urlModelMock = $this->getMock("Mage_Backend_Model_Url", array(), array(), '', false);
+        $this->_appConfigMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $this->_storeConfigMock = $this->getMock('Mage_Core_Model_Store_Config');
+        $this->_itemValidatorMock = $this->getMock('Mage_Backend_Model_Menu_Item_Validator');
+
+        $this->_params = array(
+            'acl' => $this->_aclMock,
+            'objectFactory' => $this->_objectFactoryMock,
+            'menuFactory' => $this->_factoryMock,
+            'helpers' => $this->_helpers,
+            'urlModel' => $this->_urlModelMock,
+            'appConfig' => $this->_appConfigMock,
+            'storeConfig' => $this->_storeConfigMock,
+            'validator' => $this->_itemValidatorMock
+        );
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     * @dataProvider invalidArgumentsProvider
+     */
+    public function testConstructorWithWrongParameterTypesThrowsException($param)
+    {
+        $this->_params[$param] = new Varien_Object();
+        new Mage_Backend_Model_Menu_Item_Factory($this->_params);
+    }
+
+    public function invalidArgumentsProvider()
+    {
+        return array(
+            array('acl'),
+            array('menuFactory'),
+            array('urlModel'),
+            array('appConfig'),
+            array('storeConfig'),
+            array('validator')
+        );
+    }
+
+    public function testCreateFromArray()
+    {
+        $this->_objectFactoryMock->expects($this->once())
+            ->method('getModelInstance')
+            ->with(
+                $this->equalTo('Mage_Backend_Model_Menu_Item'),
+                $this->equalTo(array(
+                    'module' => $this->_helpers['Mage_User_Helper_Data'],
+                    'dependsOnModule' => 'Mage_User_Helper_Data',
+                    'title' => 'item1',
+                    'acl' => $this->_aclMock,
+                    'menuFactory' => $this->_factoryMock,
+                    'urlModel' => $this->_urlModelMock,
+                    'appConfig' => $this->_appConfigMock,
+                    'storeConfig' => $this->_storeConfigMock,
+                    'validator' => $this->_itemValidatorMock
+                ))
+        );
+        $model = new Mage_Backend_Model_Menu_Item_Factory($this->_params);
+        $model->createFromArray(array(
+            'module' => 'Mage_User_Helper_Data',
+            'title' => 'item1',
+            'dependsOnModule' => 'Mage_User_Helper_Data'
+        ));
+    }
+
+    public function testCreateFromArrayProvidesDefaultHelper()
+    {
+        $this->_objectFactoryMock->expects($this->once())
+            ->method('getModelInstance')
+            ->with(
+                $this->equalTo('Mage_Backend_Model_Menu_Item'),
+                $this->equalTo(array(
+                    'module' => $this->_helpers['Mage_Backend_Helper_Data'],
+                    'acl' => $this->_aclMock,
+                    'menuFactory' => $this->_factoryMock,
+                    'urlModel' => $this->_urlModelMock,
+                    'appConfig' => $this->_appConfigMock,
+                    'storeConfig' => $this->_storeConfigMock,
+                    'validator' => $this->_itemValidatorMock
+                ))
+        );
+        $model = new Mage_Backend_Model_Menu_Item_Factory($this->_params);
+        $model->createFromArray(array());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/ValidatorTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/ValidatorTest.php
new file mode 100644
index 0000000000000..5e1984e0ed803
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/Item/ValidatorTest.php
@@ -0,0 +1,289 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_Item_ValidatorTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Item_Validator
+     */
+    protected $_model;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_factoryMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_urlModelMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_aclMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_helperMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_appConfigMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeConfigMock;
+
+    /**
+     * Data to be validated
+     *
+     * @var array
+     */
+    protected $_params = array(
+        'id' => 'item',
+        'title' => 'Item Title',
+        'action' => '/system/config',
+        'resource' => 'system/config',
+        'dependsOnModule' => 'Mage_Backend',
+        'dependsOnConfig' => 'system/config/isEnabled',
+        'toolTip' => 'Item tooltip',
+    );
+
+    public function setUp()
+    {
+        $this->_aclMock = $this->getMock('Mage_Backend_Model_Auth_Session', array(), array(), '', false);
+        $this->_factoryMock = $this->getMock('Mage_Backend_Model_Menu_Factory');
+        $this->_helperMock = $this->getMock('Mage_Backend_Helper_Data');
+        $this->_urlModelMock = $this->getMock("Mage_Backend_Model_Url", array(), array(), '', false);
+        $this->_appConfigMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $this->_storeConfigMock = $this->getMock('Mage_Core_Model_Store_Config');
+
+        $this->_params['acl'] = $this->_aclMock;
+        $this->_params['menuFactory'] = $this->_factoryMock;
+        $this->_params['module'] = $this->_helperMock;
+        $this->_params['urlModel'] = $this->_urlModelMock;
+        $this->_params['appConfig'] = $this->_appConfigMock;
+        $this->_params['storeConfig'] = $this->_storeConfigMock;
+        $this->_model = new Mage_Backend_Model_Menu_Item_Validator();
+    }
+
+    /**
+     * @param string $requiredParam
+     * @throws BadMethodCallException
+     * @expectedException BadMethodCallException
+     * @dataProvider requiredParamsProvider
+     */
+    public function testValidateWithMissingRequiredParamThrowsException($requiredParam)
+    {
+        try {
+            unset($this->_params[$requiredParam]);
+            $this->_model->validate($this->_params);
+        } catch (BadMethodCallException $e) {
+            $this->assertContains($requiredParam, $e->getMessage());
+            throw $e;
+        }
+    }
+
+    public function requiredParamsProvider()
+    {
+        return array(
+            array('acl'),
+            array('appConfig'),
+            array('menuFactory'),
+            array('urlModel'),
+            array('storeConfig'),
+            array('id'),
+            array('title'),
+            array('module')
+        );
+    }
+
+    /**
+     * @param string $typedParam
+     * @throws InvalidArgumentException
+     * @expectedException InvalidArgumentException
+     * @dataProvider requiredParamsProvider
+     */
+    public function testValidateWithWrongTypesThrowsException($typedParam)
+    {
+        try{
+            $this->_params[$typedParam] = new Varien_Object();
+            $this->_model->validate($this->_params);
+        } catch (InvalidArgumentException $e) {
+            $this->assertContains($typedParam, $e->getMessage());
+            throw $e;
+        }
+    }
+
+    public function typedParamsProvider()
+    {
+        return array(
+            array('acl'),
+            array('appConfig'),
+            array('menuFactory'),
+            array('urlModel'),
+            array('storeConfig'),
+            array('moduleHelper')
+        );
+    }
+
+    /**
+     * @param string $param
+     * @param mixed $invalidValue
+     * @throws InvalidArgumentException
+     * @expectedException InvalidArgumentException
+     * @dataProvider invalidParamsProvider
+     */
+    public function testValidateWithNonValidPrimitivesThrowsException($param, $invalidValue)
+    {
+        try {
+            $this->_params[$param] = $invalidValue;
+            $this->_model->validate($this->_params);
+        } catch (InvalidArgumentException $e) {
+            $this->assertContains($param, $e->getMessage());
+            throw $e;
+        }
+    }
+
+    public function invalidParamsProvider()
+    {
+        return array(
+            array('id', 'ab'),
+            array('id', 'abc$'),
+            array('title', 'a'),
+            array('title', '123456789012345678901234567890123456789012345678901'),
+            array('action', '1a'),
+            array('action', '12b|'),
+            array('resource', '1a'),
+            array('resource', '12b|'),
+            array('dependsOnModule', '1a'),
+            array('dependsOnModule', '12b|'),
+            array('dependsOnConfig', '1a'),
+            array('dependsOnConfig', '12b|'),
+            array('toolTip', 'a'),
+            array('toolTip', '123456789012345678901234567890123456789012345678901'),
+        );
+    }
+
+    /**
+     *  Validate duplicated ids
+     *
+     * @param $existedItems
+     * @param $newItem
+     * @dataProvider duplicateIdsProvider
+     * @expectedException InvalidArgumentException
+     */
+    public function testValidateWithDuplicateIdsThrowsException($existedItems, $newItem)
+    {
+        foreach ($existedItems as $item) {
+            $item = array_merge($item, $this->_params);
+            $this->_model->validate($item);
+        }
+
+        $newItem = array_merge($newItem, $this->_params);
+        $this->_model->validate($newItem);
+    }
+
+    /**
+     * Provide items with duplicates ids
+     *
+     * @return array
+     */
+    public function duplicateIdsProvider()
+    {
+        return array(
+            array(
+                array(
+                    array(
+                        'id' => 'item1',
+                        'title' => 'Item 1',
+                        'action' => 'adminhtml/controller/item1'
+                    ),
+                    array(
+                        'id' => 'item2',
+                        'title' => 'Item 2',
+                        'action' => 'adminhtml/controller/item2'
+                    )
+                ),
+                array(
+                    'id' => 'item1',
+                    'title' => 'Item 1',
+                    'action' => 'adminhtml/controller/item1'
+                )
+            ),
+            array(
+                array(
+                    array(
+                        'id' => 'Namespace_Module::item1',
+                        'title' => 'Item 1',
+                        'action' => 'adminhtml/controller/item1'
+                    ),
+                    array(
+                        'id' => 'Namespace_Module::item2',
+                        'title' => 'Item 2',
+                        'action' => 'adminhtml/controller/item2'
+                    )
+                ),
+                array(
+                    'id' => 'Namespace_Module::item1',
+                    'title' => 'Item 1',
+                    'action' => 'adminhtml/controller/item1'
+                )
+            )
+        );
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testValidateParamWithNullForRequiredParamThrowsException()
+    {
+        $this->_model->validateParam('title', null);
+    }
+
+    public function testValidateParamWithNullForNonRequiredParamDoesntValidate()
+    {
+        try{
+            $this->_model->validateParam('toolTip', null);
+        } catch (Exception $e) {
+            $this->fail("Non required null values should not be validated");
+        }
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testValidateParamValidatesPrimitiveValues()
+    {
+        $this->_model->validateParam('toolTip', '/:');
+    }
+}
+
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ItemTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ItemTest.php
new file mode 100644
index 0000000000000..695a02369fdbd
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/Menu/ItemTest.php
@@ -0,0 +1,309 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_Menu_ItemTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu_Item
+     */
+    protected $_model;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_aclMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_menuFactoryMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_urlModelMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_appConfigMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeConfigMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_helperMock;
+
+    /**
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_validatorMock;
+
+    /**
+     * @var array
+     */
+    protected $_params = array(
+        'id' => 'item',
+        'title' => 'Item Title',
+        'action' => '/system/config',
+        'resource' => 'system/config',
+        'dependsOnModule' => 'Mage_Backend',
+        'dependsOnConfig' => 'system/config/isEnabled',
+        'tooltip' => 'Item tooltip',
+    );
+
+    public function setUp()
+    {
+        $this->_aclMock = $this->getMock('Mage_Backend_Model_Auth_Session');
+        $this->_appConfigMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false);
+        $this->_storeConfigMock = $this->getMock('Mage_Core_Model_Store_Config');
+        $this->_menuFactoryMock = $this->getMock('Mage_Backend_Model_Menu_Factory', array(), array(), '', false);
+        $this->_urlModelMock = $this->getMock('Mage_Backend_Model_Url', array(), array(), '', false);
+        $this->_helperMock = $this->getMock('Mage_Backend_Helper_Data');
+        $this->_validatorMock = $this->getMock('Mage_Backend_Model_Menu_Item_Validator');
+
+        $this->_params['module'] = $this->_helperMock;
+        $this->_params['acl'] = $this->_aclMock;
+        $this->_params['appConfig'] = $this->_appConfigMock;
+        $this->_params['storeConfig'] = $this->_storeConfigMock;
+        $this->_params['menuFactory'] = $this->_menuFactoryMock;
+        $this->_params['urlModel'] = $this->_urlModelMock;
+        $this->_params['validator'] = $this->_validatorMock;
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorRequiresValidator()
+    {
+        unset($this->_params['validator']);
+        new Mage_Backend_Model_Menu_Item($this->_params);
+    }
+
+    /**
+     * @expectedException BadMethodCallException
+     */
+    public function testConstructorValidatesData()
+    {
+        $this->_validatorMock->expects($this->once())
+            ->method('validate')
+            ->will($this->throwException(new BadMethodCallException()));
+        new Mage_Backend_Model_Menu_Item($this->_params);
+    }
+
+    public function testGetFullPathReturnsPathWithItemId()
+    {
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertEquals('item', $item->getFullPath());
+    }
+
+    public function testGetUrlWithEmptyActionReturnsHashSign()
+    {
+        $this->_params['action'] = '';
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertEquals('#', $item->getUrl());
+    }
+
+    public function testGetUrlWithValidActionReturnsUrl()
+    {
+        $this->_urlModelMock->expects($this->once())
+            ->method('getUrl')
+            ->with(
+                $this->equalTo('/system/config')
+            )
+            ->will($this->returnValue('Url'));
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertEquals('Url', $item->getUrl());
+    }
+
+    public function testHasClickCallbackReturnsFalseIfItemHasAction()
+    {
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertFalse($item->hasClickCallback());
+    }
+
+    public function testHasClickCallbackReturnsTrueIfItemHasNoAction()
+    {
+        $this->_params['action'] = '';
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertTrue($item->hasClickCallback());
+    }
+
+    public function testGetClickCallbackReturnsStoppingJsIfItemDoesntHaveAction()
+    {
+        $this->_params['action'] = '';
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertEquals('return false;', $item->getClickCallback());
+    }
+
+    public function testGetClickCallbackReturnsEmptyStringIfItemHasAction()
+    {
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertEquals('', $item->getClickCallback());
+    }
+
+    public function testIsDisabledReturnsTrueIfModuleOutputIsDisabled()
+    {
+        $this->_helperMock->expects($this->once())
+            ->method('isModuleOutputEnabled')
+            ->will($this->returnValue(false));
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertTrue($item->isDisabled());
+    }
+
+    public function testIsDisabledReturnsTrueIfModuleDependenciesFail()
+    {
+        $this->_helperMock->expects($this->once())
+            ->method('isModuleOutputEnabled')
+            ->will($this->returnValue(true));
+
+        $moduleConfig = new stdClass();
+        $moduleConfig->{'Mage_Backend'} = $this->getMock('Mage_Test_Module_Config');
+        $moduleConfig->{'Mage_Backend'}->expects($this->once())
+            ->method('is')
+            ->will($this->returnValue(false));
+
+        $this->_appConfigMock->expects($this->once())
+            ->method('getNode')
+            ->will($this->returnValue($moduleConfig));
+
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertTrue($item->isDisabled());
+    }
+
+    public function testIsDisabledReturnsTrueIfConfigDependenciesFail()
+    {
+        $this->_helperMock->expects($this->once())
+            ->method('isModuleOutputEnabled')
+            ->will($this->returnValue(true));
+
+        $moduleConfig = new stdClass();
+        $moduleConfig->{'Mage_Backend'} = $this->getMock('Mage_Test_Module_Config', array('is'));
+        $moduleConfig->{'Mage_Backend'}->expects($this->once())
+            ->method('is')
+            ->will($this->returnValue(true));
+
+        $this->_appConfigMock->expects($this->once())
+            ->method('getNode')
+            ->will($this->returnValue($moduleConfig));
+
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertTrue($item->isDisabled());
+    }
+
+    public function testIsDisabledReturnsFalseIfNoDependenciesFail()
+    {
+        $this->_helperMock->expects($this->once())
+            ->method('isModuleOutputEnabled')
+            ->will($this->returnValue(true));
+
+        $moduleConfig = new stdClass();
+        $moduleConfig->{'Mage_Backend'} = $this->getMock('Mage_Test_Module_Config', array('is'));
+        $moduleConfig->{'Mage_Backend'}->expects($this->once())
+            ->method('is')
+            ->will($this->returnValue(true));
+
+        $this->_appConfigMock->expects($this->once())
+            ->method('getNode')
+            ->will($this->returnValue($moduleConfig));
+
+        $this->_storeConfigMock->expects($this->once())
+            ->method('getConfigFlag')
+            ->will($this->returnValue(true));
+
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertFalse($item->isDisabled());
+    }
+
+    public function testIsAllowedReturnsTrueIfResourceIsAvailable()
+    {
+        $this->_aclMock->expects($this->once())
+            ->method('isAllowed')
+            ->with('admin/system/config')
+            ->will($this->returnValue(true));
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertTrue($item->isAllowed());
+    }
+
+    public function testIsAllowedReturnsFalseIfResourceIsNotAvailable()
+    {
+        $this->_aclMock->expects($this->once())
+            ->method('isAllowed')
+            ->with('admin/system/config')
+            ->will($this->throwException(new Magento_Exception()));
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $this->assertFalse($item->isAllowed());
+    }
+
+    public function testGetChildrenCreatesSubmenuOnFirstCall()
+    {
+        $menuMock = $this->getMock('Mage_Backend_Model_Menu', array(), array(), '', false);
+
+        $this->_menuFactoryMock->expects($this->once())
+            ->method('getMenuInstance')
+            ->with(
+                array('path' => 'item')
+            )
+            ->will($this->returnValue($menuMock));
+
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $item->getChildren();
+        $item->getChildren();
+    }
+
+    public function testSetParentUpdatesAllChildren()
+    {
+        $menuMock = $this->getMock('Mage_Backend_Model_Menu', array(), array(), '', false);
+        $menuMock->expects($this->once())
+            ->method('setPath')
+            ->with($this->equalTo('root/item'));
+
+        $this->_menuFactoryMock->expects($this->once())
+            ->method('getMenuInstance')
+            ->will($this->returnValue($menuMock));
+
+        $item = new Mage_Backend_Model_Menu_Item($this->_params);
+        $item->getChildren();
+        $item->setPath('root/');
+    }
+}
+
+class Mage_Test_Module_Config
+{
+    /**
+     *
+     * @SuppressWarnings(PHPMD.ShortMethodName))
+     */
+    public function is()
+    {
+
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/MenuTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/MenuTest.php
new file mode 100644
index 0000000000000..38f540409202a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/MenuTest.php
@@ -0,0 +1,363 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Model_MenuTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Backend_Model_Menu
+     */
+    protected $_model;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Logger
+     */
+    protected $_logger;
+
+    /**
+     * @var Mage_Backend_Model_Menu_Item[]
+     */
+    protected $_items = array();
+
+    public function setUp()
+    {
+        $this->_items['item1'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item1']->expects($this->any())->method('getId')->will($this->returnValue('item1'));
+
+        $this->_items['item2'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item2']->expects($this->any())->method('getId')->will($this->returnValue('item2'));
+
+        $this->_items['item3'] = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_items['item3']->expects($this->any())->method('getId')->will($this->returnValue('item3'));
+
+        $this->_logger = $this->getMock('Mage_Backend_Model_Menu_Logger');
+
+        $this->_model = new Mage_Backend_Model_Menu(array('logger' => $this->_logger));
+    }
+
+    public function testAdd()
+    {
+        $item = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $this->_model->add($item);
+        $this->assertCount(1, $this->_model);
+        $this->assertEquals($item, $this->_model[0]);
+    }
+
+    public function testAddDoLogAddAction()
+    {
+        $this->_logger->expects($this->once())->method('log')
+            ->with($this->equalTo(sprintf('Add of item with id %s was processed', $this->_items['item1']->getId())));
+
+        $this->_model->add($this->_items['item1']);
+    }
+
+    public function testAddToItem()
+    {
+        $subMenu = $this->getMock("Mage_Backend_Model_Menu", array(), array(array('logger' => $this->_logger)));
+        $subMenu->expects($this->once())
+            ->method("add")
+            ->with($this->_items['item2']);
+
+        $this->_items['item1']->expects($this->once())
+            ->method("getChildren")
+            ->will($this->returnValue($subMenu));
+
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2'], 'item1');
+    }
+
+    public function testAddWithSortIndexThatAlreadyExistsAddsItemOnNextAvailableIndex()
+    {
+        $this->_model->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_model->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_model->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_model->add($this->_items['item1'], null, 2);
+        $this->assertCount(4, $this->_model);
+        $this->assertEquals($this->_items['item1'], $this->_model[3]);
+    }
+
+    public function testAddSortsItemsByTheirSortIndex()
+    {
+        $this->_model->add($this->_items['item1'], null, 10);
+        $this->_model->add($this->_items['item2'], null, 20);
+        $this->_model->add($this->_items['item3'], null, 15);
+
+        $this->assertCount(3, $this->_model);
+        $itemsOrdered = array();
+        foreach ($this->_model as $item) {
+            /** @var $item Mage_Backend_Model_Menu_Item */
+            $itemsOrdered[] = $item->getId();
+        }
+        $this->assertEquals(array('item1', 'item3', 'item2'), $itemsOrdered);
+    }
+
+    public function testGet()
+    {
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+
+        $this->assertEquals($this->_items['item1'], $this->_model[0]);
+        $this->assertEquals($this->_items['item2'], $this->_model[1]);
+        $this->assertEquals($this->_items['item1'], $this->_model->get('item1'));
+        $this->assertEquals($this->_items['item2'], $this->_model->get('item2'));
+    }
+
+    public function testGetRecursive()
+    {
+        $menu1 = new Mage_Backend_Model_Menu(array('logger' => $this->_logger));
+        $menu2 = new Mage_Backend_Model_Menu(array('logger' => $this->_logger));
+
+        $this->_items['item1']->expects($this->any())->method('hasChildren')->will($this->returnValue(true));
+        $this->_items['item1']->expects($this->any())->method('getChildren')->will($this->returnValue($menu1));
+        $this->_model->add($this->_items['item1']);
+
+        $this->_items['item2']->expects($this->any())->method('hasChildren')->will($this->returnValue(true));
+        $this->_items['item2']->expects($this->any())->method('getChildren')->will($this->returnValue($menu2));
+        $menu1->add($this->_items['item2']);
+
+        $this->_items['item3']->expects($this->any())->method('hasChildren')->will($this->returnValue(false));
+        $menu2->add($this->_items['item3']);
+
+        $this->assertEquals($this->_items['item1'], $this->_model->get('item1'));
+        $this->assertEquals($this->_items['item2'], $this->_model->get('item2'));
+        $this->assertEquals($this->_items['item3'], $this->_model->get('item3'));
+    }
+
+    public function testMove()
+    {
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+        $this->_model->add($this->_items['item3']);
+
+        $subMenu = $this->getMock("Mage_Backend_Model_Menu", array(), array(), '', false);
+        $subMenu->expects($this->once())
+            ->method("add")
+            ->with($this->_items['item3']);
+
+        $this->_items['item1']->expects($this->once())
+            ->method("getChildren")
+            ->will($this->returnValue($subMenu));
+
+        $this->_model->move('item3', 'item1');
+
+        $this->assertCount(2, $this->_model);
+        $this->assertFalse(isset($this->_model[2]), "ttt");
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testMoveNonExistentItemThrowsException()
+    {
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+        $this->_model->add($this->_items['item3']);
+
+        $this->_model->move('item4', 'item1');
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testMoveToNonExistentItemThrowsException()
+    {
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+        $this->_model->add($this->_items['item3']);
+
+        $this->_model->move('item3', 'item4');
+    }
+
+    public function testRemoveRemovesMenuItem()
+    {
+        $this->_model->add($this->_items['item1']);
+
+        $this->assertCount(1, $this->_model);
+        $this->assertEquals($this->_items['item1'], $this->_model->get('item1'));
+
+        $this->_model->remove('item1');
+        $this->assertCount(0, $this->_model);
+        $this->assertNull($this->_model->get('item1'));
+    }
+
+    public function testRemoveRemovesMenuItemRecursively()
+    {
+        $menuMock = $this->getMock('Mage_Backend_Model_Menu', array(), array(), '', false);
+        $menuMock->expects($this->once())
+            ->method('remove')
+            ->with($this->equalTo('item2'));
+
+        $this->_items['item1']->expects($this->any())->method('hasChildren')->will($this->returnValue(true));
+        $this->_items['item1']->expects($this->any())->method('getChildren')->will($this->returnValue($menuMock));
+        $this->_model->add($this->_items['item1']);
+
+        $this->_model->remove('item2');
+    }
+
+    public function testRemoveDoLogRemoveAction()
+    {
+        $this->_model->add($this->_items['item1']);
+
+        $this->_logger->expects($this->once())->method('log')
+            ->with($this->equalTo(sprintf('Remove on item with id %s was processed', $this->_items['item1']->getId())));
+
+        $this->_model->remove('item1');
+    }
+
+    public function testReorderReordersItemOnTopLevel()
+    {
+        $this->_model->add($this->_items['item1'], null, 10);
+        $this->_model->add($this->_items['item2'], null, 20);
+
+        $this->assertEquals($this->_items['item2'], $this->_model[20]);
+        $this->_model->reorder('item2', 5);
+        $this->assertEquals($this->_items['item2'], $this->_model[5]);
+        $this->assertFalse(isset($this->_model[20]));
+    }
+
+    public function testReorderReordersItemOnItsLevel()
+    {
+        $this->_logger->expects($this->any())->method('log');
+
+        $subMenu = new Mage_Backend_Model_Menu(array('logger' => $this->_logger));
+
+        $this->_items['item1']->expects($this->any())
+            ->method("hasChildren")
+            ->will($this->returnValue(true));
+
+        $this->_items['item1']->expects($this->any())
+            ->method("getChildren")
+            ->will($this->returnValue($subMenu));
+
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2'], 'item1', 10);
+        $this->_model->add($this->_items['item3'], 'item1', 20);
+
+        $this->_model->reorder('item2', 25);
+        $subMenu->reorder('item3', 30);
+
+        $this->assertEquals($this->_items['item2'], $subMenu[25]);
+        $this->assertEquals($this->_items['item3'], $subMenu[30]);
+    }
+
+    public function testIsLast()
+    {
+        $this->_model->add($this->_items['item1'], null, 10);
+        $this->_model->add($this->_items['item2'], null, 16);
+        $this->_model->add($this->_items['item3'], null, 15);
+
+        $this->assertTrue($this->_model->isLast($this->_items['item2']));
+        $this->assertFalse($this->_model->isLast($this->_items['item3']));
+    }
+
+    public function testSetPathUpdatesAllChildren()
+    {
+        $this->_items['item1']->expects($this->exactly(2))->method('setPath');
+        $this->_model->add($this->_items['item1']);
+
+        $this->_items['item2']->expects($this->exactly(2))->method('setPath');
+        $this->_model->add($this->_items['item2']);
+
+        $this->_model->setpath('root');
+    }
+
+    public function testGetFirstAvailableReturnsLeafNode()
+    {
+        $item = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $item->expects($this->once())->method('setPath');
+        $item->expects($this->never())->method('getFirstAvailable');
+        $this->_model->add($item);
+
+        $this->_items['item1']->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
+        $this->_items['item1']->expects($this->once())->method('isDisabled')->will($this->returnValue(false));
+        $this->_items['item1']->expects($this->once())->method('hasChildren');
+        $this->_model->add($this->_items['item1']);
+
+        $this->assertEquals($this->_items['item1'], $this->_model->getFirstAvailable());
+    }
+
+    public function testGetFirstAvailableReturnsOnlyAllowedAndNotDisabledItem()
+    {
+        $this->_items['item1']->expects($this->exactly(1))->method('isAllowed')->will($this->returnValue(true));
+        $this->_items['item1']->expects($this->exactly(1))->method('isDisabled')->will($this->returnValue(true));
+        $this->_model->add($this->_items['item1']);
+
+        $this->_items['item2']->expects($this->exactly(1))->method('isAllowed')->will($this->returnValue(false));
+        $this->_model->add($this->_items['item2']);
+
+        $this->_items['item3']->expects($this->exactly(1))->method('isAllowed')->will($this->returnValue(true));
+        $this->_items['item3']->expects($this->exactly(1))->method('isDisabled')->will($this->returnValue(false));
+        $this->_model->add($this->_items['item3']);
+
+        $this->assertEquals($this->_items['item3'], $this->_model->getFirstAvailable());
+    }
+
+    public function testMultipleIterationsWorkProperly()
+    {
+        $this->_model->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+        $this->_model->add($this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false));
+
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+
+        $items = array();
+        /** @var $item Mage_Backend_Model_Menu_Item */
+        foreach ($this->_model as $item) {
+            $items[] = $item->getId();
+        }
+
+        $items2 = array();
+        foreach ($this->_model as $item) {
+            $items2[] = $item->getId();
+        }
+        $this->assertEquals($items, $items2);
+    }
+
+    /**
+     * Test reset iterator to first element before each foreach
+     */
+    public function testNestedLoop()
+    {
+        $this->_model->add($this->_items['item1']);
+        $this->_model->add($this->_items['item2']);
+        $this->_model->add($this->_items['item3']);
+
+        $expected = array(
+            'item1' => array('item1', 'item2', 'item3'),
+            'item2' => array('item1', 'item2', 'item3'),
+            'item3' => array('item1', 'item2', 'item3'),
+        );
+        $actual = array();
+        foreach ($this->_model as $valLoop1) {
+            $keyLevel1 = $valLoop1->getId();
+            foreach ($this->_model as $valLoop2) {
+                $actual[$keyLevel1][] = $valLoop2->getId();
+            }
+        }
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/UrlTest.php b/dev/tests/unit/testsuite/Mage/Backend/Model/UrlTest.php
index 77378863a0519..0918ee2dfd1a6 100644
--- a/dev/tests/unit/testsuite/Mage/Backend/Model/UrlTest.php
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/UrlTest.php
@@ -35,57 +35,62 @@ class Mage_Backend_Model_UrlTest extends PHPUnit_Framework_TestCase
      */
     protected  $_model;
 
+    /**
+     * Mock menu model
+     * @var PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_menuMock;
+
     public function setUp()
     {
-        $fileName = __DIR__ . '/_files/adminhtml.xml';
-        $config = new Varien_Simplexml_Config($fileName);
+        $this->_menuMock = $this->getMock('Mage_Backend_Model_Menu', array(), array(), '', false);
 
-        $adminConfig = $this->getMock('Mage_Admin_Model_Config', array(), array(), '', false);
+        $mockItem = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $mockItem->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
+        $mockItem->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
+        $mockItem->expects($this->any())->method('getId')->will($this->returnValue('Mage_Adminhtml::system_acl_roles'));
+        $mockItem->expects($this->any())->method('getAction')->will($this->returnValue('adminhtml/user_role'));
 
-        $adminConfig->expects($this->any())
-            ->method('getAdminhtmlConfig')
-            ->will($this->returnValue($config));
+        $this->_menuMock->expects($this->any())
+            ->method('get')
+            ->with($this->equalTo('Mage_Adminhtml::system_acl_roles'))
+            ->will($this->returnValue($mockItem));
 
         $this->_model = new Mage_Backend_Model_Url(array(
-                'adminConfig' => $adminConfig,
-                'startupPageUrl' => 'system/acl/roles',
+                'startupMenuItemId' => 'Mage_Adminhtml::system_acl_roles',
+                'menu' => $this->_menuMock
             )
         );
     }
 
     public function testFindFirstAvailableMenuDenied()
     {
-        /**
-         * Test to find denied action
-         */
         $user = $this->getMock('Mage_User_Model_User', array(), array(), '', false);
         $user->expects($this->once())
             ->method('setHasAvailableResources')
             ->with($this->equalTo(false));
-
         $mockSession = $this->getMock('Mage_Backend_Model_Auth_Session',
             array('getUser', 'isAllowed'),
             array(),
             '',
             false
         );
-        $mockSession->expects($this->any())
-            ->method('isAllowed')
-            ->will($this->returnValue(false));
 
         $mockSession->expects($this->any())
             ->method('getUser')
             ->will($this->returnValue($user));
 
         $this->_model->setSession($mockSession);
+
+        $this->_menuMock->expects($this->any())
+            ->method('getFirstAvailableChild')
+            ->will($this->returnValue(null));
+
         $this->assertEquals('*/*/denied', $this->_model->findFirstAvailableMenu());
     }
 
     public function testFindFirstAvailableMenu()
     {
-        /**
-         * Test to find first available menu path
-         */
         $user = $this->getMock('Mage_User_Model_User', array(), array(), '', false);
         $mockSession = $this->getMock('Mage_Backend_Model_Auth_Session',
             array('getUser', 'isAllowed'),
@@ -93,9 +98,6 @@ public function testFindFirstAvailableMenu()
             '',
             false
         );
-        $mockSession->expects($this->any())
-            ->method('isAllowed')
-            ->will($this->returnValue(true));
 
         $mockSession->expects($this->any())
             ->method('getUser')
@@ -103,6 +105,12 @@ public function testFindFirstAvailableMenu()
 
         $this->_model->setSession($mockSession);
 
+        $itemMock = $this->getMock('Mage_Backend_Model_Menu_Item', array(), array(), '', false);
+        $itemMock->expects($this->once())->method('getAction')->will($this->returnValue('adminhtml/user'));
+        $this->_menuMock->expects($this->any())
+            ->method('getFirstAvailable')
+            ->will($this->returnValue($itemMock));
+
         $this->assertEquals('adminhtml/user', $this->_model->findFirstAvailableMenu());
     }
 
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/_files/adminhtml.xml b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_1.xml
similarity index 58%
rename from dev/tests/unit/testsuite/Mage/Backend/Model/_files/adminhtml.xml
rename to dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_1.xml
index 650454a53fb6b..1b2a7d6631cd5 100644
--- a/dev/tests/unit/testsuite/Mage/Backend/Model/_files/adminhtml.xml
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_1.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 /**
  * Magento
@@ -28,23 +28,9 @@
 -->
 <config>
     <menu>
-        <system>
-            <children>
-                <acl translate="title" module="Mage_User">
-                    <title>Permissions</title>
-                    <sort_order>70</sort_order>
-                    <children>
-                        <users translate="title">
-                            <title>Users</title>
-                            <action>adminhtml/user</action>
-                        </users>
-                        <roles translate="title">
-                            <title>Roles</title>
-                            <action>adminhtml/user_role</action>
-                        </roles>
-                    </children>
-                </acl>
-            </children>
-        </system>
+        <add id="elem_one_zero" toolTip='toolTip 1' title="Title one.zero" module="Module_One" sortOrder="90" action="adminhtml/system" resource="/one/two" dependsOnModule="Module_One" dependsOnConfig="/one/two"/>
+        <add id="elem_one_one" toolTip='toolTip 2' title="Title one.one" module="Module_One" sortOrder="90" action="adminhtml/system" parent="elem_one_zero" />
+        <update id="elem_one_zero" toolTip='toolTip 3' title="Title one.zero update" module="Module_One_Update" sortOrder="90" action="adminhtml/system" parent="elem_one_zero" />
+        <remove id="elem_one_one" />
     </menu>
 </config>
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_2.xml b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_2.xml
new file mode 100644
index 0000000000000..d41777ec5c91c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_2.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="elem_two_zero" toolTip='toolTip 4' title="Title two.zero" module="Module_Two" sortOrder="90" action="adminhtml/system" />
+        <add id="elem_two_two" toolTip='toolTip 5' title="Title two.two" module="Module_Two" sortOrder="90" action="adminhtml/system" parent="elem_two_zero" />
+        <update id="elem_two_zero" toolTip='toolTip 6' title="Title two.zero update" module="Module_Two_Update" sortOrder="90" action="adminhtml/system" parent="elem_two_zero" />
+        <remove id="elem_two_two" />
+    </menu>
+</config>
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.php b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.php
new file mode 100644
index 0000000000000..fb4cac2c49e7e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+?>
+<?php return array(
+    array (
+        'type' => 'add',
+        'id' => 'elem_one_zero',
+        'title' => 'Title one.zero',
+        'toolTip' => 'toolTip 1',
+        'module' => 'Module_One',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        'resource' => '/one/two',
+        'dependsOnModule' => 'Module_One',
+        'dependsOnConfig' => '/one/two',
+        ),
+    array (
+        'type' => 'add',
+        'id' => 'elem_one_one',
+        'title' => 'Title one.one',
+        'toolTip' => 'toolTip 2',
+        'module' => 'Module_One',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        'parent' => 'elem_one_zero',
+        ),
+    array (
+        'type' => 'update',
+        'id' => 'elem_one_zero',
+        'title' => 'Title one.zero update',
+        'toolTip' => 'toolTip 3',
+        'module' => 'Module_One_Update',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        'parent' => 'elem_one_zero',
+        ),
+    array (
+        'type' => 'remove',
+        'id' => 'elem_one_one',
+        ),
+    array (
+        'type' => 'add',
+        'id' => 'elem_two_zero',
+        'title' => 'Title two.zero',
+        'toolTip' => 'toolTip 4',
+        'module' => 'Module_Two',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        ),
+    array (
+        'type' => 'add',
+        'id' => 'elem_two_two',
+        'title' => 'Title two.two',
+        'toolTip' => 'toolTip 5',
+        'module' => 'Module_Two',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        'parent' => 'elem_two_zero',
+        ),
+    array (
+        'type' => 'update',
+        'id' => 'elem_two_zero',
+        'title' => 'Title two.zero update',
+        'toolTip' => 'toolTip 6',
+        'module' => 'Module_Two_Update',
+        'sortOrder' => 90,
+        'action' => 'adminhtml/system',
+        'parent' => 'elem_two_zero',
+        ),
+    array (
+        'type' => 'remove',
+        'id' => 'elem_two_two',
+        ),
+);
diff --git a/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.xml b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.xml
new file mode 100644
index 0000000000000..0324bf7a17826
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Backend/Model/_files/menu_merged.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Backend
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="elem_one_zero" toolTip='toolTip 1' title="Title one.zero" module="Module_One" sortOrder="90" action="adminhtml/system" resource="/one/two" dependsOnModule="Module_One" dependsOnConfig="/one/two"/>
+        <add id="elem_one_one" toolTip='toolTip 2' title="Title one.one" module="Module_One" sortOrder="90" action="adminhtml/system" parent="elem_one_zero" />
+        <update id="elem_one_zero" toolTip='toolTip 3' title="Title one.zero update" module="Module_One_Update" sortOrder="90" action="adminhtml/system" parent="elem_one_zero" />
+        <remove id="elem_one_one" />
+        <add id="elem_two_zero" toolTip='toolTip 4' title="Title two.zero" module="Module_Two" sortOrder="90" action="adminhtml/system" />
+        <add id="elem_two_two" toolTip='toolTip 5' title="Title two.two" module="Module_Two" sortOrder="90" action="adminhtml/system" parent="elem_two_zero" />
+        <update id="elem_two_zero" toolTip='toolTip 6' title="Title two.zero update" module="Module_Two_Update" sortOrder="90" action="adminhtml/system" parent="elem_two_zero" />
+        <remove id="elem_two_two" />
+    </menu>
+</config>
diff --git a/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php b/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php
new file mode 100644
index 0000000000000..735f67a4da4d7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Captcha
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Captcha_Helper_Data
+     */
+    protected $_object;
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->_object = new Mage_Captcha_Helper_Data();
+        $this->_object->setConfig($this->_getConfigStub());
+        $this->_object->setWebsite($this->_getWebsiteStub());
+        $this->_object->setStore($this->_getStoreStub());
+    }
+
+    /**
+     * @covers Mage_Captcha_Helper_Data::getCaptcha
+     */
+    public function testGetCaptcha()
+    {
+        $store = $this->_getStoreStub();
+        $store->expects($this->once())
+            ->method('isAdmin')
+            ->will($this->returnValue(false));
+
+        $store->expects($this->once())
+            ->method('getConfig')
+            ->with('customer/captcha/type', null)
+            ->will($this->returnValue('zend'));
+        $this->_object->setStore($store);
+
+        $config = $this->_getConfigStub();
+        $config->expects($this->once())
+            ->method('getModelInstance')
+            ->with('Mage_Captcha_Model_Zend', array('formId' => 'user_create', 'helper' => $this->_object))
+            ->will($this->returnValue(new Mage_Captcha_Model_Zend(array('formId' => 'user_create'))));
+        $this->_object->setConfig($config);
+
+        $this->assertInstanceOf('Mage_Captcha_Model_Zend', $this->_object->getCaptcha('user_create'));
+    }
+
+    /**
+     * @covers Mage_Captcha_Helper_Data::getConfigNode
+     */
+    public function testGetConfigNode()
+    {
+        $store = $this->_getStoreStub();
+        $store->expects($this->once())
+            ->method('isAdmin')
+            ->will($this->returnValue(false));
+
+        $store->expects($this->once())
+            ->method('getConfig')
+            ->with('customer/captcha/enable', null)
+            ->will($this->returnValue('1'));
+        $this->_object->setStore($store);
+        $this->_object->getConfigNode('enable');
+    }
+
+    /**
+     * @covers Mage_Captcha_Helper_Data::getFonts
+     */
+    public function testGetFonts()
+    {
+        $baseDir = Magento_Test_Environment::getInstance()->getTmpDir();
+        $option = $this->_getOptionStub();
+        $option->expects($this->any())
+            ->method('getDir')
+            ->will($this->returnValue($baseDir));
+        $this->_object->setOption($option);
+
+        $fonts = $this->_object->getFonts();
+
+        $this->assertEquals($fonts['linlibertine']['label'], 'LinLibertine');
+        $this->assertEquals(
+            $fonts['linlibertine']['path'],
+            $baseDir . DIRECTORY_SEPARATOR . 'lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf'
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getImgDir
+     * @covers Mage_Captcha_Helper_Data::getImgDir
+     */
+    public function testGetImgDir()
+    {
+        $captchaTmpDir = Magento_Test_Environment::getInstance()->getTmpDir() . DIRECTORY_SEPARATOR . 'captcha';
+        $option = $this->_getOptionStub();
+        $option->expects($this->once())
+            ->method('getDir')
+            ->will($this->returnValue($captchaTmpDir));
+        $this->_object->setOption($option);
+
+        $this->assertEquals(
+            $this->_object->getImgDir(),
+            $captchaTmpDir . DIRECTORY_SEPARATOR . 'captcha' . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getImgUrl
+     * @covers Mage_Captcha_Helper_Data::getImgUrl
+     */
+    public function testGetImgUrl()
+    {
+        $this->assertEquals($this->_object->getImgUrl(), 'http://localhost/pub/media/captcha/base/');
+    }
+
+    /**
+     * Create Config Stub
+     * @return Mage_Core_Model_Config
+     */
+    protected function _getConfigStub()
+    {
+        $config = $this->getMock(
+            'Mage_Core_Model_Config',
+            array('getNode', 'getModelInstance'),
+            array(), '', false
+        );
+
+        $config->expects($this->any())
+            ->method('getNode')
+            ->will($this->returnValue(
+                new SimpleXMLElement('<fonts><linlibertine><label>LinLibertine</label>'
+                    . '<path>lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf</path></linlibertine></fonts>')));
+        return $config;
+    }
+
+    /**
+     * Create option stub
+     * @return Mage_Core_Model_Config_Options
+     */
+    protected function _getOptionStub()
+    {
+        $option = $this->getMock(
+            'Mage_Core_Model_Config_Options',
+            array('getDir'),
+            array(), '', false
+        );
+        return $option;
+    }
+
+    /**
+     * Create Website Stub
+     * @return Mage_Core_Model_Website
+     */
+    protected function _getWebsiteStub()
+    {
+        $website = $this->getMock(
+            'Mage_Core_Model_Website',
+            array('getCode'),
+            array(), '', false
+        );
+
+        $website->expects($this->any())
+            ->method('getCode')
+            ->will($this->returnValue('base'));
+
+        return $website;
+    }
+
+    /**
+     * Create store stub
+     * @return Mage_Core_Model_Store
+     */
+    protected function _getStoreStub()
+    {
+        $store = $this->getMock(
+            'Mage_Core_Model_Store',
+            array('isAdmin', 'getConfig', 'getBaseUrl'),
+            array(), '', false
+        );
+
+        $store->expects($this->any())
+            ->method('getBaseUrl')
+            ->will($this->returnValue('http://localhost/pub/media/'));
+
+        return $store;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php b/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php
new file mode 100644
index 0000000000000..b57eb1b009421
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php
@@ -0,0 +1,301 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Captcha
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Captcha_Model_ZendTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Captcha default config data
+     * @var array
+     */
+    protected static $_defaultConfig = array(
+        'type' => 'zend',
+        'enable' => '1',
+        'font' => 'linlibertine',
+        'mode' => 'after_fail',
+        'forms' => 'user_forgotpassword,user_create,guest_checkout,register_during_checkout',
+        'failed_attempts_login' => '3',
+        'failed_attempts_ip' => '1000',
+        'timeout' => '7',
+        'length' => '4-5',
+        'symbols' => 'ABCDEFGHJKMnpqrstuvwxyz23456789',
+        'case_sensitive' => '0',
+        'always_for' => array(
+            'user_create',
+            'user_forgotpassword',
+            'guest_checkout',
+            'register_during_checkout',
+        ),
+    );
+
+    /**
+     * path to fonts
+     * @var array
+     */
+    protected $_fontPath = array(
+        'LinLibertine' => array(
+            'label' => 'LinLibertine',
+            'path' => 'lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf'
+        )
+    );
+
+    /**
+     * @var Mage_Captcha_Model_Zend
+     */
+    protected $_object;
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->_object = new Mage_Captcha_Model_Zend(
+            array(
+                'formId' => 'user_create',
+                'helper' => $this->_getHelperStub(),
+                'session' => $this->_getSessionStub()
+            )
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getBlockName
+     */
+    public function testGetBlockName()
+    {
+        $this->assertEquals($this->_object->getBlockName(), 'Mage_Captcha_Block_Captcha_Zend');
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::isRequired
+     */
+    public function testIsRequired()
+    {
+        $this->assertTrue($this->_object->isRequired());
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::isCaseSensitive
+     */
+    public function testIsCaseSensitive()
+    {
+        self::$_defaultConfig['case_sensitive'] = '1';
+        $this->assertEquals($this->_object->isCaseSensitive(), '1');
+        self::$_defaultConfig['case_sensitive'] = '0';
+        $this->assertEquals($this->_object->isCaseSensitive(), '0');
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getFont
+     */
+    public function testGetFont()
+    {
+        $this->assertEquals(
+            $this->_object->getFont(),
+            $this->_fontPath['LinLibertine']['path']
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getTimeout
+     * @covers Mage_Captcha_Model_Zend::getExpiration
+     */
+    public function testGetTimeout()
+    {
+        $this->assertEquals(
+            $this->_object->getTimeout(),
+            self::$_defaultConfig['timeout'] * 60
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::isCorrect
+     */
+    public function testIsCorrect()
+    {
+        self::$_defaultConfig['case_sensitive'] = '1';
+        $this->assertFalse($this->_object->isCorrect('abcdef5'));
+        $sessionData = array(
+            'user_create_word' => array(
+                'data' => 'AbCdEf5',
+                'expires' => time() + 600
+            )
+        );
+        $this->_object->getSession()->setData($sessionData);
+        self::$_defaultConfig['case_sensitive'] = '0';
+        $this->assertTrue($this->_object->isCorrect('abcdef5'));
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getImgSrc
+     */
+    public function testGetImgSrc()
+    {
+        $this->assertEquals(
+            $this->_object->getImgSrc(),
+            'http://localhost/pub/media/captcha/base/' . $this->_object->getId() . '.png'
+        );
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::logAttempt
+     */
+    public function testLogAttempt()
+    {
+        $resourceModel = $this->_getResourceModelStub();
+
+        $captcha = new Mage_Captcha_Model_Zend(
+            array(
+                'formId' => 'user_create',
+                'helper' => $this->_getHelperStub(),
+                'session' => $this->_getSessionStub(),
+                'resourceModel' => $resourceModel,
+            )
+        );
+        $captcha->logAttempt('admin');
+        $this->assertEquals($captcha->getSession()->getData('user_create_show_captcha'), 1);
+    }
+
+    /**
+     * @covers Mage_Captcha_Model_Zend::getWord
+     */
+    public function testGetWord()
+    {
+        $this->assertEquals($this->_object->getWord(), 'AbCdEf5');
+        $this->_object->getSession()->setData(
+            array(
+                'user_create_word' => array(
+                    'data' => 'AbCdEf5',
+                    'expires' => time() - 60
+                )
+            )
+        );
+        $this->assertNull($this->_object->getWord());
+    }
+
+    /**
+     * Create stub session object
+     * @return Mage_Customer_Model_Session
+     */
+    protected function _getSessionStub()
+    {
+        $session = $this->getMock(
+            'Mage_Customer_Model_Session',
+            array('isLoggedIn'),
+            array(), '', false
+        );
+
+        $session->expects($this->any())
+            ->method('Mage_Customer_Model_Session')
+            ->will($this->returnValue(true));
+
+        $session->setData(
+            array(
+                'user_create_word' => array(
+                    'data' => 'AbCdEf5',
+                    'expires' => time() + 600
+                )
+            )
+        );
+
+        return $session;
+    }
+
+    /**
+     * Create helper stub
+     * @return Mage_Captcha_Helper_Data
+     */
+    protected function _getHelperStub()
+    {
+        $helper = $this->getMock(
+            'Mage_Captcha_Helper_Data',
+            array('getConfigNode', 'getFonts', '_getWebsiteCode', 'getImgUrl')
+        );
+
+        $helper->expects($this->any())
+            ->method('getConfigNode')
+            ->will($this->returnCallback('Mage_Captcha_Model_ZendTest::getConfigNodeStub'));
+
+        $helper->expects($this->any())
+            ->method('getFonts')
+            ->will($this->returnValue($this->_fontPath));
+
+        $helper->expects($this->any())
+            ->method('_getWebsiteCode')
+            ->will($this->returnValue('base'));
+
+        $helper->expects($this->any())
+            ->method('getImgUrl')
+            ->will($this->returnValue('http://localhost/pub/media/captcha/base/'));
+
+
+        return $helper;
+    }
+
+    /**
+     * Get stub for resource model
+     * @return Mage_Captcha_Model_Resource_Log
+     */
+    protected function _getResourceModelStub()
+    {
+        $resourceModel = $this->getMock(
+            'Mage_Captcha_Model_Resource_Log',
+            array('countAttemptsByRemoteAddress', 'countAttemptsByUserLogin', 'logAttempt'),
+            array(), '', false
+        );
+
+        $resourceModel->expects($this->once())
+            ->method('logAttempt');
+
+        $resourceModel->expects($this->any())
+            ->method('countAttemptsByRemoteAddress')
+            ->will($this->returnValue(0));
+
+        $resourceModel->expects($this->any())
+            ->method('countAttemptsByUserLogin')
+            ->will($this->returnValue(3));
+        return $resourceModel;
+    }
+
+    /**
+     * Mock get config method
+     * @static
+     * @return string
+     * @throws InvalidArgumentException
+     */
+    public static function getConfigNodeStub()
+    {
+        $args = func_get_args();
+        $hashName = $args[0];
+
+        if (array_key_exists($hashName, self::$_defaultConfig)) {
+            return self::$_defaultConfig[$hashName];
+        }
+
+        throw new InvalidArgumentException('Unknow id = ' . $hashName);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Category/FlatTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Category/FlatTest.php
new file mode 100644
index 0000000000000..aaee6085f8aed
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Category/FlatTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Catalog
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Catalog_Model_Resource_Category_FlatTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Varien_Db_Adapter_Pdo_Mysql|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_dbAdapterMock;
+
+    protected function setUp()
+    {
+        $this->_dbAdapterMock = $this->getMock('Varien_Db_Adapter_Pdo_Mysql', array(), array(), '', false);
+    }
+
+    /**
+     * @param array $methods
+     * @return Mage_Catalog_Model_Resource_Category_Flat|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getModelMock(array $methods = array())
+    {
+        return $this->getMockBuilder('Mage_Catalog_Model_Resource_Category_Flat')
+            ->setMethods($methods)
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    public function testCreateTableDoesNotInvokeDdlOperationsIfTheyAreNotAllowed()
+    {
+        $model = $this->_getModelMock(array('_createTable', '_getWriteAdapter'));
+
+        // Pretend that some transaction has been started
+        $this->_dbAdapterMock->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(1));
+        $model->expects($this->any())->method('_getWriteAdapter')->will($this->returnValue($this->_dbAdapterMock));
+
+        $model->expects($this->never())->method('_createTable');
+        $model->createTable(1);
+    }
+
+    public function testCreateTableInvokesDdlOperationsIfTheyAreAllowed()
+    {
+        $model = $model = $this->_getModelMock(array('_createTable', '_getWriteAdapter'));
+
+        // Pretend that no transactions have been started
+        $this->_dbAdapterMock->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(0));
+        $model->expects($this->any())->method('_getWriteAdapter')->will($this->returnValue($this->_dbAdapterMock));
+
+        $model->expects($this->atLeastOnce())->method('_createTable');
+        $model->createTable(1);
+    }
+
+    public function testReindexAllCreatesFlatTablesAndInvokesRebuildProcessWithoutArguments()
+    {
+        $model = $this->_getModelMock(array('_createTables', 'rebuild', 'commit', 'beginTransaction', 'rollBack'));
+        $model->expects($this->once())->method('_createTables');
+        $model->expects($this->once())->method('rebuild')->with($this->isNull());
+        $model->reindexAll();
+    }
+
+    public function testRebuildDoesNotInvokeDdlOperationsIfTheyAreNotAllowed()
+    {
+        $model = $this->_getModelMock(array('_createTable', '_getWriteAdapter', '_populateFlatTables'));
+
+        // Pretend that some transaction has been started
+        $this->_dbAdapterMock->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(1));
+        $model->expects($this->any())->method('_getWriteAdapter')->will($this->returnValue($this->_dbAdapterMock));
+
+        $model->expects($this->never())->method('_createTable');
+
+        $store = $this->getMock('Mage_Core_Model_Store', array(), array(), '', false);
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+
+        $model->rebuild(array($store));
+    }
+
+    public function testRebuildInvokesDdlOperationsIfTheyAreAllowed()
+    {
+        $model = $this->_getModelMock(array('_createTable', '_getWriteAdapter', '_populateFlatTables'));
+
+        // Pretend that no transactions have been started
+        $this->_dbAdapterMock->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(0));
+        $model->expects($this->any())->method('_getWriteAdapter')->will($this->returnValue($this->_dbAdapterMock));
+
+        $model->expects($this->atLeastOnce())->method('_createTable');
+
+        $store = $this->getMock('Mage_Core_Model_Store', array(), array(), '', false);
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+
+        $model->rebuild(array($store));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php b/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php
new file mode 100644
index 0000000000000..515e77b209b59
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @param string $expectedResult
+     * @param string $nameInLayout
+     * @param array $methodArguments
+     * @dataProvider dataGetUiId
+     */
+    public function testGetUiId($expectedResult, $nameInLayout, $methodArguments)
+    {
+        /** @var $block Mage_Core_Block_Abstract */
+        $block = $this->getMock('Mage_Core_Block_Abstract', null);
+        $block->setNameInLayout($nameInLayout);
+
+        $this->assertEquals(
+            $expectedResult,
+            call_user_func_array(array($block, 'getUiId'), $methodArguments)
+        );
+    }
+
+    public static function dataGetUiId()
+    {
+        return array(
+            array(' data-ui-id="" ', null, array()),
+            array(' data-ui-id="block" ', 'block', array()),
+            array(' data-ui-id="block" ', 'block---', array()),
+            array(' data-ui-id="block" ', '--block', array()),
+            array(' data-ui-id="bl-ock" ', '--bl--ock---', array()),
+            array(' data-ui-id="bl-ock" ', '--bL--Ock---', array()),
+            array(' data-ui-id="b-l-o-c-k" ', '--b!@#$%^&**()L--O;:...c<_>k---', array()),
+            array(' data-ui-id="a0b1c2d3e4f5g6h7-i8-j9k0l1m2n-3o4p5q6r7-s8t9u0v1w2z3y4x5" ',
+                'a0b1c2d3e4f5g6h7', array('i8-j9k0l1m2n-3o4p5q6r7', 's8t9u0v1w2z3y4x5')
+            ),
+            array(' data-ui-id="capsed-block-name-cap-ed-param1-caps2-but-ton" ',
+                'CaPSed BLOCK NAME', array('cAp$Ed PaRaM1', 'caPs2', 'bUT-TOn')
+            ),
+            array(' data-ui-id="block-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20" ',
+                '!block!', range(0, 20)
+            ),
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Block/Adminhtml/Import/BeforeTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Block/Adminhtml/Import/BeforeTest.php
new file mode 100644
index 0000000000000..57c6d07298543
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Block/Adminhtml/Import/BeforeTest.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Tests for block Mage_ImportExport_Block_Adminhtml_Import_BeforeTest
+ */
+class Mage_ImportExport_Block_Adminhtml_Import_BeforeTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tested source model
+     *
+     * @var Mage_ImportExport_Model_Source_Format_Version
+     */
+    public static $sourceModel;
+
+    /**
+     * Helper registry key
+     *
+     * @var string
+     */
+    protected static $_helperKey = '_helper/Mage_ImportExport_Helper_Data';
+
+    /**
+     * Mock helper
+     *
+     * @static
+     */
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+        Mage::unregister(self::$_helperKey);
+        Mage::register(self::$_helperKey, new Mage_ImportExport_Helper_Data());
+    }
+
+    /**
+     * Unregister helper
+     *
+     * @static
+     */
+    public static function tearDownAfterClass()
+    {
+        parent::tearDownAfterClass();
+        Mage::unregister(self::$_helperKey);
+    }
+
+    /**
+     * Test getter for JS array behaviour string
+     */
+    public function testGetJsAllowedCustomerBehaviours()
+    {
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = Mage::helper('Mage_ImportExport_Helper_Data');
+        $existingVersion = 'existing_version';
+        $customerBehaviours = array('behaviour_1', 'behaviour_2');
+        $notExistingVersion = 'not_existing_version';
+
+        $reflectionBehaviours = new ReflectionProperty('Mage_ImportExport_Helper_Data', '_allowedCustomerBehaviours');
+        $reflectionBehaviours->setAccessible(true);
+        $reflectionBehaviours->setValue($helper, array($existingVersion => $customerBehaviours));
+
+        $block = new Mage_ImportExport_Block_Adminhtml_Import_Before();
+
+        $testJsBehaviours = $block->getJsAllowedCustomerBehaviours($existingVersion);
+        $correctJsBehaviours = Zend_Json::encode($customerBehaviours);
+        $this->assertEquals($correctJsBehaviours, $testJsBehaviours, 'Incorrect JS array string.');
+
+        $testJsBehaviours = $block->getJsAllowedCustomerBehaviours($notExistingVersion);
+        $correctJsBehaviours = Zend_Json::encode(array());
+        $this->assertEquals($correctJsBehaviours, $testJsBehaviours, 'Incorrect JS array string.');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Helper/DataTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Helper/DataTest.php
new file mode 100644
index 0000000000000..aa786ac706c3b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Helper/DataTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Export
+ */
+class Mage_ImportExport_Helper_DataTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test customer behaviours getter
+     */
+    public function testGetAllowedCustomerBehaviours()
+    {
+        $helper = new Mage_ImportExport_Helper_Data();
+        $importVersion = 'test_key';
+        $correctBehaviours = array('behaviour_1', 'behaviour_2');
+
+        $reflectionBehaviours = new ReflectionProperty('Mage_ImportExport_Helper_Data', '_allowedCustomerBehaviours');
+        $reflectionBehaviours->setAccessible(true);
+        $reflectionBehaviours->setValue($helper, array($importVersion => $correctBehaviours));
+
+        $testBehaviours = $helper->getAllowedCustomerBehaviours($importVersion);
+        $this->assertEquals($correctBehaviours, $testBehaviours, 'Incorrect behaviours array.');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/AbstractTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/AbstractTest.php
new file mode 100644
index 0000000000000..6d96eaae2c403
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/AbstractTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Abstract import entity model
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_Abstract', array(),
+            '', false, true, true, array('_saveValidatedBunches')
+        );
+    }
+
+    public function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Create mock for data helper and push it to registry
+     *
+     * @return Mage_ImportExport_Helper_Data|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _createDataHelperMock()
+    {
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = $this->getMock('Mage_ImportExport_Helper_Data', array('__'), array(), '', false);
+        $helper->expects($this->any())
+            ->method('__')
+            ->will($this->returnArgument(0));
+        $registryKey = '_helper/Mage_ImportExport_Helper_Data';
+        if (Mage::registry($registryKey)) {
+            Mage::unregister($registryKey);
+        }
+        Mage::register($registryKey, $helper);
+
+        return $helper;
+    }
+
+    /**
+     * Create source adapter mock and set it into model object which tested in this class
+     *
+     * @param array $columns value which will be returned by method getColNames()
+     * @return Mage_ImportExport_Model_Import_Adapter_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _createSourceAdapterMock(array $columns)
+    {
+        /** @var $source Mage_ImportExport_Model_Import_Adapter_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $source = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Adapter_Abstract', array(), '', false,
+            true, true, array('getColNames')
+        );
+        $source->expects($this->any())
+            ->method('getColNames')
+            ->will($this->returnValue($columns));
+        $this->_model->setSource($source);
+
+        return $source;
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Columns number: "%s" have empty headers
+     */
+    public function testValidateDataEmptyColumnName()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array(''));
+        $this->_model->validateData();
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Columns number: "%s" have empty headers
+     */
+    public function testValidateDataColumnNameWithWhitespaces()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array('  '));
+        $this->_model->validateData();
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Column names: "%s" are invalid
+     */
+    public function testValidateDataAttributeNames()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array('_test1'));
+        $this->_model->validateData();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php
new file mode 100644
index 0000000000000..1d6ec3833a540
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/AbstractTest.php
@@ -0,0 +1,453 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Abstract import entity model
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Abstract', array(),
+            '', false, true, true, array('_saveValidatedBunches')
+        );
+    }
+
+    public function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Create mock for data helper and push it to registry
+     *
+     * @return Mage_ImportExport_Helper_Data|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _createDataHelperMock()
+    {
+        /** @var $helper Mage_ImportExport_Helper_Data */
+        $helper = $this->getMock('Mage_ImportExport_Helper_Data', array('__'), array(), '', false);
+        $helper->expects($this->any())
+            ->method('__')
+            ->will($this->returnArgument(0));
+        $registryKey = '_helper/Mage_ImportExport_Helper_Data';
+        if (Mage::registry($registryKey)) {
+            Mage::unregister($registryKey);
+        }
+        Mage::register($registryKey, $helper);
+
+        return $helper;
+    }
+
+    /**
+     * Test for method _prepareRowForDb()
+     */
+    public function testPrepareRowForDb()
+    {
+        $expected = array(
+            'test1' => 100,
+            'test2' => null,
+            'test3' => '',
+            'test4' => 0,
+            'test5' => 'test',
+            'test6' => array(1, 2, 3),
+            'test7' => array()
+        );
+
+        $method = new ReflectionMethod($this->_model, '_prepareRowForDb');
+        $method->setAccessible(true);
+        $actual = $method->invoke($this->_model, $expected);
+
+        $expected['test3'] = null;
+        $this->assertSame($expected, $actual);
+    }
+
+    /**
+     * Test for method addRowError()
+     */
+    public function testAddRowError()
+    {
+        $this->_createDataHelperMock();
+
+        $errorCode = 'error_code ';
+        $errorColumnName = 'error_column';
+        $this->_model->addRowError($errorCode . '%s', 0, $errorColumnName);
+
+        $this->assertGreaterThan(0, $this->_model->getErrorsCount());
+
+        $errors = $this->_model->getErrorMessages();
+        $this->assertArrayHasKey($errorCode . $errorColumnName, $errors);
+    }
+
+    /**
+     * Test for method importData()
+     */
+    public function testImportData()
+    {
+        $this->_model->expects($this->once())
+            ->method('_importData');
+        $this->_model->importData();
+    }
+
+    /**
+     * Test for method isAttributeParticular()
+     */
+    public function testIsAttributeParticular()
+    {
+        $attributeCode = 'test';
+
+        $property = new ReflectionProperty($this->_model, '_particularAttributes');
+        $property->setAccessible(true);
+        $property->setValue($this->_model, array($attributeCode));
+
+        $this->assertTrue($this->_model->isAttributeParticular($attributeCode));
+    }
+
+    /**
+     * Test for method _addMessageTemplate()
+     */
+    public function testAddMessageTemplate()
+    {
+        $this->_createDataHelperMock();
+
+        $errorCode = 'test';
+        $message = 'This is test error message';
+        $this->_model->addMessageTemplate($errorCode, $message);
+
+        $this->_model->addRowError($errorCode, 0);
+        $errors = $this->_model->getErrorMessages();
+
+        $this->assertArrayHasKey($message, $errors);
+    }
+
+    /**
+     * Test for method isDataValid()
+     */
+    public function testIsDataValid()
+    {
+        /** @var $model Mage_ImportExport_Model_Import_Entity_V2_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $model = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Abstract', array(), '', false,
+            true, true, array('validateData'));
+        $model->expects($this->any())
+            ->method('validateData');
+        $this->assertTrue($model->isDataValid());
+        $model->addRowError('test', 1);
+        $this->assertFalse($model->isDataValid());
+    }
+
+    /**
+     * Test for method isRowAllowedToImport()
+     */
+    public function testIsRowAllowedToImport()
+    {
+        $rows = 4;
+        $skippedRows = array(
+            2 => true,
+            4 => true
+        );
+        $property = new ReflectionProperty($this->_model, '_skippedRows');
+        $property->setAccessible(true);
+        $property->setValue($this->_model, $skippedRows);
+
+        for ($i = 1; $i <= $rows; $i++) {
+            $this->assertFalse($this->_model->isRowAllowedToImport(array(), $i));
+        }
+
+        $this->_model->expects($this->any())
+            ->method('validateRow')
+            ->will($this->returnValue(true));
+
+        for ($i = 1; $i <= $rows; $i++) {
+            $expected = true;
+            if (isset($skippedRows[$i])) {
+                $expected = !$skippedRows[$i];
+            }
+            $this->assertSame($expected, $this->_model->isRowAllowedToImport(array(), $i));
+        }
+    }
+
+    /**
+     * Test for method getBehavior()
+     */
+    public function testGetBehavior()
+    {
+        $behaviors = array(
+            Mage_ImportExport_Model_Import::BEHAVIOR_APPEND,
+            Mage_ImportExport_Model_Import::BEHAVIOR_REPLACE,
+            Mage_ImportExport_Model_Import::BEHAVIOR_DELETE
+        );
+
+        $property = new ReflectionProperty($this->_model, '_availableBehaviors');
+        $property->setAccessible(true);
+        $property->setValue($this->_model, $behaviors);
+
+        $default = Mage_ImportExport_Model_Import::getDefaultBehavior();
+
+        foreach ($behaviors as $behavior) {
+            $this->_model->setParameters(array(
+                'behavior' => $behavior
+            ));
+            $this->assertSame($behavior, $this->_model->getBehavior());
+        }
+
+        $this->_model->setParameters(array(
+            'behavior' => 'custom'
+        ));
+        $this->assertSame($default, $this->_model->getBehavior());
+    }
+
+    /**
+     * Test for method isAttributeValid()
+     *
+     * @param array $data
+     * @dataProvider attributeList
+     */
+    public function testIsAttributeValid(array $data)
+    {
+        $registryKey = '_helper/Mage_Core_Helper_String';
+        if (!Mage::registry($registryKey)) {
+            $helper = new Mage_Core_Helper_String();
+            Mage::register($registryKey, $helper);
+        }
+
+        $attributeCode = $data['code'];
+        $attributeParams = array(
+            'type'      => $data['type'],
+            'options'   => isset($data['options']) ? $data['options'] : null,
+            'is_unique' => isset($data['is_unique']) ? $data['is_unique'] : null
+        );
+
+        $rowData = array(
+            $attributeCode => $data['valid_value']
+        );
+        $this->assertTrue($this->_model->isAttributeValid($attributeCode, $attributeParams, $rowData, 0));
+
+        $rowData[$attributeCode] = $data['invalid_value'];
+        $this->assertFalse($this->_model->isAttributeValid($attributeCode, $attributeParams, $rowData, 0));
+
+        $this->assertEquals(1, $this->_model->getErrorsCount(), 'Wrong count of errors');
+    }
+
+    /**
+     * Data provide which retrieve data for test attributes
+     *
+     * @static
+     * @return array
+     */
+    public static function attributeList()
+    {
+        $longString = str_pad('', Mage_ImportExport_Model_Import_Entity_V2_Abstract::DB_MAX_TEXT_LENGTH, 'x');
+
+        return array(
+            array(
+                array(
+                    'code'          => 'test1',
+                    'type'          => 'decimal',
+                    'valid_value'   => 1.5,
+                    'invalid_value' => 'test'
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test2',
+                    'type'          => 'varchar',
+                    'valid_value'   => 'test string',
+                    'invalid_value' => substr($longString, 0,
+                        Mage_ImportExport_Model_Import_Entity_V2_Abstract::DB_MAX_VARCHAR_LENGTH
+                    )
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test3',
+                    'type'          => 'select',
+                    'valid_value'   => 'test2',
+                    'invalid_value' => 'custom',
+                    'options'       => array(
+                        'test1' => 1,
+                        'test2' => 2,
+                        'test3' => 3
+                    )
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test4',
+                    'type'          => 'multiselect',
+                    'valid_value'   => 'test2',
+                    'invalid_value' => 'custom',
+                    'options'       => array(
+                        'test1' => 1,
+                        'test2' => 2,
+                        'test3' => 3
+                    )
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test5',
+                    'type'          => 'int',
+                    'valid_value'   => 100,
+                    'invalid_value' => 'custom'
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test6',
+                    'type'          => 'datetime',
+                    'valid_value'   => '2012-06-15 15:50',
+                    'invalid_value' => '2012-30-30'
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test7',
+                    'type'          => 'text',
+                    'valid_value'   => 'test string',
+                    'invalid_value' => $longString
+                )
+            ),
+            array(
+                array(
+                    'code'          => 'test8',
+                    'type'          => 'int',
+                    'is_unique'     => true,
+                    'valid_value'   => 1,
+                    'invalid_value' => 1
+                )
+            )
+        );
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Can not find required columns: %s
+     */
+    public function testValidateDataPermanentAttributes()
+    {
+        $this->_createDataHelperMock();
+
+        $columns = array('test1', 'test2');
+        $this->_createSourceAdapterMock($columns);
+
+        $permanentAttributes = array('test2', 'test3');
+        $property = new ReflectionProperty($this->_model, '_permanentAttributes');
+        $property->setAccessible(true);
+        $property->setValue($this->_model, $permanentAttributes);
+
+        $this->_model->validateData();
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Columns number: "%s" have empty headers
+     */
+    public function testValidateDataEmptyColumnName()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array(''));
+        $this->_model->validateData();
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Columns number: "%s" have empty headers
+     */
+    public function testValidateDataColumnNameWithWhitespaces()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array('  '));
+        $this->_model->validateData();
+    }
+
+    /**
+     * Test for method validateData()
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Abstract::validateData()
+     * @expectedException Mage_Core_Exception
+     * @expectedExceptionMessage Column names: "%s" are invalid
+     */
+    public function testValidateDataAttributeNames()
+    {
+        $this->_createDataHelperMock();
+        $this->_createSourceAdapterMock(array('_test1'));
+        $this->_model->validateData();
+    }
+
+    /**
+     * Create source adapter mock and set it into model object which tested in this class
+     *
+     * @param array $columns value which will be returned by method getColNames()
+     * @return Mage_ImportExport_Model_Import_Adapter_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _createSourceAdapterMock(array $columns)
+    {
+        /** @var $source Mage_ImportExport_Model_Import_Adapter_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $source = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Adapter_Abstract', array(), '', false,
+            true, true, array('getColNames')
+        );
+        $source->expects($this->any())
+            ->method('getColNames')
+            ->will($this->returnValue($columns));
+        $this->_model->setSource($source);
+
+        return $source;
+    }
+
+    /**
+     * Test entity subtype getter
+     */
+    public function testGetEntitySubtype()
+    {
+        $this->assertNull($this->_model->getEntitySubtype());
+
+        $entitySubtype = 'customers';
+        $this->_model->setParameters(array('entity_subtype' => $entitySubtype));
+
+        $this->assertEquals($entitySubtype, $this->_model->getEntitySubtype());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php
new file mode 100644
index 0000000000000..0b885074d9c1e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/AbstractTest.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**#@+
+     * Mage registry singleton prefix
+     */
+    const MAGE_REGISTRY_SINGLETON_PREFIX = '_singleton/';
+    /**#@-*/
+
+    /**#@+
+     * Mage_Eav_Model_Config class name
+     */
+    const MAGE_EAV_MODEL_CONFIG = 'Mage_Eav_Model_Config';
+    /**#@-*/
+
+    /**#@+
+     * Mage entity type code and id
+     */
+    const ENTITY_TYPE_CODE = 'type_code';
+    const ENTITY_TYPE_ID   = 1;
+    /**#@-*/
+
+    /**
+     * Abstract import entity eav model
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_unregisterMageEavModelConfigSingleton();
+        $this->_mockMageEavModelConfigSingletonAndRegisterInRegistry();
+        $this->_model = $this->_getModelMock();
+    }
+
+    public function tearDown()
+    {
+        unset($this->_model);
+        $this->_unregisterMageEavModelConfigSingleton();
+
+        parent::tearDown();
+    }
+
+    /**
+     * Get abstract import entity eav model mock
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getModelMock()
+    {
+        $modelMock = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract', array(),
+            '', false, true, true, array('getEntityTypeCode')
+        );
+
+        $modelMock->expects($this->once())
+            ->method('getEntityTypeCode')
+            ->will($this->returnValue(self::ENTITY_TYPE_CODE));
+
+        return $modelMock;
+    }
+
+    /**
+     * Create mock for Mage_Eav_Model_Config singleton and put it to the registry
+     */
+    protected function _mockMageEavModelConfigSingletonAndRegisterInRegistry()
+    {
+        $modelMock = $this->getMock(self::MAGE_EAV_MODEL_CONFIG, array('getEntityType'), array(), '', false, true,
+            true
+        );
+
+        $modelMock->expects($this->once())
+            ->method('getEntityType')
+            ->with(self::ENTITY_TYPE_CODE)
+            ->will($this->returnValue(new Stub_Mage_Eav_Model_Entity_Type()));
+
+        Mage::register(self::MAGE_REGISTRY_SINGLETON_PREFIX . self::MAGE_EAV_MODEL_CONFIG, $modelMock);
+    }
+
+    /**
+     * Remove mock for Mage_Eav_Model_Config singleton from the registry
+     */
+    protected function _unregisterMageEavModelConfigSingleton()
+    {
+        Mage::unregister(self::MAGE_REGISTRY_SINGLETON_PREFIX . self::MAGE_EAV_MODEL_CONFIG);
+    }
+
+    /**
+     * Test entity type id getter
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Abstract::getEntityTypeId()
+     */
+    public function testGetEntityTypeId()
+    {
+        $this->assertEquals(self::ENTITY_TYPE_ID, $this->_model->getEntityTypeId());
+    }
+}
+
+/**
+ * Stub class for Mage_Eav_Model_Entity_Type
+ */
+class Stub_Mage_Eav_Model_Entity_Type
+{
+    /**
+     * Stub for Mage_Eav_Model_Entity_Type::getEntityTypeId()
+     *
+     * @return int
+     */
+    public function getEntityTypeId()
+    {
+        return Mage_ImportExport_Model_Import_Entity_V2_Eav_AbstractTest::ENTITY_TYPE_ID;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AbstractTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AbstractTest.php
new file mode 100644
index 0000000000000..244315883b9f3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AbstractTest.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Abstract customer export model
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    /**
+     * Websites array (website id => code)
+     *
+     * @var array
+     */
+    protected $_websites = array(
+        1 => 'website1',
+        2 => 'website2',
+    );
+
+    /**
+     * Customers array
+     *
+     * @var array
+     */
+    protected $_customers = array(
+        array(
+            'id'         => 1,
+            'email'      => 'test1@email.com',
+            'website_id' => 1
+        ),
+        array(
+            'id'         => 2,
+            'email'      => 'test2@email.com',
+            'website_id' => 2
+        ),
+    );
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = $this->_getModelMock();
+    }
+
+    public function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Create mock for abstract customer model class
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getModelMock()
+    {
+        $customerCollection = new Varien_Data_Collection();
+        foreach ($this->_customers as $customer) {
+            $customerCollection->addItem(new Varien_Object($customer));
+        }
+
+        $modelMock = $this->getMockForAbstractClass('Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract',
+            array(), '', false, true, true, array('_getCustomerCollection')
+        );
+        $property = new ReflectionProperty($modelMock, '_websiteCodeToId');
+        $property->setAccessible(true);
+        $property->setValue($modelMock, array_flip($this->_websites));
+
+        $modelMock->expects($this->any())
+            ->method('_getCustomerCollection')
+            ->will($this->returnValue($customerCollection));
+
+        return $modelMock;
+    }
+
+    /**
+     * Check whether Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract::_customers is filled correctly
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract::_initCustomers()
+     */
+    public function testInitCustomers()
+    {
+        $customers = array();
+        foreach ($this->_customers as $customer) {
+            $email = strtolower($customer['email']);
+            if (!isset($this->_customers[$email])) {
+                $customers[$email] = array();
+            }
+            $customers[$email][$customer['website_id']] = $customer['id'];
+        }
+
+        $method = new ReflectionMethod($this->_model, '_initCustomers');
+        $method->setAccessible(true);
+        $method->invoke($this->_model);
+
+        $this->assertAttributeEquals($customers, '_customers', $this->_model);
+    }
+
+    /**
+     * Check whether Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract::_getCustomerId() returns
+     * correct values
+     *
+     * @depends testInitCustomers
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Abstract::_getCustomerId()
+     */
+    public function testGetCustomerId()
+    {
+        $method = new ReflectionMethod($this->_model, '_initCustomers');
+        $method->setAccessible(true);
+        $method->invoke($this->_model);
+
+        $method = new ReflectionMethod($this->_model, '_getCustomerId');
+        $method->setAccessible(true);
+
+        $this->assertEquals($this->_customers[0]['id'],
+            $method->invokeArgs($this->_model, array($this->_customers[0]['email'],
+                $this->_websites[$this->_customers[0]['website_id']])
+            )
+        );
+        $this->assertEquals($this->_customers[1]['id'],
+            $method->invokeArgs($this->_model, array($this->_customers[1]['email'],
+                $this->_websites[$this->_customers[1]['website_id']])
+            )
+        );
+        $this->assertFalse(
+            $method->invokeArgs($this->_model, array($this->_customers[0]['email'], 'website3'))
+        );
+        $this->assertFalse(
+            $method->invokeArgs($this->_model,
+                array('test3@email.com', $this->_websites[$this->_customers[0]['website_id']])
+            )
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php
new file mode 100644
index 0000000000000..cecf232dcd305
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/AddressTest.php
@@ -0,0 +1,381 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address
+ */
+class Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_AddressTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Abstract customer address export model
+     *
+     * @var Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    /**
+     * Websites array (website id => code)
+     *
+     * @var array
+     */
+    protected $_websites = array(
+        1 => 'website1',
+        2 => 'website2',
+    );
+
+    /**
+     * Attributes array
+     *
+     * @var array
+     */
+    protected $_attributes = array(
+        'country_id' => array(
+            'id'          => 1,
+            'code'        => 'country_id',
+            'table'       => '',
+            'is_required' => true,
+            'is_static'   => false,
+            'rules'       => null,
+            'type'        => 'select',
+            'options'     => null
+        ),
+    );
+
+    /**
+     * Customers array
+     *
+     * @var array
+     */
+    protected $_customers = array(
+        array(
+            'id'         => 1,
+            'email'      => 'test1@email.com',
+            'website_id' => 1
+        ),
+        array(
+            'id'         => 2,
+            'email'      => 'test2@email.com',
+            'website_id' => 2
+        ),
+    );
+
+    /**
+     * Customers array
+     *
+     * @var array
+     */
+    protected $_regions = array(
+        array(
+            'id'           => 1,
+            'country_id'   => 'c1',
+            'code'         => 'code1',
+            'default_name' => 'region1',
+        ),
+        array(
+            'id'           => 2,
+            'country_id'   => 'c1',
+            'code'         => 'code2',
+            'default_name' => 'region2',
+        ),
+    );
+
+    /**
+     * Init entity adapter model
+     */
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->_model = $this->_getModelMock();
+    }
+
+    /**
+     * Unset entity adapter model
+     */
+    public function tearDown()
+    {
+        unset($this->_model);
+
+        parent::tearDown();
+    }
+
+    /**
+     * Create mock for customer address model class (for testInitCountryRegions() method)
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getModelMockForTestInitCountryRegions()
+    {
+        $regionCollection = new Varien_Data_Collection();
+        foreach ($this->_regions as $region) {
+            $regionCollection->addItem(new Varien_Object($region));
+        }
+
+        $modelMock = $this->getMock('Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address',
+            array('_getRegionCollection'), array(), '', false, true, true
+        );
+
+        $modelMock->expects($this->any())
+            ->method('_getRegionCollection')
+            ->will($this->returnValue($regionCollection));
+
+        return $modelMock;
+    }
+
+    /**
+     * Create mock for customer address model class
+     *
+     * @return Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getModelMock()
+    {
+        $modelMock = $this->getMock('Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address',
+            array('_getRegionCollection', 'isAttributeValid', '_getCustomerCollection'), array(), '', false, true, true
+        );
+
+        $regionCollection = new Varien_Data_Collection();
+        foreach ($this->_regions as $region) {
+            $regionCollection->addItem(new Varien_Object($region));
+        }
+
+        $modelMock->expects($this->any())
+            ->method('_getRegionCollection')
+            ->will($this->returnValue($regionCollection));
+
+        $modelMock->expects($this->any())
+            ->method('isAttributeValid')
+            ->will($this->returnValue(true));
+
+        $customerCollection = new Varien_Data_Collection();
+        foreach ($this->_customers as $customer) {
+            $customerCollection->addItem(new Varien_Object($customer));
+        }
+
+        $modelMock->expects($this->any())
+            ->method('_getCustomerCollection')
+            ->will($this->returnValue($customerCollection));
+
+        $method = new ReflectionMethod($modelMock, '_initCustomers');
+        $method->setAccessible(true);
+        $method->invoke($modelMock);
+
+        $property = new ReflectionProperty($modelMock, '_websiteCodeToId');
+        $property->setAccessible(true);
+        $property->setValue($modelMock, array_flip($this->_websites));
+
+        $property = new ReflectionProperty($modelMock, '_attributes');
+        $property->setAccessible(true);
+        $property->setValue($modelMock, $this->_attributes);
+
+        $regions = array();
+        $countryRegions = array();
+        foreach ($this->_regions as $region) {
+            $countryNormalized = strtolower($region['country_id']);
+            $regionCode = strtolower($region['code']);
+            $regionName = strtolower($region['default_name']);
+            $countryRegions[$countryNormalized][$regionCode] = $region['id'];
+            $countryRegions[$countryNormalized][$regionName] = $region['id'];
+            $regions[$region['id']] = $region['default_name'];
+        }
+
+        $method = new ReflectionMethod($modelMock, '_initCountryRegions');
+        $method->setAccessible(true);
+        $method->invoke($modelMock);
+
+        return $modelMock;
+    }
+
+    /**
+     * Data provider of row data and errors
+     *
+     * @return array
+     */
+    public function validateRowDataProvider()
+    {
+        return array(
+            'valid' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_valid.php',
+                '$errors'  => array(),
+                '$isValid' => true,
+            ),
+            'empty address id' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_empty_address_id.php',
+                '$errors' => array(),
+                '$isValid' => true,
+            ),
+            'no website' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_no_website.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_WEBSITE_IS_EMPTY => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_WEBSITE)
+                    )
+                ),
+            ),
+            'empty website' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_empty_website.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_WEBSITE_IS_EMPTY => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_WEBSITE)
+                    )
+                ),
+            ),
+            'no email' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_no_email.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_EMAIL_IS_EMPTY => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_EMAIL)
+                    )
+                ),
+            ),
+            'empty email' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_empty_email.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_EMAIL_IS_EMPTY => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_EMAIL)
+                    )
+                ),
+            ),
+            'invalid email' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_invalid_email.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_INVALID_EMAIL => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_EMAIL)
+                    )
+                ),
+            ),
+            'invalid website' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_invalid_website.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_INVALID_WEBSITE => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_WEBSITE)
+                    )
+                ),
+            ),
+            'no customer' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_no_customer.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_CUSTOMER_NOT_FOUND => array(
+                        array(1, null)
+                    )
+                ),
+            ),
+            'absent required attribute' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_absent_required_attribute.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_VALUE_IS_REQUIRED => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_COUNTRY_ID)
+                    )
+                ),
+            ),
+            'invalid region' => array(
+                '$rowData' => include __DIR__ . '/_files/row_data_invalid_region.php',
+                '$errors' => array(
+                    Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::ERROR_INVALID_REGION => array(
+                        array(1, Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_REGION)
+                    )
+                ),
+            ),
+        );
+    }
+
+    /**
+     * Check whether Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_regions and
+     * Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_countryRegions are filled correctly
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::_initCountryRegions()
+     */
+    public function testInitCountryRegions()
+    {
+        $modelMock = $this->_getModelMockForTestInitCountryRegions();
+
+        $regions = array();
+        $countryRegions = array();
+        foreach ($this->_regions as $region) {
+            $countryNormalized = strtolower($region['country_id']);
+            $regionCode = strtolower($region['code']);
+            $regionName = strtolower($region['default_name']);
+            $countryRegions[$countryNormalized][$regionCode] = $region['id'];
+            $countryRegions[$countryNormalized][$regionName] = $region['id'];
+            $regions[$region['id']] = $region['default_name'];
+        }
+
+        $method = new ReflectionMethod($modelMock, '_initCountryRegions');
+        $method->setAccessible(true);
+        $method->invoke($modelMock);
+
+        $this->assertAttributeEquals($regions, '_regions', $modelMock);
+        $this->assertAttributeEquals($countryRegions, '_countryRegions', $modelMock);
+    }
+
+    /**
+     * Test Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::validateRow() with different values
+     *
+     * @covers Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::validateRow()
+     * @dataProvider validateRowDataProvider
+     * @depends testInitCountryRegions
+     *
+     * @param array $rowData
+     * @param array $errors
+     * @param boolean $isValid
+     */
+    public function testValidateRow(array $rowData, array $errors, $isValid = false)
+    {
+        if ($isValid) {
+            $this->assertTrue($this->_model->validateRow($rowData, 0));
+        } else {
+            $this->assertFalse($this->_model->validateRow($rowData, 0));
+        }
+        $this->assertAttributeEquals($errors, '_errors', $this->_model);
+    }
+
+    /**
+     * Test entity type code getter
+     */
+    public function testGetEntityTypeCode()
+    {
+        $this->assertEquals('customer_address', $this->_model->getEntityTypeCode());
+    }
+
+    /**
+     * Test default address attribute mapping array
+     */
+    public function testGetDefaultAddressAttributeMapping()
+    {
+        $attributeMapping = $this->_model->getDefaultAddressAttributeMapping();
+        $this->assertInternalType('array', $attributeMapping, 'Default address attribute mapping must be an array.');
+        $this->assertArrayHasKey(
+            Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_DEFAULT_BILLING,
+            $attributeMapping,
+            'Default address attribute mapping array must have a default billing column.'
+        );
+        $this->assertArrayHasKey(
+            Mage_ImportExport_Model_Import_Entity_V2_Eav_Customer_Address::COLUMN_DEFAULT_SHIPPING,
+            $attributeMapping,
+            'Default address attribute mapping array must have a default shipping column.'
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_absent_required_attribute.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_absent_required_attribute.php
new file mode 100644
index 0000000000000..d8926865b919d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_absent_required_attribute.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_address_id.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_address_id.php
new file mode 100644
index 0000000000000..bdc51b15158fd
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_address_id.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_email.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_email.php
new file mode 100644
index 0000000000000..6b697c797fdfc
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_email.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => '',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_website.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_website.php
new file mode 100644
index 0000000000000..e02f2a7ab4c28
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_empty_website.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => '',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_email.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_email.php
new file mode 100644
index 0000000000000..6cfb90ec5d8ff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_email.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test1email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_region.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_region.php
new file mode 100644
index 0000000000000..76185b2fa91f3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_region.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region3',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_website.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_website.php
new file mode 100644
index 0000000000000..15de1ad1f2ab0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_invalid_website.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website3',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_customer.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_customer.php
new file mode 100644
index 0000000000000..a6cd9121b0928
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_customer.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test3@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_email.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_email.php
new file mode 100644
index 0000000000000..4358b6f227111
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_email.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_website.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_website.php
new file mode 100644
index 0000000000000..b99bfa0613e70
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_no_website.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_valid.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_valid.php
new file mode 100644
index 0000000000000..814e168e20dff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Import/Entity/V2/Eav/Customer/_files/row_data_valid.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+return array(
+    '_website'                   => 'website1',
+    '_email'                     => 'test1@email.com',
+    '_entity_id'                 => '1',
+    'city'                       => 'Culver City',
+    'company'                    => '',
+    'country_id'                 => 'C1',
+    'fax'                        => '',
+    'firstname'                  => 'John',
+    'lastname'                   => 'Doe',
+    'middlename'                 => '',
+    'postcode'                   => '90232',
+    'prefix'                     => '',
+    'region'                     => 'region1',
+    'region_id'                  => '1',
+    'street'                     => '10441 Jefferson Blvd. Suite 200 Culver City',
+    'suffix'                     => '',
+    'telephone'                  => '12312313',
+    'vat_id'                     => '',
+    'vat_is_valid'               => '',
+    'vat_request_date'           => '',
+    'vat_request_id'             => '',
+    'vat_request_success'        => '',
+    '_address_default_billing_'  => '1',
+    '_address_default_shipping_' => '1',
+);
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Format/VersionTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Format/VersionTest.php
new file mode 100644
index 0000000000000..f024e7a14fb98
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Format/VersionTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for version source model Mage_ImportExport_Model_Source_Format_Version
+ */
+class Mage_ImportExport_Model_Source_Format_VersionTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tested source model
+     *
+     * @var Mage_ImportExport_Model_Source_Format_Version
+     */
+    public static $sourceModel;
+
+    /**
+     * Helper registry key
+     *
+     * @var string
+     */
+    protected static $_helperKey = '_helper/Mage_ImportExport_Helper_Data';
+
+    /**
+     * Helper property
+     *
+     * @var Mage_ImportExport_Helper_Data|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected static $_helper;
+
+    /**
+     * Init source model
+     *
+     * @static
+     */
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+        self::$sourceModel = new Mage_ImportExport_Model_Source_Format_Version();
+    }
+
+    /**
+     * Unregister source model and helper
+     *
+     * @static
+     */
+    public static function tearDownAfterClass()
+    {
+        parent::tearDownAfterClass();
+        Mage::unregister(self::$_helperKey);
+        self::$_helper = null;
+        self::$sourceModel = null;
+    }
+
+    /**
+     * Helper initialization
+     *
+     * @return Mage_ImportExport_Helper_Data
+     */
+    protected function _initHelper()
+    {
+        if (!self::$_helper) {
+            self::$_helper = $this->getMock(
+                'Mage_ImportExport_Helper_Data',
+                array('__')
+            );
+            self::$_helper->expects($this->any())
+                ->method('__')
+                ->will($this->returnArgument(0));
+
+            Mage::unregister(self::$_helperKey);
+            Mage::register(self::$_helperKey, self::$_helper);
+        }
+        return self::$_helper;
+    }
+
+    /**
+     * Is result variable an array
+     */
+    public function testToArray()
+    {
+        $this->_initHelper();
+
+        $basicArray = self::$sourceModel->toArray();
+        $this->assertInternalType('array', $basicArray, 'Result variable must be an array.');
+    }
+
+    /**
+     * Is result variable an correct optional array
+     */
+    public function testToOptionArray()
+    {
+        $this->_initHelper();
+
+        $optionalArray = self::$sourceModel->toOptionArray();
+        $this->assertInternalType('array', $optionalArray, 'Result variable must be an array.');
+
+        $basicArray = self::$sourceModel->toArray();
+        // count + 1 = all values + header
+        $this->assertCount(count($basicArray) + 1, $optionalArray, 'Incorrect number of elements in optional array.');
+
+        foreach ($optionalArray as $option) {
+            $this->assertArrayHasKey('label', $option, 'Option must have label property.');
+            $this->assertArrayHasKey('value', $option, 'Option must have value property.');
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/BehaviorTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/BehaviorTest.php
new file mode 100644
index 0000000000000..94e50504234fc
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/BehaviorTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for behaviour source model Mage_ImportExport_Model_Source_Import_Behavior
+ */
+class Mage_ImportExport_Model_Source_Import_BehaviorTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tested source model
+     *
+     * @var Mage_ImportExport_Model_Source_Import_Behavior
+     */
+    public static $sourceModel;
+
+    /**
+     * Helper registry key
+     *
+     * @var string
+     */
+    protected static $_helperKey = '_helper/Mage_ImportExport_Helper_Data';
+
+    /**
+     * Helper property
+     *
+     * @var Mage_ImportExport_Helper_Data|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected static $_helper;
+
+    /**
+     * Init source model
+     *
+     * @static
+     */
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+        self::$sourceModel = new Mage_ImportExport_Model_Source_Import_Behavior();
+    }
+
+    /**
+     * Unregister source model and helper
+     *
+     * @static
+     */
+    public static function tearDownAfterClass()
+    {
+        parent::tearDownAfterClass();
+        Mage::unregister(self::$_helperKey);
+        self::$_helper = null;
+        self::$sourceModel = null;
+    }
+
+    /**
+     * Helper initialization
+     *
+     * @return Mage_ImportExport_Helper_Data
+     */
+    protected function _initHelper()
+    {
+        if (!self::$_helper) {
+            self::$_helper = $this->getMock(
+                'Mage_ImportExport_Helper_Data',
+                array('__')
+            );
+            self::$_helper->expects($this->any())
+                ->method('__')
+                ->will($this->returnArgument(0));
+
+            Mage::unregister(self::$_helperKey);
+            Mage::register(self::$_helperKey, self::$_helper);
+        }
+        return self::$_helper;
+    }
+
+    /**
+     * Is result variable an correct optional array
+     */
+    public function testToOptionArray()
+    {
+        $this->_initHelper();
+
+        $optionalArray = self::$sourceModel->toOptionArray();
+        $this->assertInternalType('array', $optionalArray, 'Result variable must be an array.');
+
+        foreach ($optionalArray as $option) {
+            $this->assertArrayHasKey('label', $option, 'Option must have label property.');
+            $this->assertArrayHasKey('value', $option, 'Option must have value property.');
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/EntityTest.php b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/EntityTest.php
new file mode 100644
index 0000000000000..a9d220c35e09e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/ImportExport/Model/Source/Import/EntityTest.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_ImportExport
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test class for entity source model Mage_ImportExport_Model_Source_Import_Entity
+ */
+class Mage_ImportExport_Model_Source_Import_EntityTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tested source model
+     *
+     * @var Mage_ImportExport_Model_Source_Import_Entity
+     */
+    public static $sourceModel;
+
+    /**
+     * Helper registry key
+     *
+     * @var string
+     */
+    protected static $_helperKey = '_helper/Mage_ImportExport_Helper_Data';
+
+    /**
+     * Helper property
+     *
+     * @var Mage_ImportExport_Helper_Data|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected static $_helper;
+
+    /**
+     * Test entity
+     *
+     * @var array
+     */
+    protected $_testEntity = array(
+        'label' => 'test_label',
+        'node'  => 'test_node'
+    );
+
+    /**
+     * Init source model
+     *
+     * @static
+     */
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+        self::$sourceModel = new Mage_ImportExport_Model_Source_Import_Entity();
+    }
+
+    /**
+     * Unregister source model and helper
+     *
+     * @static
+     */
+    public static function tearDownAfterClass()
+    {
+        parent::tearDownAfterClass();
+        Mage::unregister(self::$_helperKey);
+        self::$_helper = null;
+        self::$sourceModel = null;
+
+        $config = new ReflectionProperty('Mage', '_config');
+        $config->setAccessible(true);
+        $config->setValue(null, null);
+        $config->setAccessible(false);
+    }
+
+    /**
+     * Helper initialization
+     *
+     * @return Mage_ImportExport_Helper_Data
+     */
+    protected function _initHelper()
+    {
+        if (!self::$_helper) {
+            self::$_helper = $this->getMock(
+                'Mage_ImportExport_Helper_Data',
+                array('__')
+            );
+            self::$_helper->expects($this->any())
+                ->method('__')
+                ->will($this->returnArgument(0));
+
+            Mage::unregister(self::$_helperKey);
+            Mage::register(self::$_helperKey, self::$_helper);
+        }
+        return self::$_helper;
+    }
+
+    /**
+     * Mock config
+     */
+    protected function _mockConfig()
+    {
+        $configObject = new Mage_Core_Model_Config_Base(new Varien_Simplexml_Element('<config></config>'));
+        $configObject->setNode(
+            'global/importexport/import_entities/' . $this->_testEntity['node'] . '/model_token',
+            'Some_Class'
+        );
+        $configObject->setNode(
+            'global/importexport/import_entities/' . $this->_testEntity['node'] . '/label',
+            $this->_testEntity['label']
+        );
+
+        $config = new ReflectionProperty('Mage', '_config');
+        $config->setAccessible(true);
+        $config->setValue(null, $configObject);
+    }
+
+    /**
+     * Is result variable an correct optional array
+     */
+    public function testToOptionArray()
+    {
+        $this->_initHelper();
+        $this->_mockConfig();
+
+        $optionalArray = self::$sourceModel->toOptionArray();
+
+        $this->assertInternalType('array', $optionalArray, 'Result variable must be an array.');
+        $this->assertCount(2, $optionalArray);
+
+        foreach ($optionalArray as $option) {
+            $this->assertArrayHasKey('label', $option, 'Option must have label property.');
+            $this->assertArrayHasKey('value', $option, 'Option must have value property.');
+        }
+
+        $headerElement = $optionalArray[0];
+        $dataElement = $optionalArray[1];
+
+        $this->assertEmpty($headerElement['value'], 'Value must be empty.');
+        $this->assertEquals($this->_testEntity['node'], $dataElement['value'], 'Incorrect element value.');
+        $this->assertEquals($this->_testEntity['label'], $dataElement['label'], 'Incorrect element label.');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Varien/Data/Collection/DbTest.php b/dev/tests/unit/testsuite/Varien/Data/Collection/DbTest.php
index aafd854221b99..5cf52af8723c6 100644
--- a/dev/tests/unit/testsuite/Varien/Data/Collection/DbTest.php
+++ b/dev/tests/unit/testsuite/Varien/Data/Collection/DbTest.php
@@ -86,17 +86,10 @@ public function testUnshiftOrder($adapter)
      */
     public function testAddFieldToFilter()
     {
-        $adapter =$this->_getAdapterMock(
-            'Zend_Db_Adapter_Pdo_Mysql',
-            array('fetchAll', 'prepareSqlCondition'),
-            null
-        );
+        $adapter = $this->_getAdapterMock('Zend_Db_Adapter_Pdo_Mysql', array('prepareSqlCondition'), null);
         $adapter->expects($this->any())
             ->method('prepareSqlCondition')
-            ->with(
-                $this->stringContains('is_imported'),
-                $this->anything()
-            )
+            ->with($this->stringContains('is_imported'), $this->anything())
             ->will($this->returnValue('is_imported = 1'));
         $this->_collection->setConnection($adapter);
         $select = $this->_collection->getSelect()->from('test');
@@ -111,31 +104,21 @@ public function testAddFieldToFilter()
      */
     public function testAddFieldToFilterWithMultipleParams()
     {
-        $adapter = $this->_getAdapterMock(
-            'Zend_Db_Adapter_Pdo_Mysql',
-            array('fetchAll', 'prepareSqlCondition'),
-            null
-        );
+        $adapter = $this->_getAdapterMock('Zend_Db_Adapter_Pdo_Mysql', array('prepareSqlCondition'), null);
         $adapter->expects($this->at(0))
             ->method('prepareSqlCondition')
-            ->with(
-                'weight',
-                array('in' => array(1,3))
-            )
+            ->with('weight', array('in' => array(1, 3)))
             ->will($this->returnValue('weight in (1, 3)'));
         $adapter->expects($this->at(1))
             ->method('prepareSqlCondition')
-            ->with(
-                'name',
-                array('like' => 'M%')
-            )
+            ->with('name', array('like' => 'M%'))
             ->will($this->returnValue("name like 'M%'"));
         $this->_collection->setConnection($adapter);
         $select = $this->_collection->getSelect()->from("test");
 
         $this->_collection->addFieldToFilter(
             array('weight', 'name'),
-            array(array('in' => array(1,3)), array('like' => 'M%'))
+            array(array('in' => array(1, 3)), array('like' => 'M%'))
         );
 
         $this->assertEquals(
@@ -157,4 +140,28 @@ public function testAddFieldToFilterWithMultipleParams()
             $select->assemble()
         );
     }
+
+    /**
+     * Test that adding field to filter by value which contains question mark produce correct SQL
+     */
+    public function testAddFieldToFilterValueContainsQuestionMark()
+    {
+        $adapter = $this->_getAdapterMock(
+            'Zend_Db_Adapter_Pdo_Mysql',
+            array('select', 'prepareSqlCondition', 'supportStraightJoin'),
+            null
+        );
+        $adapter->expects($this->once())
+            ->method('prepareSqlCondition')
+            ->with('email', array('like' => 'value?'))
+            ->will($this->returnValue('email LIKE \'%value?%\''));
+        $adapter->expects($this->once())
+            ->method('select')
+            ->will($this->returnValue(new Varien_Db_Select($adapter)));
+        $this->_collection->setConnection($adapter);
+
+        $select = $this->_collection->getSelect()->from('test');
+        $this->_collection->addFieldToFilter('email', array('like' => 'value?'));
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (email LIKE '%value?%')", $select->assemble());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Varien/Db/SelectTest.php b/dev/tests/unit/testsuite/Varien/Db/SelectTest.php
new file mode 100644
index 0000000000000..5dc518f47bdde
--- /dev/null
+++ b/dev/tests/unit/testsuite/Varien/Db/SelectTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Varien
+ * @package     Varien_Db
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Varien_Db_SelectTest extends Magento_Test_TestCase_ZendDbAdapterAbstract
+{
+    public function testWhere()
+    {
+        $select = new Varien_Db_Select($this->_getAdapterMockWithMockedQuote(1, "'5'"));
+        $select->from('test')->where('field = ?', 5);
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (field = '5')", $select->assemble());
+
+        $select = new Varien_Db_Select($this->_getAdapterMockWithMockedQuote(1, "''"));
+        $select->from('test')->where('field = ?');
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (field = '')", $select->assemble());
+
+        $select = new Varien_Db_Select($this->_getAdapterMockWithMockedQuote(1, "'%?%'"));
+        $select->from('test')->where('field LIKE ?', '%value?%');
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (field LIKE '%?%')", $select->assemble());
+
+        $select = new Varien_Db_Select($this->_getAdapterMockWithMockedQuote(0));
+        $select->from('test')->where("field LIKE '%value?%'", null, Varien_Db_Select::TYPE_CONDITION);
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (field LIKE '%value?%')", $select->assemble());
+
+        $select = new Varien_Db_Select($this->_getAdapterMockWithMockedQuote(1, "'1', '2', '4', '8'"));
+        $select->from('test')->where("id IN (?)", array(1, 2, 4, 8));
+        $this->assertEquals("SELECT `test`.* FROM `test` WHERE (id IN ('1', '2', '4', '8'))", $select->assemble());
+    }
+
+    /**
+     * Retrieve mock of adapter with mocked quote method
+     *
+     * @param int $callCount
+     * @param string|null $returnValue
+     * @return Zend_Db_Adapter_Abstract|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getAdapterMockWithMockedQuote($callCount, $returnValue = null)
+    {
+        $adapter = $this->_getAdapterMock('Zend_Db_Adapter_Pdo_Mysql', array('supportStraightJoin', 'quote'), null);
+        $method = $adapter->expects($this->exactly($callCount))->method('quote');
+        if ($callCount > 0) {
+            $method->will($this->returnValue($returnValue));
+        }
+        return $adapter;
+    }
+}
diff --git a/dev/tools/batch_tests/batch.php b/dev/tools/batch_tests/batch.php
index 4d6b51e672898..5118b6a3d6500 100644
--- a/dev/tools/batch_tests/batch.php
+++ b/dev/tools/batch_tests/batch.php
@@ -26,20 +26,22 @@
  */
 
 $tests = array(
-    '../../tests/unit/framework/tests/unit' => '',
-    '../../tests/unit' => '',
-    '../../tests/static/framework/tests/unit' => '',
-    '../../tests/integration/framework/tests/unit' => '',
-    '../../tests/integration' => '',
-    '../../tests/static' => '',
+    0 => array('../../tests/unit/framework/tests/unit', ''),
+    1 => array('../../tests/unit', ''),
+    2 => array('../../tests/static/framework/tests/unit', ''),
+    3 => array('../../tests/integration/framework/tests/unit', ''),
+    4 => array('../../tests/integration', ''),
+    5 => array('../../tests/static', ''),
 );
 $arguments = getopt('', array('all'));
 if (isset($arguments['all'])) {
-    $tests['../../tests/static'] = ' -c phpunit-all.xml.dist';
+    $tests[] = array('../../tests/integration', ' testsuite/integrity');
+    $tests[5][1] = ' -c phpunit-all.xml.dist';
 }
 
 $failures = array();
-foreach ($tests as $dir => $options) {
+foreach ($tests as $row) {
+    list($dir, $options) = $row;
     $dirName = realpath(__DIR__ . '/' . $dir);
     chdir($dirName);
     $command = 'phpunit' . $options;
diff --git a/lib/Magento/Config/XmlAbstract.php b/lib/Magento/Config/XmlAbstract.php
index 1c4c9b554b89d..7c2c577bdd371 100644
--- a/lib/Magento/Config/XmlAbstract.php
+++ b/lib/Magento/Config/XmlAbstract.php
@@ -37,6 +37,12 @@ abstract class Magento_Config_XmlAbstract
      */
     protected $_data;
 
+    /**
+     * Dom configuration model
+     * @var Magento_Config_Dom
+     */
+    protected $_domConfig = null;
+
     /**
      * Instantiate with the list of files to merge
      *
@@ -75,22 +81,56 @@ abstract protected function _extractData(DOMDocument $dom);
      */
     protected function _merge($configFiles)
     {
-        $domConfig = new Magento_Config_Dom($this->_getInitialXml(), $this->_getIdAttributes());
         foreach ($configFiles as $file) {
             if (!file_exists($file)) {
                 throw new Magento_Exception("File does not exist: {$file}");
             }
-            $domConfig->merge(file_get_contents($file));
-            if (!$domConfig->validate($this->getSchemaFile(), $errors)) {
-                $message = "Invalid XML-file: {$file}\n";
-                /** @var libXMLError $error */
-                foreach ($errors as $error) {
-                    $message .= "{$error->message} Line: {$error->line}\n";
-                }
-                throw new Magento_Exception($message);
+            $this->_getDomConfigModel()->merge(file_get_contents($file));
+            if ($this->_isRuntimeValidated()) {
+                $this->_performValidate($file);
             }
         }
-        return $domConfig->getDom();
+        return $this->_getDomConfigModel()->getDom();
+    }
+
+    /**
+     * Perform xml validation
+     * @param string $file
+     * @return Magento_Config_XmlAbstract
+     * @throws Magento_Exception if invalid XML-file passed
+     */
+    protected function _performValidate($file = null)
+    {
+        if (!$this->_getDomConfigModel()->validate($this->getSchemaFile(), $errors)) {
+            $message = is_null($file) ?  "Invalid Document \n" : "Invalid XML-file: {$file}\n";
+            /** @var libXMLError $error */
+            foreach ($errors as $error) {
+                $message .= "{$error->message} Line: {$error->line}\n";
+            }
+            throw new Magento_Exception($message);
+        }
+        return $this;
+    }
+
+    /**
+     * Get if xml files must be runtime validated
+     * @return boolean
+     */
+    protected function _isRuntimeValidated()
+    {
+        return true;
+    }
+
+    /**
+     * Get Dom configuration model
+     * @return Magento_Config_Dom
+     */
+    protected function _getDomConfigModel()
+    {
+        if (is_null($this->_domConfig)) {
+            $this->_domConfig = new Magento_Config_Dom($this->_getInitialXml(), $this->_getIdAttributes());
+        }
+        return $this->_domConfig;
     }
 
     /**
diff --git a/lib/Varien/Data/Collection/Db.php b/lib/Varien/Data/Collection/Db.php
index 0906ba8dd4f3a..2915b9601c9ee 100644
--- a/lib/Varien/Data/Collection/Db.php
+++ b/lib/Varien/Data/Collection/Db.php
@@ -180,6 +180,7 @@ protected function _getItemId(Varien_Object $item)
      *
      * @param Zend_Db_Adapter_Abstract $conn
      * @return Varien_Data_Collection_Db
+     * @throws Zend_Exception
      */
     public function setConnection($conn)
     {
@@ -374,28 +375,24 @@ protected function _renderFiltersBefore()
      *
      * @see self::_getConditionSql for $condition
      *
-     * @param   string|array $field
-     * @param   null|string|array $condition
-     *
-     * @return  Mage_Eav_Model_Entity_Collection_Abstract
+     * @param string|array $field
+     * @param null|string|array $condition
+     * @return Varien_Data_Collection_Db
      */
     public function addFieldToFilter($field, $condition = null)
     {
-        if (!is_array($field)) {
-            $resultCondition = $this->_translateCondition($field, $condition);
-        } else {
+        if (is_array($field)) {
             $conditions = array();
-            foreach ($field as $key => $currField) {
-                $conditions[] = $this->_translateCondition(
-                    $currField,
-                    isset($condition[$key]) ? $condition[$key] : null
-                );
+            foreach ($field as $key => $value) {
+                $conditions[] = $this->_translateCondition($value, isset($condition[$key]) ? $condition[$key] : null);
             }
 
-            $resultCondition = '(' . join(') ' . Zend_Db_Select::SQL_OR . ' (', $conditions) . ')';
+            $resultCondition = '(' . implode(') ' . Zend_Db_Select::SQL_OR . ' (', $conditions) . ')';
+        } else {
+            $resultCondition = $this->_translateCondition($field, $condition);
         }
 
-        $this->_select->where($resultCondition);
+        $this->_select->where($resultCondition, null, Varien_Db_Select::TYPE_CONDITION);
 
         return $this;
     }
diff --git a/lib/Varien/Db/Select.php b/lib/Varien/Db/Select.php
index 3ee9b4d8bf771..5a508540c1214 100644
--- a/lib/Varien/Db/Select.php
+++ b/lib/Varien/Db/Select.php
@@ -102,18 +102,14 @@ public function __construct(Zend_Db_Adapter_Abstract $adapter)
      *
      * @param string   $cond  The WHERE condition.
      * @param string   $value OPTIONAL A single value to quote into the condition.
-     * @param constant $type  OPTIONAL The type of the given value
-     * @return Varien_Db_Select This Zend_Db_Select object.
+     * @param string|int|null $type  OPTIONAL The type of the given value
+     * @return Varien_Db_Select
      */
     public function where($cond, $value = null, $type = null)
     {
-        if (is_null($value) && is_null($type)) {
+        if ($value === null && $type === null) {
             $value = '';
-        }
-        /**
-         * Additional internal type used for really null value
-         */
-        if ($type == self::TYPE_CONDITION) {
+        } elseif ($type == self::TYPE_CONDITION) {
             $type = null;
         }
         if (is_array($value)) {
diff --git a/pub/js/mage/adminhtml/grid.js b/pub/js/mage/adminhtml/grid.js
index 29a141a978659..3f7ed6f6a198a 100644
--- a/pub/js/mage/adminhtml/grid.js
+++ b/pub/js/mage/adminhtml/grid.js
@@ -160,16 +160,13 @@ varienGrid.prototype = {
         }
     },
     reload:function (url, onSuccessCallback) {
-        if (!this.reloadParams) {
-            this.reloadParams = {form_key:FORM_KEY};
-        } else {
-            this.reloadParams.form_key = FORM_KEY;
-        }
+        this.reloadParams = this.reloadParams || {};
+        this.reloadParams.form_key = FORM_KEY;
         url = url || this.url;
         if(this.useAjax){
             new Ajax.Request(url + (url.match(new RegExp('\\?')) ? '&ajax=true' : '?ajax=true' ), {
                 loaderArea: this.containerId,
-                parameters: this.reloadParams || {},
+                parameters: this.reloadParams,
                 evalScripts: true,
                 onFailure: this._processFailure.bind(this),
                 onComplete: this.initGridAjax.bind(this),
@@ -458,7 +455,6 @@ varienGridMassaction.prototype = {
         this.getOldCallback('init_row')(grid, row);
     },
     onGridRowClick: function(grid, evt) {
-
         var tdElement = Event.findElement(evt, 'td');
         var trElement = Event.findElement(evt, 'tr');
 
@@ -577,8 +573,7 @@ varienGridMassaction.prototype = {
         }.bind(this));
         return result;
     },
-    getCheckboxesValuesAsString: function()
-    {
+    getCheckboxesValuesAsString: function() {
         return this.getCheckboxesValues().join(',');
     },
     setCheckbox: function(checkbox) {
diff --git a/pub/js/mage/adminhtml/tools.js b/pub/js/mage/adminhtml/tools.js
index cc37ac6b04c5c..d16a0b82b9392 100644
--- a/pub/js/mage/adminhtml/tools.js
+++ b/pub/js/mage/adminhtml/tools.js
@@ -151,6 +151,11 @@ function toggleValueElements(checkbox, container, excludedElements, checked){
             }
         });
         if (navigator && navigator.userAgent.indexOf('Chrome') != -1) {
+            if (!checkbox.checked) {
+                $(checkbox).writeAttribute('checked', false);
+            } else {
+                $(checkbox).writeAttribute('checked', 'checked');
+            }
             // fix chrome bug: rerender page updating parent content
             var p = elems[0].nodeName.toLowerCase() == 'img'
                 ? elems[1].parentNode
diff --git a/pub/js/mage/captcha.js b/pub/js/mage/captcha.js
index 7e7ca1eac0019..6a47307ef821f 100644
--- a/pub/js/mage/captcha.js
+++ b/pub/js/mage/captcha.js
@@ -50,38 +50,3 @@ Captcha.prototype = {
         });
     }
 };
-
-document.observe('billing-request:completed', function(event) {
-    if (typeof window.checkout != 'undefined') {
-        if (window.checkout.method == 'guest' && $('guest_checkout')){
-            $('guest_checkout').captcha.refresh()
-        }
-        if (window.checkout.method == 'register' && $('register_during_checkout')){
-            $('register_during_checkout').captcha.refresh()
-        }
-    }
-});
-
-
-document.observe('login:setMethod', function(event) {
-    var switchCaptchaElement = function(shown, hidden) {
-        var inputPrefix = 'captcha-input-box-', imagePrefix = 'captcha-image-box-';
-        if ($(inputPrefix + hidden)) {
-            $(inputPrefix + hidden).hide();
-            $(imagePrefix + hidden).hide();
-        }
-        if ($(inputPrefix + shown)) {
-            $(inputPrefix + shown).show();
-            $(imagePrefix + shown).show();
-        }
-    };
-
-    switch (event.memo.method) {
-        case 'guest':
-            switchCaptchaElement('guest_checkout', 'register_during_checkout');
-            break;
-        case 'register':
-            switchCaptchaElement('register_during_checkout', 'guest_checkout');
-            break;
-    }
-});