From 873d38c884fb56411c4ac3bb46a9d4343e4545fe Mon Sep 17 00:00:00 2001
From: mage2-team <mage2-team@magento.com>
Date: Fri, 26 Sep 2014 10:30:20 -0700
Subject: [PATCH] 0.1.0-alpha97 * Various improvements:    * Implemented a
 general way of using RSS module    * Created a cron job in the Customer
 module for cleaning the customer_visitor table    * Added a warning message
 to the Use HTTP Only option in the Admin panel    * Implemented the Grid
 component in the Magento UI Library    * Reimplemented the URL Rewrites
 functionality in the new UrlRedirect module  * Framework improvements:    *
 Added the ability to install Magento 2 using CLI    * Aggregated Magento
 installation and upgrade into one tool    * Refactored CustomerService REST
 WebApi to be more RESTful    * Increased unit and integration test coverage  
  * Moved page asset management to page configuration API, and eliminated the
 \Magento\Theme\Block\Html\Head block    * Eliminated the Root, Html and Title
 blocks  * Themes update:    * Removed widgets from the default Magento
 installation  * Fixed bugs:    * Fixed an issue with wishlist creation for
 non-registered customer    * Fixed an issue with Google Mapping where
 Condition did not show correct value    * Fixed an issue  where there were
 too many notifications for admin user by default    * Fixed a Daylight
 Savings Time calculation error    * Fixed an issue where default cookie path
 and lifetime were not validated prior to saving    * Fixed an issue where
 current admin password was not required for resetting admin password    *
 Fixed an issue where custom customer attribute or customer address attribute
 was not accessible when custom_attribute is used as the attribute code    *
 Fixed an issue where integration entity could not be deleted after being
 searched in grid    * Fixed an issue where invalid parameter value was shown
 in SOAP    * Fixed an issue where exception was thrown for Array to String
 conversion in SOAP    * Fixed an issue where exception was thrown due to
 invalid argument supplied for foreach() statement in REST    * Fixed an issue
 where admin tax notifications did not appear correctly in the System Messages
 dialog box    * Fixed an issue where tax details were missing when viewing
 order in the Admin panel    * Fixed an issue where styles for the storefront
 store selector were absent    * Fixed an issue where customer got 404 page
 when switching store views on the product page of a product with different
 URL keys in different store views    * Fixed an issue where the Add To Cart
 button in the MAP pop-up did not work for configurable and bundle products   
 * Fixed an issue where for specifying options for configurable product was
 absent after adding a product from the MAP pop-up    * Fixed an issue where a
 fatal error was thrown after selecting shipping method on PayPal Express
 Checkout    * Fixed an issue with sending invoice email    * Fixed an issue
 where integration tests failed with a fatal error    * Fixed an issue where
 credit memo entry was not created after performing a refund for an order    *
 Fixed an issue where categories layout for widgets did not work    * Fixed an
 issue where opening a page restricted by ACL lead to blank page instead of
 the Access Denied page    * Fixed an issue where a blank page was displayed
 instead of the using the Advanced Search result    * Fixed an issue where the
 "Please wait" spinner was absent on Ajax requests for order creation in the
 Admin panel    * Fixed an issue with the main navigation menu location on the
 page  * Modularity:    * Implemented the automatic applying of the MAP policy
  * Indexers:    * Eliminated the old Magento_Index module  * Search library  
  * Added wildcards filter    * Eliminated unused queries and filters    *
 Added IN to Term filter    * Moved the "value" attribute from <match> to
 <query> for the Match query    * Refactored the usage of negation    *
 Implemented Request Builder  * CatalogSearch adapter    * Pluginized adding
 attribute to search index    * Merged base declaration with searchable
 attributes  * Added the following Setup CLI tools in the setup folder    *
 Deployment Configuration Tool    * Schema Setup and Update Tool    * DB Data
 Update Tool    * Admin User Setup Tool    * User Configuration Tool    *
 Installation Tool    * Update Tool  * GitHub requests:    * [#615]
 (https://github.com/magento/magento2/issues/615) -- Use info as object in
 checkout_cart_update_items_before    * [#659]
 (https://github.com/magento/magento2/issues/659) -- Recently viewed products
 sidebar issue    * [#660] (https://github.com/magento/magento2/issues/660) --
 RSS global setting    * [#663]
 (https://github.com/magento/magento2/issues/663) -- session.save_path not
 valid    * [#445] (https://github.com/magento/magento2/issues/445) -- use of
 registry in Magento\Tax\Helper\Data    * [#646]
 (https://github.com/magento/magento2/issues/646) -- Fixed flat category
 indexer bug    * [#643] (https://github.com/magento/magento2/issues/643) --
 Configurable Products Performance    * [#640]
 (https://github.com/magento/magento2/issues/640) -- [Insight] Files should
 not be executable    * [#667] (https://github.com/magento/magento2/pull/667)
 -- Tiny improvement on render() method in Column/Renderer/Concat    * [#288]
 (https://github.com/magento/magento2/issues/288) -- Add Cell Phone to
 Customer Address Form    * [#607]
 (https://github.com/magento/magento2/issues/607) -- sitemap.xml filename is
 not variable    * [#633] (https://github.com/magento/magento2/pull/633) --
 Fixed Typo ($_attribite -> $_attribute)    * [#634]
 (https://github.com/magento/magento2/issues/634) -- README.md contains broken
 link to X.commerce Agreement    * [#569]
 (https://github.com/magento/magento2/issues/569) -- ObjectManager's Factory
 should be replaceable depending on service    * [#654]
 (https://github.com/magento/magento2/issues/654) -- Demo notice overlapping 
 * Functional tests:    * Abandoned carts report    * Adding products from
 wishlist to cart    * Create invoice for offline payment methods    * Delete
 products from shopping cart    * Delete widget    * Global search    * Order
 count report    * Order total report

---
 CHANGELOG.md                                  |   94 +-
 CONTRIBUTOR_LICENSE_AGREEMENT.html            |  131 +
 README.md                                     |    2 +-
 .../Magento/AdminNotification/Helper/Data.php |  114 -
 .../Model/Config/Source/Frequency.php         |    2 +-
 .../Magento/AdminNotification/Model/Feed.php  |   28 +-
 .../Model/System/Message.php                  |    3 +
 .../Magento/AdminNotification/composer.json   |   11 +-
 .../Magento/AdminNotification/etc/module.xml  |    1 -
 .../view/adminhtml/layout/default.xml         |   10 +-
 app/code/Magento/Authorization/composer.json  |    6 +-
 app/code/Magento/Authorizenet/composer.json   |   18 +-
 .../Magento/Backend/Block/Media/Uploader.php  |    9 +-
 app/code/Magento/Backend/Block/Page.php       |   15 +-
 app/code/Magento/Backend/Block/Page/Head.php  |  113 -
 .../Block/Page/RequireJs.php}                 |   39 +-
 .../Block/System/Account/Edit/Form.php        |   23 +-
 .../Backend/Block/Template/Context.php        |   10 +-
 app/code/Magento/Backend/Block/Urlrewrite.php |   96 -
 .../Urlrewrite/Catalog/Category/Edit.php      |  137 -
 .../Urlrewrite/Catalog/Category/Tree.php      |  196 -
 .../Block/Urlrewrite/Catalog/Edit/Form.php    |  239 -
 .../Block/Urlrewrite/Catalog/Product/Edit.php |  239 -
 .../Block/Urlrewrite/Catalog/Product/Grid.php |   88 -
 .../Block/Urlrewrite/Cms/Page/Edit.php        |  136 -
 .../Block/Urlrewrite/Cms/Page/Edit/Form.php   |  175 -
 .../Block/Urlrewrite/Cms/Page/Grid.php        |  113 -
 .../Magento/Backend/Block/Urlrewrite/Edit.php |  300 -
 .../Backend/Block/Urlrewrite/Edit/Form.php    |  417 --
 .../Backend/Block/Urlrewrite/Selector.php     |  100 -
 .../Magento/Backend/Block/Widget/Context.php  |    8 +
 .../Magento/Backend/Block/Widget/Grid.php     |   49 -
 .../Block/Widget/Grid/Column/Filter/Date.php  |   11 -
 .../Grid/Column/Renderer/AbstractRenderer.php |   26 +-
 .../Widget/Grid/Column/Renderer/Concat.php    |   20 +-
 .../Adminhtml/System/Account/Save.php         |   21 +-
 .../Adminhtml/System/Design/Edit.php          |    1 -
 .../Controller/Adminhtml/Urlrewrite/Save.php  |  262 -
 .../Model/Config/Backend/Cookie/Domain.php    |   74 +
 .../Model/Config/Backend/Cookie/Lifetime.php  |   73 +
 .../Model/Config/Backend/Cookie/Path.php      |   72 +
 .../Backend/Currency/AbstractCurrency.php     |    6 +-
 .../{ => Model/Session}/AdminConfig.php       |   18 +-
 app/code/Magento/Backend/composer.json        |   37 +-
 app/code/Magento/Backend/etc/adminhtml/di.xml |    6 +-
 .../Magento/Backend/etc/adminhtml/system.xml  |    7 +-
 app/code/Magento/Backend/etc/config.xml       |    7 -
 app/code/Magento/Backend/etc/module.xml       |    3 +-
 app/code/Magento/Backend/i18n/de_DE.csv       |    4 +-
 app/code/Magento/Backend/i18n/en_US.csv       |    4 +-
 app/code/Magento/Backend/i18n/es_ES.csv       |    4 +-
 app/code/Magento/Backend/i18n/fr_FR.csv       |    4 +-
 app/code/Magento/Backend/i18n/nl_NL.csv       |    4 +-
 app/code/Magento/Backend/i18n/pt_BR.csv       |    4 +-
 app/code/Magento/Backend/i18n/zh_CN.csv       |    4 +-
 .../adminhtml/layout/adminhtml_denied.xml     |    2 +-
 .../layout/adminhtml_system_config_edit.xml   |    1 -
 .../layout/adminhtml_urlrewrite_index.xml     |  136 -
 .../Backend/view/adminhtml/layout/default.xml |  181 +-
 .../Backend/view/adminhtml/layout/editor.xml  |   25 +-
 .../view/adminhtml/templates/admin/page.phtml |   77 +
 .../adminhtml/templates/admin/popup.phtml     |   79 -
 .../view/adminhtml/templates/page/head.phtml  |   68 -
 .../templates/page/js/head_scripts.phtml      |   35 +
 .../templates/page/js/require_js.phtml        |   37 +
 .../templates/urlrewrite/selector.phtml       |   45 -
 .../adminhtml/templates/widget/grid.phtml     |    8 +-
 .../templates/widget/grid/extended.phtml      |    7 +-
 .../Controller/Adminhtml/Index/Rollback.php   |    2 +-
 app/code/Magento/Backup/Helper/Data.php       |   25 +-
 app/code/Magento/Backup/composer.json         |   13 +-
 app/code/Magento/Backup/etc/module.xml        |    1 -
 .../Catalog/Product/Edit/Tab/Attributes.php   |   35 -
 .../Catalog/Product/View/Type/Bundle.php      |   11 +-
 .../Magento/Bundle/Model/Product/Type.php     |   56 -
 app/code/Magento/Bundle/composer.json         |   31 +-
 app/code/Magento/Bundle/etc/di.xml            |    1 -
 app/code/Magento/Bundle/etc/module.xml        |    1 -
 .../layout/catalog_product_bundle.xml         |   10 +-
 .../templates/product/price/final_price.phtml |    4 +-
 .../catalog_product_view_type_bundle.xml      |    8 +-
 app/code/Magento/Captcha/composer.json        |   14 +-
 .../layout/checkout_onepage_index.xml         |    1 -
 .../Block/Adminhtml/Category/Edit/Form.php    |    8 -
 .../Adminhtml/Category/Tab/Attributes.php     |   59 -
 .../Block/Adminhtml/Category/Tab/General.php  |  143 -
 .../Adminhtml/Product/Edit/Tab/Attributes.php |   53 -
 .../Block/Adminhtml/Product/Edit/Tabs.php     |    1 -
 .../Catalog/Block/Adminhtml/Product/Grid.php  |    7 +-
 .../Adminhtml/Product/Helper/Form/Price.php   |    2 +-
 .../Catalog/Block/Adminhtml/Rss/Grid/Link.php |   97 +
 .../Block/Adminhtml/Rss/NotifyStock.php       |  116 +
 .../Magento/Catalog/Block/Breadcrumbs.php     |    4 +-
 .../Catalog/Block/Category/Rss/Link.php       |  104 +
 .../Magento/Catalog/Block/Category/View.php   |   71 +-
 .../Catalog/Block/Product/AbstractProduct.php |   12 +-
 .../Block/Product/Compare/ListCompare.php     |   12 +-
 .../Magento/Catalog/Block/Product/Context.php |   10 +-
 .../Magento/Catalog/Block/Product/Gallery.php |    5 +-
 .../Block/Product/ProductList/Crosssell.php   |    7 -
 .../Block/Product/ProductList/Related.php     |    7 -
 .../Block/Product/ProductList/Upsell.php      |    7 -
 .../Magento/Catalog/Block/Product/View.php    |   64 +-
 .../Block/Product/View/Options/Type/Date.php  |   11 -
 .../Magento/Catalog/Block/Rss/Category.php    |  266 +
 .../Catalog/Block/Rss/Product/NewProducts.php |  218 +
 .../Catalog/Block/Rss/Product/Special.php     |  267 +
 .../Magento/Catalog/Block/Widget/Link.php     |   75 +-
 .../Controller/Adminhtml/Category/Edit.php    |    1 -
 .../Controller/Adminhtml/Category/Save.php    |    9 +-
 .../Product/Action/Attribute/Save.php         |    3 +-
 .../Controller/Adminhtml/Product/Edit.php     |    2 -
 .../Product/Initialization/Helper.php         |    7 -
 .../Adminhtml/Product/NewAction.php           |    2 -
 .../Controller/Adminhtml/Product/Set/Edit.php |    2 -
 .../Controller/Adminhtml/Search/Edit.php      |    2 -
 .../Catalog/Controller/Category/View.php      |   10 +-
 app/code/Magento/Catalog/Helper/Catalog.php   |   23 -
 app/code/Magento/Catalog/Helper/Category.php  |   56 -
 app/code/Magento/Catalog/Helper/Data.php      |  245 +-
 app/code/Magento/Catalog/Helper/Product.php   |   31 -
 .../Magento/Catalog/Helper/Product/View.php   |    8 +-
 app/code/Magento/Catalog/Model/Category.php   |  133 +-
 .../Product/Price/Plugin/CustomerGroup.php    |   20 +-
 .../Magento/Catalog/Model/Indexer/Url.php     |  302 -
 app/code/Magento/Catalog/Model/Observer.php   |   22 +-
 app/code/Magento/Catalog/Model/Product.php    |   42 +-
 .../Magento/Catalog/Model/Product/Action.php  |   22 -
 .../Model/Product/Attribute/Backend/Msrp.php  |   78 -
 .../Product/Attribute/Backend/Urlkey.php      |   53 -
 .../Attribute/Source/Msrp/Type/Enabled.php    |  128 -
 .../Magento/Catalog/Model/Product/Copier.php  |   16 +-
 .../Model/Product/Type/AbstractType.php       |   21 +-
 .../Catalog/Model/Product/Type/Price.php      |    0
 .../Magento/Catalog/Model/Product/Url.php     |   77 +-
 .../Model/Resource/Category/Collection.php    |   18 +-
 .../Catalog/Model/Resource/Category/Flat.php  |   37 +-
 .../Resource/Category/Flat/Collection.php     |   21 +-
 .../Product/Attribute/Backend/Urlkey.php      |   83 -
 .../Resource/Product/Attribute/Collection.php |    2 -
 .../Model/Resource/Product/Collection.php     |   51 +-
 .../Product/Indexer/AbstractIndexer.php       |    2 +-
 .../Model/Resource/Product/Indexer/Eav.php    |  233 -
 .../Product/Indexer/Price/DefaultPrice.php    |   10 -
 .../Product/Indexer/Price/PriceInterface.php  |    8 -
 .../Magento/Catalog/Model/Resource/Setup.php  |   51 +-
 .../Magento/Catalog/Model/Resource/Url.php    |  833 +--
 .../Magento/Catalog/Model/Rss/Category.php    |   96 +
 .../Catalog/Model/Rss/Product/NewProducts.php |  119 +
 .../Catalog/Model/Rss/Product/NotifyStock.php |   98 +
 .../Catalog/Model/Rss/Product/Special.php     |   89 +
 .../Backend/Catalog/Url/Rewrite/Suffix.php    |  123 +-
 app/code/Magento/Catalog/Model/Url.php        | 1045 ----
 app/code/Magento/Catalog/Pricing/Render.php   |    1 -
 .../Pricing/Render/ConfiguredPriceBox.php     |    2 +-
 .../Catalog/Pricing/Render/FinalPriceBox.php  |    9 +-
 .../Catalog/Pricing/Render/PriceBox.php       |    1 -
 .../Service/V1/Product/TierPriceService.php   |    3 +-
 app/code/Magento/Catalog/composer.json        |   48 +-
 .../data-upgrade-1.6.0.0.20-1.6.0.0.21.php    |    1 -
 .../data-upgrade-1.6.0.0.23-1.6.0.0.24.php    |   14 -
 .../data-upgrade-1.6.0.0.28-1.6.0.0.29.php}   |   28 +-
 .../data-upgrade-1.6.0.0.3-1.6.0.0.4.php      |   54 -
 .../data-upgrade-1.6.0.0.5-1.6.0.0.6.php      |    4 -
 app/code/Magento/Catalog/etc/acl.xml          |    5 -
 app/code/Magento/Catalog/etc/adminhtml/di.xml |    7 +
 .../Magento/Catalog/etc/adminhtml/menu.xml    |    1 -
 .../Magento/Catalog/etc/adminhtml/system.xml  |   58 +-
 .../Catalog/etc/catalog_attributes.xml        |    2 -
 app/code/Magento/Catalog/etc/config.xml       |    9 -
 app/code/Magento/Catalog/etc/di.xml           |   15 +-
 .../Magento/Catalog/etc/eav_attributes.xml    |    3 -
 app/code/Magento/Catalog/etc/module.xml       |    7 +-
 app/code/Magento/Catalog/i18n/de_DE.csv       |   14 +-
 app/code/Magento/Catalog/i18n/en_US.csv       |   14 +-
 app/code/Magento/Catalog/i18n/es_ES.csv       |   14 +-
 app/code/Magento/Catalog/i18n/fr_FR.csv       |   14 +-
 app/code/Magento/Catalog/i18n/nl_NL.csv       |   14 +-
 app/code/Magento/Catalog/i18n/pt_BR.csv       |   14 +-
 app/code/Magento/Catalog/i18n/zh_CN.csv       |   14 +-
 .../sql/catalog_setup/install-1.6.0.0.0.php   |   38 -
 .../layout/catalog_category_edit.xml          |   17 +-
 .../layout/catalog_product_index.xml          |    5 +
 .../adminhtml/layout/catalog_product_new.xml  |   28 +-
 .../catalog/category/edit/form.phtml          |   84 +-
 .../templates/catalog/category/tree.phtml     |   75 +-
 .../templates/catalog/product/edit.phtml      |    2 +-
 .../adminhtml/templates/rss/grid/link.phtml   |   29 +
 .../base/layout/catalog_product_prices.xml    |    4 -
 .../product/price/amount/default.phtml        |   14 +-
 .../product/price/configured_price.phtml      |    2 +-
 .../templates/product/price/final_price.phtml |   21 +-
 .../templates/product/price/tier_prices.phtml |    9 +-
 .../frontend/layout/catalog_category_view.xml |    4 +-
 .../layout/catalog_product_compare_index.xml  |    1 -
 .../frontend/layout/catalog_product_view.xml  |   14 +-
 .../Catalog/view/frontend/layout/default.xml  |    4 +-
 .../frontend/templates/category/rss.phtml}    |    4 +-
 .../view/frontend/web/js/price-option.js      |    3 +
 .../Magento/CatalogImportExport/composer.json |   20 +-
 .../Magento/CatalogInventory/composer.json    |   20 +-
 app/code/Magento/CatalogInventory/etc/di.xml  |    1 -
 app/code/Magento/CatalogRule/Model/Rule.php   |    8 -
 app/code/Magento/CatalogRule/composer.json    |   17 +-
 app/code/Magento/CatalogRule/etc/module.xml   |    1 -
 .../catalog_rule_promo_catalog_edit.xml       |    8 -
 .../Magento/CatalogSearch/Block/Result.php    |    3 +-
 .../Model/Indexer/Fulltext/Action/Full.php    |    9 +
 .../Model/Search/ReaderPlugin.php             |   60 +
 .../Model/Search/RequestGenerator.php         |  163 +
 app/code/Magento/CatalogSearch/composer.json  |   22 +-
 app/code/Magento/CatalogSearch/etc/di.xml     |    3 +
 .../CatalogSearch/etc/search_request.xml      |   44 +-
 .../layout/catalogsearch_advanced_index.xml   |    8 +-
 .../layout/catalogsearch_advanced_result.xml  |    8 +-
 .../layout/catalogsearch_result_index.xml     |    8 +-
 .../layout/catalogsearch_term_popular.xml     |    8 +-
 .../Block/UrlKeyRenderer.php}                 |   32 +-
 .../Magento/CatalogUrlRewrite/Helper/Data.php |  277 -
 .../Category/CanonicalUrlRewriteGenerator.php |   69 +
 .../Category/ChildrenCategoriesProvider.php   |   63 +
 .../Category/ChildrenUrlRewriteGenerator.php  |   69 +
 .../CurrentUrlRewritesRegenerator.php         |  144 +
 .../Model/Category/Observer.php               |  206 +-
 .../Model/Category/Plugin/Category/Move.php   |   64 +
 .../Model/Category/Plugin/Category/Remove.php |  107 +
 .../Model/Category/Plugin/Storage.php         |  130 +
 .../Model/Category/Plugin/Store/Group.php     |  165 +
 .../Model/Category/Plugin/Store/View.php      |  171 +
 .../Model/Category/Product.php}               |   15 +-
 .../Model/CategoryUrlPathGenerator.php        |  156 +
 .../Model/CategoryUrlRewriteGenerator.php     |  132 +
 .../Model/ObjectRegistry.php}                 |   50 +-
 .../Product/CanonicalUrlRewriteGenerator.php  |   69 +
 .../Product/CategoriesUrlRewriteGenerator.php |   74 +
 .../Product/CurrentUrlRewritesRegenerator.php |  179 +
 .../Model/Product/Observer.php                |   66 +-
 .../Model/Product/Plugin/Import.php           |  105 +
 .../Model/ProductUrlPathGenerator.php         |  138 +
 .../Model/ProductUrlRewriteGenerator.php      |  180 +
 .../Model/Resource/Category/Product.php       |   84 +
 .../Resource/Category/ProductCollection.php   |   31 +
 .../Model/Storage/DbStorage.php               |   54 +
 .../CategorySaveRewritesHistorySetter.php}    |   27 +-
 .../Observer/CategoryUrlPathAutogenerator.php |   54 +
 .../Observer/ProductUrlKeyAutogenerator.php   |   53 +
 .../Adminhtml/Category/Tab/Attributes.php     |   57 +
 .../Product/Edit/Tab/Attributes.php}          |   32 +-
 .../Product/Initialization/Helper.php}        |   45 +-
 .../Service/V1/AbstractUrlGenerator.php       |   40 -
 .../Service/V1/CategoryUrlGenerator.php       |  213 -
 .../Service/V1/ProductUrlGenerator.php        |  254 -
 .../V1/ProductUrlGeneratorInterface.php       |   45 -
 .../Service/V1/StoreViewService.php           |   78 +
 .../Magento/CatalogUrlRewrite/composer.json   |   15 +-
 .../data-install-1.0.0.0.php                  |   76 +
 .../CatalogUrlRewrite/etc/adminhtml/di.xml    |   29 +-
 .../etc/adminhtml/events.xml                  |   19 +-
 .../etc/adminhtml/system.xml                  |   52 +
 .../etc/catalog_attributes.xml                |   33 +
 .../{Index => CatalogUrlRewrite}/etc/di.xml   |   13 +-
 .../etc/eav_attributes.xml}                   |    8 +-
 .../etc/install}/di.xml                       |   18 +-
 .../CatalogUrlRewrite/etc/install/events.xml  |   42 +
 .../Magento/CatalogUrlRewrite/etc/module.xml  |   10 +-
 .../install-1.0.0.0.php}                      |   66 +-
 app/code/Magento/Centinel/composer.json       |   14 +-
 app/code/Magento/Checkout/Block/Cart.php      |    4 +-
 .../Checkout/Block/Cart/AbstractCart.php      |   23 -
 .../Magento/Checkout/Block/Cart/Coupon.php    |    4 +-
 .../Magento/Checkout/Block/Cart/Shipping.php  |    4 +-
 .../Magento/Checkout/Block/Cart/Sidebar.php   |    4 +-
 .../Magento/Checkout/Block/Cart/Totals.php    |    4 +-
 .../Magento/Checkout/Block/Shipping/Price.php |    4 +-
 .../Magento/Checkout/Block/Total/Nominal.php  |    4 +-
 .../Checkout/Controller/Cart/Index.php        |    2 +-
 .../Magento/Checkout/Controller/Onepage.php   |    0
 .../Checkout/Controller/Onepage/Index.php     |    2 +-
 app/code/Magento/Checkout/Model/Cart.php      |   11 +-
 app/code/Magento/Checkout/composer.json       |   35 +-
 app/code/Magento/Checkout/etc/module.xml      |    1 +
 .../frontend/layout/checkout_cart_index.xml   |    4 +-
 .../Checkout/view/frontend/layout/default.xml |    3 +
 .../templates/cart/item/default.phtml         |   27 +-
 .../templates/cart/item/price/sidebar.phtml   |    8 +-
 .../frontend/templates/cart/minicart.phtml    |   14 +-
 .../frontend/templates/cart/shipping.phtml    |    2 +-
 .../templates/cart/sidebar/default.phtml      |   89 +-
 .../frontend/templates/cart/subtotal.phtml    |   31 +
 .../view/frontend/templates/cart/totals.phtml |    4 -
 .../frontend/templates/item/price/row.phtml   |    4 +-
 .../frontend/templates/item/price/unit.phtml  |    4 +-
 .../frontend/templates/onepage/billing.phtml  |    2 +-
 .../templates/onepage/review/info.phtml       |   16 +-
 .../templates/onepage/review/item.phtml       |   42 +-
 .../review/item/price/row_excl_tax.phtml      |    2 +-
 .../review/item/price/row_incl_tax.phtml      |    2 +-
 .../review/item/price/unit_excl_tax.phtml     |    2 +-
 .../review/item/price/unit_incl_tax.phtml     |    2 +-
 .../templates/onepage/review/totals.phtml     |    2 +-
 .../frontend/templates/onepage/shipping.phtml |    2 +-
 .../Magento/CheckoutAgreements/composer.json  |   10 +-
 .../Cms/Block/Adminhtml/Block/Edit/Form.php   |   13 -
 .../Block/Adminhtml/Page/Edit/Tab/Content.php |   13 -
 app/code/Magento/Cms/Block/Page.php           |   10 +-
 .../Adminhtml/AbstractMassDelete.php          |  161 +
 .../Controller/Adminhtml/Block/MassDelete.php |   52 +
 .../Controller/Adminhtml/Page/MassDelete.php  |   52 +
 .../Cms/Controller/Adminhtml/Page/Save.php    |   12 +-
 app/code/Magento/Cms/Model/Page.php           |    1 +
 app/code/Magento/Cms/Model/Resource/Page.php  |   46 +-
 .../Model/Resource/Page/Grid/Collection.php   |   88 +
 .../Cms/Ui/DataProvider/Block/Row/Actions.php |   68 +
 .../Ui/DataProvider/Page/Options/IsActive.php |   66 +
 .../DataProvider/Page/Options/PageLayout.php} |   47 +-
 .../Cms/Ui/DataProvider/Page/Row/Actions.php  |   87 +
 app/code/Magento/Cms/composer.json            |   19 +-
 app/code/Magento/Cms/etc/module.xml           |    2 +-
 .../view/adminhtml/layout/cms_block_edit.xml  |   18 +-
 .../view/adminhtml/layout/cms_block_index.xml |   81 +-
 .../adminhtml/layout/cms_block_listing.xml    |  148 +
 .../view/adminhtml/layout/cms_page_edit.xml   |   16 +-
 .../view/adminhtml/layout/cms_page_index.xml  |    2 +-
 .../adminhtml/layout/cms_page_listing.xml     |  150 +
 .../layout/cms_wysiwyg_images_index.xml       |    1 -
 .../Model/CmsPageUrlPathGenerator.php}        |   46 +-
 .../CmsPageUrlRewriteGenerator.php}           |   54 +-
 .../Magento/CmsUrlRewrite/Model/Observer.php  |   36 +-
 .../Plugin/Cms/Model/Resource/Page.php        |   59 +
 app/code/Magento/CmsUrlRewrite/composer.json  |    7 +-
 .../CmsUrlRewrite/etc/adminhtml/di.xml        |    4 +-
 app/code/Magento/CmsUrlRewrite/etc/module.xml |    5 +-
 .../ConfigurableImportExport/composer.json    |   14 +-
 .../Model/Product/Type/Configurable.php       |   14 +-
 .../Configurable/Attribute/Collection.php     |  189 +-
 .../Configurable/Attribute/Price/Data.php}    |   49 +-
 .../Magento/ConfigurableProduct/composer.json |   29 +-
 .../data-install-1.0.0.0.php                  |    3 -
 .../ConfigurableProduct/etc/module.xml        |    1 -
 .../install-1.0.0.0.php                       |    0
 .../layout/catalog_product_configurable.xml   |   10 +-
 .../adminhtml/layout/catalog_product_new.xml  |   10 +-
 ...catalog_product_view_type_configurable.xml |    8 +-
 app/code/Magento/Contact/composer.json        |   12 +-
 .../Contact/view/email/submitted_form.html    |    2 +-
 .../frontend/layout/contact_index_index.xml   |    8 +-
 .../view/frontend/templates/form.phtml        |   15 +-
 app/code/Magento/Core/Helper/Data.php         |   12 +-
 .../Core/Helper/File/Storage/Database.php     |    3 +-
 app/code/Magento/Core/Helper/Url.php          |   17 +-
 .../Core/Model/PageLayout/Config/Builder.php  |    2 +-
 app/code/Magento/Core/composer.json           |   16 +-
 app/code/Magento/Core/etc/body.xsd            |   40 +
 app/code/Magento/Core/etc/di.xml              |    5 +-
 app/code/Magento/Core/etc/head.xsd            |   67 +
 .../indexers_merged.xsd => Core/etc/html.xsd} |   27 +-
 app/code/Magento/Core/etc/layouts.xsd         |   44 +
 app/code/Magento/Core/etc/page.xsd            |   29 +-
 app/code/Magento/Cron/composer.json           |    8 +-
 .../Model/System/Currencysymbol.php           |   40 +-
 app/code/Magento/CurrencySymbol/composer.json |   14 +-
 .../Magento/Customer/Block/Address/Book.php   |    3 +-
 .../Magento/Customer/Block/Address/Edit.php   |    4 +-
 app/code/Magento/Customer/Block/Form/Edit.php |    0
 .../Magento/Customer/Block/Form/Login.php     |    2 +-
 .../Magento/Customer/Block/Form/Register.php  |    5 +-
 .../Customer/Controller/Account/Edit.php      |    2 +-
 .../Customer/Controller/Account/EditPost.php  |    2 +-
 .../Customer/Controller/Account/Index.php     |    2 +-
 .../Controller/Adminhtml/Group/Save.php       |    6 +-
 .../Adminhtml/Index/MassAssignGroup.php       |    2 +-
 .../Controller/Adminhtml/Index/Save.php       |    2 +-
 app/code/Magento/Customer/Helper/Address.php  |   37 +-
 .../Model/Address/AbstractAddress.php         |    2 +-
 app/code/Magento/Customer/Model/Group.php     |   20 -
 .../Magento/Customer/Model/GroupRegistry.php  |    2 +-
 .../Magento/Customer/Model/Resource/Setup.php |    2 +-
 app/code/Magento/Customer/Model/Session.php   |    0
 .../Service/V1/AddressMetadataService.php     |   11 +-
 .../Service/V1/CustomerAccountService.php     |   65 +-
 .../V1/CustomerAccountServiceInterface.php    |   45 +-
 .../V1/CustomerAddressServiceInterface.php    |   12 +-
 .../Service/V1/CustomerGroupService.php       |   59 +-
 .../V1/CustomerGroupServiceInterface.php      |   27 +-
 .../Service/V1/CustomerMetadataService.php    |   11 +-
 .../Data/Eav/AttributeMetadataConverter.php   |   14 +-
 .../Customer/Service/V1/Data/Eav/Option.php   |   14 +-
 .../Service/V1/Data/Eav/OptionBuilder.php     |   12 +
 app/code/Magento/Customer/composer.json       |   37 +-
 app/code/Magento/Customer/etc/module.xml      |    1 -
 app/code/Magento/Customer/etc/webapi.xml      |  197 +-
 .../view/frontend/layout/customer_account.xml |    8 +-
 .../layout/customer_account_confirmation.xml  |    8 +-
 .../customer_account_createpassword.xml       |    8 +-
 .../customer_account_forgotpassword.xml       |    8 +-
 .../frontend/templates/address/edit.phtml     |    4 +-
 .../view/frontend/templates/form/edit.phtml   |    0
 .../frontend/templates/form/register.phtml    |    4 +-
 .../CustomerImportExport/composer.json        |   16 +-
 .../Controller/Varien/Router/Standard.php     |   20 +-
 .../Magento/DesignEditor/Model/Observer.php   |   42 +-
 app/code/Magento/DesignEditor/composer.json   |   15 +-
 app/code/Magento/DesignEditor/etc/module.xml  |    1 -
 ...nhtml_system_design_editor_files_index.xml |    1 -
 ...tml_system_design_editor_firstentrance.xml |   16 +-
 .../adminhtml_system_design_editor_index.xml  |   16 +-
 .../adminhtml_system_design_editor_launch.xml |  100 +-
 .../view/adminhtml/templates/editor.phtml     |   26 +-
 app/code/Magento/Dhl/composer.json            |   22 +-
 .../Model/Config/Source/Country/Full.php      |    3 +
 app/code/Magento/Directory/composer.json      |   10 +-
 .../Catalog/Product/Edit/Tab/Downloadable.php |    7 +-
 .../Controller/Customer/Products.php          |    5 +-
 app/code/Magento/Downloadable/composer.json   |   33 +-
 .../data-upgrade-1.6.0.0.0-1.6.0.0.1.php      |   53 -
 app/code/Magento/Downloadable/etc/module.xml  |    1 +
 ...catalog_product_view_type_downloadable.xml |    4 +-
 .../templates/catalog/product/links.phtml     |   10 +-
 .../templates/catalog/product/samples.phtml   |    8 +-
 .../checkout/cart/item/default.phtml          |   21 +-
 .../invoice/items/renderer/downloadable.phtml |    2 +-
 .../view/frontend/web/downloadable.js         |   17 +
 .../Eav/Model/Attribute/Data/AbstractData.php |    8 +-
 .../Model/Entity/Attribute/Source/Table.php   |   24 +-
 app/code/Magento/Eav/composer.json            |   12 +-
 .../Block/Adminhtml/Template/Edit/Form.php    |   20 +-
 app/code/Magento/Email/composer.json          |   13 +-
 app/code/Magento/Email/etc/module.xml         |    1 -
 .../layout/adminhtml_email_template_edit.xml  |   10 +-
 app/code/Magento/Fedex/composer.json          |   18 +-
 app/code/Magento/GiftMessage/composer.json    |   23 +-
 app/code/Magento/GiftMessage/etc/module.xml   |    1 -
 .../adminhtml/layout/sales_order_view.xml     |   10 +-
 app/code/Magento/GoogleAdwords/composer.json  |    8 +-
 .../Magento/GoogleAnalytics/composer.json     |    8 +-
 .../Magento/GoogleOptimizer/composer.json     |   14 +-
 .../frontend/layout/catalog_category_view.xml |    4 +-
 .../frontend/layout/catalog_product_view.xml  |    4 +-
 .../view/frontend/layout/cms_page_view.xml    |    4 +-
 .../Model/Attribute/Condition.php             |    1 +
 app/code/Magento/GoogleShopping/composer.json |   21 +-
 .../GoogleShopping/etc/adminhtml/events.xml   |    2 +-
 .../Magento/GoogleShopping/etc/module.xml     |    1 -
 .../adminhtml_googleshopping_items_index.xml  |   14 +-
 .../view/frontend/layout/cms_index_index.xml  |    4 +-
 .../Magento/GroupedImportExport/composer.json |   14 +-
 .../Model/Product/Type/Grouped.php            |   21 +
 app/code/Magento/GroupedProduct/composer.json |   24 +-
 .../Magento/GroupedProduct/etc/module.xml     |    2 +-
 .../layout/catalog_product_grouped.xml        |   10 +-
 .../view/adminhtml/web/js/grouped-product.js  |    3 +-
 .../templates/product/price/final_price.phtml |    2 +-
 app/code/Magento/ImportExport/composer.json   |   14 +-
 app/code/Magento/Index/App/Indexer.php        |  108 -
 app/code/Magento/Index/App/Shell.php          |   88 -
 .../Magento/Index/Block/Adminhtml/Process.php |   39 -
 .../Index/Block/Adminhtml/Process/Edit.php    |  106 -
 .../Block/Adminhtml/Process/Edit/Tab/Main.php |  131 -
 .../Index/Block/Adminhtml/Process/Grid.php    |  326 -
 .../Index/Controller/Adminhtml/Process.php    |   92 -
 .../Controller/Adminhtml/Process/Edit.php     |   52 -
 .../Adminhtml/Process/MassChangeMode.php      |   61 -
 .../Adminhtml/Process/MassReindex.php         |   60 -
 .../Adminhtml/Process/ReindexProcess.php      |   56 -
 .../Controller/Adminhtml/Process/Save.php     |   57 -
 app/code/Magento/Index/Model/Event.php        |  384 --
 .../Magento/Index/Model/EventRepository.php   |   68 -
 app/code/Magento/Index/Model/Indexer.php      |  339 --
 .../Index/Model/Indexer/AbstractIndexer.php   |  181 -
 .../Magento/Index/Model/Indexer/Config.php    |   72 -
 .../Index/Model/Indexer/Config/Converter.php  |   61 -
 .../Model/Indexer/Config/SchemaLocator.php    |   72 -
 .../Magento/Index/Model/IndexerInterface.php  |  100 -
 app/code/Magento/Index/Model/Lock/Storage.php |   83 -
 app/code/Magento/Index/Model/Observer.php     |  154 -
 app/code/Magento/Index/Model/Process.php      |  634 --
 app/code/Magento/Index/Model/Process/File.php |  134 -
 .../Magento/Index/Model/Resource/Event.php    |  135 -
 .../Index/Model/Resource/Event/Collection.php |  136 -
 .../Magento/Index/Model/Resource/Process.php  |  180 -
 .../Model/Resource/Process/Collection.php     |   72 -
 .../Magento/Index/Model/Resource/Setup.php    |  106 -
 app/code/Magento/Index/Model/Shell.php        |  268 -
 .../Model/System/Message/IndexOutdated.php    |  128 -
 app/code/Magento/Index/etc/events.xml         |   48 -
 app/code/Magento/Index/etc/indexers.xsd       |   97 -
 app/code/Magento/Index/i18n/de_DE.csv         |   42 -
 app/code/Magento/Index/i18n/en_US.csv         |   42 -
 app/code/Magento/Index/i18n/es_ES.csv         |   42 -
 app/code/Magento/Index/i18n/fr_FR.csv         |   42 -
 app/code/Magento/Index/i18n/nl_NL.csv         |   42 -
 app/code/Magento/Index/i18n/pt_BR.csv         |   42 -
 app/code/Magento/Index/i18n/zh_CN.csv         |   42 -
 .../Index/sql/index_setup/install-1.6.0.0.php |  189 -
 .../layout/adminhtml_process_edit.xml         |   38 -
 app/code/Magento/Indexer/App/Indexer.php      |    5 -
 .../Indexer/Block/Backend/Container.php       |    2 +-
 .../Adminhtml/Indexer/ListAction.php          |    2 +-
 .../Model/Resource/AbstractResource.php       |    2 +-
 app/code/Magento/Indexer/composer.json        |    8 +-
 app/code/Magento/Indexer/etc/acl.xml          |    2 +-
 .../Magento/Indexer/etc/adminhtml/menu.xml    |    2 +-
 app/code/Magento/Indexer/i18n/de_DE.csv       |    4 +-
 app/code/Magento/Indexer/i18n/en_US.csv       |    4 +-
 app/code/Magento/Indexer/i18n/es_ES.csv       |    4 +-
 app/code/Magento/Indexer/i18n/fr_FR.csv       |    4 +-
 app/code/Magento/Indexer/i18n/nl_NL.csv       |    4 +-
 app/code/Magento/Indexer/i18n/pt_BR.csv       |    4 +-
 app/code/Magento/Indexer/i18n/zh_CN.csv       |    4 +-
 app/code/Magento/Install/composer.json        |   14 +-
 .../Install/view/adminhtml/layout/default.xml |   10 +-
 .../Install/view/install/templates/page.phtml |    5 -
 app/code/Magento/Integration/composer.json    |   17 +-
 app/code/Magento/Integration/etc/module.xml   |    1 -
 .../layout/adminhtml_integration_index.xml    |   10 +-
 .../layout/adminhtml_integration_new.xml      |   12 +-
 .../integration/popup_container.phtml         |    4 +-
 .../Magento/LayeredNavigation/composer.json   |    8 +-
 .../{page_one_column.xml => 1column.xml}      |    0
 ...two_columns_left.xml => 2columns-left.xml} |    0
 ...o_columns_right.xml => 2columns-right.xml} |    0
 .../{page_three_columns.xml => 3columns.xml}  |    0
 .../catalog_category_view_type_layered.xml    |    8 +-
 .../layout/catalogsearch_advanced_result.xml  |    2 +-
 app/code/Magento/Log/composer.json            |   14 +-
 ...ine_index.xml => visitor_online_index.xml} |    0
 .../Adminhtml/Product/Helper/Form/Type.php    |   76 +
 .../Product/Helper/Form/Type/Price.php        |   66 +
 .../Widget/Link.php => Msrp/Block/Popup.php}  |   49 +-
 .../Block/Total.php}                          |   53 +-
 app/code/Magento/Msrp/Helper/Data.php         |  180 +
 app/code/Magento/Msrp/Model/Config.php        |  150 +
 .../code/Magento/Msrp/Model/Msrp.php          |   51 +-
 .../Frontend/Quote/SetCanApplyMsrp.php        |   20 +-
 .../Model/Product/Attribute/Source}/Type.php  |   17 +-
 .../Product/Attribute/Source}/Type/Price.php  |   37 +-
 .../Magento/Msrp/Model/Product/Options.php    |   93 +
 .../Model/Quote/Address/Total.php}            |   27 +-
 .../Catalog/Product/Edit/Tab/Attributes.php   |   65 +
 .../Pricing/Price/MsrpPrice.php               |   43 +-
 .../Pricing/Price/MsrpPriceInterface.php      |    6 +-
 app/code/Magento/Msrp/composer.json           |   29 +
 .../data/msrp_setup/data-install-1.0.0.0.php} |   55 +-
 app/code/Magento/Msrp/etc/adminhtml/di.xml    |   30 +
 .../Magento/Msrp/etc/adminhtml/system.xml     |   51 +
 .../Magento/Msrp/etc/catalog_attributes.xml   |    7 +-
 app/code/Magento/Msrp/etc/config.xml          |   37 +
 app/code/Magento/Msrp/etc/di.xml              |   64 +
 app/code/Magento/Msrp/etc/frontend/events.xml |   30 +
 .../{UrlRedirect => Msrp}/etc/module.xml      |   14 +-
 app/code/Magento/Msrp/etc/sales.xml           |   32 +
 .../base/layout/catalog_product_prices.xml    |   39 +
 .../base/templates/product/price/msrp.phtml}  |   34 +-
 .../view/base/web/js/msrp.js                  |   35 +-
 .../frontend/layout/catalog_category_view.xml |    6 +-
 .../layout/catalog_product_compare_index.xml  |   28 +
 .../frontend/layout/catalog_product_view.xml  |   39 +
 ...atalog_product_view_type_downloadable.xml} |    9 +-
 .../layout/catalogsearch_advanced_result.xml  |    2 +-
 .../layout/catalogsearch_result_index.xml     |    2 +-
 .../frontend/layout/checkout_cart_index.xml}  |   15 +-
 .../layout/checkout_onepage_failure.xml       |    2 +-
 .../layout/checkout_onepage_success.xml       |    2 +-
 .../Msrp/view/frontend/layout/default.xml     |   34 +
 .../view/frontend/layout/msrp_popup.xml}      |    2 +-
 .../frontend/layout/review_product_list.xml   |    4 +-
 ...ist_index_configure_type_downloadable.xml} |    6 +-
 .../frontend/layout/wishlist_index_index.xml  |    4 +-
 .../frontend/layout/wishlist_search_view.xml  |    4 +-
 .../frontend/layout/wishlist_shared_index.xml |    4 +-
 .../frontend/templates/cart/subtotal.phtml    |   19 +-
 .../view/frontend/templates/cart/totals.phtml |   27 +
 .../view/frontend/templates}/popup.phtml      |   19 +-
 .../render/item/price_msrp_item.phtml         |    2 +-
 .../render/item/price_msrp_rss.phtml          |    2 +-
 .../Block/Checkout/Address/Select.php         |    4 +-
 .../Block/Checkout/Addresses.php              |    5 +-
 .../Multishipping/Block/Checkout/Billing.php  |    5 +-
 .../Multishipping/Block/Checkout/Overview.php |    7 +-
 .../Multishipping/Block/Checkout/Shipping.php |    4 +-
 .../Multishipping/Controller/Checkout.php     |    0
 .../Checkout/Address/EditAddress.php          |    7 +-
 .../Checkout/Address/EditBilling.php          |    6 +-
 .../Checkout/Address/EditShipping.php         |    6 +-
 .../Checkout/Address/NewBilling.php           |    6 +-
 .../Checkout/Address/NewShipping.php          |    6 +-
 app/code/Magento/Multishipping/composer.json  |   20 +-
 .../templates/checkout/overview.phtml         |   50 +-
 .../templates/checkout/overview/item.phtml    |   60 +-
 .../templates/checkout/shipping.phtml         |   76 +-
 .../Newsletter/Block/Adminhtml/Queue/Edit.php |   13 -
 .../Block/Adminhtml/Template/Edit.php         |    8 +-
 .../Newsletter/Controller/Manage/Index.php    |    2 +-
 .../Newsletter/Controller/Manage/Save.php     |    2 +-
 .../Model/Plugin/CustomerPlugin.php           |    4 +-
 .../Newsletter/Model/Resource/Queue.php       |    2 +-
 app/code/Magento/Newsletter/composer.json     |   23 +-
 app/code/Magento/Newsletter/etc/module.xml    |    1 -
 .../layout/newsletter_queue_edit.xml          |   16 +-
 .../layout/newsletter_queue_preview.xml       |   20 +-
 .../layout/newsletter_template_edit.xml       |   16 +-
 .../layout/newsletter_template_preview.xml    |   20 +-
 .../templates/preview/iframeswitcher.phtml    |   11 -
 .../Magento/OfflinePayments/composer.json     |    6 +-
 .../Magento/OfflineShipping/composer.json     |   20 +-
 app/code/Magento/Ogone/composer.json          |   12 +-
 .../App/FrontController/BuiltinPlugin.php     |    0
 .../App/FrontController/VarnishPlugin.php     |    0
 app/code/Magento/PageCache/composer.json      |    8 +-
 .../view/frontend/layout/default.xml          |    3 +-
 .../PayPalRecurringPayment/composer.json      |   16 +-
 app/code/Magento/Payment/composer.json        |   14 +-
 .../AbstractExpress/SaveShippingMethod.php    |    2 +-
 app/code/Magento/Paypal/composer.json         |   30 +-
 .../layout/adminhtml_system_config_edit.xml   |   10 +-
 .../view/frontend/layout/customer_account.xml |    8 +-
 .../layout/paypal_payflowexpress_review.xml   |    4 +-
 .../templates/billing/agreement/view.phtml    |  158 +-
 .../templates/billing/agreements.phtml        |    2 +-
 .../frontend/templates/express/review.phtml   |   95 +-
 .../templates/express/review/details.phtml    |   24 +-
 .../express/review/shipping/method.phtml      |    2 +-
 app/code/Magento/Persistent/composer.json     |   16 +-
 app/code/Magento/ProductAlert/composer.json   |   12 +-
 .../Controller/RecurringPayment.php           |    2 +-
 .../Magento/RecurringPayment/composer.json    |   26 +-
 .../layout/sales_recurringpayment_index.xml   |    8 +-
 app/code/Magento/Reports/composer.json        |   36 +-
 .../Reports/view/frontend/layout/default.xml  |    4 -
 .../RequireJs/Block/Html/Head/Config.php      |   22 +-
 app/code/Magento/RequireJs/composer.json      |    5 +-
 app/code/Magento/RequireJs/etc/module.xml     |    6 +-
 .../Magento/Review/Block/Adminhtml/Grid.php   |    5 +-
 .../Magento/Review/Block/Adminhtml/Rss.php    |  123 +
 .../Review/Block/Adminhtml/Rss/Grid/Link.php  |   98 +
 .../Magento/Review/Block/Product/View.php     |    1 +
 .../Adminhtml/Product/NewAction.php           |    2 -
 .../Review/Controller/Customer/Index.php      |    2 +-
 .../Review/Controller/Customer/View.php       |    2 +-
 app/code/Magento/Review/Model/Rss.php         |   71 +
 app/code/Magento/Review/composer.json         |   22 +-
 app/code/Magento/Review/etc/adminhtml/di.xml  |    7 +
 .../adminhtml/layout/review_product_index.xml |   32 +
 .../adminhtml/templates/rss/grid/link.phtml   |   29 +
 .../Rss/App/Action/Plugin/Authentication.php  |   44 +-
 .../Rss/Block/Catalog/AbstractCatalog.php     |  103 -
 .../Magento/Rss/Block/Catalog/Category.php    |  238 -
 .../Magento/Rss/Block/Catalog/NewCatalog.php  |  236 -
 .../Magento/Rss/Block/Catalog/NotifyStock.php |  159 -
 app/code/Magento/Rss/Block/Catalog/Review.php |  139 -
 .../Magento/Rss/Block/Catalog/Salesrule.php   |  141 -
 .../Magento/Rss/Block/Catalog/Special.php     |  277 -
 app/code/Magento/Rss/Block/Feeds.php          |  103 +
 app/code/Magento/Rss/Block/ListBlock.php      |  252 -
 app/code/Magento/Rss/Block/Order/NewOrder.php |  138 -
 app/code/Magento/Rss/Block/Order/Status.php   |  131 -
 .../Magento/Rss/Controller/Adminhtml/Feed.php |   65 +
 .../{Catalog/Review.php => Feed/Index.php}    |   35 +-
 .../Controller/Adminhtml/Order/NewAction.php  |   40 -
 .../Rss/Controller/{Catalog.php => Feed.php}  |   65 +-
 .../Notifystock.php => Feed/Index.php}        |   35 +-
 app/code/Magento/Rss/Controller/Index.php     |   22 +-
 app/code/Magento/Rss/Helper/Order.php         |  133 -
 app/code/Magento/Rss/Model/Rss.php            |   74 +-
 app/code/Magento/Rss/Model/RssManager.php     |   90 +
 app/code/Magento/Rss/Model/UrlBuilder.php     |   68 +
 app/code/Magento/Rss/composer.json            |   15 +-
 app/code/Magento/Rss/etc/adminhtml/system.xml |   26 -
 .../etc/adminhtml/menu.xml => Rss/etc/di.xml} |    7 +-
 app/code/Magento/Rss/etc/module.xml           |   13 -
 .../Rss/view/frontend/layout/default.xml      |    5 +-
 .../frontend/layout/rss_catalog_category.xml  |   36 -
 .../view/frontend/layout/rss_catalog_new.xml  |   37 -
 .../view/frontend/layout/rss_index_index.xml  |    2 +-
 .../Rss/view/frontend/templates/feeds.phtml   |   49 +
 .../Rss/view/frontend/templates/list.phtml    |   66 -
 app/code/Magento/Rule/composer.json           |   12 +-
 .../Block/Adminhtml}/Order/Details.php        |    6 +-
 .../Block/Adminhtml/Order/Totals/Tax.php      |   26 +-
 .../Block/Adminhtml/Rss/Order/Grid/Link.php}  |   64 +-
 .../Magento/Sales/Block/Order/Creditmemo.php  |    5 +-
 .../Magento/Sales/Block/Order/History.php     |    8 -
 app/code/Magento/Sales/Block/Order/Info.php   |    4 +-
 .../Sales/Block/Order/Info/Buttons/Rss.php    |  120 +
 .../Magento/Sales/Block/Order/Invoice.php     |    5 +-
 .../Block/Order/PrintOrder/Creditmemo.php     |    4 +-
 .../Sales/Block/Order/PrintOrder/Invoice.php  |    5 +-
 .../Sales/Block/Order/PrintOrder/Shipment.php |    5 +-
 .../Sales/Block/Order/PrintShipment.php       |    4 +-
 app/code/Magento/Sales/Block/Order/View.php   |    5 +-
 .../Invoice/AbstractInvoice/Email.php         |    2 +-
 .../Magento/Sales/Controller/Guest/Form.php   |    2 +-
 .../Sales/Controller/Order/History.php        |    2 +-
 .../Sales/Model/Order/Address/Validator.php   |    2 +-
 .../OrderRepository/Plugin/Authorization.php  |   76 +
 .../Sales/Model/Resource/Order/Address.php    |    2 +-
 .../Sales/Model/Resource/Order/Creditmemo.php |   23 +-
 .../Model/Resource/Order/Rss/OrderStatus.php} |   18 +-
 .../Sales/Model/Resource/Order/Shipment.php   |   21 +-
 app/code/Magento/Sales/Model/Rss/NewOrder.php |  171 +
 .../Magento/Sales/Model/Rss/OrderStatus.php   |  237 +
 .../Magento/Sales/Model/Service/Quote.php     |    2 +-
 .../Sales/Service/V1/Data/OrderPayment.php    |    2 +-
 app/code/Magento/Sales/composer.json          |   44 +-
 .../{Index => Sales}/etc/adminhtml/di.xml     |    6 +-
 .../Magento/Sales/etc/adminhtml/system.xml    |    9 +
 .../Magento/Sales/etc/catalog_attributes.xml  |    3 -
 app/code/Magento/Sales/etc/di.xml             |    7 +
 .../Magento/Sales/etc/frontend/events.xml     |    3 -
 app/code/Magento/Sales/etc/sales.xml          |    1 -
 app/code/Magento/Sales/etc/webapi_rest/di.xml |    3 +
 app/code/Magento/Sales/etc/webapi_soap/di.xml |    3 +
 .../Sales/sql/sales_setup/install-1.6.0.0.php |    4 +-
 .../layout/sales_order_create_index.xml       |   18 +-
 .../layout/sales_order_grid_block.xml         |    3 +
 .../adminhtml/layout/sales_order_view.xml     |   12 +-
 .../adminhtml}/templates/order/details.phtml  |    0
 .../templates/rss/order/grid/link.phtml       |   29 +
 .../layout/sales_guest_creditmemo.xml         |    3 +
 .../frontend/layout/sales_guest_invoice.xml   |    3 +
 .../frontend/layout/sales_guest_shipment.xml  |    3 +
 .../view/frontend/layout/sales_guest_view.xml |    7 +-
 .../layout/sales_order_creditmemo.xml         |    3 +
 .../frontend/layout/sales_order_invoice.xml   |    3 +
 .../frontend/layout/sales_order_shipment.xml  |    3 +
 .../view/frontend/layout/sales_order_view.xml |    3 +
 .../frontend/templates/items/price/row.phtml  |    2 +-
 .../frontend/templates/items/price/unit.phtml |    2 +-
 .../templates/order/info/buttons/rss.phtml    |   31 +
 .../order/items/renderer/default.phtml        |    1 -
 .../Magento/SalesRule/Block/Rss/Discounts.php |  191 +
 .../Magento/SalesRule/Model/Rss/Discounts.php |   69 +
 app/code/Magento/SalesRule/composer.json      |   34 +-
 .../SalesRule/etc/adminhtml/system.xml        |    8 +
 app/code/Magento/SalesRule/etc/di.xml         |    7 +
 .../layout/sales_rule_promo_quote_edit.xml    |    8 -
 app/code/Magento/Sendfriend/composer.json     |   14 +-
 .../Magento/Shipping/Block/Order/Shipment.php |    5 +-
 app/code/Magento/Shipping/composer.json       |   26 +-
 .../Sitemap/Block/Adminhtml/Edit/Form.php     |    2 +-
 .../Controller/Adminhtml/Sitemap/Save.php     |    7 +-
 app/code/Magento/Sitemap/Helper/Data.php      |   45 +-
 .../Model/Resource/Catalog/Category.php       |   30 +-
 .../Model/Resource/Catalog/Product.php        |   22 +-
 app/code/Magento/Sitemap/composer.json        |   17 +-
 app/code/Magento/Sitemap/etc/config.xml       |    7 +
 app/code/Magento/Sitemap/etc/module.xml       |    1 +
 .../Magento/Store/Block/Store/Switcher.php    |   11 +-
 app/code/Magento/Store/Block/Switcher.php     |    9 +-
 app/code/Magento/Store/Model/Store.php        |   30 +-
 .../code/Magento/Store/Ui/DataType/Store.php  |   10 +-
 app/code/Magento/Store/composer.json          |   10 +-
 app/code/Magento/Store/etc/module.xml         |    2 +-
 .../view/base/layout/ui_components.xml}       |   13 +-
 .../view/base}/requirejs-config.js            |    9 +-
 .../view/base/web/js/listing/filter/store.js  |  108 +
 .../view/base/web/templates/filter/store.html |   13 +
 .../base/web/templates/filter/store/item.html |    9 +
 .../frontend/templates/switch/stores.phtml    |   18 +-
 .../Block/Checkout/Cart/Sidebar/Totals.php    |    4 +-
 .../Magento/Tax/Block/Checkout/Discount.php   |    4 +-
 .../Magento/Tax/Block/Checkout/Grandtotal.php |    4 +-
 .../Magento/Tax/Block/Checkout/Shipping.php   |    4 +-
 .../Tax/Block/Checkout/Shipping/Price.php     |   13 +-
 .../Magento/Tax/Block/Checkout/Subtotal.php   |    4 +-
 app/code/Magento/Tax/Helper/Data.php          |  129 +-
 .../Model/System/Message/Notifications.php    |   15 +-
 .../Magento/Tax/Pricing/Render/Adjustment.php |   21 +-
 app/code/Magento/Tax/composer.json            |   29 +-
 app/code/Magento/Tax/etc/module.xml           |    1 -
 .../view/adminhtml/layout/tax_rule_edit.xml   |   22 +-
 .../base/layout/catalog_product_prices.xml    |   10 -
 .../base/templates/pricing/adjustment.phtml   |    9 +-
 .../templates/pricing/adjustment/bundle.phtml |    8 +-
 .../pricing/adjustment/downloadable.phtml     |   42 -
 .../checkout/cart/item/price/sidebar.phtml    |   31 +-
 .../checkout/cart/minicart/totals.phtml       |   17 +-
 .../templates/checkout/shipping/price.phtml   |   14 +-
 .../frontend/templates/item/price/row.phtml   |    8 +-
 .../item/price/total_after_discount.phtml     |    2 +-
 .../frontend/templates/item/price/unit.phtml  |    8 +-
 .../Magento/TaxImportExport/composer.json     |   12 +-
 app/code/Magento/Theme/Block/Html.php         |  258 -
 app/code/Magento/Theme/Block/Html/Head.php    |  479 --
 app/code/Magento/Theme/Block/Html/Title.php   |   40 +-
 .../Magento/Theme/Model/Favicon/Favicon.php   |  127 +
 app/code/Magento/Theme/composer.json          |   16 +-
 app/code/Magento/Theme/etc/module.xml         |    2 +-
 .../view/adminhtml/layout/admin-1column.xml   |   15 +-
 .../adminhtml/layout/admin-2columns-left.xml  |   17 +-
 .../adminhtml_system_design_theme_edit.xml    |   40 +-
 ...html_system_design_wysiwyg_files_index.xml |    1 -
 .../view/adminhtml/templates/empty.phtml      |   39 -
 .../Magento/Theme/view/base/layout/empty.xml  |    8 +-
 .../Theme/view/base/templates/root.phtml      |   21 +-
 .../Theme/view/frontend/layout/1column.xml    |    4 +-
 .../Theme/view/frontend/layout/default.xml    |   33 +-
 .../frontend/layout/default_head_blocks.xml   |   44 +-
 .../Theme/view/frontend/layout/print.xml      |   47 -
 .../view/frontend/templates/html/head.phtml   |   43 -
 .../frontend/templates/js/require_js.phtml    |   32 +
 .../Theme/view/frontend/templates/popup.phtml |   50 -
 .../Theme/view/frontend/templates/print.phtml |   59 -
 app/code/Magento/Translation/Block/Js.php     |   18 +-
 app/code/Magento/Translation/composer.json    |   10 +-
 .../view/base/templates/translate.phtml       |   32 +
 app/code/Magento/Ui/AbstractView.php          |  293 +
 app/code/Magento/Ui/Configuration.php         |  127 +
 app/code/Magento/Ui/ConfigurationStorage.php  |  294 +
 .../ContentType/Builders/ConfigJson.php}      |   30 +-
 .../Builders/ConfigStorageJson.php            |   70 +
 .../Ui/ContentType/ContentTypeFactory.php     |   90 +
 .../Ui/ContentType/ContentTypeInterface.php   |   41 +
 app/code/Magento/Ui/ContentType/Html.php      |   79 +
 app/code/Magento/Ui/ContentType/Json.php      |   71 +
 app/code/Magento/Ui/ContentType/Xml.php       |  120 +
 app/code/Magento/Ui/Context/DataProvider.php  |   40 +
 .../code/Magento/Ui/Control/Action.php        |   18 +-
 app/code/Magento/Ui/Control/ActionPool.php    |  148 +
 .../Ui/Control/ActionPoolInterface.php        |   60 +
 app/code/Magento/Ui/Control/Button.php        |  141 +
 app/code/Magento/Ui/Control/Container.php     |   73 +
 .../Magento/Ui/Control/ControlInterface.php   |   34 +
 app/code/Magento/Ui/Control/Item.php          |   34 +
 app/code/Magento/Ui/Control/Link.php          |   34 +
 .../Controller/Adminhtml/Listing/Ajax.php}    |   63 +-
 .../Magento/Ui/DataProvider/Options/Store.php |  110 +
 .../DataProvider/OptionsFactory.php}          |   60 +-
 .../DataProvider/OptionsInterface.php}        |   13 +-
 .../Magento/Ui/DataProvider/Row/Store.php     |   97 +
 .../DataProvider/RowInterface.php}            |   18 +-
 app/code/Magento/Ui/DataProvider/RowPool.php  |   74 +
 .../DataType/AbstractDataType.php}            |   24 +-
 app/code/Magento/Ui/DataType/Boolean.php      |   32 +
 .../Magento/Ui/DataType/DataTypeInterface.php |   47 +
 app/code/Magento/Ui/DataType/Date.php         |   32 +
 app/code/Magento/Ui/DataType/Media.php        |   32 +
 app/code/Magento/Ui/DataType/Number.php       |   32 +
 app/code/Magento/Ui/DataType/Password.php     |   32 +
 app/code/Magento/Ui/DataType/Text.php         |   32 +
 .../Filter/FilterInterface.php}               |   16 +-
 app/code/Magento/Ui/Filter/FilterPool.php     |   86 +
 app/code/Magento/Ui/Filter/Type/Date.php      |  172 +
 .../Script.php => Ui/Filter/Type/Input.php}   |   22 +-
 .../Urlkey.php => Ui/Filter/Type/Range.php}   |   41 +-
 .../Css.php => Ui/Filter/Type/Select.php}     |   22 +-
 .../Filter/Type/Store.php}                    |   20 +-
 app/code/Magento/Ui/Filter/View.php           |  122 +
 app/code/Magento/Ui/FilterPool/View.php       |  197 +
 .../Form/Field.php}                           |   29 +-
 .../FormElement/AbstractFormElement.php}      |   43 +-
 app/code/Magento/Ui/FormElement/Checkbox.php  |   32 +
 .../Ui/FormElement/ElementInterface.php       |   52 +
 .../FormElement/Input.php}                    |   15 +-
 .../FormElement/Radio.php}                    |   14 +-
 .../Special.php => Ui/FormElement/Range.php}  |   14 +-
 app/code/Magento/Ui/FormElement/Select.php    |   32 +
 app/code/Magento/Ui/FormElement/Textarea.php  |   32 +
 app/code/Magento/Ui/Listing/View.php          |  271 +
 .../Ui/ListingContainer/Massaction/View.php   |   74 +
 app/code/Magento/Ui/Paging/View.php           |   82 +
 app/code/Magento/Ui/Search/View.php           |   34 +
 app/code/Magento/Ui/Sorting/View.php          |   84 +
 app/code/Magento/{Index => Ui}/composer.json  |   12 +-
 .../etc/adminhtml/routes.xml                  |    4 +-
 app/code/Magento/Ui/etc/di.xml                |   35 +
 app/code/Magento/{Index => Ui}/etc/module.xml |   10 +-
 .../Magento/Ui/view/base/layout/default.xml   |   34 +
 .../Ui/view/base/layout/ui_components.xml     |  134 +
 .../Magento/Ui/view/base/requirejs-config.js  |   32 +
 .../view/base/templates/context/default.phtml |   30 +
 .../templates/control/action/default.phtml    |   30 +
 .../templates/control/button/default.phtml    |   34 +
 .../templates/data_type/boolean/default.phtml |   30 +
 .../templates/data_type/date/default.phtml    |   30 +
 .../templates/data_type/media/default.phtml   |   30 +
 .../templates/data_type/number/default.phtml  |   30 +
 .../data_type/password/default.phtml          |   30 +
 .../templates/data_type/text/default.phtml    |   30 +
 .../view/base/templates/filter/content.phtml  |   38 +
 .../view/base/templates/filter/default.phtml} |   18 +-
 .../templates/filter/type/date/content.phtml  |   52 +
 .../templates/filter/type/date/label.phtml    |   30 +
 .../templates/filter/type/input/content.phtml |   37 +
 .../templates/filter/type/input/label.phtml   |   30 +
 .../templates/filter/type/range/content.phtml |   52 +
 .../templates/filter/type/range/label.phtml   |   30 +
 .../filter/type/select/content.phtml          |   38 +
 .../templates/filter/type/select/label.phtml  |   30 +
 .../base/templates/filter_pool/active.phtml   |   30 +
 .../base/templates/filter_pool/default.phtml  |   72 +
 .../form_element/checkbox/content.phtml       |   30 +
 .../form_element/checkbox/label.phtml         |   30 +
 .../form_element/input/content.phtml          |   29 +
 .../templates/form_element/input/label.phtml  |   30 +
 .../form_element/radio/content.phtml          |   28 +
 .../templates/form_element/radio/label.phtml  |   30 +
 .../form_element/range/content.phtml}         |   36 +-
 .../templates/form_element/range/label.phtml  |   30 +
 .../form_element/select/content.phtml         |   51 +
 .../templates/form_element/select/label.phtml |   30 +
 .../form_element/textarea/content.phtml       |   28 +
 .../form_element/textarea/label.phtml         |   30 +
 .../view/base/templates/label/default.phtml   |   30 +
 .../templates/listing/horizontal_grid.phtml   |   80 +
 .../listingcontainer/massaction/default.phtml |   36 +
 .../massaction/page_actions.phtml             |   35 +
 .../view/base/templates/paging/default.phtml  |   65 +
 .../view/base/templates/sorting/default.phtml |   34 +
 .../Magento/Ui/view/base/web/js/lib/class.js  |   76 +
 .../Ui/view/base/web/js/lib/component.js      |   77 +
 .../Magento/Ui/view/base/web/js/lib/events.js |   91 +
 .../Ui/view/base/web/js/lib/ko/bind/date.js   |   47 +
 .../base/web/js/lib/ko/bind/datepicker.js     |   74 +
 .../base/web/js/lib/ko/bind/outer_click.js    |   51 +
 .../Ui/view/base/web/js/lib/ko/bind/scope.js  |  103 +
 .../web/js/lib/ko/bind/stop_propagation.js    |   42 +
 .../Ui/view/base/web/js/lib/ko/initialize.js  |   39 +
 .../Ui/view/base/web/js/lib/ko/scope.js       |  107 +
 .../base/web/js/lib/ko/template/engine.js     |  120 +
 .../js/lib/ko/template/observable_source.js   |   56 +
 .../Magento/Ui/view/base/web/js/lib/loader.js |  101 +
 .../Ui/view/base/web/js/lib/mixins/loader.js  |   49 +
 .../view/base/web/js/lib/registry/events.js   |  124 +
 .../view/base/web/js/lib/registry/registry.js |  138 +
 .../view/base/web/js/lib/registry/storage.js  |   88 +
 .../base/web/js/lib/renderer/overrides.js     |  110 +
 .../view/base/web/js/lib/renderer/renderer.js |  290 +
 .../Ui/view/base/web/js/lib/spinner.js        |   39 +
 .../Ui/view/base/web/js/lib/storage/index.js  |   39 +
 .../Ui/view/base/web/js/lib/storage/meta.js   |  204 +
 .../view/base/web/js/lib/storage/storage.js   |   92 +
 .../Magento/Ui/view/base/web/js/lib/utils.js  |   96 +
 .../Ui/view/base/web/js/listing/filter.js     |  297 +
 .../base/web/js/listing/filter/abstract.js    |   45 +
 .../view/base/web/js/listing/filter/date.js   |   29 +
 .../base/web/js/listing/filter/filters.js     |   39 +
 .../view/base/web/js/listing/filter/input.js  |   81 +
 .../view/base/web/js/listing/filter/range.js  |  107 +
 .../view/base/web/js/listing/filter/select.js |  100 +
 .../Ui/view/base/web/js/listing/grid.js       |  240 +
 .../Ui/view/base/web/js/listing/massaction.js |  422 ++
 .../Ui/view/base/web/js/listing/paging.js     |  209 +
 .../Ui/view/base/web/js/listing/sorting.js    |  154 +
 .../web/js/listing/utils/data_provider.js     |  131 +
 .../base/web/js/listing/utils/provider.js     |   64 +
 .../web/js/listing/utils/request_builder.js   |  159 +
 .../Ui/view/base/web/js/listing/utils/rest.js |  103 +
 .../Ui/view/base/web/templates/filter.html    |   60 +
 .../web/templates/filter/filter_date.html     |   45 +
 .../web/templates/filter/filter_input.html    |   32 +
 .../web/templates/filter/filter_range.html}   |   40 +-
 .../web/templates/filter/filter_select.html   |   32 +
 .../view/base/web/templates/listing/grid.html |   54 +
 .../templates/listing/grid/cell/actions.html  |   34 +
 .../web/templates/listing/grid/cell/date.html |   27 +
 .../templates/listing/grid/cell/store.html    |   27 +
 .../web/templates/listing/grid/cell/text.html |   32 +
 .../listing/grid/extender/selectable.html     |   56 +
 .../listing/grid/extender/sortable.html       |   43 +
 .../view/base/web/templates/massaction.html   |   36 +
 .../view/base/web/templates/pageactions.html} |   39 +-
 .../view/base/web/templates/pagination.html   |   50 +
 app/code/Magento/Ups/composer.json            |   18 +-
 .../Controller/Adminhtml/UrlRedirect.php      |  468 --
 .../Magento/UrlRedirect/Controller/Router.php |   94 -
 .../Magento/UrlRedirect/Helper/UrlRewrite.php |   95 -
 .../Model/Resource/UrlRedirect.php            |   77 -
 .../Magento/UrlRedirect/Model/Storage/Db.php  |  104 -
 .../UrlRedirect/Service/V1/Data/Filter.php    |  138 -
 .../UrlRedirect/Service/V1/UrlManager.php     |  127 -
 .../Service/V1/UrlMatcherInterface.php        |   67 -
 app/code/Magento/UrlRedirect/composer.json    |   24 -
 app/code/Magento/UrlRedirect/i18n/de_DE.csv   |   57 -
 app/code/Magento/UrlRedirect/i18n/en_US.csv   |   62 -
 app/code/Magento/UrlRedirect/i18n/es_ES.csv   |   57 -
 app/code/Magento/UrlRedirect/i18n/fr_FR.csv   |   57 -
 app/code/Magento/UrlRedirect/i18n/nl_NL.csv   |   57 -
 app/code/Magento/UrlRedirect/i18n/pt_BR.csv   |   57 -
 app/code/Magento/UrlRedirect/i18n/zh_CN.csv   |   57 -
 .../sql/urlredirect_setup/install-1.0.0.0.php |  109 -
 .../UrlRewrite/App/Request/RewriteService.php |   75 -
 .../Block/Catalog/Category/Edit.php           |   20 +-
 .../Block/Catalog/Category/Tree.php           |   12 +-
 .../Block/Catalog/Edit/Form.php               |   70 +-
 .../Block/Catalog/Product/Edit.php            |   36 +-
 .../Block/Catalog/Product/Grid.php            |   12 +-
 .../Block/Cms/Page/Edit.php                   |   20 +-
 .../Block/Cms/Page/Edit/Form.php              |   43 +-
 .../Block/Cms/Page/Grid.php                   |    2 +-
 .../Block/Edit.php                            |   37 +-
 .../Block/Edit/Form.php                       |   33 +-
 .../Block/GridContainer.php                   |   13 +-
 .../Block/Link.php                            |    2 +-
 .../Block/Selector.php                        |    6 +-
 .../Controller/Adminhtml/Url/Rewrite.php}     |   50 +-
 .../Adminhtml/Url/Rewrite}/CategoriesJson.php |    8 +-
 .../Adminhtml/Url/Rewrite}/CmsPageGrid.php    |    6 +-
 .../Adminhtml/Url/Rewrite}/Delete.php         |    4 +-
 .../Adminhtml/Url/Rewrite}/Edit.php           |   32 +-
 .../Adminhtml/Url/Rewrite}/Index.php          |    8 +-
 .../Adminhtml/Url/Rewrite}/ProductGrid.php    |    6 +-
 .../Controller/Adminhtml/Url/Rewrite/Save.php |  193 +
 .../Magento/UrlRewrite/Controller/Router.php  |  137 +
 .../Magento/UrlRewrite/Helper/UrlRewrite.php  |   32 +-
 .../UrlRewrite/Model/OptionProvider.php       |   36 +-
 .../UrlRewrite/Model/Resource/UrlRewrite.php  |   99 +-
 .../Model/Resource/UrlRewrite/Collection.php  |  119 -
 .../Model/Resource/UrlRewriteCollection.php}  |   12 +-
 .../Model/Storage/AbstractStorage.php         |   60 +-
 .../UrlRewrite/Model/Storage/DbStorage.php    |  165 +
 .../Model/Storage/DuplicateEntryException.php |   28 +
 .../UrlRewrite/Model/StorageInterface.php     |   28 +
 .../UrlRewrite/Model/UrlFinderInterface.php   |   46 +
 .../Model/UrlPersistInterface.php}            |   28 +-
 .../Magento/UrlRewrite/Model/UrlRewrite.php   |  314 +-
 .../Model/UrlRewrite/OptionProvider.php       |   77 -
 .../Service/V1/Data/UrlRewrite.php            |   46 +-
 .../Service/V1/Data/UrlRewriteBuilder.php     |   45 +-
 app/code/Magento/UrlRewrite/composer.json     |   14 +-
 .../etc => UrlRewrite/etc/adminhtml}/acl.xml  |    4 +-
 .../etc/adminhtml/menu.xml                    |    4 +-
 .../etc/adminhtml/routes.xml                  |    2 +-
 .../etc/config.xml                            |    0
 .../{UrlRedirect => UrlRewrite}/etc/di.xml    |    6 +-
 .../Magento/UrlRewrite/etc/frontend/di.xml    |   12 +-
 app/code/Magento/UrlRewrite/etc/module.xml    |   10 +-
 app/code/Magento/UrlRewrite/i18n/de_DE.csv    |   54 +-
 app/code/Magento/UrlRewrite/i18n/en_US.csv    |   59 +-
 app/code/Magento/UrlRewrite/i18n/es_ES.csv    |   54 +-
 app/code/Magento/UrlRewrite/i18n/fr_FR.csv    |   54 +-
 app/code/Magento/UrlRewrite/i18n/nl_NL.csv    |   54 +-
 app/code/Magento/UrlRewrite/i18n/pt_BR.csv    |   54 +-
 app/code/Magento/UrlRewrite/i18n/zh_CN.csv    |   54 +-
 .../sql/urlrewrite_setup/install-1.0.0.0.php  |   77 +-
 .../layout/adminhtml_url_rewrite_index.xml}   |   21 +-
 .../view/adminhtml/templates/categories.phtml |    2 +-
 .../view/adminhtml/templates}/edit.phtml      |    5 +-
 .../view/adminhtml/templates/selector.phtml   |   10 +-
 .../Magento/User/Block/User/Edit/Tab/Main.php |   44 +-
 .../Adminhtml/User/Role/EditRole.php          |    1 -
 .../User/Controller/Adminhtml/User/Save.php   |   17 +-
 app/code/Magento/User/Model/User.php          |   33 +-
 app/code/Magento/User/composer.json           |   14 +-
 app/code/Magento/Usps/composer.json           |   18 +-
 .../Controller/ServiceArgsSerializer.php      |    1 +
 .../Controller/Soap/Request/Handler.php       |    3 -
 .../Config/ClassReflector/TypeProcessor.php   |   14 +-
 .../Magento/Webapi/Model/Config/Converter.php |   14 +-
 app/code/Magento/Webapi/composer.json         |   16 +-
 .../Weee/Pricing/Render/Adjustment.php        |   15 +-
 app/code/Magento/Weee/composer.json           |   24 +-
 .../base/templates/pricing/adjustment.phtml   |   19 +-
 .../Weee/view/frontend/layout/default.xml     |    4 +-
 .../checkout/cart/item/price/sidebar.phtml    |   85 +-
 .../review/item/price/row_excl_tax.phtml      |   18 +-
 .../review/item/price/row_incl_tax.phtml      |   16 +-
 .../review/item/price/unit_excl_tax.phtml     |   16 +-
 .../review/item/price/unit_incl_tax.phtml     |   18 +-
 .../frontend/templates/item/price/row.phtml   |   30 +-
 .../frontend/templates/item/price/unit.phtml  |   35 +-
 .../Magento/Widget/Model/Widget/Instance.php  |    2 +-
 app/code/Magento/Widget/composer.json         |   15 +-
 app/code/Magento/Widget/etc/module.xml        |    1 -
 .../layout/adminhtml_widget_instance_edit.xml |   25 +-
 .../Wishlist/Block/Customer/Sharing.php       |    5 +-
 .../Wishlist/Block/Customer/Wishlist.php      |    5 +-
 app/code/Magento/Wishlist/Block/Rss.php       |  231 -
 .../Email/Rss.php => Rss/EmailLink.php}       |    8 +-
 app/code/Magento/Wishlist/Block/Rss/Link.php  |  102 +
 .../Magento/Wishlist/Block/Share/Wishlist.php |    6 +-
 .../Magento/Wishlist/Controller/Index/Rss.php |  108 -
 .../Wishlist/Controller/Index/Send.php        |    2 +-
 .../Wishlist/Controller/WishlistProvider.php  |    8 +-
 app/code/Magento/Wishlist/Helper/Data.php     |    6 -
 app/code/Magento/Wishlist/Model/Observer.php  |    2 +-
 .../Magento/Wishlist/Model/Rss/Wishlist.php   |  277 +
 app/code/Magento/Wishlist/composer.json       |   32 +-
 app/code/Magento/Wishlist/etc/di.xml          |    6 +-
 .../wishlist_index_configure_type_bundle.xml  |    8 +-
 ...list_index_configure_type_configurable.xml |    8 +-
 ...list_index_configure_type_downloadable.xml |    1 -
 .../frontend/layout/wishlist_index_index.xml  |    1 +
 .../frontend/layout/wishlist_index_rss.xml    |   30 -
 .../{email/rss.phtml => rss/email.phtml}      |    7 +-
 .../frontend/templates/rss/wishlist.phtml}    |   10 +-
 .../view/frontend/templates/view.phtml        |    6 +-
 .../Magento_Backend/layout/default.xml        |   80 +-
 .../Magento_Ui/web/css/source/module.less     |  431 ++
 .../adminhtml/Magento/backend/composer.json   |    4 +-
 .../adminhtml/Magento/backend/theme.xml       |    2 +-
 .../Magento/backend/web/css/pages.less        |   60 +-
 .../Magento/backend/web/css/source/table.less |    2 +-
 .../backend/web/less/styles/debug.less        |    2 +-
 .../backend/web/less/styles/pages.less        |    2 +-
 .../Magento_Bundle/web/css/source/module.less |   10 +-
 .../web/css/source/listings.less              |   93 +-
 .../web/css/source/module.less                |   97 +-
 .../web/css/source/toolbar.less               |    4 +-
 .../web/css/source/widgets.less               |    4 +-
 .../web/css/source/module.less                |    8 +-
 .../layout/checkout_cart_index.xml            |    2 +-
 .../Magento_Checkout/web/css/source/cart.less |   26 +-
 .../web/css/source/minicart.less              |   89 +-
 .../web/css/source/module.less                |   38 +-
 .../Magento_Cms/web/css/source/widgets.less   |    2 +-
 .../layout/customer_account.xml               |   10 +-
 .../web/css/source/module.less                |  119 +-
 .../web/css/source/module.less                |   24 +
 .../web/css/source/module.less                |   17 +-
 .../web/css/source/module.less                |    4 +-
 .../web/css/source/module.less                |   24 +-
 .../web/css/source/module.less                |    5 +-
 .../Magento_Paypal/web/css/source/module.less |  136 +-
 .../Magento_Review/web/css/source/module.less |    4 +-
 .../Magento_Sales/web/css/source/module.less  |   46 +-
 .../web/css/source/module.less                |    4 +-
 .../layout/default_head_blocks.xml            |   10 +-
 .../css/source/collapsible_navigation.less    |  104 +
 .../Magento_Theme/web/css/source/module.less  |   23 +-
 .../Magento_Weee/web/css/source/module.less   |   39 +
 .../web/css/source/module.less                |   13 +-
 .../frontend/Magento/blank/composer.json      |    4 +-
 app/design/frontend/Magento/blank/theme.xml   |    2 +-
 .../blank/web/css/source/abstract.less        |  168 +-
 .../blank/web/css/source/actions-toolbar.less |    4 +-
 .../Magento/blank/web/css/source/forms.less   |    4 +-
 .../Magento/blank/web/css/source/layout.less  |   45 +-
 .../Magento/blank/web/css/source/price.less   |   45 +-
 .../frontend/Magento/plushe/composer.json     |    6 +-
 app/design/frontend/Magento/plushe/theme.xml  |    2 +-
 app/design/install/Magento/basic/theme.xml    |    2 +-
 app/etc/di.xml                                |   25 +-
 app/i18n/magento/de_de/composer.json          |    4 +-
 app/i18n/magento/en_us/composer.json          |    4 +-
 app/i18n/magento/es_es/composer.json          |    4 +-
 app/i18n/magento/fr_fr/composer.json          |    4 +-
 app/i18n/magento/nl_nl/composer.json          |    4 +-
 app/i18n/magento/pt_br/composer.json          |    4 +-
 app/i18n/magento/zh_cn/composer.json          |    4 +-
 composer.json                                 |    9 +-
 dev/shell/indexer.php                         |    4 +-
 dev/shell/newindexer.php                      |   35 -
 dev/shell/run_data_fixtures.php               |    3 +-
 dev/shell/run_schema_updater.php              |    3 +-
 .../Selenium/Element/ConditionsElement.php    |    1 +
 .../Selenium/Element/GlobalSearchElement.php  |  138 +
 dev/tests/functional/phpunit.xml.dist         |    6 +-
 .../Backend/Test/Block/Page/Header.php        |   33 +
 .../Backend/Test/Block/Widget/Grid.php        |   11 +
 .../AssertGlobalSearchCustomerName.php        |   71 +
 .../AssertGlobalSearchNoRecordsFound.php      |   72 +
 .../Constraint/AssertGlobalSearchOrderId.php  |   71 +
 .../AssertGlobalSearchProductName.php         |   76 +
 .../Backend/Test/Fixture/GlobalSearch.php     |   49 +
 .../Backend/Test/Fixture/GlobalSearch.xml     |   35 +
 .../Test/Fixture/GlobalSearch/Query.php}      |   96 +-
 .../Test/TestCase/GlobalSearchEntityTest.php  |   82 +
 .../TestCase/GlobalSearchEntityTest/test.csv  |    6 +
 .../Magento/Backend/Test/etc/constraint.xml   |   39 +
 .../app/Magento/Backend/Test/etc/fixture.xml  |   31 +
 .../Test/Block/Catalog/Product/View.php       |    4 +-
 .../AssertTierPriceOnBundleProductPage.php    |    4 +-
 .../Bundle/Test/Fixture/BundleProduct.php     |   13 -
 .../Bundle/Test/Fixture/BundleProduct.xml     |    7 -
 .../Fixture/BundleProduct/CheckoutData.php    |    5 +-
 .../Bundle/Test/Repository/BundleProduct.php  |    6 +-
 ...CartFromCustomerWishlistOnFrontendTest.php |   51 +
 .../test.csv                                  |    3 +
 .../Test/Block/Product/ListProduct.php        |   10 +-
 .../Catalog/Test/Block/Product/Price.php      |    8 +-
 .../Catalog/Test/Block/Product/View.php       |   26 +-
 .../AssertProductTierPriceOnProductPage.php   |    4 +-
 .../Catalog/Test/Fixture/Cart/Item.php        |    4 +
 .../Catalog/Test/Fixture/CatalogCategory.php  |   11 +
 .../Catalog/Test/Fixture/CatalogCategory.xml  |    5 +
 .../Test/Fixture/CatalogProductSimple.php     |   19 +-
 .../Test/Fixture/CatalogProductSimple.xml     |   13 +-
 .../CatalogProductSimple/CheckoutData.php     |   21 +-
 .../Test/Fixture/CatalogProductVirtual.php    |   19 +-
 .../Test/Fixture/CatalogProductVirtual.xml    |   13 +-
 .../CatalogProductVirtual/CheckoutData.php    |    5 +
 .../Magento/Catalog/Test/Fixture/Product.php  |    2 +-
 .../Test/Handler/CatalogCategory/Curl.php     |    4 +
 .../CatalogProductAttributeIndex.xml          |    2 +-
 .../Adminhtml/CatalogProductAttributeNew.xml  |    2 +-
 .../Test/Repository/CatalogCategory.php       |    9 +
 .../Repository/CatalogProductAttribute.php    |   41 +
 .../Test/Repository/CatalogProductSimple.php  |   44 +-
 .../Test/Repository/CatalogProductVirtual.php |   18 -
 .../Catalog/Test/Repository/SimpleProduct.php |    6 -
 .../TestCase/Category/AssignProductTest.php   |    5 -
 .../Test/Page/AdvancedResult.xml              |    4 +-
 .../app/Magento/Checkout/Test/Block/Cart.php  |    2 +-
 .../Test/Block/Cart/AbstractCartItem.php      |    4 +-
 .../Test/Block/Cart/CartEmpty.php}            |   35 +-
 .../Checkout/Test/Block/Cart/CartItem.php     |   34 +
 .../Test/Constraint/AssertCartIsEmpty.php     |   87 +
 .../AssertProductQtyInMiniShoppingCart.php    |   43 +-
 .../Checkout/Test/Page/CheckoutCart.xml       |    5 +
 .../TestStep/AddProductsToTheCartStep.php     |    2 +-
 .../Magento/Checkout/Test/etc/constraint.xml  |    3 +
 .../app/Magento/Cms/Test/Page/CmsIndex.xml    |    7 +-
 ...tConfigurableProductInItemsOrderedGrid.php |    2 +-
 .../AssertProductAttributeIsConfigurable.php  |    4 +-
 .../Fixture/ConfigurableProductInjectable.php |   13 -
 .../Fixture/ConfigurableProductInjectable.xml |    7 -
 .../ConfigurableAttributesData.php            |  107 +-
 .../Test/Repository/ConfigurableProduct.php   |    6 -
 .../ConfigurableProductInjectable.php         |   36 +
 ...CartFromCustomerWishlistOnFrontendTest.php |   51 +
 .../test.csv                                  |    2 +
 .../Test/etc/constraint.xml                   |    3 +
 .../app/Magento/Core/Test/Block/Messages.php  |   18 +
 .../Constraint/AssertCustomVariableInPage.php |   16 +-
 .../UpdateCustomVariableEntityTest.php        |    2 +-
 .../Test/Repository/CustomerInjectable.php    |    1 -
 .../TestStep/LoginCustomerOnFrontendStep.php  |   97 +
 .../Test/Block/Catalog/Product/View.php       |    2 +-
 .../Test/Block/Catalog/Product/View/Links.php |    2 +-
 .../Block/Catalog/Product/View/Samples.php    |    4 +-
 .../AssertDownloadableSamplesData.php         |    4 +-
 .../Fixture/DownloadableProductInjectable.php |   13 -
 .../Fixture/DownloadableProductInjectable.xml |    7 -
 ...CartFromCustomerWishlistOnFrontendTest.php |   51 +
 .../test.csv                                  |    2 +
 .../testCreateDownloadableProduct.csv         |    2 +-
 .../Test/Block/Checkout/Cart/CartItem.php     |   14 +
 ...CartFromCustomerWishlistOnFrontendTest.php |   39 +-
 .../test.csv                                  |    2 +
 .../Magento/Index/Test/Page/ProcessList.php   |   89 -
 .../Viewed/Filter.php => AbstractFilter.php}  |   65 +-
 .../Adminhtml/Customer/Counts/Filter.php      |   18 +-
 .../Adminhtml/Customer/Counts/Filter.xml      |   38 +
 .../Block/Adminhtml/Customer/Counts/Grid.php  |   20 +-
 .../Adminhtml/Customer/Totals/Filter.php      |   42 +
 .../Adminhtml/Customer/Totals/Filter.xml      |   38 +
 .../Block/Adminhtml/Customer/Totals/Grid.php  |  102 +
 .../Products}/Viewed/Action.php               |    2 +-
 .../Review/Products/Viewed/Filter.php         |   36 +
 .../Products}/Viewed/Filter.xml               |    0
 .../Products}/Viewed/ProductGrid.php          |   15 +-
 .../Block/Adminhtml/Sales/Coupons/Filter.php  |   40 +-
 .../Adminhtml/Shopcart/Abandoned/Grid.php     |   60 +
 ...bstractAssertCustomerOrderReportResult.php |   74 +
 .../AssertAbandonedCartCustomerInfoResult.php |   89 +
 .../AssertCustomerOrderCountReportResult.php  |   75 +
 .../AssertCustomerOrderTotalReportResult.php  |   75 +
 .../Test/Page/Adminhtml/AbandonedCarts.xml    |   34 +
 .../Test/Page/Adminhtml/Bestsellers.xml       |   49 -
 .../Page/Adminhtml/CustomerOrdersReport.xml   |   39 +
 .../Page/Adminhtml/CustomerTotalsReport.xml   |   39 +
 .../Test/Page/Adminhtml/ProductReportView.xml |    6 +-
 .../AbandonedCartsReportEntityTest.php        |  170 +
 .../AbandonedCartsReportEntityTest/test.csv   |    3 +
 .../BestsellerProductsReportEntityTest.php    |   89 -
 .../test.csv                                  |    4 -
 .../CustomersOrderCountReportEntityTest.php   |  101 +
 .../test.csv                                  |    4 +
 .../CustomersOrderTotalReportEntityTest.php   |  101 +
 .../test.csv                                  |    4 +
 .../TestCase/SearchTermsReportEntityTest.php  |    2 +-
 .../ViewedProductsReportEntityTest/test.csv   |    4 +-
 .../Magento/Reports/Test/etc/constraint.xml   |   11 +-
 .../app/Magento/Reports/Test/etc/page.xml     |   20 +-
 .../app/Magento/Store/Test/Block/Switcher.php |    5 +
 .../Magento/Store/Test/Handler/Store/Curl.php |   13 +-
 .../Store/Test/Handler/StoreGroup/Curl.php    |   21 +-
 .../Store/Test/Handler/Website/Curl.php       |   17 +-
 .../Test/TestCase/CreateStoreEntityTest.php   |    4 +-
 .../TestCase/CreateStoreEntityTest/test.csv   |    8 +-
 .../Test/TestCase/UpdateStoreEntityTest.php   |    1 +
 .../TestCase/UpdateStoreEntityTest/test.csv   |    4 +-
 .../UpdateStoreGroupEntityTest/test.csv       |    4 +-
 .../Test/Block/Adminhtml/Rule/Edit/Form.php   |    1 +
 .../Magento/Theme/Test/Block/Html/Footer.php  |    5 +-
 .../Block/Adminhtml/Catalog/Category/Grid.php |    2 +-
 .../Adminhtml/Catalog/Edit/UrlRewriteForm.xml |   18 +-
 .../Test/Block/Adminhtml/Cms/Page/Grid.php    |    4 +-
 .../Test/Block/Adminhtml/Selector.php         |    4 +-
 .../AssertUrlRewriteCategoryRedirect.php      |    2 +-
 .../AssertUrlRewriteDeletedMessage.php        |    6 +-
 .../Constraint/AssertUrlRewriteInGrid.php     |   12 +-
 .../Constraint/AssertUrlRewriteNotInGrid.php  |   12 +-
 .../AssertUrlRewriteSaveMessage.php           |    6 +-
 .../UrlRewrite/Test/Fixture/UrlRewrite.php    |   21 +-
 .../UrlRewrite/Test/Fixture/UrlRewrite.xml    |   17 +-
 .../Test/Fixture/UrlRewriteCategory.php       |   10 +
 .../Test/Handler/UrlRewrite/Curl.php          |   10 +-
 ...{UrlrewriteEdit.xml => UrlRewriteEdit.xml} |    4 +-
 ...rlrewriteIndex.xml => UrlRewriteIndex.xml} |    2 +-
 .../UrlRewrite/Test/Repository/UrlRewrite.php |    8 +-
 .../Test/Repository/UrlRewriteCategory.php    |    3 +-
 .../Test/Repository/UrlRewriteProduct.php     |    2 +-
 .../UrlRewrite/Test/TestCase/CategoryTest.php |   13 +-
 .../CreateCategoryRewriteEntityTest.php       |   16 +-
 .../testCreateCategoryRewrite.csv             |    2 +-
 .../CreateCustomUrlRewriteEntityTest.php      |   18 +-
 .../CreateCustomUrlRewriteEntityTest/test.csv |    2 +-
 .../CreateProductUrlRewriteEntityTest.php     |   16 +-
 .../testProductUrlRewrite.csv                 |    4 +-
 .../DeleteCategoryUrlRewriteEntityTest.php    |   24 +-
 .../testDeleteCategoryUrlRewrite.csv          |    2 +-
 .../DeleteCustomUrlRewriteEntityTest.php      |   14 +-
 .../DeleteProductUrlRewriteEntityTest.php     |   22 +-
 .../UrlRewrite/Test/TestCase/ProductTest.php  |   10 +-
 .../UpdateCategoryUrlRewriteEntityTest.php    |   22 +-
 .../test.csv                                  |    4 +-
 .../UpdateCustomUrlRewriteEntityTest.php      |   14 +-
 .../UpdateCustomUrlRewriteEntityTest/test.csv |    2 +-
 .../UpdateProductUrlRewriteEntityTest.php     |   20 +-
 .../testUpdateProductUrlRewrite.csv           |    2 +-
 .../UrlRewrite/Test/etc/constraint.xml        |    4 +-
 .../Magento/UrlRewrite/Test/etc/fixture.xml   |    4 +-
 .../app/Magento/UrlRewrite/Test/etc/page.xml  |   16 +-
 .../Test/Block/Adminhtml/User/UserForm.xml    |    1 +
 .../Magento/User/Test/Fixture/AdminUser.php   |    7 +
 .../app/Magento/User/Test/Fixture/User.php    |   52 +
 .../app/Magento/User/Test/Fixture/User.xml    |    4 +
 .../app/Magento/User/Test/Repository/User.php |   13 +-
 .../CreateAdminUserEntityTest/test.csv        |   14 +-
 .../testUpdateAdminUser.csv                   |    8 +-
 .../testUpdateAdminUserRolesEntity.csv        |    6 +-
 .../Test/Block/Customer/Wishlist/Items.php    |   19 +-
 .../Block/Customer/Wishlist/Items/Product.php |   40 +-
 .../Block/Customer/Wishlist/Items/Product.xml |   35 +
 ...p => AssertProductsIsAbsentInWishlist.php} |   24 +-
 .../Test/Constraint/AssertWishlistIsEmpty.php |   73 +
 ...CartFromCustomerWishlistOnFrontendTest.php |  230 +
 .../test.csv                                  |    4 +
 ...oductFromCustomerWishlistOnBackendTest.php |    3 +-
 .../test.csv                                  |    4 +-
 .../Magento/Wishlist/Test/etc/constraint.xml  |    7 +-
 .../framework/tests/unit/phpunit.xml.dist     |    6 +-
 dev/tests/integration/phpunit.xml.dist        |    6 +-
 .../Magento/Backend/App/RouterTest.php        |    2 +-
 .../Magento/Backend/Block/Page/HeadTest.php   |   42 -
 .../Adminhtml/System/AccountTest.php          |    5 +
 ...{UrlrewriteTest.php => UrlRewriteTest.php} |    6 +-
 .../Backend/{ => Cookie}/DomainTest.php       |   15 +-
 .../Config/Backend/Cookie/LifetimeTest.php    |   45 +
 .../Model/Config/Backend/Cookie/PathTest.php  |   45 +
 .../Backend/Model/Session/AdminConfigTest.php |   68 +
 .../Catalog/Block/Product/AbstractTest.php    |   19 +-
 .../Catalog/Block/Product/ViewTest.php        |   18 +-
 .../Catalog/Controller/CategoryTest.php       |    6 +-
 .../Magento/Catalog/Helper/CategoryTest.php   |   45 -
 .../Magento/Catalog/Helper/DataTest.php       |   13 -
 .../Catalog/Helper/Product/ViewTest.php       |    2 +-
 .../Magento/Catalog/Helper/ProductTest.php    |    8 +-
 .../Magento/Catalog/Model/CategoryTest.php    |    7 -
 .../Catalog/Model/CategoryTreeTest.php        |    8 +-
 .../Model/Indexer/Category/ProductTest.php    |    2 +
 .../Magento/Catalog/Model/Product/UrlTest.php |   26 +-
 .../Catalog/Model/ProductExternalTest.php     |   11 +-
 .../Model/Resource/_files/url_rewrites.php    |    6 +-
 .../Magento/Catalog/Model/UrlTest.php         |  218 -
 .../Catalog/_files/category_backend.php       |   26 +
 .../_files/category_backend_rollback.php      |   38 +
 .../Catalog/_files/multiple_products.php      |    6 +-
 .../Magento/Catalog/_files/url_rewrites.php   |    2 +-
 .../Import/Product/Type/AbstractTest.php      |   16 +-
 .../CatalogUrlRewrite/_files/categories.php   |   84 +
 .../_files/product_simple.php                 |   28 +
 .../testsuite/Magento/Cms/Model/PageTest.php  |   24 +-
 .../Controller/Adminhtml/ProductTest.php      |    3 -
 .../layout_test_handle_sample.xml             |   28 +-
 .../Magento/Core/_files/url_rewrite.php       |   47 -
 .../Model/System/CurrencysymbolTest.php       |  108 +
 .../Controller/Adminhtml/IndexTest.php        |    2 +-
 .../Service/V1/AddressMetadataServiceTest.php |   27 +
 .../Service/V1/CustomerAccountServiceTest.php |   22 +-
 .../Service/V1/CustomerGroupServiceTest.php   |   21 +-
 .../V1/CustomerMetadataServiceTest.php        |   46 +
 ..._user_defined_address_custom_attribute.php |   71 +
 ...ttribute_user_defined_custom_attribute.php |   68 +
 .../Customer/_files/customer_group.php        |    2 +-
 .../DesignEditor/Model/ObserverTest.php       |   14 +-
 .../Magento/Directory/Model/ObserverTest.php  |  111 +
 .../Search/Adapter/Mysql/AdapterTest.php      |  303 +-
 .../Adapter/Mysql/Builder/Query/MatchTest.php |   35 +-
 .../Search/Request/Config/ConverterTest.php   |    2 -
 .../Framework/Search/_files/products.php      |   10 +-
 .../Framework/Search/_files/requests.xml      |  204 +-
 .../Search/_files/search_request.xml          |    6 +-
 .../Search/_files/search_request_config.php   |    5 +-
 .../Validator/CookieDomainValidatorTest.php   |   58 +
 .../Validator/CookieLifetimeValidatorTest.php |   58 +
 .../Validator/CookiePathValidatorTest.php}    |   40 +-
 .../Magento/Framework/Session/ConfigTest.php  |  193 +-
 .../ValidatorFactoryTest.php}                 |   38 +-
 .../Framework/View/Layout/ElementTest.php     |   14 +-
 .../View/Layout/_files/_layout_update.xml     |   35 +-
 .../Magento/Framework/View/Utility/Layout.php |   27 +-
 .../layout_test_handle_sample.xml             |   28 +-
 .../Magento/Index/Model/Process/FileTest.php  |  186 -
 .../Magento/Index/Model/ProcessTest.php       |  175 -
 .../Magento/Index/Model/ShellTest.php         |  107 -
 .../Newsletter/Model/Plugin/PluginTest.php    |    2 +-
 .../_files/recurring_payment.php              |    4 +-
 .../Magento/Rss/Controller/CatalogTest.php    |  182 -
 .../Magento/Rss/Controller/OrderTest.php      |   89 -
 .../Report/Filter/Form/CouponTest.php         |    3 -
 .../Tax/Model/Sales/Total/Quote/SetupUtil.php |    2 +-
 .../Tax/Model/TaxClass/Type/CustomerTest.php  |    2 +-
 .../Modular/IndexerConfigFilesTest.php        |   72 +-
 .../Modular/NewIndexerConfigFilesTest.php     |   74 -
 .../Integrity/Modular/TemplateFilesTest.php   |    3 +-
 .../Test/Integrity/StaticFilesTest.php        |    6 +-
 .../Magento/Theme/Block/Html/HeadTest.php     |  191 -
 .../Magento/Theme/Block/HtmlTest.php          |  116 -
 .../Block}/Catalog/Category/EditTest.php      |   71 +-
 .../Block}/Catalog/Category/TreeTest.php      |   18 +-
 .../Block}/Catalog/Edit/FormTest.php          |   66 +-
 .../Block}/Catalog/Product/EditTest.php       |   81 +-
 .../Block}/Catalog/Product/GridTest.php       |    8 +-
 .../Block}/Cms/Page/Edit/FormTest.php         |   20 +-
 .../Block}/Cms/Page/EditTest.php              |   71 +-
 .../Block}/Cms/Page/GridTest.php              |   12 +-
 .../Block}/Edit/FormTest.php                  |   45 +-
 .../Block}/EditTest.php                       |   23 +-
 .../UrlRewrite/Helper/UrlRewriteTest.php      |   90 -
 .../UrlRewrite/Model/UrlRewriteTest.php       |  307 -
 .../User/Block/User/Edit/Tab/MainTest.php     |    9 +-
 .../User/Controller/Adminhtml/UserTest.php    |   37 +-
 .../Webapi/Model/Config/_files/webapi.php     |   32 +-
 .../testsuite/Magento/Weee/Model/TaxTest.php  |    2 +-
 .../Magento/Wishlist/Block/RssTest.php        |  107 -
 .../Magento/Wishlist/Controller/IndexTest.php |   23 -
 .../testsuite/lib/ko/datepicker/datepicker.js |   51 +
 .../js/testsuite/lib/ko/datepicker/index.html |   37 +-
 .../Magento/TestFramework/Application.php     |    4 -
 .../framework/tests/unit/phpunit.xml.dist     |    6 +-
 .../Magento/Test/ApplicationTest.php          |   20 +-
 .../Fixture/Complex/ComplexGeneratorTest.php  |    5 -
 .../Fixture/Complex/PatternTest.php           |    5 -
 .../ImportExport/Fixture/GeneratorTest.php    |    5 -
 .../Magento/TestFramework/Utility/Classes.php |    2 +-
 .../framework/tests/unit/phpunit.xml.dist     |    6 +-
 dev/tests/static/phpunit-all.xml.dist         |    6 +-
 dev/tests/static/phpunit.xml.dist             |    6 +-
 .../Test/Integrity/Di/CompilerTest.php        |   28 +-
 .../Test/Integrity/Layout/HandlesTest.php     |   21 +
 .../Test/Integrity/Library/DependencyTest.php |   62 +-
 .../Integrity/Library/_files/blacklist.txt    |    1 +
 .../Magento/Framework/Search/ConfigTest.php   |    3 -
 .../Search/_files/invalid_partial.xml         |   41 +-
 .../Magento/Framework/Search/_files/valid.xml |   80 +-
 .../Framework/Search/_files/valid_partial.xml |    6 +-
 .../Magento/Test/Integrity/Xml/SchemaTest.php |   56 +-
 .../Integrity/_files/blacklist/composer.txt   |    1 +
 .../Integrity/_files/blacklist/namespace.txt  |    3 -
 .../_files/dependency_test/tables_ce.php      |    6 -
 .../Test/Legacy/_files/obsolete_classes.php   |   34 +-
 .../Legacy/_files/obsolete_config_nodes.php   |    3 +-
 .../Test/Legacy/_files/obsolete_constants.php |   11 +-
 .../Test/Legacy/_files/obsolete_methods.php   |   18 +-
 .../Legacy/_files/obsolete_properties.php     |    3 -
 .../Test/Php/_files/blacklist/common.txt      |    4 +-
 .../Php/_files/phpcpd/blacklist/common.txt    |    6 +-
 .../Test/Php/_files/whitelist/common.txt      |   23 +-
 dev/tests/unit/filename                       |    0
 dev/tests/unit/filename.csv                   |    0
 dev/tests/unit/filename.invalid_type          |    0
 .../framework/Magento/Test/BaseTestCase.php   |   63 +
 .../framework/tests/unit/phpunit.xml.dist     |    6 +-
 dev/tests/unit/phpunit.xml.dist               |    9 +-
 .../AdminNotification/Model/FeedTest.php      |  179 +
 .../Magento/Backend/Block/UrlrewriteTest.php  |  109 -
 .../Grid/Column/Renderer/ConcatTest.php       |   76 +
 .../Magento/Backend/Block/Widget/GridTest.php |   87 -
 .../Adminhtml/Dashboard/TunnelTest.php        |   12 +-
 .../Adminhtml/System/Account/SaveTest.php     |    6 +-
 .../Backend/{ => Cookie}/DomainTest.php       |   51 +-
 .../Config/Backend/Cookie/LifetimeTest.php    |  119 +
 .../Model/Config/Backend/Cookie/PathTest.php  |  113 +
 .../{ => Model/Session}/AdminConfigTest.php   |   54 +-
 .../Widget/Grid/Row/UrlGeneratorTest.php      |    3 +-
 .../Magento/Backup/Helper/DataTest.php        |   28 -
 .../Block/Adminhtml/Rss/Grid/LinkTest.php     |   78 +
 .../Block/Adminhtml/Rss/NotifyStockTest.php   |  133 +
 .../Catalog/Block/Category/Rss/LinkTest.php   |  143 +
 .../Catalog/Block/Category/ViewTest.php       |    8 +-
 .../Catalog/Block/Rss/CategoryTest.php        |  268 +
 .../Block/Rss/Product/NewProductsTest.php     |  204 +
 .../Catalog/Block/Rss/Product/SpecialTest.php |  246 +
 .../Magento/Catalog/Block/Widget/LinkTest.php |  196 +
 .../Product/Initialization/HelperTest.php     |   17 -
 .../Magento/Catalog/Model/CategoryTest.php    |   42 +-
 .../Price/Plugin/CustomerGroupTest.php        |    9 +-
 .../Magento/Catalog/Model/ObserverTest.php    |  196 +
 .../Catalog/Model/Product/ActionTest.php      |   23 +-
 .../Product/Attribute/Backend/UrlkeyTest.php  |   93 -
 .../Source/Msrp/Type/EnabledTest.php          |   69 -
 .../Catalog/Model/Product/CopierTest.php      |   12 +-
 .../Magento/Catalog/Model/Product/UrlTest.php |   97 +-
 .../Catalog/Model/Rss/CategoryTest.php        |  186 +
 .../Model/Rss/Product/NewProductsTest.php     |  117 +
 .../Model/Rss/Product/NotifyStockTest.php     |  118 +
 .../Catalog/Model/Rss/Product/SpecialTest.php |  103 +
 .../Magento/Catalog/Model/UrlTest.php         |  313 -
 .../Pricing/Render/FinalPriceBoxTest.php      |   11 +-
 .../V1/Product/TierPriceServiceTest.php       |   21 -
 .../Catalog/_files/eav_attributes_data.php    |  468 --
 .../Indexer/Fulltext/Action/FullTest.php      |  135 +
 .../Model/Search/ReaderPluginTest.php         |   63 +
 .../Model/Search/RequestGeneratorTest.php     |  135 +
 .../CanonicalUrlRewriteGeneratorTest.php      |   94 +
 .../ChildrenCategoriesProviderTest.php        |   90 +
 .../ChildrenUrlRewriteGeneratorTest.php       |   99 +
 .../CurrentUrlRewritesRegeneratorTest.php     |  298 +
 .../Model/CategoryUrlPathGeneratorTest.php    |  264 +
 .../Model/CategoryUrlRewriteGeneratorTest.php |  116 +
 .../Model/ObjectRegistryTest.php              |   70 +
 .../CanonicalUrlRewriteGeneratorTest.php      |  103 +
 .../CategoriesUrlRewriteGeneratorTest.php     |  121 +
 .../CurrentUrlRewritesRegeneratorTest.php     |  337 ++
 .../Model/ProductUrlPathGeneratorTest.php     |  181 +
 .../Model/ProductUrlRewriteGeneratorTest.php  |  210 +
 .../categoryUrlRewritesDataProvider.php       |  116 +
 .../Service/V1/StoreViewServiceTest.php       |  129 +
 .../Checkout/Controller/Onepage/IndexTest.php |   17 +-
 .../Magento/Checkout/Model/CartTest.php       |   40 +-
 .../Service/V1/Cart/ReadServiceTest.php       |   21 +-
 .../Magento/Cms/Model/Page/UrlrewriteTest.php |   87 -
 .../Configurable/Attribute/Price/DataTest.php |   43 +
 .../Magento/Core/App/Router/BaseTest.php      |  277 +
 .../Core/App/Router/NoRouteHandlerTest.php    |  121 +
 .../Core/Controller/Index/IndexTest.php       |   33 +-
 .../Core/Controller/Index/NoCookiesTest.php   |  162 +
 .../Core/Controller/Index/NotFoundTest.php    |   56 +
 .../Magento/Core/Helper/DataTest.php          |  253 +-
 .../Magento/Core/Helper/File/MediaTest.php    |  172 +
 .../Core/Helper/File/Storage/DatabaseTest.php |  503 ++
 .../Magento/Core/Helper/File/StorageTest.php  |  195 +
 .../testsuite/Magento/Core/Helper/UrlTest.php |  218 +
 .../Magento/Core/Model/App/EmulationTest.php  |  209 +
 .../Magento/Core/Model/Asset/ConfigTest.php   |  101 +
 .../Asset/Plugin/CleanMergedJsCssTest.php     |   89 +
 .../Model/Address/AbstractAddressTest.php     |    2 +-
 .../Customer/Model/GroupRegistryTest.php      |    4 +-
 .../Service/V1/CustomerAccountServiceTest.php |   35 +-
 .../V1/CustomerMetadataServiceTest.php        |    6 +
 .../Controller/Varien/Router/StandardTest.php |   39 +-
 .../Model/Config/Source/AllRegionTest.php     |  238 +
 .../Magento/Directory/Model/ObserverTest.php  |  143 +
 .../Entity/Attribute/Source/TableTest.php     |  165 +-
 .../Framework/App/Action/ActionTest.php       |   18 +-
 .../Magento/Framework/App/BootstrapTest.php   |    2 +-
 .../Magento/Framework/App/FactoryStub.php     |   55 +
 .../Framework/App/MaintenanceModeTest.php     |   58 +-
 .../App/ObjectManagerFactoryTest.php          |   68 +
 .../Magento/Framework/App/ViewTest.php        |  118 +-
 .../App/_files/app/etc/di.xml}                |    7 +-
 .../Framework/Code/NameBuilderTest.php        |    4 +-
 .../Magento/Framework/Config/DataTest.php     |   76 +
 .../Search/Adapter/Mysql/AdapterTest.php      |    9 +-
 .../Adapter/Mysql/Builder/Query/MatchTest.php |   12 +-
 .../Adapter/Mysql/ConditionManagerTest.php    |  173 +
 .../Search/Adapter/Mysql/DimensionsTest.php   |   52 +-
 .../Mysql/Filter/Builder/RangeTest.php        |   93 +-
 .../Adapter/Mysql/Filter/Builder/TermTest.php |   74 +-
 .../Mysql/Filter/Builder/WildcardTest.php     |  120 +
 .../Adapter/Mysql/Filter/BuilderTest.php      |  192 +-
 .../Search/Adapter/Mysql/MapperTest.php       |    5 +-
 .../Framework/Search/Request/BinderTest.php   |   74 +
 .../Framework/Search/Request/BuilderTest.php  |  231 +
 .../Framework/Search/Request/CleanerTest.php  |  260 +
 .../Framework/Search/Request/MapperTest.php   |   90 +
 .../Framework/Search/RequestFactoryTest.php   |  167 -
 .../Magento/Framework/Session/ConfigTest.php  |  349 +-
 .../Stdlib/DateTime/DateTimeTest.php          |   30 +-
 .../Stdlib/DateTime/TimezoneTest.php          |    8 +-
 .../Framework/ValidatorFactoryTest.php        |   67 +
 .../View/Page/Config/GeneratorTest.php        |  134 +
 .../Framework/View/Page/Config/ReaderTest.php |  115 +
 .../View/Page/Config/RendererTest.php         |  386 ++
 .../View/Page/Config/StructureTest.php        |  131 +
 .../View/Page/Config/_files/template_body.xml |   10 +-
 .../View/Page/Config/_files/template_head.xml |   36 +
 .../View/Page/Config/_files/template_html.xml |   10 +-
 .../Framework/View/PageLayout/ConfigTest.php  |   84 +
 .../View/PageLayout/_files/layouts_one.xml    |   12 +-
 .../View/PageLayout/_files/layouts_two.xml    |   12 +-
 .../Framework/View/Result/PageTest.php        |  294 +
 .../Model/Attribute/ConditionTest.php         |  131 +
 .../Magento/Index/App/IndexerTest.php         |  101 -
 .../testsuite/Magento/Index/App/ShellTest.php |   82 -
 .../Magento/Index/Model/Config/XsdTest.php    |  115 -
 .../Config/_files/invalidIndexersXmlArray.php |   79 -
 .../_files/invalidIndexersXmlMergedArray.php  |   32 -
 .../Config/_files/valid_indexers_merged.xml   |   31 -
 .../Index/Model/EventRepositoryTest.php       |   92 -
 .../Model/Indexer/Config/ConverterTest.php    |   50 -
 .../Indexer/Config/SchemaLocatorTest.php      |   73 -
 .../Index/Model/Indexer/ConfigTest.php        |   97 -
 .../Magento/Index/Model/Lock/StorageTest.php  |  100 -
 .../Index/Model/Process/FileFactoryTest.php   |   64 -
 .../Magento/Index/Model/ProcessTest.php       |  200 -
 .../Magento/Indexer/App/ShellTest.php         |    2 +-
 .../Frontend/Quote/SetCanApplyMsrpTest.php    |  112 +
 .../Attribute/Source}/Type/PriceTest.php      |    6 +-
 .../Pricing/Price/MsrpPriceTest.php           |   22 +-
 .../RequireJs/Block/Html/Head/ConfigTest.php  |   37 +-
 .../Block/Adminhtml/Rss/Grid/LinkTest.php     |   78 +
 .../Review/Block/Adminhtml/RssTest.php        |  161 +
 .../Magento/Review/Model/RssTest.php          |   98 +
 .../Rss/Block/Catalog/AbstractCatalogTest.php |   70 -
 .../Rss/Block/Catalog/CategoryTest.php        |  146 -
 .../Rss/Block/Catalog/NewCatalogTest.php      |  148 -
 .../Magento/Rss/Block/Catalog/ReviewTest.php  |  149 -
 .../Magento/Rss/Block/Catalog/SpecialTest.php |  270 -
 .../testsuite/Magento/Rss/Block/FeedsTest.php |   87 +
 .../Rss/Block/Order/Info/Buttons/RssTest.php  |   75 -
 .../Controller/Adminhtml/Feed/IndexTest.php   |  125 +
 .../Magento/Rss/Controller/Feed/IndexTest.php |  120 +
 .../Magento/Rss/Model/RssManagerTest.php      |   80 +
 .../testsuite/Magento/Rss/Model/RssTest.php   |   91 +-
 .../Magento/Rss/Model/UrlBuilderTest.php      |   85 +
 .../Block/Adminhtml/Order/Totals/TaxTest.php  |  121 +-
 .../Adminhtml/Rss/Order/Grid/LinkTest.php     |   99 +
 .../Magento/Sales/Block/Order/HistoryTest.php |   11 +-
 .../Block/Order/Info/Buttons/RssTest.php      |  120 +
 .../Invoice/AbstractInvoice/EmailTest.php     |  228 +
 .../Magento/Sales/Model/Rss/NewOrderTest.php  |  189 +
 .../Sales/Model/Rss/OrderStatusTest.php       |  198 +
 .../SalesRule/Block/Rss/DiscountsTest.php     |  254 +
 .../SalesRule/Model/Rss/DiscountsTest.php     |   96 +
 .../Magento/Sitemap/Helper/DataTest.php       |   66 +
 .../Magento/Store/Block/SwitchTest.php        |   77 -
 .../Magento/Store/Block/SwitcherTest.php      |   95 +
 .../Magento/Store/Model/StoreTest.php         |   16 +-
 .../testsuite/Magento/Tax/Helper/DataTest.php |   96 +-
 .../Tax/Pricing/Render/AdjustmentTest.php     |   48 +-
 .../Magento/Theme/Block/Html/Head/CssTest.php |   73 -
 .../Theme/Block/Html/Head/LinkTest.php        |   73 -
 .../Theme/Block/Html/Head/ScriptTest.php      |   73 -
 .../Magento/Theme/Block/Html/HeadTest.php     |  137 -
 .../ContentType/Builders/ConfigJsonTest.php   |   52 +
 .../Builders/ConfigStorageJsonTest.php        |  108 +
 .../Ui/ContentType/ContentTypeFactoryTest.php |  102 +
 .../Magento/Ui/ContentType/HtmlTest.php       |  102 +
 .../ListingContainer/Massaction/ViewTest.php  |  167 +
 .../testsuite/Magento/Ui/Paging/ViewTest.php  |  145 +
 .../testsuite/Magento/Ui/Sorting/ViewTest.php |  206 +
 .../UrlRedirect/Model/OptionProviderTest.php  |   37 -
 .../App/Request/RewriteServiceTest.php        |   93 -
 .../UrlRewrite/Controller/RouterTest.php      |  194 +
 .../UrlRewrite/Helper/UrlRewriteTest.php      |   79 +-
 .../Resource/UrlRewriteCollectionTest.php     |  167 +
 .../Model/Storage/AbstractStorageTest.php     |  152 +
 .../Model/Storage/DbStorageTest.php           |  324 +
 .../Model/UrlRewrite/OptionProviderTest.php   |   43 -
 .../Model/UrlRewrite/TypeProviderTest.php     |   39 -
 .../UrlRewrite/Model/UrlRewriteTest.php       |  103 -
 .../testsuite/Magento/User/Model/UserTest.php |   87 +-
 .../Webapi/Model/Config/_files/webapi.php     |   29 +-
 .../Weee/Pricing/Render/AdjustmentTest.php    |   52 +-
 .../Magento/Wishlist/Block/Rss/LinkTest.php   |  101 +
 .../Controller/WishlistProviderTest.php       |  211 +
 .../Magento/Wishlist/Helper/DataTest.php      |  103 +-
 .../Magento/Wishlist/Model/ObserverTest.php   |   25 +-
 .../Rss/WishlistTest.php}                     |  235 +-
 .../Migration/Acl/log/AclXPathToAclId.log     |    2 +-
 .../Tools/Migration/Acl/log/MenuIdToAclId.log |    2 +-
 .../factory_table_names/replace_ce.php        |    2 -
 .../Magento/Framework/App/Action/Action.php   |    7 +-
 .../Magento/Framework/App/Action/Context.php  |    2 +
 .../Magento/Framework/App/ActionFactory.php   |    2 -
 .../Framework/App/ObjectManagerFactory.php    |    6 +-
 .../App/Rss/DataProviderInterface.php         |   62 +
 .../Framework/App/Rss/RssManagerInterface.php |   23 +-
 .../Magento/Framework/App/Rss/UrlBuilder.php  |   19 +-
 .../Framework/App/Rss/UrlBuilderInterface.php |   18 +-
 lib/internal/Magento/Framework/App/State.php  |   10 +
 lib/internal/Magento/Framework/App/View.php   |   13 +-
 .../Magento/Framework/AppInterface.php        |    2 +-
 .../Magento/Framework/Config/Data.php         |   56 +-
 .../Magento/Framework/Event/etc/events.xsd    |    2 +-
 .../Framework/Search/AbstractKeyValuePair.php |    2 +-
 .../Search/Adapter/Mysql/ConditionManager.php |   85 +
 .../Search/Adapter/Mysql/Dimensions.php       |   36 +-
 .../Search/Adapter/Mysql/Filter/Builder.php   |  133 +-
 .../Mysql/Filter/Builder/FilterInterface.php  |   10 +-
 .../Adapter/Mysql/Filter/Builder/Range.php    |  109 +-
 .../Adapter/Mysql/Filter/Builder/Term.php     |   48 +-
 .../Adapter/Mysql/Filter/Builder/Wildcard.php |   65 +
 .../Adapter/Mysql/Filter/BuilderInterface.php |    3 +-
 .../Framework/Search/Adapter/Mysql/Mapper.php |   64 +-
 .../Adapter/Mysql/Query/Builder/Match.php     |   27 +-
 .../Mysql/Query/Builder/QueryInterface.php    |    4 +-
 .../Framework/Search/Request/Binder.php       |   96 +
 .../Builder.php}                              |  154 +-
 .../Framework/Search/Request/Cleaner.php      |  206 +
 .../Framework/Search/Request/Config.php       |    9 +-
 .../Request/Config/FilesystemReader.php       |   26 +-
 .../Framework/Search/Request/Filter/Term.php  |   38 +-
 .../Search/Request/Filter/Wildcard.php        |   46 +-
 .../Search/Request/FilterInterface.php        |    2 +
 .../Framework/Search/Request/Mapper.php       |  120 +-
 .../Framework/Search/Request/Query/Match.php  |   25 +-
 .../Magento/Framework/Search/etc/requests.xsd |    3 +-
 .../Magento/Framework/Session/Config.php      |  111 +-
 .../Validator/CookieDomainValidator.php       |   28 +-
 .../Validator/CookieLifetimeValidator.php     |   45 +
 .../Config/Validator/CookiePathValidator.php  |   19 +-
 .../Framework/Session/SessionManager.php      |    2 +-
 .../Framework/Stdlib/DateTime/DateTime.php    |    2 +-
 .../Framework/Stdlib/DateTime/Timezone.php    |    2 +-
 .../Magento/Framework/ValidatorFactory.php    |   14 +-
 .../Magento/Framework/View/Asset/Source.php   |    2 +-
 .../Design/FileResolution/Fallback/File.php   |    2 +-
 .../Framework/View/Element/Template.php       |    7 +
 .../View/Element/Template/Context.php         |   18 +-
 .../UiComponent/ConfigBuilderInterface.php    |   14 +-
 .../Element/UiComponent/ConfigFactory.php     |   48 +-
 .../Element/UiComponent/ConfigInterface.php   |   70 +
 .../ConfigStorageBuilderInterface.php         |   39 +
 .../UiComponent/ConfigStorageInterface.php    |  175 +
 .../View/Element/UiComponent/Context.php      |  230 +
 .../View/Element/UiComponentFactory.php       |  215 +
 .../View/Element/UiComponentInterface.php     |   92 +
 .../Magento/Framework/View/FileSystem.php     |    2 +-
 .../Magento/Framework/View/Layout.php         |  141 +-
 .../Magento/Framework/View/Layout/Element.php |    5 +
 .../Magento/Framework/View/Page/Config.php    |  412 +-
 .../Framework/View/Page/Config/Generator.php  |  190 +
 .../Framework/View/Page/Config/Reader.php     |  181 +
 .../Framework/View/Page/Config/Renderer.php   |  377 ++
 .../Framework/View/Page/Config/Structure.php  |  216 +
 .../Framework/View/Page/FaviconInterface.php  |   40 +
 .../Framework/View/PageLayout/Config.php      |    1 +
 .../Magento/Framework/View/Result/Layout.php  |    4 +-
 .../Magento/Framework/View/Result/Page.php    |   52 +-
 lib/internal/Magento/Framework/composer.json  |    2 +-
 lib/web/app-config.js                         |    9 +-
 lib/web/css/source/lib/variables.less         |   10 +-
 lib/web/date-format-normalizer.js             |   62 +
 lib/web/jquery/autocomplete/autocomplete.css  |    5 +
 .../autocomplete/jquery.autocomplete.js       |  915 +++
 .../css/bootstrap-carousel.css                |  151 -
 .../jquery.bootstrap-carousel.js              |  290 -
 .../jquery.bootstrap-transition.js            |   60 -
 lib/web/ko/ko.js                              | 5299 +++++++++++++++++
 lib/web/mage/apply/main.js                    |  133 +
 lib/web/mage/apply/registry.js                |   99 +
 lib/web/mage/backend/bootstrap.js             |    5 +-
 lib/web/mage/bootstrap.js                     |    5 +-
 lib/web/mage/components.js                    |    2 +-
 lib/web/mage/dropdown.js                      |    1 -
 lib/web/moment.js                             |    6 +
 lib/web/requirejs/text.js                     |  390 ++
 lib/web/underscore.js                         | 1146 ++--
 setup/composer.json                           |   11 +-
 setup/config/application.config.php           |   10 +-
 setup/module/Magento/Config/Module.php        |   17 +-
 setup/module/Magento/Config/phpunit.xml.dist  |   10 +-
 setup/module/Magento/Config/src/Config.php    |    1 -
 setup/module/Magento/Config/src/Dom.php       |  386 --
 .../Config/src/Dom/NodePathMatcher.php        |   58 -
 .../Magento/Config/src/Reader/Filesystem.php  |   10 +-
 setup/module/Magento/Filesystem/Module.php    |   19 +-
 setup/module/Magento/Framework/Module.php     |   44 -
 .../Framework/src/DB/ExpressionConverter.php  |  102 -
 .../Magento/Framework/src/Math/Random.php     |   84 -
 setup/module/Magento/Locale/Module.php        |   44 -
 setup/module/Magento/Module/Module.php        |   58 -
 .../Magento/Module/config/di.config.php       |   36 -
 .../Magento/Module/config/module.config.php   |   25 -
 .../Magento/Module/src/Setup/Config.php       |  192 -
 setup/module/Magento/Setup/Module.php         |   35 +-
 .../module/Magento/Setup/config/di.config.php |    7 +
 .../Magento/Setup/config/router.config.php    |    5 +-
 setup/module/Magento/Setup/phpunit.xml.dist   |    8 +-
 .../src/Controller/ConsoleController.php      |  406 ++
 .../Controller/Data/DatabaseController.php    |   20 +-
 .../Data/FilePermissionsController.php        |   13 +-
 .../Install/ClearProgressController.php       |   34 +-
 .../Controller/Install/ProgressController.php |   26 +-
 .../Controller/Install/StartController.php    |  271 +-
 .../DB/Adapter/AdapterInterface.php           |   32 +-
 .../src/Framework}/DB/Adapter/Pdo/Mysql.php   |   74 +-
 .../src/Framework}/DB/Ddl/Table.php           |    4 +-
 .../src/Framework}/DB/Ddl/Trigger.php         |    2 +-
 .../Magento/Setup/src/Model/AdminAccount.php  |   53 +-
 .../Setup/src/Model/AdminAccountFactory.php   |   41 +-
 .../Magento/Setup/src/Model/ConsoleLogger.php |   83 +
 .../Magento/Setup/src/Model/DatabaseCheck.php |    2 +-
 .../Setup/src/Model/FilePermissions.php       |   12 +
 .../Magento/Setup/src/Model/Installer.php     |  321 +
 .../Setup/src/Model/InstallerFactory.php      |   61 +
 .../src/Model/LoggerInterface.php}            |   44 +-
 .../Setup/src/Model/UserConfigurationData.php |  133 +
 .../src/Model/{Logger.php => WebLogger.php}   |   75 +-
 .../src/Module}/Converter/Dom.php             |    2 +-
 .../src/Module}/Dependency/Manager.php        |    2 +-
 .../Module}/Dependency/ManagerInterface.php   |    2 +-
 .../{Module/src => Setup/src/Module}/Dir.php  |    6 +-
 .../src => Setup/src/Module}/FileResolver.php |    2 +-
 .../src => Setup/src/Module}/ModuleList.php   |    4 +-
 .../src/Module}/ModuleListInterface.php       |    2 +-
 .../src/Module}/Reader/Filesystem.php         |   14 +-
 .../src/Module}/Resource/Resource.php         |   16 +-
 .../src/Module}/ResourceInterface.php         |    2 +-
 .../src/Module}/SchemaLocator.php             |    2 +-
 .../src => Setup/src/Module}/Setup.php        |  362 +-
 .../Magento/Setup/src/Module/Setup/Config.php |  251 +
 .../Setup/src/Module/Setup/ConfigFactory.php  |   55 +
 .../src/Module}/Setup/Connection/Adapter.php  |   15 +-
 .../Setup/Connection/AdapterInterface.php     |    4 +-
 .../src/Module}/Setup/FileResolver.php        |   71 +-
 .../src => Setup/src/Module}/SetupFactory.php |   84 +-
 .../Magento/Setup/src/Module/SetupModule.php  |  269 +
 .../src/Module}/Updater/SetupInterface.php    |   15 +-
 setup/pub/magento/setup/install.js            |   11 +-
 setup/pub/magento/setup/web-configuration.js  |    8 +-
 1816 files changed, 63493 insertions(+), 37399 deletions(-)
 create mode 100644 CONTRIBUTOR_LICENSE_AGREEMENT.html
 delete mode 100644 app/code/Magento/AdminNotification/Helper/Data.php
 delete mode 100644 app/code/Magento/Backend/Block/Page/Head.php
 rename app/code/Magento/{Catalog/Block/Product/Widget/Link.php => Backend/Block/Page/RequireJs.php} (64%)
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Tree.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Catalog/Edit/Form.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Grid.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/Form.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Grid.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Edit.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Edit/Form.php
 delete mode 100644 app/code/Magento/Backend/Block/Urlrewrite/Selector.php
 delete mode 100644 app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php
 create mode 100644 app/code/Magento/Backend/Model/Config/Backend/Cookie/Domain.php
 create mode 100644 app/code/Magento/Backend/Model/Config/Backend/Cookie/Lifetime.php
 create mode 100644 app/code/Magento/Backend/Model/Config/Backend/Cookie/Path.php
 rename app/code/Magento/Backend/{ => Model/Session}/AdminConfig.php (90%)
 delete mode 100644 app/code/Magento/Backend/view/adminhtml/layout/adminhtml_urlrewrite_index.xml
 create mode 100644 app/code/Magento/Backend/view/adminhtml/templates/admin/page.phtml
 delete mode 100644 app/code/Magento/Backend/view/adminhtml/templates/admin/popup.phtml
 delete mode 100644 app/code/Magento/Backend/view/adminhtml/templates/page/head.phtml
 create mode 100644 app/code/Magento/Backend/view/adminhtml/templates/page/js/head_scripts.phtml
 create mode 100644 app/code/Magento/Backend/view/adminhtml/templates/page/js/require_js.phtml
 delete mode 100644 app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/selector.phtml
 delete mode 100644 app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/General.php
 create mode 100644 app/code/Magento/Catalog/Block/Adminhtml/Rss/Grid/Link.php
 create mode 100644 app/code/Magento/Catalog/Block/Adminhtml/Rss/NotifyStock.php
 create mode 100644 app/code/Magento/Catalog/Block/Category/Rss/Link.php
 create mode 100644 app/code/Magento/Catalog/Block/Rss/Category.php
 create mode 100644 app/code/Magento/Catalog/Block/Rss/Product/NewProducts.php
 create mode 100644 app/code/Magento/Catalog/Block/Rss/Product/Special.php
 delete mode 100644 app/code/Magento/Catalog/Model/Indexer/Url.php
 delete mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Backend/Msrp.php
 delete mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Backend/Urlkey.php
 delete mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php
 mode change 100755 => 100644 app/code/Magento/Catalog/Model/Product/Type/Price.php
 delete mode 100644 app/code/Magento/Catalog/Model/Resource/Product/Attribute/Backend/Urlkey.php
 delete mode 100644 app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav.php
 create mode 100644 app/code/Magento/Catalog/Model/Rss/Category.php
 create mode 100644 app/code/Magento/Catalog/Model/Rss/Product/NewProducts.php
 create mode 100644 app/code/Magento/Catalog/Model/Rss/Product/NotifyStock.php
 create mode 100644 app/code/Magento/Catalog/Model/Rss/Product/Special.php
 delete mode 100644 app/code/Magento/Catalog/Model/Url.php
 rename app/code/Magento/{Rss/Controller/Index/Nofeed.php => Catalog/data/catalog_setup/data-upgrade-1.6.0.0.28-1.6.0.0.29.php} (58%)
 delete mode 100644 app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.3-1.6.0.0.4.php
 create mode 100644 app/code/Magento/Catalog/view/adminhtml/templates/rss/grid/link.phtml
 rename app/code/Magento/{Rss/view/frontend/templates/category/link.phtml => Catalog/view/frontend/templates/category/rss.phtml} (82%)
 create mode 100644 app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php
 create mode 100644 app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
 rename app/code/Magento/{Catalog/Block/Adminhtml/Form/Renderer/Attribute/Urlkey.php => CatalogUrlRewrite/Block/UrlKeyRenderer.php} (79%)
 delete mode 100644 app/code/Magento/CatalogUrlRewrite/Helper/Data.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProvider.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php
 rename app/code/Magento/{Cms/Model/Resource/Page/Urlrewrite.php => CatalogUrlRewrite/Model/Category/Product.php} (77%)
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php
 rename app/code/Magento/{UrlRewrite/Model/UrlRewrite/TypeProvider.php => CatalogUrlRewrite/Model/ObjectRegistry.php} (57%)
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Product/Plugin/Import.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/Product.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/ProductCollection.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php
 rename app/code/Magento/{Index/Controller/Adminhtml/Process/ListAction.php => CatalogUrlRewrite/Observer/CategorySaveRewritesHistorySetter.php} (58%)
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Observer/ProductUrlKeyAutogenerator.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
 rename app/code/Magento/{Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Price.php => CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php} (53%)
 rename app/code/Magento/{UrlRewrite/App/FrontController/Plugin/UrlRewrite.php => CatalogUrlRewrite/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php} (55%)
 delete mode 100644 app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php
 delete mode 100644 app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php
 delete mode 100644 app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php
 delete mode 100644 app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/Service/V1/StoreViewService.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/data/catalogurlrewrite_setup/data-install-1.0.0.0.php
 create mode 100644 app/code/Magento/CatalogUrlRewrite/etc/adminhtml/system.xml
 create mode 100644 app/code/Magento/CatalogUrlRewrite/etc/catalog_attributes.xml
 rename app/code/Magento/{Index => CatalogUrlRewrite}/etc/di.xml (70%)
 rename app/code/Magento/{Catalog/etc/indexers.xml => CatalogUrlRewrite/etc/eav_attributes.xml} (82%)
 rename app/code/Magento/{UrlRedirect/etc/frontend => CatalogUrlRewrite/etc/install}/di.xml (68%)
 create mode 100644 app/code/Magento/CatalogUrlRewrite/etc/install/events.xml
 rename app/code/Magento/{Cms/sql/cms_setup/upgrade-1.6.0.1-1.6.0.2.php => CatalogUrlRewrite/sql/catalogurlrewrite_setup/install-1.0.0.0.php} (56%)
 mode change 100755 => 100644 app/code/Magento/Checkout/Controller/Onepage.php
 create mode 100644 app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
 create mode 100644 app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
 create mode 100644 app/code/Magento/Cms/Controller/Adminhtml/Block/MassDelete.php
 create mode 100644 app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
 create mode 100644 app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
 create mode 100644 app/code/Magento/Cms/Ui/DataProvider/Block/Row/Actions.php
 create mode 100644 app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php
 rename app/code/Magento/{UrlRedirect/Service/V1/Data/Converter.php => Cms/Ui/DataProvider/Page/Options/PageLayout.php} (53%)
 create mode 100644 app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
 create mode 100644 app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
 create mode 100644 app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
 rename app/code/Magento/{Cms/Model/Page/Urlrewrite.php => CmsUrlRewrite/Model/CmsPageUrlPathGenerator.php} (59%)
 rename app/code/Magento/CmsUrlRewrite/{Service/V1/CmsPageUrlGenerator.php => Model/CmsPageUrlRewriteGenerator.php} (64%)
 create mode 100644 app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/Resource/Page.php
 rename app/code/Magento/{UrlRedirect/Model/StorageInterface.php => ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php} (51%)
 rename app/code/Magento/ConfigurableProduct/sql/{configurable_setup => configurableproduct_setup}/install-1.0.0.0.php (100%)
 create mode 100644 app/code/Magento/Core/etc/body.xsd
 create mode 100644 app/code/Magento/Core/etc/head.xsd
 rename app/code/Magento/{Index/etc/indexers_merged.xsd => Core/etc/html.xsd} (60%)
 mode change 100755 => 100644 app/code/Magento/Customer/Block/Form/Edit.php
 mode change 100755 => 100644 app/code/Magento/Customer/Helper/Address.php
 mode change 100755 => 100644 app/code/Magento/Customer/Model/Session.php
 mode change 100755 => 100644 app/code/Magento/Customer/view/frontend/templates/form/edit.phtml
 delete mode 100644 app/code/Magento/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php
 delete mode 100644 app/code/Magento/Index/App/Indexer.php
 delete mode 100644 app/code/Magento/Index/App/Shell.php
 delete mode 100644 app/code/Magento/Index/Block/Adminhtml/Process.php
 delete mode 100644 app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
 delete mode 100644 app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tab/Main.php
 delete mode 100644 app/code/Magento/Index/Block/Adminhtml/Process/Grid.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php
 delete mode 100644 app/code/Magento/Index/Controller/Adminhtml/Process/Save.php
 delete mode 100644 app/code/Magento/Index/Model/Event.php
 delete mode 100644 app/code/Magento/Index/Model/EventRepository.php
 delete mode 100644 app/code/Magento/Index/Model/Indexer.php
 delete mode 100644 app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
 delete mode 100644 app/code/Magento/Index/Model/Indexer/Config.php
 delete mode 100644 app/code/Magento/Index/Model/Indexer/Config/Converter.php
 delete mode 100644 app/code/Magento/Index/Model/Indexer/Config/SchemaLocator.php
 delete mode 100644 app/code/Magento/Index/Model/IndexerInterface.php
 delete mode 100644 app/code/Magento/Index/Model/Lock/Storage.php
 delete mode 100644 app/code/Magento/Index/Model/Observer.php
 delete mode 100644 app/code/Magento/Index/Model/Process.php
 delete mode 100644 app/code/Magento/Index/Model/Process/File.php
 delete mode 100644 app/code/Magento/Index/Model/Resource/Event.php
 delete mode 100644 app/code/Magento/Index/Model/Resource/Event/Collection.php
 delete mode 100644 app/code/Magento/Index/Model/Resource/Process.php
 delete mode 100644 app/code/Magento/Index/Model/Resource/Process/Collection.php
 delete mode 100644 app/code/Magento/Index/Model/Resource/Setup.php
 delete mode 100644 app/code/Magento/Index/Model/Shell.php
 delete mode 100644 app/code/Magento/Index/Model/System/Message/IndexOutdated.php
 delete mode 100644 app/code/Magento/Index/etc/events.xml
 delete mode 100644 app/code/Magento/Index/etc/indexers.xsd
 delete mode 100644 app/code/Magento/Index/i18n/de_DE.csv
 delete mode 100644 app/code/Magento/Index/i18n/en_US.csv
 delete mode 100644 app/code/Magento/Index/i18n/es_ES.csv
 delete mode 100644 app/code/Magento/Index/i18n/fr_FR.csv
 delete mode 100644 app/code/Magento/Index/i18n/nl_NL.csv
 delete mode 100644 app/code/Magento/Index/i18n/pt_BR.csv
 delete mode 100644 app/code/Magento/Index/i18n/zh_CN.csv
 delete mode 100644 app/code/Magento/Index/sql/index_setup/install-1.6.0.0.php
 delete mode 100644 app/code/Magento/Index/view/adminhtml/layout/adminhtml_process_edit.xml
 rename app/code/Magento/{Index => Indexer}/Model/Resource/AbstractResource.php (99%)
 rename app/code/Magento/LayeredNavigation/view/frontend/layout/{page_one_column.xml => 1column.xml} (100%)
 rename app/code/Magento/LayeredNavigation/view/frontend/layout/{page_two_columns_left.xml => 2columns-left.xml} (100%)
 rename app/code/Magento/LayeredNavigation/view/frontend/layout/{page_two_columns_right.xml => 2columns-right.xml} (100%)
 rename app/code/Magento/LayeredNavigation/view/frontend/layout/{page_three_columns.xml => 3columns.xml} (100%)
 rename app/code/Magento/Log/view/adminhtml/layout/{customer_online_index.xml => visitor_online_index.xml} (100%)
 create mode 100644 app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type.php
 create mode 100644 app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type/Price.php
 rename app/code/Magento/{Catalog/Block/Category/Widget/Link.php => Msrp/Block/Popup.php} (60%)
 rename app/code/Magento/{Rss/Block/AbstractBlock.php => Msrp/Block/Total.php} (54%)
 create mode 100644 app/code/Magento/Msrp/Helper/Data.php
 create mode 100644 app/code/Magento/Msrp/Model/Config.php
 rename setup/module/Magento/Config/src/Dom/NodeMergingConfig.php => app/code/Magento/Msrp/Model/Msrp.php (50%)
 rename app/code/Magento/{Sales => Msrp}/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php (81%)
 rename app/code/Magento/{Catalog/Model/Product/Attribute/Source/Msrp => Msrp/Model/Product/Attribute/Source}/Type.php (81%)
 rename app/code/Magento/{Catalog/Model/Product/Attribute/Source/Msrp => Msrp/Model/Product/Attribute/Source}/Type/Price.php (71%)
 create mode 100644 app/code/Magento/Msrp/Model/Product/Options.php
 rename app/code/Magento/{Sales/Model/Quote/Address/Total/Msrp.php => Msrp/Model/Quote/Address/Total.php} (68%)
 create mode 100644 app/code/Magento/Msrp/Plugin/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
 rename app/code/Magento/{Catalog => Msrp}/Pricing/Price/MsrpPrice.php (67%)
 rename app/code/Magento/{Catalog => Msrp}/Pricing/Price/MsrpPriceInterface.php (92%)
 create mode 100644 app/code/Magento/Msrp/composer.json
 rename app/code/Magento/{Catalog/data/catalog_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php => Msrp/data/msrp_setup/data-install-1.0.0.0.php} (67%)
 create mode 100644 app/code/Magento/Msrp/etc/adminhtml/di.xml
 create mode 100644 app/code/Magento/Msrp/etc/adminhtml/system.xml
 rename dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml => app/code/Magento/Msrp/etc/catalog_attributes.xml (82%)
 create mode 100644 app/code/Magento/Msrp/etc/config.xml
 create mode 100644 app/code/Magento/Msrp/etc/di.xml
 create mode 100644 app/code/Magento/Msrp/etc/frontend/events.xml
 rename app/code/Magento/{UrlRedirect => Msrp}/etc/module.xml (72%)
 create mode 100644 app/code/Magento/Msrp/etc/sales.xml
 create mode 100644 app/code/Magento/Msrp/view/base/layout/catalog_product_prices.xml
 rename app/code/Magento/{Catalog/view/base/templates/product/price/msrp_price.phtml => Msrp/view/base/templates/product/price/msrp.phtml} (72%)
 rename app/code/Magento/{Catalog => Msrp}/view/base/web/js/msrp.js (75%)
 rename app/code/Magento/{Rss => Msrp}/view/frontend/layout/catalog_category_view.xml (75%)
 create mode 100644 app/code/Magento/Msrp/view/frontend/layout/catalog_product_compare_index.xml
 create mode 100644 app/code/Magento/Msrp/view/frontend/layout/catalog_product_view.xml
 rename app/code/Magento/{Rss/view/adminhtml/layout/sales_order_grid_block.xml => Msrp/view/frontend/layout/catalog_product_view_type_downloadable.xml} (75%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/catalogsearch_advanced_result.xml (96%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/catalogsearch_result_index.xml (96%)
 rename app/code/Magento/{Rss/view/frontend/layout/rss_catalog_special.xml => Msrp/view/frontend/layout/checkout_cart_index.xml} (64%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/checkout_onepage_failure.xml (96%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/checkout_onepage_success.xml (96%)
 create mode 100644 app/code/Magento/Msrp/view/frontend/layout/default.xml
 rename app/code/Magento/{Catalog/view/frontend/layout/MAP_popup.xml => Msrp/view/frontend/layout/msrp_popup.xml} (90%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/review_product_list.xml (92%)
 rename app/code/Magento/{Catalog/view/frontend/layout/checkout_cart_index.xml => Msrp/view/frontend/layout/wishlist_index_configure_type_downloadable.xml} (84%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/wishlist_index_index.xml (92%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/wishlist_search_view.xml (92%)
 rename app/code/Magento/{Catalog => Msrp}/view/frontend/layout/wishlist_shared_index.xml (92%)
 rename lib/web/requirejs-config.js => app/code/Magento/Msrp/view/frontend/templates/cart/subtotal.phtml (82%)
 create mode 100644 app/code/Magento/Msrp/view/frontend/templates/cart/totals.phtml
 rename app/code/Magento/{Catalog/view/frontend/templates/msrp => Msrp/view/frontend/templates}/popup.phtml (84%)
 rename app/code/Magento/{Wishlist => Msrp}/view/frontend/templates/render/item/price_msrp_item.phtml (99%)
 rename app/code/Magento/{Wishlist => Msrp}/view/frontend/templates/render/item/price_msrp_rss.phtml (92%)
 mode change 100755 => 100644 app/code/Magento/Multishipping/Controller/Checkout.php
 mode change 100755 => 100644 app/code/Magento/PageCache/Model/App/FrontController/BuiltinPlugin.php
 mode change 100755 => 100644 app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php
 create mode 100644 app/code/Magento/Review/Block/Adminhtml/Rss.php
 create mode 100644 app/code/Magento/Review/Block/Adminhtml/Rss/Grid/Link.php
 create mode 100644 app/code/Magento/Review/Model/Rss.php
 create mode 100644 app/code/Magento/Review/view/adminhtml/layout/review_product_index.xml
 create mode 100644 app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/AbstractCatalog.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/Category.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/NewCatalog.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/NotifyStock.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/Review.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/Salesrule.php
 delete mode 100644 app/code/Magento/Rss/Block/Catalog/Special.php
 create mode 100644 app/code/Magento/Rss/Block/Feeds.php
 delete mode 100644 app/code/Magento/Rss/Block/ListBlock.php
 delete mode 100644 app/code/Magento/Rss/Block/Order/NewOrder.php
 delete mode 100644 app/code/Magento/Rss/Block/Order/Status.php
 create mode 100644 app/code/Magento/Rss/Controller/Adminhtml/Feed.php
 rename app/code/Magento/Rss/Controller/Adminhtml/{Catalog/Review.php => Feed/Index.php} (52%)
 delete mode 100644 app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
 rename app/code/Magento/Rss/Controller/{Catalog.php => Feed.php} (55%)
 rename app/code/Magento/Rss/Controller/{Adminhtml/Catalog/Notifystock.php => Feed/Index.php} (53%)
 delete mode 100644 app/code/Magento/Rss/Helper/Order.php
 create mode 100644 app/code/Magento/Rss/Model/RssManager.php
 create mode 100644 app/code/Magento/Rss/Model/UrlBuilder.php
 rename app/code/Magento/{Index/etc/adminhtml/menu.xml => Rss/etc/di.xml} (76%)
 delete mode 100644 app/code/Magento/Rss/view/frontend/layout/rss_catalog_category.xml
 delete mode 100644 app/code/Magento/Rss/view/frontend/layout/rss_catalog_new.xml
 create mode 100644 app/code/Magento/Rss/view/frontend/templates/feeds.phtml
 delete mode 100644 app/code/Magento/Rss/view/frontend/templates/list.phtml
 rename app/code/Magento/{Rss/Block => Sales/Block/Adminhtml}/Order/Details.php (89%)
 rename app/code/Magento/{Rss/Block/Order/Info/Buttons/Rss.php => Sales/Block/Adminhtml/Rss/Order/Grid/Link.php} (57%)
 create mode 100644 app/code/Magento/Sales/Block/Order/Info/Buttons/Rss.php
 create mode 100644 app/code/Magento/Sales/Model/OrderRepository/Plugin/Authorization.php
 rename app/code/Magento/{Rss/Model/Resource/Order.php => Sales/Model/Resource/Order/Rss/OrderStatus.php} (84%)
 create mode 100644 app/code/Magento/Sales/Model/Rss/NewOrder.php
 create mode 100644 app/code/Magento/Sales/Model/Rss/OrderStatus.php
 mode change 100755 => 100644 app/code/Magento/Sales/Model/Service/Quote.php
 rename app/code/Magento/{Index => Sales}/etc/adminhtml/di.xml (84%)
 rename app/code/Magento/{Rss/view/frontend => Sales/view/adminhtml}/templates/order/details.phtml (100%)
 create mode 100644 app/code/Magento/Sales/view/adminhtml/templates/rss/order/grid/link.phtml
 create mode 100644 app/code/Magento/Sales/view/frontend/templates/order/info/buttons/rss.phtml
 create mode 100644 app/code/Magento/SalesRule/Block/Rss/Discounts.php
 create mode 100644 app/code/Magento/SalesRule/Model/Rss/Discounts.php
 rename setup/module/Magento/Config/src/Dom/ValidationException.php => app/code/Magento/Store/Ui/DataType/Store.php (84%)
 rename app/code/Magento/{Rss/view/frontend/layout/rss_catalog_salesrule.xml => Store/view/base/layout/ui_components.xml} (69%)
 rename app/code/Magento/{ConfigurableProduct/view/frontend => Store/view/base}/requirejs-config.js (86%)
 create mode 100644 app/code/Magento/Store/view/base/web/js/listing/filter/store.js
 create mode 100644 app/code/Magento/Store/view/base/web/templates/filter/store.html
 create mode 100644 app/code/Magento/Store/view/base/web/templates/filter/store/item.html
 delete mode 100644 app/code/Magento/Tax/view/base/templates/pricing/adjustment/downloadable.phtml
 delete mode 100644 app/code/Magento/Theme/Block/Html.php
 delete mode 100644 app/code/Magento/Theme/Block/Html/Head.php
 create mode 100644 app/code/Magento/Theme/Model/Favicon/Favicon.php
 delete mode 100644 app/code/Magento/Theme/view/adminhtml/templates/empty.phtml
 delete mode 100644 app/code/Magento/Theme/view/frontend/layout/print.xml
 delete mode 100644 app/code/Magento/Theme/view/frontend/templates/html/head.phtml
 create mode 100644 app/code/Magento/Theme/view/frontend/templates/js/require_js.phtml
 delete mode 100644 app/code/Magento/Theme/view/frontend/templates/popup.phtml
 delete mode 100644 app/code/Magento/Theme/view/frontend/templates/print.phtml
 create mode 100644 app/code/Magento/Translation/view/base/templates/translate.phtml
 create mode 100644 app/code/Magento/Ui/AbstractView.php
 create mode 100644 app/code/Magento/Ui/Configuration.php
 create mode 100644 app/code/Magento/Ui/ConfigurationStorage.php
 rename app/code/Magento/{Index/Block/Adminhtml/Process/Grid/Massaction.php => Ui/ContentType/Builders/ConfigJson.php} (62%)
 create mode 100644 app/code/Magento/Ui/ContentType/Builders/ConfigStorageJson.php
 create mode 100644 app/code/Magento/Ui/ContentType/ContentTypeFactory.php
 create mode 100644 app/code/Magento/Ui/ContentType/ContentTypeInterface.php
 create mode 100644 app/code/Magento/Ui/ContentType/Html.php
 create mode 100644 app/code/Magento/Ui/ContentType/Json.php
 create mode 100644 app/code/Magento/Ui/ContentType/Xml.php
 create mode 100644 app/code/Magento/Ui/Context/DataProvider.php
 rename dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php => app/code/Magento/Ui/Control/Action.php (81%)
 create mode 100644 app/code/Magento/Ui/Control/ActionPool.php
 create mode 100644 app/code/Magento/Ui/Control/ActionPoolInterface.php
 create mode 100644 app/code/Magento/Ui/Control/Button.php
 create mode 100644 app/code/Magento/Ui/Control/Container.php
 create mode 100644 app/code/Magento/Ui/Control/ControlInterface.php
 create mode 100644 app/code/Magento/Ui/Control/Item.php
 create mode 100644 app/code/Magento/Ui/Control/Link.php
 rename app/code/Magento/{Rss/Controller/Order/Status.php => Ui/Controller/Adminhtml/Listing/Ajax.php} (50%)
 create mode 100644 app/code/Magento/Ui/DataProvider/Options/Store.php
 rename app/code/Magento/{UrlRedirect/Model/OptionProvider.php => Ui/DataProvider/OptionsFactory.php} (52%)
 rename app/code/Magento/{Theme/Block/Html/Head/AssetBlockInterface.php => Ui/DataProvider/OptionsInterface.php} (81%)
 create mode 100644 app/code/Magento/Ui/DataProvider/Row/Store.php
 rename app/code/Magento/{Rss/Controller/Catalog/Salesrule.php => Ui/DataProvider/RowInterface.php} (81%)
 create mode 100644 app/code/Magento/Ui/DataProvider/RowPool.php
 rename app/code/Magento/{Theme/Block/Html/Head/Link.php => Ui/DataType/AbstractDataType.php} (68%)
 create mode 100644 app/code/Magento/Ui/DataType/Boolean.php
 create mode 100644 app/code/Magento/Ui/DataType/DataTypeInterface.php
 create mode 100644 app/code/Magento/Ui/DataType/Date.php
 create mode 100644 app/code/Magento/Ui/DataType/Media.php
 create mode 100644 app/code/Magento/Ui/DataType/Number.php
 create mode 100644 app/code/Magento/Ui/DataType/Password.php
 create mode 100644 app/code/Magento/Ui/DataType/Text.php
 rename app/code/Magento/{UrlRedirect/Service/V1/UrlSaveInterface.php => Ui/Filter/FilterInterface.php} (77%)
 create mode 100644 app/code/Magento/Ui/Filter/FilterPool.php
 create mode 100644 app/code/Magento/Ui/Filter/Type/Date.php
 rename app/code/Magento/{Theme/Block/Html/Head/Script.php => Ui/Filter/Type/Input.php} (69%)
 rename app/code/Magento/{Catalog/Model/Category/Attribute/Backend/Urlkey.php => Ui/Filter/Type/Range.php} (56%)
 rename app/code/Magento/{Theme/Block/Html/Head/Css.php => Ui/Filter/Type/Select.php} (70%)
 rename app/code/Magento/{Index/App/Shell/ErrorHandler.php => Ui/Filter/Type/Store.php} (76%)
 create mode 100644 app/code/Magento/Ui/Filter/View.php
 create mode 100644 app/code/Magento/Ui/FilterPool/View.php
 rename app/code/Magento/{Customer/Model/Resource/Form/Attribute/CollectionFactory.php => Ui/Form/Field.php} (62%)
 rename app/code/Magento/{Index/Model/Process/FileFactory.php => Ui/FormElement/AbstractFormElement.php} (58%)
 create mode 100644 app/code/Magento/Ui/FormElement/Checkbox.php
 create mode 100644 app/code/Magento/Ui/FormElement/ElementInterface.php
 rename app/code/Magento/{Index/Controller/Adminhtml/Process/ReindexAll.php => Ui/FormElement/Input.php} (79%)
 rename app/code/Magento/{Rss/Controller/Catalog/NewAction.php => Ui/FormElement/Radio.php} (83%)
 rename app/code/Magento/{Rss/Controller/Catalog/Special.php => Ui/FormElement/Range.php} (83%)
 create mode 100644 app/code/Magento/Ui/FormElement/Select.php
 create mode 100644 app/code/Magento/Ui/FormElement/Textarea.php
 create mode 100644 app/code/Magento/Ui/Listing/View.php
 create mode 100644 app/code/Magento/Ui/ListingContainer/Massaction/View.php
 create mode 100644 app/code/Magento/Ui/Paging/View.php
 create mode 100644 app/code/Magento/Ui/Search/View.php
 create mode 100644 app/code/Magento/Ui/Sorting/View.php
 rename app/code/Magento/{Index => Ui}/composer.json (51%)
 rename app/code/Magento/{UrlRedirect => Ui}/etc/adminhtml/routes.xml (91%)
 create mode 100644 app/code/Magento/Ui/etc/di.xml
 rename app/code/Magento/{Index => Ui}/etc/module.xml (88%)
 create mode 100644 app/code/Magento/Ui/view/base/layout/default.xml
 create mode 100644 app/code/Magento/Ui/view/base/layout/ui_components.xml
 create mode 100644 app/code/Magento/Ui/view/base/requirejs-config.js
 create mode 100644 app/code/Magento/Ui/view/base/templates/context/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/control/action/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/control/button/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/boolean/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/date/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/media/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/number/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/password/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/data_type/text/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/content.phtml
 rename app/code/Magento/{UrlRedirect/view/adminhtml/templates/edit.phtml => Ui/view/base/templates/filter/default.phtml} (71%)
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/date/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/date/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/input/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/input/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/range/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/range/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/select/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter/type/select/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/checkbox/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/checkbox/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/input/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/input/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/radio/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/radio/label.phtml
 rename app/code/Magento/{Backend/view/adminhtml/templates/urlrewrite/categories.phtml => Ui/view/base/templates/form_element/range/content.phtml} (54%)
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/range/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/select/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/select/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/textarea/content.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/form_element/textarea/label.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/label/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/paging/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/templates/sorting/default.phtml
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/class.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/component.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/events.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/bind/datepicker.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/bind/scope.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/bind/stop_propagation.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/ko/template/observable_source.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/loader.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/spinner.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/storage/index.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/lib/utils.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/date.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/input.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/range.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/filter/select.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/grid.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/massaction.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/paging.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/sorting.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/utils/data_provider.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/utils/provider.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/utils/request_builder.js
 create mode 100644 app/code/Magento/Ui/view/base/web/js/listing/utils/rest.js
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/filter.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html
 rename app/code/Magento/{Reports/view/frontend/templates/product_compared.phtml => Ui/view/base/web/templates/filter/filter_range.html} (50%)
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/massaction.html
 rename app/code/Magento/{Reports/view/frontend/templates/product_viewed.phtml => Ui/view/base/web/templates/pageactions.html} (52%)
 create mode 100644 app/code/Magento/Ui/view/base/web/templates/pagination.html
 delete mode 100644 app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php
 delete mode 100644 app/code/Magento/UrlRedirect/Controller/Router.php
 delete mode 100644 app/code/Magento/UrlRedirect/Helper/UrlRewrite.php
 delete mode 100644 app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php
 delete mode 100644 app/code/Magento/UrlRedirect/Model/Storage/Db.php
 delete mode 100644 app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php
 delete mode 100644 app/code/Magento/UrlRedirect/Service/V1/UrlManager.php
 delete mode 100644 app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php
 delete mode 100644 app/code/Magento/UrlRedirect/composer.json
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/de_DE.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/en_US.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/es_ES.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/fr_FR.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/nl_NL.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/pt_BR.csv
 delete mode 100644 app/code/Magento/UrlRedirect/i18n/zh_CN.csv
 delete mode 100644 app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php
 delete mode 100644 app/code/Magento/UrlRewrite/App/Request/RewriteService.php
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Catalog/Category/Edit.php (83%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Catalog/Category/Tree.php (95%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Catalog/Edit/Form.php (72%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Catalog/Product/Edit.php (83%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Catalog/Product/Grid.php (88%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Cms/Page/Edit.php (83%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Cms/Page/Edit/Form.php (75%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Cms/Page/Grid.php (98%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Edit.php (87%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Edit/Form.php (91%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/GridContainer.php (88%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Link.php (97%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Block/Selector.php (94%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite.php => UrlRewrite/Controller/Adminhtml/Url/Rewrite.php} (71%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/CategoriesJson.php (83%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/CmsPageGrid.php (81%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/Delete.php (92%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/Edit.php (80%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/Index.php (81%)
 rename app/code/Magento/{Backend/Controller/Adminhtml/Urlrewrite => UrlRewrite/Controller/Adminhtml/Url/Rewrite}/ProductGrid.php (81%)
 create mode 100644 app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
 create mode 100644 app/code/Magento/UrlRewrite/Controller/Router.php
 rename dev/tests/integration/testsuite/Magento/Backend/AdminConfigTest.php => app/code/Magento/UrlRewrite/Model/OptionProvider.php (64%)
 delete mode 100644 app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite/Collection.php
 rename app/code/Magento/{UrlRedirect/Model/Resource/UrlRedirect/Collection.php => UrlRewrite/Model/Resource/UrlRewriteCollection.php} (86%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Model/Storage/AbstractStorage.php (57%)
 create mode 100644 app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
 create mode 100644 app/code/Magento/UrlRewrite/Model/Storage/DuplicateEntryException.php
 create mode 100644 app/code/Magento/UrlRewrite/Model/StorageInterface.php
 create mode 100644 app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
 rename app/code/Magento/{UrlRedirect/Model/UrlRedirect.php => UrlRewrite/Model/UrlPersistInterface.php} (66%)
 delete mode 100644 app/code/Magento/UrlRewrite/Model/UrlRewrite/OptionProvider.php
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Service/V1/Data/UrlRewrite.php (74%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/Service/V1/Data/UrlRewriteBuilder.php (70%)
 rename app/code/Magento/{UrlRedirect/etc => UrlRewrite/etc/adminhtml}/acl.xml (86%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/etc/adminhtml/menu.xml (85%)
 rename app/code/Magento/{Index => UrlRewrite}/etc/adminhtml/routes.xml (94%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/etc/config.xml (100%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/etc/di.xml (75%)
 rename app/code/Magento/{UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml => UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml} (90%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/view/adminhtml/templates/categories.phtml (96%)
 rename app/code/Magento/{Backend/view/adminhtml/templates/urlrewrite => UrlRewrite/view/adminhtml/templates}/edit.phtml (94%)
 rename app/code/Magento/{UrlRedirect => UrlRewrite}/view/adminhtml/templates/selector.phtml (76%)
 delete mode 100644 app/code/Magento/Wishlist/Block/Rss.php
 rename app/code/Magento/Wishlist/Block/{Share/Email/Rss.php => Rss/EmailLink.php} (82%)
 create mode 100644 app/code/Magento/Wishlist/Block/Rss/Link.php
 delete mode 100644 app/code/Magento/Wishlist/Controller/Index/Rss.php
 create mode 100644 app/code/Magento/Wishlist/Model/Rss/Wishlist.php
 delete mode 100644 app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_rss.xml
 rename app/code/Magento/Wishlist/view/frontend/templates/{email/rss.phtml => rss/email.phtml} (75%)
 rename app/code/Magento/{Rss/view/frontend/templates/order/info/buttons/rss.phtml => Wishlist/view/frontend/templates/rss/wishlist.phtml} (74%)
 create mode 100644 app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
 create mode 100644 app/design/frontend/Magento/blank/Magento_Theme/web/css/source/collapsible_navigation.less
 create mode 100644 app/design/frontend/Magento/blank/Magento_Weee/web/css/source/module.less
 delete mode 100644 dev/shell/newindexer.php
 create mode 100644 dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/GlobalSearchElement.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchCustomerName.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchNoRecordsFound.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchOrderId.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchProductName.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml
 rename dev/tests/functional/tests/app/Magento/{UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php => Backend/Test/Fixture/GlobalSearch/Query.php} (52%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest/test.csv
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/etc/constraint.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/etc/fixture.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest/test.csv
 rename dev/tests/functional/tests/app/Magento/{Index/Test/Block/Adminhtml/Process/Index.php => Checkout/Test/Block/Cart/CartEmpty.php} (63%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php
 create mode 100644 dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
 create mode 100644 dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
 rename app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Enabled.php => dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest.php (57%)
 create mode 100644 dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest/test.csv
 delete mode 100644 dev/tests/functional/tests/app/Magento/Index/Test/Page/ProcessList.php
 rename dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/{Product/Viewed/Filter.php => AbstractFilter.php} (52%)
 rename app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php => dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.php (74%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.xml
 rename app/code/Magento/Rss/Controller/Catalog/Category.php => dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Grid.php (80%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Grid.php
 rename dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/{Product => Review/Products}/Viewed/Action.php (95%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.php
 rename dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/{Product => Review/Products}/Viewed/Filter.xml (100%)
 rename dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/{Product => Review/Products}/Viewed/ProductGrid.php (80%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Shopcart/Abandoned/Grid.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AbstractAssertCustomerOrderReportResult.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertAbandonedCartCustomerInfoResult.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderCountReportResult.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderTotalReportResult.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/AbandonedCarts.xml
 delete mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/Bestsellers.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerOrdersReport.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerTotalsReport.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest/test.csv
 delete mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php
 delete mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest/test.csv
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest/test.csv
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest/test.csv
 rename dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/{UrlrewriteEdit.xml => UrlRewriteEdit.xml} (94%)
 rename dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/{UrlrewriteIndex.xml => UrlRewriteIndex.xml} (96%)
 rename app/code/Magento/Index/Model/Indexer/Factory.php => dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php (60%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.xml
 rename dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/{AssertProductIsAbsentInWishlist.php => AssertProductsIsAbsentInWishlist.php} (80%)
 create mode 100644 dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertWishlistIsEmpty.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest/test.csv
 delete mode 100644 dev/tests/integration/testsuite/Magento/Backend/Block/Page/HeadTest.php
 rename dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/{UrlrewriteTest.php => UrlRewriteTest.php} (92%)
 rename dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/{ => Cookie}/DomainTest.php (81%)
 create mode 100644 dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/UrlTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/categories.php
 create mode 100644 dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_simple.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Core/_files/url_rewrite.php
 create mode 100644 dev/tests/integration/testsuite/Magento/CurrencySymbol/Model/System/CurrencysymbolTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_address_custom_attribute.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_custom_attribute.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Directory/Model/ObserverTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieDomainValidatorTest.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieLifetimeValidatorTest.php
 rename dev/tests/integration/testsuite/Magento/{Rss/Controller/IndexTest.php => Framework/Session/Config/Validator/CookiePathValidatorTest.php} (50%)
 rename dev/tests/integration/testsuite/Magento/{Rss/Block/Order/StatusTest.php => Framework/ValidatorFactoryTest.php} (57%)
 delete mode 100644 dev/tests/integration/testsuite/Magento/Index/Model/Process/FileTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Index/Model/ProcessTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Index/Model/ShellTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Rss/Controller/CatalogTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Rss/Controller/OrderTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/NewIndexerConfigFilesTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Theme/Block/Html/HeadTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Theme/Block/HtmlTest.php
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Catalog/Category/EditTest.php (83%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Catalog/Category/TreeTest.php (82%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Catalog/Edit/FormTest.php (79%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Catalog/Product/EditTest.php (86%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Catalog/Product/GridTest.php (89%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Cms/Page/Edit/FormTest.php (86%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Cms/Page/EditTest.php (83%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Cms/Page/GridTest.php (87%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/Edit/FormTest.php (84%)
 rename dev/tests/integration/testsuite/Magento/{Backend/Block/Urlrewrite => UrlRewrite/Block}/EditTest.php (89%)
 delete mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
 delete mode 100644 dev/tests/integration/testsuite/Magento/Wishlist/Block/RssTest.php
 create mode 100644 dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js
 rename app/code/Magento/Index/etc/acl.xml => dev/tests/js/testsuite/lib/ko/datepicker/index.html (57%)
 create mode 100644 dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/composer.txt
 create mode 100644 dev/tests/unit/filename
 create mode 100644 dev/tests/unit/filename.csv
 create mode 100644 dev/tests/unit/filename.invalid_type
 create mode 100644 dev/tests/unit/framework/Magento/Test/BaseTestCase.php
 create mode 100644 dev/tests/unit/testsuite/Magento/AdminNotification/Model/FeedTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Backend/Block/UrlrewriteTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Backend/Block/Widget/Grid/Column/Renderer/ConcatTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Backend/Block/Widget/GridTest.php
 rename dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/{ => Cookie}/DomainTest.php (65%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
 rename dev/tests/unit/testsuite/Magento/Backend/{ => Model/Session}/AdminConfigTest.php (60%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/Grid/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/NotifyStockTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Category/Rss/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/CategoryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/NewProductsTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/SpecialTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Block/Widget/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/UrlkeyTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/CategoryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NewProductsTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NotifyStockTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/SpecialTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Catalog/_files/eav_attributes_data.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/FullTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/ReaderPluginTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/RequestGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProviderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ObjectRegistryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlPathGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/_files/categoryUrlRewritesDataProvider.php
 create mode 100644 dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Service/V1/StoreViewServiceTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Cms/Model/Page/UrlrewriteTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/DataTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/App/Router/BaseTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/App/Router/NoRouteHandlerTest.php
 rename app/code/Magento/Backend/Block/Urlrewrite/Link.php => dev/tests/unit/testsuite/Magento/Core/Controller/Index/IndexTest.php (62%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Controller/Index/NoCookiesTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Controller/Index/NotFoundTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Helper/File/MediaTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Helper/File/Storage/DatabaseTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Helper/File/StorageTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Helper/UrlTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Model/App/EmulationTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Model/Asset/ConfigTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Core/Model/Asset/Plugin/CleanMergedJsCssTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Directory/Model/Config/Source/AllRegionTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Directory/Model/ObserverTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/App/FactoryStub.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/App/ObjectManagerFactoryTest.php
 rename dev/tests/unit/testsuite/Magento/{Index/Model/Config/_files/valid_indexers.xml => Framework/App/_files/app/etc/di.xml} (81%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Config/DataTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/WildcardTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/Request/BinderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/Request/BuilderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/Request/CleanerTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Framework/Search/RequestFactoryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/ValidatorFactoryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/GeneratorTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/ReaderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/StructureTest.php
 rename app/code/Magento/Rss/view/adminhtml/layout/rss_order_new.xml => dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_body.xml (77%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_head.xml
 rename app/code/Magento/Rss/view/frontend/layout/rss_order_status.xml => dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_html.xml (77%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/ConfigTest.php
 rename app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_notifystock.xml => dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_one.xml (73%)
 rename app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_review.xml => dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_two.xml (73%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Framework/View/Result/PageTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ConditionTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/App/IndexerTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/App/ShellTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Config/XsdTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlArray.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlMergedArray.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers_merged.xml
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/EventRepositoryTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/ConverterTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/SchemaLocatorTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Indexer/ConfigTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Lock/StorageTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/Process/FileFactoryTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Index/Model/ProcessTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrpTest.php
 rename dev/tests/unit/testsuite/Magento/{Catalog/Model/Product/Attribute/Source/Msrp => Msrp/Model/Product/Attribute/Source}/Type/PriceTest.php (90%)
 rename dev/tests/unit/testsuite/Magento/{Catalog => Msrp}/Pricing/Price/MsrpPriceTest.php (89%)
 create mode 100644 dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/Rss/Grid/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/RssTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Review/Model/RssTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/AbstractCatalogTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/CategoryTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/NewCatalogTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/ReviewTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/SpecialTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/FeedsTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Rss/Block/Order/Info/Buttons/RssTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Rss/Controller/Adminhtml/Feed/IndexTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Rss/Controller/Feed/IndexTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Rss/Model/RssManagerTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Rss/Model/UrlBuilderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Block/Order/Info/Buttons/RssTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/EmailTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Model/Rss/NewOrderTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Model/Rss/OrderStatusTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/SalesRule/Block/Rss/DiscountsTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/SalesRule/Model/Rss/DiscountsTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Sitemap/Helper/DataTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Store/Block/SwitchTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Store/Block/SwitcherTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/CssTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/LinkTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/ScriptTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/Theme/Block/Html/HeadTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigJsonTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigStorageJsonTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/ContentType/ContentTypeFactoryTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/ContentType/HtmlTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/ListingContainer/Massaction/ViewTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/Paging/ViewTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Ui/Sorting/ViewTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/App/Request/RewriteServiceTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Controller/RouterTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Resource/UrlRewriteCollectionTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/AbstractStorageTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/DbStorageTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/OptionProviderTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/TypeProviderTest.php
 delete mode 100644 dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Wishlist/Block/Rss/LinkTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php
 rename dev/tests/unit/testsuite/Magento/Wishlist/{Block/RssTest.php => Model/Rss/WishlistTest.php} (56%)
 create mode 100644 lib/internal/Magento/Framework/App/Rss/DataProviderInterface.php
 rename app/code/Magento/Index/Model/Indexer/ConfigInterface.php => lib/internal/Magento/Framework/App/Rss/RssManagerInterface.php (73%)
 rename app/code/Magento/Catalog/Model/Config/Backend/Seo/Product.php => lib/internal/Magento/Framework/App/Rss/UrlBuilder.php (77%)
 rename app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php => lib/internal/Magento/Framework/App/Rss/UrlBuilderInterface.php (78%)
 create mode 100644 lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php
 create mode 100644 lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php
 create mode 100644 lib/internal/Magento/Framework/Search/Request/Binder.php
 rename lib/internal/Magento/Framework/Search/{RequestFactory.php => Request/Builder.php} (52%)
 create mode 100644 lib/internal/Magento/Framework/Search/Request/Cleaner.php
 rename app/code/Magento/Index/Model/Indexer/Config/Reader.php => lib/internal/Magento/Framework/Search/Request/Config/FilesystemReader.php (70%)
 rename app/code/Magento/Index/Block/Adminhtml/Process/Edit/Form.php => lib/internal/Magento/Framework/Search/Request/Filter/Wildcard.php (57%)
 rename app/code/Magento/Backend/Model/Config/Backend/Domain.php => lib/internal/Magento/Framework/Session/Config/Validator/CookieDomainValidator.php (65%)
 create mode 100644 lib/internal/Magento/Framework/Session/Config/Validator/CookieLifetimeValidator.php
 rename app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tabs.php => lib/internal/Magento/Framework/Session/Config/Validator/CookiePathValidator.php (71%)
 rename app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php => lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php (76%)
 rename app/code/Magento/Theme/Block/Html/Body.php => lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php (55%)
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
 create mode 100644 lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
 create mode 100644 lib/internal/Magento/Framework/View/Page/Config/Generator.php
 create mode 100644 lib/internal/Magento/Framework/View/Page/Config/Reader.php
 create mode 100644 lib/internal/Magento/Framework/View/Page/Config/Renderer.php
 create mode 100644 lib/internal/Magento/Framework/View/Page/Config/Structure.php
 create mode 100644 lib/internal/Magento/Framework/View/Page/FaviconInterface.php
 create mode 100644 lib/web/date-format-normalizer.js
 create mode 100644 lib/web/jquery/autocomplete/autocomplete.css
 create mode 100644 lib/web/jquery/autocomplete/jquery.autocomplete.js
 delete mode 100644 lib/web/jquery/bootstrap-carousel/css/bootstrap-carousel.css
 delete mode 100644 lib/web/jquery/bootstrap-carousel/jquery.bootstrap-carousel.js
 delete mode 100644 lib/web/jquery/bootstrap-carousel/jquery.bootstrap-transition.js
 create mode 100644 lib/web/ko/ko.js
 create mode 100644 lib/web/mage/apply/main.js
 create mode 100644 lib/web/mage/apply/registry.js
 create mode 100644 lib/web/moment.js
 create mode 100644 lib/web/requirejs/text.js
 delete mode 100644 setup/module/Magento/Config/src/Dom.php
 delete mode 100644 setup/module/Magento/Config/src/Dom/NodePathMatcher.php
 delete mode 100644 setup/module/Magento/Framework/Module.php
 delete mode 100644 setup/module/Magento/Framework/src/DB/ExpressionConverter.php
 delete mode 100644 setup/module/Magento/Framework/src/Math/Random.php
 delete mode 100644 setup/module/Magento/Locale/Module.php
 delete mode 100644 setup/module/Magento/Module/Module.php
 delete mode 100644 setup/module/Magento/Module/config/di.config.php
 delete mode 100644 setup/module/Magento/Module/config/module.config.php
 delete mode 100644 setup/module/Magento/Module/src/Setup/Config.php
 create mode 100644 setup/module/Magento/Setup/src/Controller/ConsoleController.php
 rename dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/UrlTest.php => setup/module/Magento/Setup/src/Controller/Install/ClearProgressController.php (60%)
 rename setup/module/Magento/{Framework/src => Setup/src/Framework}/DB/Adapter/AdapterInterface.php (94%)
 rename setup/module/Magento/{Framework/src => Setup/src/Framework}/DB/Adapter/Pdo/Mysql.php (98%)
 rename setup/module/Magento/{Framework/src => Setup/src/Framework}/DB/Ddl/Table.php (99%)
 rename setup/module/Magento/{Framework/src => Setup/src/Framework}/DB/Ddl/Trigger.php (99%)
 create mode 100644 setup/module/Magento/Setup/src/Model/ConsoleLogger.php
 create mode 100644 setup/module/Magento/Setup/src/Model/Installer.php
 create mode 100644 setup/module/Magento/Setup/src/Model/InstallerFactory.php
 rename setup/module/Magento/{Composer/Module.php => Setup/src/Model/LoggerInterface.php} (62%)
 create mode 100644 setup/module/Magento/Setup/src/Model/UserConfigurationData.php
 rename setup/module/Magento/Setup/src/Model/{Logger.php => WebLogger.php} (59%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Converter/Dom.php (99%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Dependency/Manager.php (99%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Dependency/ManagerInterface.php (97%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Dir.php (96%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/FileResolver.php (99%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/ModuleList.php (95%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/ModuleListInterface.php (97%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Reader/Filesystem.php (93%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Resource/Resource.php (91%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/ResourceInterface.php (97%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/SchemaLocator.php (98%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Setup.php (50%)
 create mode 100644 setup/module/Magento/Setup/src/Module/Setup/Config.php
 create mode 100644 setup/module/Magento/Setup/src/Module/Setup/ConfigFactory.php
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Setup/Connection/Adapter.php (70%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Setup/Connection/AdapterInterface.php (89%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Setup/FileResolver.php (64%)
 rename setup/module/Magento/{Module/src => Setup/src/Module}/SetupFactory.php (52%)
 create mode 100644 setup/module/Magento/Setup/src/Module/SetupModule.php
 rename setup/module/Magento/{Module/src => Setup/src/Module}/Updater/SetupInterface.php (82%)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f687b47a222..1538aca81b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,102 @@
+0.1.0-alpha97
+=============
+ * Various improvements:
+   * Implemented a general way of using RSS module
+   * Created a cron job in the Customer module for cleaning the customer_visitor table
+   * Added a warning message to the Use HTTP Only option in the Admin panel
+   * Implemented the Grid component in the Magento UI Library
+   * Reimplemented the URL Rewrites functionality in the new UrlRedirect module
+ * Framework improvements:
+   * Added the ability to install Magento 2 using CLI
+   * Aggregated Magento installation and upgrade into one tool
+   * Refactored CustomerService REST WebApi to be more RESTful
+   * Increased unit and integration test coverage
+   * Moved page asset management to page configuration API, and eliminated the \Magento\Theme\Block\Html\Head block
+   * Eliminated the Root, Html and Title blocks
+ * Themes update:
+   * Removed widgets from the default Magento installation
+ * Fixed bugs:
+   * Fixed an issue with wishlist creation for non-registered customer
+   * Fixed an issue with Google Mapping where Condition did not show correct value
+   * Fixed an issue  where there were too many notifications for admin user by default
+   * Fixed a Daylight Savings Time calculation error
+   * Fixed an issue where default cookie path and lifetime were not validated prior to saving
+   * Fixed an issue where current admin password was not required for resetting admin password
+   * Fixed an issue where custom customer attribute or customer address attribute was not accessible when ‘custom_attribute’ is used as the attribute code
+   * Fixed an issue where integration entity could not be deleted after being searched in grid
+   * Fixed an issue where invalid parameter value was shown in SOAP
+   * Fixed an issue where exception was thrown for Array to String conversion in SOAP
+   * Fixed an issue where exception was thrown due to invalid argument supplied for foreach() statement in REST
+   * Fixed an issue where admin tax notifications did not appear correctly in the System Messages dialog box
+   * Fixed an issue where tax details were missing when viewing order in the Admin panel
+   * Fixed an issue where styles for the storefront store selector were absent
+   * Fixed an issue where customer got 404 page when switching store views on the product page of a product with different URL keys in different store views
+   * Fixed an issue where the Add To Cart button in the MAP pop-up did not work for configurable and bundle products
+   * Fixed an issue where for specifying options for configurable product was absent after adding a product from the MAP pop-up
+   * Fixed an issue where a fatal error was thrown after selecting shipping method on PayPal Express Checkout
+   * Fixed an issue with sending invoice email
+   * Fixed an issue where integration tests failed with a fatal error
+   * Fixed an issue where credit memo entry was not created after performing a refund for an order
+   * Fixed an issue where categories layout for widgets did not work
+   * Fixed an issue where opening a page restricted by ACL lead to blank page instead of the Access Denied page
+   * Fixed an issue where a blank page was displayed instead of the using the Advanced Search result
+   * Fixed an issue where the "Please wait" spinner was absent on Ajax requests for order creation in the Admin panel
+   * Fixed an issue with the main navigation menu location on the page
+ * Modularity:
+   * Implemented the automatic applying of the MAP policy
+ * Indexers:
+   * Eliminated the old Magento_Index module
+ * Search library
+   * Added wildcards filter
+   * Eliminated unused queries and filters
+   * Added IN to Term filter
+   * Moved the "value" attribute from <match> to <query> for the Match query
+   * Refactored the usage of negation
+   * Implemented Request Builder
+ * CatalogSearch adapter
+   * Pluginized adding attribute to search index
+   * Merged base declaration with searchable attributes
+ * Added the following “Setup CLI tools” in the setup folder
+   * Deployment Configuration Tool
+   * Schema Setup and Update Tool
+   * DB Data Update Tool
+   * Admin User Setup Tool
+   * User Configuration Tool
+   * Installation Tool
+   * Update Tool
+ * GitHub requests:
+   * [#615] (https://github.com/magento/magento2/issues/615) -- Use info as object in checkout_cart_update_items_before
+   * [#659] (https://github.com/magento/magento2/issues/659) -- Recently viewed products sidebar issue
+   * [#660] (https://github.com/magento/magento2/issues/660) -- RSS global setting
+   * [#663] (https://github.com/magento/magento2/issues/663) -- session.save_path not valid
+   * [#445] (https://github.com/magento/magento2/issues/445) -- use of registry in Magento\Tax\Helper\Data
+   * [#646] (https://github.com/magento/magento2/issues/646) -- Fixed flat category indexer bug
+   * [#643] (https://github.com/magento/magento2/issues/643) -- Configurable Products Performance
+   * [#640] (https://github.com/magento/magento2/issues/640) -- [Insight] Files should not be executable
+   * [#667] (https://github.com/magento/magento2/pull/667) -- Tiny improvement on render() method in Column/Renderer/Concat
+   * [#288] (https://github.com/magento/magento2/issues/288) -- Add Cell Phone to Customer Address Form
+   * [#607] (https://github.com/magento/magento2/issues/607) -- sitemap.xml filename is not variable
+   * [#633] (https://github.com/magento/magento2/pull/633) -- Fixed Typo ($_attribite -> $_attribute)
+   * [#634] (https://github.com/magento/magento2/issues/634) -- README.md contains broken link to X.commerce Agreement
+   * [#569] (https://github.com/magento/magento2/issues/569) -- ObjectManager's Factory should be replaceable depending on service
+   * [#654] (https://github.com/magento/magento2/issues/654) -- Demo notice overlapping
+ * Functional tests:
+   * Abandoned carts report
+   * Adding products from wishlist to cart
+   * Create invoice for offline payment methods
+   * Delete products from shopping cart
+   * Delete widget
+   * Global search
+   * Order count report
+   * Order total report
+
 0.1.0-alpha96
 =============
  * Framework improvements:
    * Increased unit tests code coverage for Magento_Persistent, Magento_GiftMessage, Magento_Checkout modules
  * Modularity:
    * Removed module dependency on the Weee module
- * Fixed Bugs:
+ * Fixed bugs:
    * Fixed an issue in composer installation where Magento/Framework marshaling did not work
    * Fixed an issue where shipping tax was included twice in tax details
    * Renamed the getDistinct method in Tax Model
diff --git a/CONTRIBUTOR_LICENSE_AGREEMENT.html b/CONTRIBUTOR_LICENSE_AGREEMENT.html
new file mode 100644
index 00000000000..58281b8e8ae
--- /dev/null
+++ b/CONTRIBUTOR_LICENSE_AGREEMENT.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>CONTRIBUTOR LICENSE AGREEMENT</title>
+    <style>
+        body {
+            font-size: 14px;
+        }
+
+        ol {
+            counter-reset: list1;
+            font-family: Verdana, Arial, Helvetica, sans-serif;
+            padding-bottom: 12px;
+        }
+        li {
+            list-style-type: none;
+            padding-top: 12px;
+        }
+        ol li:before {
+            counter-increment: list1;
+            content: counter(list1) ". ";
+        }
+        ol ol {
+            counter-reset: list2;
+        }
+        ol ol li:before {
+            counter-increment: list2;
+            content: counter(list1) "." counter(list2) ". ";
+        }
+        h2 {
+            text-align: center;
+            font-family: Verdana, Arial, Helvetica, sans-serif;
+        }
+        p {
+            font-family: Verdana, Arial, Helvetica, sans-serif;
+        }
+        div {
+            width: 800px;
+            margin: 0 auto;
+        }
+    </style>
+</head>
+<body>
+<div>
+<h2>
+    CONTRIBUTOR LICENSE AGREEMENT
+</h2>
+<p>
+    This Contributor License Agreement ("Agreement") is made and entered into as of _______________, 20__ (the "Effective Date"), by and between X.commerce, Inc. dba Magento, Inc., a Delaware corporation with its principal place of business at 10441 Jefferson Blvd., Suite 200, Culver City, CA 90232 ("Magento", "we", "us", or "our"), and ______________________________, a _______________ with its principal place of business at _______________________________________ ("Contributor", "you" or "your", and collectively with Magento, the "Parties").
+</p>
+<ol>
+    <li><strong><u>Definitions:</u></strong>
+        <ol>
+            <li>
+                <strong>"Contribution"</strong> means any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to Magento for inclusion in, or documentation of, any of the products or services owned or managed by Magento (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication provided to Magento or its representatives, including, but not limited to, communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Magento for the purpose of discussing, modifying, revising, and improving the Work, including identification of errors and/or issues and the remedy thereof.
+            </li>
+            <li>
+                <strong>"Contributor"</strong>, <strong>"you"</strong>, or <strong>"your"</strong> means the copyright owner or legal entity authorized by the copyright owner that is entering into this Agreement.
+            </li>
+            <li>
+                <strong>"Contributor Affiliate"</strong> means any past, present or future subsidiary, parent company, sister company, or other corporation, firm, business, partnership, joint venture or entity that controls, is controlled by, or is under common control of Contributor or any of its subsidiaries.
+            </li>
+            <li>
+                <strong>"Control"</strong> means (i) the power, direct or indirect, to cause the direction or management of an entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares of an entity, or (iii) beneficial ownership of an entity.
+            </li>
+            <li>
+                <strong>"Magento Affiliate"</strong> means any past, present or future subsidiary, parent company, sister company, or other corporation, firm, business, partnership, joint venture or entity that controls, is controlled by, or is under common control of Magento or any of its subsidiaries.
+            </li>
+        </ol>
+    </li>
+    <li><strong><u>License Grants:</u></strong>
+        <ol>
+            <li><strong>Grant of Copyright License.</strong> Subject to the terms and conditions of this Agreement, Contributor and Contributor Affiliates hereby grant to Magento, Magento Affiliates and all third party recipients of software, services, and all other information distributed by Magento as part of any Magento project, product or service a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Contributions and such derivative works.</li>
+            <li><strong>Grant of Patent License.</strong> Subject to the terms and conditions of this Agreement, Contributor and Contributor Affiliates hereby grant to Magento, Magento Affiliates, and all third party recipients of software, services, and information distributed by Magento as part of any Magento project, product or service a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Contributions, where such license applies only to those patent claims licensable by Contributor that are necessarily infringed by Contributions alone or by combination with software and/or information related to any Magento project, product or service.</li>
+            <li><strong>Grant to Magento and Magento Affiliates.</strong> The rights conferred in this Agreement on Magento shall automatically and immediately extend to any entity that later becomes a Magento Affiliate or a part of Magento.</li>
+            <li><strong>Contributions.</strong> Contributor agrees to the terms and conditions of this Agreement for present and future Contributions, which Contributor submits to Magento.  Except for the licenses granted herein, Contributor reserves all right, title, and interest in and to Contributor Contributions.</li>
+        </ol>
+    </li>
+    <li>
+        <strong><u>Representations:</u></strong>
+        <ol>
+            <li><strong>Original Work.</strong> Contributor represents that each Contribution is Contributor’s own original creation and that Contributor is the copyright owner or legal entity authorized by the copyright owner of all Contributions.</li>
+            <li><strong>Ownership and Authority.</strong> Contributor represents that it is legally entitled to grant the licenses above and that the Contributions do not include any third party copyrights, patents, trade secrets, licenses, or other restrictions ("Third Party IP"), and that Contributor will not declare any dependencies on any open source projects, proprietary software or Third Party IP, unless Contributor has made a Complete Disclosure prior to or at the time of the Contribution submission.</li>
+            <li><strong>Complete Disclosure.</strong> If applicable, Contributor represents that each and every Contribution submission includes complete details of any third-party license or other restrictions associated with any part of the Contribution.</li>
+            <li><strong>Support.</strong> Contributor is not expected to provide support for Contributions, except to the extent Contributor desires to provide support.  Contributor may provide support for free, for a fee, or not at all.</li>
+            <li><strong>Notification of any Change.</strong> You agree to notify Magento if any of the facts, circumstances or representations made herein are or become inaccurate in any respect.</li>
+        </ol>
+    </li>
+    <li>
+        <strong><u>General:</u></strong>
+        <ol>
+            <li><strong>Waiver.</strong> Contributor waives all other claims of any nature, including express contract, implied-in-fact contract, or quasi-contract, arising out of any disclosure of the Contributions to Magento.  As such, Magento is under no obligation to use or implement the Contributions in any respect.</li>
+            <li><strong>Competitive or Similar Materials.</strong> In no event shall Magento or Magento Affiliates be precluded from discussing, reviewing, developing for itself, having developed, or developing for third parties, materials which are competitive with those set forth in the Contributions irrespective of their similarity to the information in the Contributions, so long as Magento complies with the terms of this Agreement.</li>
+            <li><strong>Term.</strong> This Agreement shall remain in effect for a period of five (5) years from the Effective Date or until termination in writing by either party is delivered to the other party.</li>
+            <li><strong>Governing Law.</strong> This Agreement will be construed as if both parties jointly wrote it, governed by California law except for its conflicts of laws principles, and any cause of action arising under or relating to this Agreement must be brought exclusively in a court in Santa Clara County, California. </li>
+            <li><strong>Survival.</strong> Upon termination or expiration of this Agreement, all terms of the Agreement, including the license grants, shall remain in full force and effect, except that Contributor will no longer make submissions to Magento.</li>
+        </ol>
+    </li>
+</ol>
+<p><strong>IN WITNESS WHEREOF,</strong> the Parties have caused this Agreement to be executed by their duly authorized representatives as of the Effective Date.</p>
+<table border="0" width="100%">
+    <tr>
+        <td width="9%"><strong>Magento, Inc.</strong></td>
+        <td width="15%"></td>
+        <td width="6%"></td>
+        <td width="9%"></td>
+        <td width="15%"><strong>Contributor</strong><br>
+    </tr>
+    <tr>
+        <td>By:</td>
+        <td><hr></td>
+        <td></td>
+        <td>By:</td>
+        <td><hr></td>
+    </tr>
+        <td>Name:</td>
+        <td><hr></td>
+        <td></td>
+        <td>Name:</td>
+        <td><hr></td>
+    </tr>
+    <tr>
+        <td>Title:</td>
+        <td><hr></td>
+        <td></td>
+        <td>Title:</td>
+        <td><hr></td>
+</table>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/README.md b/README.md
index 2b7d837ea17..8bde2948519 100644
--- a/README.md
+++ b/README.md
@@ -6,4 +6,4 @@ All Submissions you make to Magento, an eBay Inc. company (“Magento”) throug
 
 1. You grant Magento a perpetual, worldwide, non-exclusive, no charge, royalty free, irrevocable license under your applicable copyrights and patents to reproduce, prepare derivative works of, display, publically perform, sublicense and distribute any feedback, ideas, code, or other information (“Submission”) you submit through GitHub.
 2. Your Submission is an original work of authorship and you are the owner or are legally entitled to grant the license stated above.
-3. You agree to the X.commerce Agreement found here: https://www.x.com/developers/x.commerce/x.commerce-user-agreement.
+3. You agree to the X.commerce Agreement found here: http://magento.com/legal/terms.
diff --git a/app/code/Magento/AdminNotification/Helper/Data.php b/app/code/Magento/AdminNotification/Helper/Data.php
deleted file mode 100644
index 8df06e5b1b1..00000000000
--- a/app/code/Magento/AdminNotification/Helper/Data.php
+++ /dev/null
@@ -1,114 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\AdminNotification\Helper;
-
-/**
- * AdminNotification Data helper
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Data extends \Magento\Framework\App\Helper\AbstractHelper
-{
-    const XML_PATH_POPUP_URL = 'system/adminnotification/popup_url';
-
-    /**
-     * Widget Popup Notification Object URL
-     *
-     * @var string
-     */
-    protected $_popupUrl;
-
-    /**
-     * Is readable Popup Notification Object flag
-     *
-     * @var bool
-     */
-    protected $_popupReadable;
-
-    /**
-     * Last Notice object
-     *
-     * @var \Magento\AdminNotification\Model\Inbox
-     */
-    protected $_latestNotice;
-
-    /**
-     * Count of unread notes by type
-     *
-     * @var array
-     */
-    protected $_unreadNoticeCounts;
-
-    /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $_scopeConfig;
-
-    /**
-     * @var \Magento\AdminNotification\Model\InboxFactory
-     */
-    protected $_inboxFactory;
-
-    /**
-     * @param \Magento\Framework\App\Helper\Context $context
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\AdminNotification\Model\InboxFactory $inboxFactory
-     */
-    public function __construct(
-        \Magento\Framework\App\Helper\Context $context,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\AdminNotification\Model\InboxFactory $inboxFactory
-    ) {
-        parent::__construct($context);
-        $this->_scopeConfig = $scopeConfig;
-        $this->_inboxFactory = $inboxFactory;
-    }
-
-    /**
-     * Retrieve latest notice model
-     *
-     * @return \Magento\AdminNotification\Model\Inbox
-     */
-    public function getLatestNotice()
-    {
-        if (is_null($this->_latestNotice)) {
-            $this->_latestNotice = $this->_inboxFactory->create()->loadLatestNotice();
-        }
-        return $this->_latestNotice;
-    }
-
-    /**
-     * Retrieve count of unread notes by type
-     *
-     * @param int $severity
-     * @return int
-     */
-    public function getUnreadNoticeCount($severity)
-    {
-        if (is_null($this->_unreadNoticeCounts)) {
-            $this->_unreadNoticeCounts = $this->_inboxFactory->create()->getNoticeStatus();
-        }
-        return isset($this->_unreadNoticeCounts[$severity]) ? $this->_unreadNoticeCounts[$severity] : 0;
-    }
-}
diff --git a/app/code/Magento/AdminNotification/Model/Config/Source/Frequency.php b/app/code/Magento/AdminNotification/Model/Config/Source/Frequency.php
index 40f8554f5b1..0a92bac8ff1 100644
--- a/app/code/Magento/AdminNotification/Model/Config/Source/Frequency.php
+++ b/app/code/Magento/AdminNotification/Model/Config/Source/Frequency.php
@@ -26,7 +26,7 @@ namespace Magento\AdminNotification\Model\Config\Source;
 /**
  * AdminNotification update frequency source
  *
- * @author      Magento Core Team <core@magentocommerce.com>
+ * @codeCoverageIgnore
  */
 class Frequency implements \Magento\Framework\Option\ArrayInterface
 {
diff --git a/app/code/Magento/AdminNotification/Model/Feed.php b/app/code/Magento/AdminNotification/Model/Feed.php
index c1fba9cb653..57ff524528f 100644
--- a/app/code/Magento/AdminNotification/Model/Feed.php
+++ b/app/code/Magento/AdminNotification/Model/Feed.php
@@ -55,6 +55,11 @@ class Feed extends \Magento\Framework\Model\AbstractModel
      */
     protected $_inboxFactory;
 
+    /**
+     * @var \Magento\Framework\HTTP\Adapter\CurlFactory
+     */
+    protected $curlFactory;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -62,6 +67,7 @@ class Feed extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\AdminNotification\Model\InboxFactory $inboxFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param \Magento\Framework\HTTP\Adapter\curlFactory $curlFactory
      * @param array $data
      */
     public function __construct(
@@ -69,6 +75,7 @@ class Feed extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Registry $registry,
         \Magento\Backend\App\ConfigInterface $backendConfig,
         \Magento\AdminNotification\Model\InboxFactory $inboxFactory,
+        \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
@@ -76,6 +83,7 @@ class Feed extends \Magento\Framework\Model\AbstractModel
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
         $this->_backendConfig = $backendConfig;
         $this->_inboxFactory = $inboxFactory;
+        $this->curlFactory = $curlFactory;
     }
 
     /**
@@ -116,15 +124,19 @@ class Feed extends \Magento\Framework\Model\AbstractModel
 
         $feedXml = $this->getFeedData();
 
+        $installDate = $this->_appState->getInstallDate();
+
         if ($feedXml && $feedXml->channel && $feedXml->channel->item) {
             foreach ($feedXml->channel->item as $item) {
-                $feedData[] = array(
-                    'severity' => (int)$item->severity,
-                    'date_added' => $this->getDate((string)$item->pubDate),
-                    'title' => (string)$item->title,
-                    'description' => (string)$item->description,
-                    'url' => (string)$item->link
-                );
+                if ($installDate <= strtotime((string)$item->pubDate)) {
+                    $feedData[] = array(
+                        'severity' => (int)$item->severity,
+                        'date_added' => $this->getDate((string)$item->pubDate),
+                        'title' => (string)$item->title,
+                        'description' => (string)$item->description,
+                        'url' => (string)$item->link
+                    );
+                }
             }
 
             if ($feedData) {
@@ -185,7 +197,7 @@ class Feed extends \Magento\Framework\Model\AbstractModel
      */
     public function getFeedData()
     {
-        $curl = new \Magento\Framework\HTTP\Adapter\Curl();
+        $curl = $this->curlFactory->create();
         $curl->setConfig(array('timeout' => 2));
         $curl->write(\Zend_Http_Client::GET, $this->getFeedUrl(), '1.0');
         $data = $curl->read();
diff --git a/app/code/Magento/AdminNotification/Model/System/Message.php b/app/code/Magento/AdminNotification/Model/System/Message.php
index 47014047848..650e26e407d 100644
--- a/app/code/Magento/AdminNotification/Model/System/Message.php
+++ b/app/code/Magento/AdminNotification/Model/System/Message.php
@@ -23,6 +23,9 @@
  */
 namespace Magento\AdminNotification\Model\System;
 
+/**
+ * @codeCoverageIgnore
+ */
 class Message extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\Notification\MessageInterface
 {
     /**
diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json
index ea51992822d..946ca70e54c 100644
--- a/app/code/Magento/AdminNotification/composer.json
+++ b/app/code/Magento/AdminNotification/composer.json
@@ -3,16 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/AdminNotification/etc/module.xml b/app/code/Magento/AdminNotification/etc/module.xml
index e767d17381c..68a4115f67c 100644
--- a/app/code/Magento/AdminNotification/etc/module.xml
+++ b/app/code/Magento/AdminNotification/etc/module.xml
@@ -33,7 +33,6 @@
             <module name="Magento_Store"/>
             <module name="Magento_Core"/>
             <module name="Magento_Backend"/>
-            <module name="Magento_Theme"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml b/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml
index 09d661912c1..be68c170e83 100644
--- a/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml
+++ b/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml
@@ -32,11 +32,7 @@
     <referenceContainer name="header">
         <block class="Magento\AdminNotification\Block\ToolbarEntry" before="user" template="toolbar_entry.phtml" />
     </referenceContainer>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
 </page>
diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json
index 9cf98d75bdd..e4b92a7168f 100644
--- a/app/code/Magento/Authorization/composer.json
+++ b/app/code/Magento/Authorization/composer.json
@@ -3,12 +3,12 @@
     "description": "Authorization module provides access to Magento ACL functionality.",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json
index 4c698ea9a02..a29aeab87e2 100644
--- a/app/code/Magento/Authorizenet/composer.json
+++ b/app/code/Magento/Authorizenet/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-centinel": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-centinel": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php
index 50e29c07426..c14435b8afd 100644
--- a/app/code/Magento/Backend/Block/Media/Uploader.php
+++ b/app/code/Magento/Backend/Block/Media/Uploader.php
@@ -102,14 +102,7 @@ class Uploader extends \Magento\Backend\Block\Widget
      */
     protected function _prepareLayout()
     {
-        $head = $this->getLayout()->getBlock('head');
-        if ($head) {
-            $head->addChild(
-                'jquery-fileUploader-css-jquery-fileupload-ui-css',
-                'Magento\Theme\Block\Html\Head\Css',
-                array('file' => 'jquery/fileUploader/css/jquery.fileupload-ui.css')
-            );
-        }
+        $this->pageConfig->addPageAsset('jquery/fileUploader/css/jquery.fileupload-ui.css');
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Backend/Block/Page.php b/app/code/Magento/Backend/Block/Page.php
index 2dbd390a065..870bb4180aa 100644
--- a/app/code/Magento/Backend/Block/Page.php
+++ b/app/code/Magento/Backend/Block/Page.php
@@ -59,7 +59,7 @@ class Page extends \Magento\Backend\Block\Template
     {
         parent::_construct();
 
-        $this->addBodyClass($this->_request->getFullActionName('-'));
+        $this->pageConfig->addBodyClass($this->_request->getFullActionName('-'));
     }
 
     /**
@@ -75,19 +75,6 @@ class Page extends \Magento\Backend\Block\Template
         return $this->getData('lang');
     }
 
-    /**
-     * Add CSS class to page body tag
-     *
-     * @param string $className
-     * @return $this
-     */
-    public function addBodyClass($className)
-    {
-        $className = preg_replace('#[^a-z0-9]+#', '-', strtolower($className));
-        $this->setBodyClass($this->getBodyClass() . ' ' . $className);
-        return $this;
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Backend/Block/Page/Head.php b/app/code/Magento/Backend/Block/Page/Head.php
deleted file mode 100644
index 5c86ceb63f3..00000000000
--- a/app/code/Magento/Backend/Block/Page/Head.php
+++ /dev/null
@@ -1,113 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Adminhtml header block
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Backend\Block\Page;
-
-class Head extends \Magento\Theme\Block\Html\Head
-{
-    /**
-     * @var string
-     */
-    protected $_template = 'page/head.phtml';
-
-    /**
-     * @var \Magento\Framework\Data\Form\FormKey
-     */
-    protected $formKey;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase
-     * @param \Magento\Framework\ObjectManager $objectManager
-     * @param \Magento\Framework\View\Asset\GroupedCollection $assets
-     * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
-     * @param \Magento\Framework\View\Asset\MinifyService $assetMinifyService
-     * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
-     * @param \Magento\Translation\Block\Js $jsTranslation
-     * @param \Magento\Framework\App\Action\Title $titles
-     * @param \Magento\Framework\Data\Form\FormKey $formKey
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase,
-        \Magento\Framework\ObjectManager $objectManager,
-        \Magento\Framework\View\Asset\GroupedCollection $assets,
-        \Magento\Framework\View\Asset\MergeService $assetMergeService,
-        \Magento\Framework\View\Asset\MinifyService $assetMinifyService,
-        \Magento\Framework\Locale\ResolverInterface $localeResolver,
-        \Magento\Translation\Block\Js $jsTranslation,
-        \Magento\Framework\App\Action\Title $titles,
-        \Magento\Framework\Data\Form\FormKey $formKey,
-        array $data = array()
-    ) {
-        $this->_titles = $titles;
-        $this->formKey = $formKey;
-        parent::__construct(
-            $context,
-            $fileStorageDatabase,
-            $objectManager,
-            $assets,
-            $assetMergeService,
-            $assetMinifyService,
-            $localeResolver,
-            $jsTranslation,
-            $data
-        );
-        $this->formKey = $formKey;
-    }
-
-    /**
-     * Retrieve Session Form Key
-     *
-     * @return string
-     */
-    public function getFormKey()
-    {
-        return $this->formKey->getFormKey();
-    }
-
-    /**
-     * @return array|string
-     */
-    public function getTitle()
-    {
-        /** Get default title */
-        $title = parent::getTitle();
-
-        /** Add default title */
-        $this->_titles->add($title, true);
-
-        /** Set title list */
-        $this->setTitle(array_reverse($this->_titles->get()));
-
-        /** Render titles */
-        return parent::getTitle();
-    }
-}
diff --git a/app/code/Magento/Catalog/Block/Product/Widget/Link.php b/app/code/Magento/Backend/Block/Page/RequireJs.php
similarity index 64%
rename from app/code/Magento/Catalog/Block/Product/Widget/Link.php
rename to app/code/Magento/Backend/Block/Page/RequireJs.php
index 6bedd127700..f5513c049ee 100644
--- a/app/code/Magento/Catalog/Block/Product/Widget/Link.php
+++ b/app/code/Magento/Backend/Block/Page/RequireJs.php
@@ -22,28 +22,43 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Backend\Block\Page;
+
 /**
- * Widget to display link to the product
- *
- * @author     Magento Core Team <core@magentocommerce.com>
+ * Require Js block
  */
-namespace Magento\Catalog\Block\Product\Widget;
-
-class Link extends \Magento\Catalog\Block\Widget\Link
+class RequireJs extends \Magento\Framework\View\Element\Template
 {
+    /**
+     * @var \Magento\Framework\Data\Form\FormKey
+     */
+    protected $formKey;
+
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite
-     * @param \Magento\Catalog\Model\Resource\Product $catalogProduct
+     * @param \Magento\Framework\Data\Form\FormKey $formKey
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite,
-        \Magento\Catalog\Model\Resource\Product $catalogProduct,
+        \Magento\Framework\Data\Form\FormKey $formKey,
         array $data = array()
     ) {
-        parent::__construct($context, $urlRewrite, $data);
-        $this->_entityResource = $catalogProduct;
+        $this->formKey = $formKey;
+        parent::__construct(
+            $context,
+            $data
+        );
+        $this->formKey = $formKey;
+    }
+
+    /**
+     * Retrieve Session Form Key
+     *
+     * @return string
+     */
+    public function getFormKey()
+    {
+        return $this->formKey->getFormKey();
     }
 }
diff --git a/app/code/Magento/Backend/Block/System/Account/Edit/Form.php b/app/code/Magento/Backend/Block/System/Account/Edit/Form.php
index fe9f26aaf10..bf15a0ca776 100644
--- a/app/code/Magento/Backend/Block/System/Account/Edit/Form.php
+++ b/app/code/Magento/Backend/Block/System/Account/Edit/Form.php
@@ -30,6 +30,8 @@ namespace Magento\Backend\Block\System\Account\Edit;
  */
 class Form extends \Magento\Backend\Block\Widget\Form\Generic
 {
+    const IDENTITY_VERIFICATION_PASSWORD_FIELD = 'current_password';
+
     /**
      * @var \Magento\Backend\Model\Auth\Session
      */
@@ -142,7 +144,26 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
             )
         );
 
-        $form->setValues($user->getData());
+        $verificationFieldset = $form->addFieldset(
+            'current_user_verification_fieldset',
+            ['legend' => __('Current User Identity Verification')]
+        );
+        $verificationFieldset->addField(
+            self::IDENTITY_VERIFICATION_PASSWORD_FIELD,
+            'password',
+            array(
+                'name' => self::IDENTITY_VERIFICATION_PASSWORD_FIELD,
+                'label' => __('Your Password'),
+                'id' => self::IDENTITY_VERIFICATION_PASSWORD_FIELD,
+                'title' => __('Your Password'),
+                'class' => 'input-text validate-current-password required-entry',
+                'required' => true
+            )
+        );
+
+        $data = $user->getData();
+        unset($data[self::IDENTITY_VERIFICATION_PASSWORD_FIELD]);
+        $form->setValues($data);
         $form->setAction($this->getUrl('adminhtml/system_account/save'));
         $form->setMethod('post');
         $form->setUseContainer(true);
diff --git a/app/code/Magento/Backend/Block/Template/Context.php b/app/code/Magento/Backend/Block/Template/Context.php
index 70680f30e22..656b3931b13 100644
--- a/app/code/Magento/Backend/Block/Template/Context.php
+++ b/app/code/Magento/Backend/Block/Template/Context.php
@@ -56,6 +56,11 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      */
     protected $nameBuilder;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\View\LayoutInterface $layout
@@ -80,6 +85,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      * @param \Magento\Framework\View\TemplateEnginePool $enginePool
      * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      * @param \Magento\Framework\AuthorizationInterface $authorization
      * @param \Magento\Backend\Model\Session $backendSession
      * @param \Magento\Framework\Math\Random $mathRandom
@@ -112,6 +118,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
         \Magento\Framework\View\TemplateEnginePool $enginePool,
         \Magento\Framework\App\State $appState,
         \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\View\Page\Config $pageConfig,
         \Magento\Framework\AuthorizationInterface $authorization,
         \Magento\Backend\Model\Session $backendSession,
         \Magento\Framework\Math\Random $mathRandom,
@@ -146,7 +153,8 @@ class Context extends \Magento\Framework\View\Element\Template\Context
             $viewFileSystem,
             $enginePool,
             $appState,
-            $storeManager
+            $storeManager,
+            $pageConfig
         );
     }
 
diff --git a/app/code/Magento/Backend/Block/Urlrewrite.php b/app/code/Magento/Backend/Block/Urlrewrite.php
deleted file mode 100644
index d3306b3dab3..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite.php
+++ /dev/null
@@ -1,96 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block;
-
-/**
- * Block for Urlrewrites grid container
- *
- * @method \Magento\Backend\Block\Urlrewrite setSelectorBlock(\Magento\Backend\Block\Urlrewrite\Selector $value)
- * @method null|\Magento\Backend\Block\Urlrewrite\Selector getSelectorBlock()
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Urlrewrite extends \Magento\Backend\Block\Widget\Grid\Container
-{
-    /**
-     * Part for generating apropriate grid block name
-     *
-     * @var string
-     */
-    protected $_controller = 'urlrewrite';
-
-    /**
-     * @var \Magento\Backend\Block\Urlrewrite\Selector
-     */
-    protected $_urlrewriteSelector;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\Backend\Block\Urlrewrite\Selector $urlrewriteSelector
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\Backend\Block\Urlrewrite\Selector $urlrewriteSelector,
-        array $data = array()
-    ) {
-        $this->_urlrewriteSelector = $urlrewriteSelector;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Set custom labels and headers
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_headerText = __('URL Rewrite Management');
-        $this->_addButtonLabel = __('Add URL Rewrite');
-        parent::_construct();
-    }
-
-    /**
-     * Customize grid row URLs
-     *
-     * @see \Magento\Backend\Block\Urlrewrite\Selector
-     * @return string
-     */
-    public function getCreateUrl()
-    {
-        $url = $this->getUrl('adminhtml/*/edit');
-
-        $selectorBlock = $this->getSelectorBlock();
-        if ($selectorBlock === null) {
-            $selectorBlock = $this->_urlrewriteSelector;
-        }
-
-        if ($selectorBlock) {
-            $modes = array_keys($selectorBlock->getModes());
-            $url .= reset($modes);
-        }
-
-        return $url;
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
deleted file mode 100644
index c8ffa03ca60..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
+++ /dev/null
@@ -1,137 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Category;
-
-/**
- * Block for Catalog Category URL rewrites
- *
- * @method \Magento\Catalog\Model\Category getCategory()
- * @method \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit
- *    setCategory(\Magento\Catalog\Model\Category $category)
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
-{
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        array $data = array()
-    ) {
-        $this->_categoryFactory = $categoryFactory;
-        parent::__construct($context, $rewriteFactory, $adminhtmlData, $data);
-    }
-
-    /**
-     * Prepare layout for URL rewrite creating for category
-     *
-     * @return void
-     */
-    protected function _prepareLayoutFeatures()
-    {
-        if ($this->_getUrlRewrite()->getId()) {
-            $this->_headerText = __('Edit URL Rewrite for a Category');
-        } else {
-            $this->_headerText = __('Add URL Rewrite for a Category');
-        }
-
-        if ($this->_getCategory()->getId()) {
-            $this->_addCategoryLinkBlock();
-            $this->_addEditFormBlock();
-            $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'category');
-        } else {
-            $this->_addUrlRewriteSelectorBlock();
-            $this->_addCategoryTreeBlock();
-        }
-    }
-
-    /**
-     * Get or create new instance of category
-     *
-     * @return \Magento\Catalog\Model\Product
-     */
-    private function _getCategory()
-    {
-        if (!$this->hasData('category')) {
-            $this->setCategory($this->_categoryFactory->create());
-        }
-        return $this->getCategory();
-    }
-
-    /**
-     * Add child category link block
-     *
-     * @return void
-     */
-    private function _addCategoryLinkBlock()
-    {
-        $this->addChild(
-            'category_link',
-            'Magento\Backend\Block\Urlrewrite\Link',
-            array(
-                'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'category',
-                'item_name' => $this->_getCategory()->getName(),
-                'label' => __('Category:')
-            )
-        );
-    }
-
-    /**
-     * Add child category tree block
-     *
-     * @return void
-     */
-    private function _addCategoryTreeBlock()
-    {
-        $this->addChild('categories_tree', 'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree');
-    }
-
-    /**
-     * Creates edit form block
-     *
-     * @return \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form
-     */
-    protected function _createEditFormBlock()
-    {
-        return $this->getLayout()->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form',
-            '',
-            array('data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite()))
-        );
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Tree.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Tree.php
deleted file mode 100644
index 3075a987d46..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Tree.php
+++ /dev/null
@@ -1,196 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Category;
-
-/**
- * Categories tree block for URL rewrites editing process
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Tree extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
-{
-    /**
-     * List of allowed category ids
-     *
-     * @var int[]|null
-     */
-    protected $_allowedCategoryIds = null;
-
-    /**
-     * @var string
-     */
-    protected $_template = 'urlrewrite/categories.phtml';
-
-    /**
-     * Adminhtml data
-     *
-     * @var \Magento\Backend\Helper\Data
-     */
-    protected $_adminhtmlData = null;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\Framework\Json\EncoderInterface
-     */
-    protected $_jsonEncoder;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Catalog\Model\Resource\Category\Tree $categoryTree
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Catalog\Model\Resource\Category\Tree $categoryTree,
-        \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Framework\Json\EncoderInterface $jsonEncoder,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        array $data = array()
-    ) {
-        $this->_jsonEncoder = $jsonEncoder;
-        $this->_categoryFactory = $categoryFactory;
-        $this->_productFactory = $productFactory;
-        $this->_adminhtmlData = $adminhtmlData;
-        parent::__construct($context, $categoryTree, $registry, $categoryFactory, $data);
-    }
-
-    /**
-     * Get categories tree as recursive array
-     *
-     * @param int $parentId
-     * @param bool $asJson
-     * @param int $recursionLevel
-     * @return array
-     */
-    public function getTreeArray($parentId = null, $asJson = false, $recursionLevel = 3)
-    {
-        $productId = $this->_request->getParam('product');
-        if ($productId) {
-            $product = $this->_productFactory->create()->setId($productId);
-            $this->_allowedCategoryIds = $product->getCategoryIds();
-            unset($product);
-        }
-
-        $result = array();
-        if ($parentId) {
-            $category = $this->_categoryFactory->create()->load($parentId);
-            if (!empty($category)) {
-                $tree = $this->_getNodesArray($this->getNode($category, $recursionLevel));
-                if (!empty($tree) && !empty($tree['children'])) {
-                    $result = $tree['children'];
-                }
-            }
-        } else {
-            $result = $this->_getNodesArray($this->getRoot(null, $recursionLevel));
-        }
-
-        if ($asJson) {
-            return $this->_jsonEncoder->encode($result);
-        }
-
-        $this->_allowedCategoryIds = null;
-
-        return $result;
-    }
-
-    /**
-     * Get categories collection
-     *
-     * @return \Magento\Catalog\Model\Resource\Category\Collection
-     */
-    public function getCategoryCollection()
-    {
-        $collection = $this->_getData('category_collection');
-        if (is_null($collection)) {
-            $collection = $this->_categoryFactory->create()->getCollection()->addAttributeToSelect(
-                array('name', 'is_active')
-            )->setLoadProductCount(
-                true
-            );
-            $this->setData('category_collection', $collection);
-        }
-
-        return $collection;
-    }
-
-    /**
-     * Convert categories tree to array recursively
-     *
-     * @param  \Magento\Framework\Data\Tree\Node $node
-     * @return array
-     */
-    protected function _getNodesArray($node)
-    {
-        $result = array(
-            'id' => (int)$node->getId(),
-            'parent_id' => (int)$node->getParentId(),
-            'children_count' => (int)$node->getChildrenCount(),
-            'is_active' => (bool)$node->getIsActive(),
-            'name' => $node->getName(),
-            'level' => (int)$node->getLevel(),
-            'product_count' => (int)$node->getProductCount()
-        );
-
-        if (is_array($this->_allowedCategoryIds) && !in_array($result['id'], $this->_allowedCategoryIds)) {
-            $result['disabled'] = true;
-        }
-
-        if ($node->hasChildren()) {
-            $result['children'] = array();
-            foreach ($node->getChildren() as $childNode) {
-                $result['children'][] = $this->_getNodesArray($childNode);
-            }
-        }
-        $result['cls'] = ($result['is_active'] ? '' : 'no-') . 'active-category';
-        $result['expanded'] = !empty($result['children']);
-
-        return $result;
-    }
-
-    /**
-     * Get URL for categories tree ajax loader
-     *
-     * @return string
-     */
-    public function getLoadTreeUrl()
-    {
-        return $this->_adminhtmlData->getUrl('adminhtml/*/categoriesJson');
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Edit/Form.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Edit/Form.php
deleted file mode 100644
index ed612197dab..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Edit/Form.php
+++ /dev/null
@@ -1,239 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Edit form for Catalog product and category URL rewrites
- *
- * @method \Magento\Catalog\Model\Product getProduct()
- * @method \Magento\Catalog\Model\Category getCategory()
- * @method \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form setProduct(\Magento\Catalog\Model\Product $product)
- * @method \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form setCategory(\Magento\Catalog\Model\Category $category)
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- *
- */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Edit;
-
-/**
- * @SuppressWarnings(PHPMD.DepthOfInheritance)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class Form extends \Magento\Backend\Block\Urlrewrite\Edit\Form
-{
-    /**
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_catalogUrl;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Store\Model\System\Store $systemStore
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\Catalog\Model\Url $catalogUrl
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Store\Model\System\Store $systemStore,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Catalog\Model\Url $catalogUrl,
-        array $data = array()
-    ) {
-        $this->_productFactory = $productFactory;
-        $this->_categoryFactory = $categoryFactory;
-        $this->_catalogUrl = $catalogUrl;
-        parent::__construct(
-            $context,
-            $registry,
-            $formFactory,
-            $typesFactory,
-            $optionFactory,
-            $rewriteFactory,
-            $systemStore,
-            $adminhtmlData,
-            $data
-        );
-    }
-
-    /**
-     * Form post init
-     *
-     * @param \Magento\Framework\Data\Form $form
-     * @return \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form
-     */
-    protected function _formPostInit($form)
-    {
-        // Set form action
-        $form->setAction(
-            $this->_adminhtmlData->getUrl(
-                'adminhtml/*/save',
-                array(
-                    'id' => $this->_getModel()->getId(),
-                    'product' => $this->_getProduct()->getId(),
-                    'category' => $this->_getCategory()->getId()
-                )
-            )
-        );
-
-        // Fill id path, request path and target path elements
-        /** @var $idPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $idPath = $this->getForm()->getElement('id_path');
-        /** @var $requestPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $requestPath = $this->getForm()->getElement('request_path');
-        /** @var $targetPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $targetPath = $this->getForm()->getElement('target_path');
-
-        $model = $this->_getModel();
-        $disablePaths = false;
-        if (!$model->getId()) {
-            $product = null;
-            $category = null;
-            if ($this->_getProduct()->getId()) {
-                $product = $this->_getProduct();
-                $category = $this->_getCategory();
-            } elseif ($this->_getCategory()->getId()) {
-                $category = $this->_getCategory();
-            }
-
-            if ($product || $category) {
-                $idPath->setValue($this->_catalogUrl->generatePath('id', $product, $category));
-
-                $sessionData = $this->_getSessionData();
-                if (!isset($sessionData['request_path'])) {
-                    $requestPath->setValue($this->_catalogUrl->generatePath('request', $product, $category, ''));
-                }
-                $targetPath->setValue($this->_catalogUrl->generatePath('target', $product, $category));
-                $disablePaths = true;
-            }
-        } else {
-            $disablePaths = $model->getProductId() || $model->getCategoryId();
-        }
-
-        // Disable id_path and target_path elements
-        if ($disablePaths) {
-            $idPath->setData('disabled', true);
-            $targetPath->setData('disabled', true);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Get catalog entity associated stores
-     *
-     * @return array
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function _getEntityStores()
-    {
-        $product = $this->_getProduct();
-        $category = $this->_getCategory();
-        $entityStores = array();
-
-        // showing websites that only associated to products
-        if ($product->getId()) {
-            $entityStores = (array)$product->getStoreIds();
-
-            //if category is chosen, reset stores which are not related with this category
-            if ($category->getId()) {
-                $categoryStores = (array)$category->getStoreIds();
-                $entityStores = array_intersect($entityStores, $categoryStores);
-            }
-            // @codingStandardsIgnoreStart
-            if (!$entityStores) {
-                throw new \Magento\Framework\Model\Exception(
-                    __(
-                        'We can\'t set up a URL rewrite because the product you chose is not associated with a website.'
-                    )
-                );
-            }
-            $this->_requireStoresFilter = true;
-        } elseif ($category->getId()) {
-            $entityStores = (array)$category->getStoreIds();
-            if (!$entityStores) {
-                throw new \Magento\Framework\Model\Exception(
-                    __(
-                        'We can\'t set up a URL rewrite because the category your chose is not associated with a website.'
-                    )
-                );
-            }
-            $this->_requireStoresFilter = true;
-        }
-        // @codingStandardsIgnoreEnd
-
-        return $entityStores;
-    }
-
-    /**
-     * Get product model instance
-     *
-     * @return \Magento\Catalog\Model\Product
-     */
-    protected function _getProduct()
-    {
-        if (!$this->hasData('product')) {
-            $this->setProduct($this->_productFactory->create());
-        }
-        return $this->getProduct();
-    }
-
-    /**
-     * Get category model instance
-     *
-     * @return \Magento\Catalog\Model\Category
-     */
-    protected function _getCategory()
-    {
-        if (!$this->hasData('category')) {
-            $this->setCategory($this->_categoryFactory->create());
-        }
-        return $this->getCategory();
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
deleted file mode 100644
index 648aa40029c..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
+++ /dev/null
@@ -1,239 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Product;
-
-/**
- * Block for Catalog Category URL rewrites editing
- *
- * @method \Magento\Catalog\Model\Category getCategory()
- * @method
- * \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit setCategory(\Magento\Catalog\Model\Category $category)
- * @method \Magento\Catalog\Model\Product getProduct()
- * @method \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit setProduct(\Magento\Catalog\Model\Product $product)
- * @method bool getIsCategoryMode()
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
-{
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        array $data = array()
-    ) {
-        $this->_categoryFactory = $categoryFactory;
-        $this->_productFactory = $productFactory;
-        parent::__construct($context, $rewriteFactory, $adminhtmlData, $data);
-    }
-
-    /**
-     * Prepare layout for URL rewrite creating for product
-     *
-     * @return void
-     */
-    protected function _prepareLayoutFeatures()
-    {
-        if ($this->_getUrlRewrite()->getId()) {
-            $this->_headerText = __('Edit URL Rewrite for a Product');
-        } else {
-            $this->_headerText = __('Add URL Rewrite for a Product');
-        }
-
-        if ($this->_getProduct()->getId()) {
-            $this->_addProductLinkBlock($this->_getProduct());
-        }
-
-        if ($this->_getCategory()->getId()) {
-            $this->_addCategoryLinkBlock();
-        }
-
-        if ($this->_getProduct()->getId()) {
-            if ($this->_getCategory()->getId() || !$this->getIsCategoryMode()) {
-                $this->_addEditFormBlock();
-                $this->_updateBackButtonLink(
-                    $this->_adminhtmlData->getUrl(
-                        'adminhtml/*/edit',
-                        array('product' => $this->_getProduct()->getId())
-                    ) . 'category'
-                );
-            } else {
-                // categories selector & skip categories button
-                $this->_addCategoriesTreeBlock();
-                $this->_addSkipCategoriesBlock();
-                $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'product');
-            }
-        } else {
-            $this->_addUrlRewriteSelectorBlock();
-            $this->_addProductsGridBlock();
-        }
-    }
-
-    /**
-     * Get or create new instance of product
-     *
-     * @return \Magento\Catalog\Model\Product
-     */
-    private function _getProduct()
-    {
-        if (!$this->hasData('product')) {
-            $this->setProduct($this->_productFactory->create());
-        }
-        return $this->getProduct();
-    }
-
-    /**
-     * Get or create new instance of category
-     *
-     * @return \Magento\Catalog\Model\Category
-     */
-    private function _getCategory()
-    {
-        if (!$this->hasData('category')) {
-            $this->setCategory($this->_categoryFactory->create());
-        }
-        return $this->getCategory();
-    }
-
-    /**
-     * Add child product link block
-     *
-     * @return void
-     */
-    private function _addProductLinkBlock()
-    {
-        $this->addChild(
-            'product_link',
-            'Magento\Backend\Block\Urlrewrite\Link',
-            array(
-                'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'product',
-                'item_name' => $this->_getProduct()->getName(),
-                'label' => __('Product:')
-            )
-        );
-    }
-
-    /**
-     * Add child category link block
-     *
-     * @return void
-     */
-    private function _addCategoryLinkBlock()
-    {
-        $this->addChild(
-            'category_link',
-            'Magento\Backend\Block\Urlrewrite\Link',
-            array(
-                'item_url' => $this->_adminhtmlData->getUrl(
-                    'adminhtml/*/*',
-                    array('product' => $this->_getProduct()->getId())
-                ) . 'category',
-                'item_name' => $this->_getCategory()->getName(),
-                'label' => __('Category:')
-            )
-        );
-    }
-
-    /**
-     * Add child products grid block
-     *
-     * @return void
-     */
-    private function _addProductsGridBlock()
-    {
-        $this->addChild('products_grid', 'Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid');
-    }
-
-    /**
-     * Add child Categories Tree block
-     *
-     * @return void
-     */
-    private function _addCategoriesTreeBlock()
-    {
-        $this->addChild('categories_tree', 'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree');
-    }
-
-    /**
-     * Add child Skip Categories block
-     *
-     * @return void
-     */
-    private function _addSkipCategoriesBlock()
-    {
-        $this->addChild(
-            'skip_categories',
-            'Magento\Backend\Block\Widget\Button',
-            array(
-                'label' => __('Skip Category Selection'),
-                'onclick' => 'window.location = \'' . $this->_adminhtmlData->getUrl(
-                    'adminhtml/*/*',
-                    array('product' => $this->_getProduct()->getId())
-                ) . '\'',
-                'class' => 'save',
-                'level' => -1
-            )
-        );
-    }
-
-    /**
-     * Creates edit form block
-     *
-     * @return \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form
-     */
-    protected function _createEditFormBlock()
-    {
-        return $this->getLayout()->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form',
-            '',
-            array(
-                'data' => array(
-                    'product' => $this->_getProduct(),
-                    'category' => $this->_getCategory(),
-                    'url_rewrite' => $this->_getUrlRewrite()
-                )
-            )
-        );
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Grid.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Grid.php
deleted file mode 100644
index 5eba26e0e75..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Grid.php
+++ /dev/null
@@ -1,88 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Product;
-
-/**
- * Products grid for URL rewrites editing
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid
-{
-    /**
-     * Disable massaction
-     *
-     * @return $this
-     */
-    protected function _prepareMassaction()
-    {
-        return $this;
-    }
-
-    /**
-     * Prepare columns layout
-     *
-     * @return $this
-     */
-    protected function _prepareColumns()
-    {
-        $this->addColumn('entity_id', array('header' => __('ID'), 'width' => 50, 'index' => 'entity_id'));
-
-        $this->addColumn('name', array('header' => __('Name'), 'index' => 'name'));
-
-        $this->addColumn('sku', array('header' => __('SKU'), 'width' => 80, 'index' => 'sku'));
-        $this->addColumn(
-            'status',
-            array(
-                'header' => __('Status'),
-                'width' => 50,
-                'index' => 'status',
-                'type' => 'options',
-                'options' => $this->_status->getOptionArray()
-            )
-        );
-        return $this;
-    }
-
-    /**
-     * Get URL for dispatching grid ajax requests
-     *
-     * @return string
-     */
-    public function getGridUrl()
-    {
-        return $this->getUrl('adminhtml/*/productGrid', array('_current' => true));
-    }
-
-    /**
-     * Return row url for js event handlers
-     *
-     * @param \Magento\Catalog\Model\Product|\Magento\Framework\Object $row
-     * @return string
-     */
-    public function getRowUrl($row)
-    {
-        return $this->getUrl('adminhtml/*/edit', array('product' => $row->getId())) . 'category';
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
deleted file mode 100644
index ccb5872dac8..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
+++ /dev/null
@@ -1,136 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page;
-
-/**
- * Block for CMS pages URL rewrites
- *
- * @method \Magento\Cms\Model\Page getCmsPage()
- * @method \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit setCmsPage(\Magento\Cms\Model\Page $cmsPage)
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
-{
-    /**
-     * @var \Magento\Cms\Model\PageFactory
-     */
-    protected $_pageFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Cms\Model\PageFactory $pageFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Cms\Model\PageFactory $pageFactory,
-        array $data = array()
-    ) {
-        $this->_pageFactory = $pageFactory;
-        parent::__construct($context, $rewriteFactory, $adminhtmlData, $data);
-    }
-
-    /**
-     * Prepare layout for URL rewrite creating for CMS page
-     *
-     * @return void
-     */
-    protected function _prepareLayoutFeatures()
-    {
-        if ($this->_getUrlRewrite()->getId()) {
-            $this->_headerText = __('Edit URL Rewrite for CMS page');
-        } else {
-            $this->_headerText = __('Add URL Rewrite for CMS page');
-        }
-
-        if ($this->_getCmsPage()->getId()) {
-            $this->_addCmsPageLinkBlock();
-            $this->_addEditFormBlock();
-            $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'cms_page');
-        } else {
-            $this->_addUrlRewriteSelectorBlock();
-            $this->_addCmsPageGridBlock();
-        }
-    }
-
-    /**
-     * Get or create new instance of CMS page
-     *
-     * @return \Magento\Cms\Model\Page
-     */
-    private function _getCmsPage()
-    {
-        if (!$this->hasData('cms_page')) {
-            $this->setCmsPage($this->_pageFactory->create());
-        }
-        return $this->getCmsPage();
-    }
-
-    /**
-     * Add child CMS page link block
-     *
-     * @return void
-     */
-    private function _addCmsPageLinkBlock()
-    {
-        $this->addChild(
-            'cms_page_link',
-            'Magento\Backend\Block\Urlrewrite\Link',
-            array(
-                'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'cms_page',
-                'item_name' => $this->getCmsPage()->getTitle(),
-                'label' => __('CMS page:')
-            )
-        );
-    }
-
-    /**
-     * Add child CMS page block
-     *
-     * @return void
-     */
-    private function _addCmsPageGridBlock()
-    {
-        $this->addChild('cms_pages_grid', 'Magento\Backend\Block\Urlrewrite\Cms\Page\Grid');
-    }
-
-    /**
-     * Creates edit form block
-     *
-     * @return \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form
-     */
-    protected function _createEditFormBlock()
-    {
-        return $this->getLayout()->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form',
-            '',
-            array('data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite()))
-        );
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/Form.php b/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/Form.php
deleted file mode 100644
index ad42ead070c..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/Form.php
+++ /dev/null
@@ -1,175 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page\Edit;
-
-/**
- * Edit form for CMS page URL rewrites
- *
- * @method \Magento\Cms\Model\Page getCmsPage()
- * @method \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form setCmsPage(\Magento\Cms\Model\Page $model)
- * @SuppressWarnings(PHPMD.DepthOfInheritance)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class Form extends \Magento\Backend\Block\Urlrewrite\Edit\Form
-{
-    /**
-     * @var \Magento\Cms\Model\PageFactory
-     */
-    protected $_pageFactory;
-
-    /**
-     * @var \Magento\Cms\Model\Page\UrlrewriteFactory
-     */
-    protected $_urlRewriteFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Store\Model\System\Store $systemStore
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory
-     * @param \Magento\Cms\Model\PageFactory $pageFactory
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Store\Model\System\Store $systemStore,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory,
-        \Magento\Cms\Model\PageFactory $pageFactory,
-        array $data = array()
-    ) {
-        $this->_urlRewriteFactory = $urlRewriteFactory;
-        $this->_pageFactory = $pageFactory;
-        parent::__construct(
-            $context,
-            $registry,
-            $formFactory,
-            $typesFactory,
-            $optionFactory,
-            $rewriteFactory,
-            $systemStore,
-            $adminhtmlData,
-            $data
-        );
-    }
-
-    /**
-     * Form post init
-     *
-     * @param \Magento\Framework\Data\Form $form
-     * @return \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form
-     */
-    protected function _formPostInit($form)
-    {
-        $cmsPage = $this->getCmsPageInstance();
-        $form->setAction(
-            $this->_adminhtmlData->getUrl(
-                'adminhtml/*/save',
-                array('id' => $this->_getModel()->getId(), 'cms_page' => $cmsPage->getId())
-            )
-        );
-
-        // Fill id path, request path and target path elements
-        /** @var $idPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $idPath = $this->getForm()->getElement('id_path');
-        /** @var $requestPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $requestPath = $this->getForm()->getElement('request_path');
-        /** @var $targetPath \Magento\Framework\Data\Form\Element\AbstractElement */
-        $targetPath = $this->getForm()->getElement('target_path');
-
-        $model = $this->_getModel();
-        /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsPageUrlRewrite = $this->_urlRewriteFactory->create();
-        if (!$model->getId()) {
-            $idPath->setValue($cmsPageUrlRewrite->generateIdPath($cmsPage));
-
-            $sessionData = $this->_getSessionData();
-            if (!isset($sessionData['request_path'])) {
-                $requestPath->setValue($cmsPageUrlRewrite->generateRequestPath($cmsPage));
-            }
-            $targetPath->setValue($cmsPageUrlRewrite->generateTargetPath($cmsPage));
-            $disablePaths = true;
-        } else {
-            $cmsPageUrlRewrite->load($this->_getModel()->getId(), 'url_rewrite_id');
-            $disablePaths = $cmsPageUrlRewrite->getId() > 0;
-        }
-        if ($disablePaths) {
-            $idPath->setData('disabled', true);
-            $targetPath->setData('disabled', true);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Get catalog entity associated stores
-     *
-     * @return array
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function _getEntityStores()
-    {
-        $cmsPage = $this->getCmsPageInstance();
-        $entityStores = array();
-
-        // showing websites that only associated to CMS page
-        if ($this->getCmsPageInstance()->getId()) {
-            $entityStores = (array)$cmsPage->getResource()->lookupStoreIds($cmsPage->getId());
-            $this->_requireStoresFilter = !in_array(0, $entityStores);
-
-            if (!$entityStores) {
-                throw new \Magento\Framework\Model\Exception(
-                    __('Chosen cms page is not associated with any website.')
-                );
-            }
-        }
-
-        return $entityStores;
-    }
-
-    /**
-     * Get CMS page model instance
-     *
-     * @return \Magento\Cms\Model\Page
-     */
-    protected function getCmsPageInstance()
-    {
-        if (!$this->hasData('cms_page')) {
-            $this->setCmsPage($this->_pageFactory->create());
-        }
-        return $this->getCmsPage();
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Grid.php b/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Grid.php
deleted file mode 100644
index 905ad2184bc..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Grid.php
+++ /dev/null
@@ -1,113 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page;
-
-/**
- * CMS pages grid for URL rewrites
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Grid extends \Magento\Cms\Block\Adminhtml\Page\Grid
-{
-    /**
-     * Constructor
-     *
-     * @return void
-     */
-    public function _construct()
-    {
-        parent::_construct();
-        $this->setUseAjax(true);
-    }
-
-    /**
-     * Disable massaction
-     *
-     * @return $this
-     */
-    protected function _prepareMassaction()
-    {
-        return $this;
-    }
-
-    /**
-     * Prepare columns layout
-     *
-     * @return $this
-     */
-    protected function _prepareColumns()
-    {
-        $this->addColumn('title', array('header' => __('Title'), 'align' => 'left', 'index' => 'title'));
-
-        $this->addColumn('identifier', array('header' => __('URL Key'), 'align' => 'left', 'index' => 'identifier'));
-
-        if (!$this->_storeManager->isSingleStoreMode()) {
-            $this->addColumn(
-                'store_id',
-                array(
-                    'header' => __('Store View'),
-                    'index' => 'store_id',
-                    'type' => 'store',
-                    'store_all' => true,
-                    'store_view' => true,
-                    'sortable' => false,
-                    'filter_condition_callback' => array($this, '_filterStoreCondition')
-                )
-            );
-        }
-
-        $this->addColumn(
-            'is_active',
-            array(
-                'header' => __('Status'),
-                'index' => 'is_active',
-                'type' => 'options',
-                'options' => $this->_cmsPage->getAvailableStatuses()
-            )
-        );
-
-        return $this;
-    }
-
-    /**
-     * Get URL for dispatching grid ajax requests
-     *
-     * @return string
-     */
-    public function getGridUrl()
-    {
-        return $this->getUrl('adminhtml/*/cmsPageGrid', array('_current' => true));
-    }
-
-    /**
-     * Return row url for js event handlers
-     *
-     * @param \Magento\Cms\Model\Page|\Magento\Framework\Object $row
-     * @return string
-     */
-    public function getRowUrl($row)
-    {
-        return $this->getUrl('adminhtml/*/edit', array('cms_page' => $row->getId()));
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Edit.php
deleted file mode 100644
index 66ae64dbdde..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Edit.php
+++ /dev/null
@@ -1,300 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite;
-
-/**
- * Block for URL rewrites edit page
- *
- * @method \Magento\UrlRewrite\Model\UrlRewrite getUrlRewrite()
- * @method \Magento\Backend\Block\Urlrewrite\Edit setUrlRewrite(\Magento\UrlRewrite\Model\UrlRewrite $urlRewrite)
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Backend\Block\Widget\Container
-{
-    /**
-     * @var \Magento\Backend\Block\Urlrewrite\Selector
-     */
-    private $_selectorBlock;
-
-    /**
-     * Part for building some blocks names
-     *
-     * @var string
-     */
-    protected $_controller = 'urlrewrite';
-
-    /**
-     * Generated buttons html cache
-     *
-     * @var string
-     */
-    protected $_buttonsHtml;
-
-    /**
-     * Adminhtml data
-     *
-     * @var \Magento\Backend\Helper\Data
-     */
-    protected $_adminhtmlData = null;
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
-     */
-    protected $_rewriteFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        array $data = array()
-    ) {
-        $this->_rewriteFactory = $rewriteFactory;
-        $this->_adminhtmlData = $adminhtmlData;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Prepare URL rewrite editing layout
-     *
-     * @return $this
-     */
-    protected function _prepareLayout()
-    {
-        $this->setTemplate('urlrewrite/edit.phtml');
-
-        $this->_addBackButton();
-        $this->_prepareLayoutFeatures();
-
-        return parent::_prepareLayout();
-    }
-
-    /**
-     * Prepare featured blocks for layout of URL rewrite editing
-     *
-     * @return void
-     */
-    protected function _prepareLayoutFeatures()
-    {
-        if ($this->_getUrlRewrite()->getId()) {
-            $this->_headerText = __('Edit URL Rewrite');
-        } else {
-            $this->_headerText = __('Add New URL Rewrite');
-        }
-
-        $this->_updateBackButtonLink(
-            $this->_adminhtmlData->getUrl('adminhtml/*/edit') . $this->_getSelectorBlock()->getDefaultMode()
-        );
-        $this->_addUrlRewriteSelectorBlock();
-        $this->_addEditFormBlock();
-    }
-
-    /**
-     * Add child edit form block
-     *
-     * @return void
-     */
-    protected function _addEditFormBlock()
-    {
-        $this->setChild('form', $this->_createEditFormBlock());
-
-        if ($this->_getUrlRewrite()->getId()) {
-            $this->_addResetButton();
-            $this->_addDeleteButton();
-        }
-
-        $this->_addSaveButton();
-    }
-
-    /**
-     * Add reset button
-     *
-     * @return void
-     */
-    protected function _addResetButton()
-    {
-        $this->buttonList->add(
-            'reset',
-            array(
-                'label' => __('Reset'),
-                'onclick' => '$(\'edit_form\').reset()',
-                'class' => 'scalable',
-                'level' => -1
-            )
-        );
-    }
-
-    /**
-     * Add back button
-     *
-     * @return void
-     */
-    protected function _addBackButton()
-    {
-        $this->buttonList->add(
-            'back',
-            array(
-                'label' => __('Back'),
-                'onclick' => 'setLocation(\'' . $this->_adminhtmlData->getUrl('adminhtml/*/') . '\')',
-                'class' => 'back',
-                'level' => -1
-            )
-        );
-    }
-
-    /**
-     * Update Back button location link
-     *
-     * @param string $link
-     * @return void
-     */
-    protected function _updateBackButtonLink($link)
-    {
-        $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $link . '\')');
-    }
-
-    /**
-     * Add delete button
-     *
-     * @return void
-     */
-    protected function _addDeleteButton()
-    {
-        $this->buttonList->add(
-            'delete',
-            array(
-                'label' => __('Delete'),
-                'onclick' => 'deleteConfirm(\'' . addslashes(
-                    __('Are you sure you want to do this?')
-                ) . '\', \'' . $this->_adminhtmlData->getUrl(
-                    'adminhtml/*/delete',
-                    array('id' => $this->getUrlRewrite()->getId())
-                ) . '\')',
-                'class' => 'scalable delete',
-                'level' => -1
-            )
-        );
-    }
-
-    /**
-     * Add save button
-     *
-     * @return void
-     */
-    protected function _addSaveButton()
-    {
-        $this->buttonList->add(
-            'save',
-            array(
-                'label' => __('Save'),
-                'class' => 'save primary save-url-redirect',
-                'level' => -1,
-                'data_attribute' => array(
-                    'mage-init' => array('button' => array('event' => 'save', 'target' => '#edit_form'))
-                )
-            )
-        );
-    }
-
-    /**
-     * Creates edit form block
-     *
-     * @return \Magento\Backend\Block\Urlrewrite\Edit\Form
-     */
-    protected function _createEditFormBlock()
-    {
-        return $this->getLayout()->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Edit\Form',
-            '',
-            array('data' => array('url_rewrite' => $this->_getUrlRewrite()))
-        );
-    }
-
-    /**
-     * Add child URL rewrite selector block
-     *
-     * @return void
-     */
-    protected function _addUrlRewriteSelectorBlock()
-    {
-        $this->setChild('selector', $this->_getSelectorBlock());
-    }
-
-    /**
-     * Get selector block
-     *
-     * @return \Magento\Backend\Block\Urlrewrite\Selector
-     */
-    private function _getSelectorBlock()
-    {
-        if (!$this->_selectorBlock) {
-            $this->_selectorBlock = $this->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Selector');
-        }
-        return $this->_selectorBlock;
-    }
-
-    /**
-     * Get container buttons HTML
-     *
-     * Since buttons are set as children, we remove them as children after generating them
-     * not to duplicate them in future
-     *
-     * @param null $area
-     * @return string
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function getButtonsHtml($area = null)
-    {
-        if (null === $this->_buttonsHtml) {
-            $this->_buttonsHtml = parent::getButtonsHtml();
-            $layout = $this->getLayout();
-            foreach ($this->getChildNames() as $name) {
-                $alias = $layout->getElementAlias($name);
-                if (false !== strpos($alias, '_button')) {
-                    $layout->unsetChild($this->getNameInLayout(), $alias);
-                }
-            }
-        }
-        return $this->_buttonsHtml;
-    }
-
-    /**
-     * Get or create new instance of URL rewrite
-     *
-     * @return \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    protected function _getUrlRewrite()
-    {
-        if (!$this->hasData('url_rewrite')) {
-            $this->setUrlRewrite($this->_rewriteFactory->create());
-        }
-        return $this->getUrlRewrite();
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Edit/Form.php b/app/code/Magento/Backend/Block/Urlrewrite/Edit/Form.php
deleted file mode 100644
index 42f7d0264e0..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Edit/Form.php
+++ /dev/null
@@ -1,417 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite\Edit;
-
-/**
- * URL rewrites edit form
- *
- * @method \Magento\UrlRewrite\Model\UrlRewrite getUrlRewrite()
- * @method \Magento\Backend\Block\Urlrewrite\Edit\Form setUrlRewrite(\Magento\UrlRewrite\Model\UrlRewrite $model)
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- *
- *
- * @SuppressWarnings(PHPMD.DepthOfInheritance)
- */
-class Form extends \Magento\Backend\Block\Widget\Form\Generic
-{
-    /**
-     * @var array
-     */
-    protected $_sessionData = null;
-
-    /**
-     * @var array
-     */
-    protected $_allStores = null;
-
-    /**
-     * @var bool
-     */
-    protected $_requireStoresFilter = false;
-
-    /**
-     * @var array
-     */
-    protected $_formValues = array();
-
-    /**
-     * Adminhtml data
-     *
-     * @var \Magento\Backend\Helper\Data
-     */
-    protected $_adminhtmlData = null;
-
-    /**
-     * @var \Magento\Store\Model\System\Store
-     */
-    protected $_systemStore;
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
-     */
-    protected $_rewriteFactory;
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory
-     */
-    protected $_optionFactory;
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory
-     */
-    protected $_typesFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Store\Model\System\Store $systemStore
-     * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\TypeProviderFactory $typesFactory,
-        \Magento\UrlRewrite\Model\UrlRewrite\OptionProviderFactory $optionFactory,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Store\Model\System\Store $systemStore,
-        \Magento\Backend\Helper\Data $adminhtmlData,
-        array $data = array()
-    ) {
-        $this->_typesFactory = $typesFactory;
-        $this->_optionFactory = $optionFactory;
-        $this->_rewriteFactory = $rewriteFactory;
-        $this->_systemStore = $systemStore;
-        $this->_adminhtmlData = $adminhtmlData;
-        parent::__construct($context, $registry, $formFactory, $data);
-    }
-
-    /**
-     * Set form id and title
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setId('urlrewrite_form');
-        $this->setTitle(__('Block Information'));
-    }
-
-    /**
-     * Initialize form values
-     * Set form data either from model values or from session
-     *
-     * @return $this
-     */
-    protected function _initFormValues()
-    {
-        $model = $this->_getModel();
-        $this->_formValues = array(
-            'store_id' => $model->getStoreId(),
-            'id_path' => $model->getIdPath(),
-            'request_path' => $model->getRequestPath(),
-            'target_path' => $model->getTargetPath(),
-            'options' => $model->getOptions(),
-            'description' => $model->getDescription()
-        );
-
-        $sessionData = $this->_getSessionData();
-        if ($sessionData) {
-            foreach (array_keys($this->_formValues) as $key) {
-                if (isset($sessionData[$key])) {
-                    $this->_formValues[$key] = $sessionData[$key];
-                }
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * Prepare the form layout
-     *
-     * @return $this
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    protected function _prepareForm()
-    {
-        $this->_initFormValues();
-
-        // Prepare form
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create(
-            array('data' => array('id' => 'edit_form', 'use_container' => true, 'method' => 'post'))
-        );
-
-        $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('URL Rewrite Information')));
-
-        /** @var $typesModel \Magento\UrlRewrite\Model\UrlRewrite\TypeProvider */
-        $typesModel = $this->_typesFactory->create();
-        $fieldset->addField(
-            'is_system',
-            'select',
-            array(
-                'label' => __('Type'),
-                'title' => __('Type'),
-                'name' => 'is_system',
-                'required' => true,
-                'options' => $typesModel->getAllOptions(),
-                'disabled' => true,
-                'value' => $this->_getModel()->getIsSystem()
-            )
-        );
-
-        $fieldset->addField(
-            'id_path',
-            'text',
-            array(
-                'label' => __('ID Path'),
-                'title' => __('ID Path'),
-                'name' => 'id_path',
-                'required' => true,
-                'disabled' => false,
-                'value' => $this->_formValues['id_path']
-            )
-        );
-
-        $fieldset->addField(
-            'request_path',
-            'text',
-            array(
-                'label' => __('Request Path'),
-                'title' => __('Request Path'),
-                'name' => 'request_path',
-                'required' => true,
-                'value' => $this->_formValues['request_path']
-            )
-        );
-
-        $fieldset->addField(
-            'target_path',
-            'text',
-            array(
-                'label' => __('Target Path'),
-                'title' => __('Target Path'),
-                'name' => 'target_path',
-                'required' => true,
-                'disabled' => false,
-                'value' => $this->_formValues['target_path']
-            )
-        );
-
-        /** @var $optionsModel \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider */
-        $optionsModel = $this->_optionFactory->create();
-        $fieldset->addField(
-            'options',
-            'select',
-            array(
-                'label' => __('Redirect'),
-                'title' => __('Redirect'),
-                'name' => 'options',
-                'options' => $optionsModel->getAllOptions(),
-                'value' => $this->_formValues['options']
-            )
-        );
-
-        $fieldset->addField(
-            'description',
-            'textarea',
-            array(
-                'label' => __('Description'),
-                'title' => __('Description'),
-                'name' => 'description',
-                'cols' => 20,
-                'rows' => 5,
-                'value' => $this->_formValues['description'],
-                'wrap' => 'soft'
-            )
-        );
-
-        $this->_prepareStoreElement($fieldset);
-
-        $this->setForm($form);
-        $this->_formPostInit($form);
-
-        return parent::_prepareForm();
-    }
-
-    /**
-     * Prepare store element
-     *
-     * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
-     * @return void
-     */
-    protected function _prepareStoreElement($fieldset)
-    {
-        // get store switcher or a hidden field with it's id
-        if ($this->_storeManager->isSingleStoreMode()) {
-            $fieldset->addField(
-                'store_id',
-                'hidden',
-                array('name' => 'store_id', 'value' => $this->_storeManager->getStore(true)->getId()),
-                'id_path'
-            );
-        } else {
-            /** @var $renderer \Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element */
-            $renderer = $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
-            );
-
-            $storeElement = $fieldset->addField(
-                'store_id',
-                'select',
-                array(
-                    'label' => __('Store'),
-                    'title' => __('Store'),
-                    'name' => 'store_id',
-                    'required' => true,
-                    'values' => $this->_getRestrictedStoresList(),
-                    'disabled' => $this->_getModel()->getIsSystem(),
-                    'value' => $this->_formValues['store_id']
-                ),
-                'id_path'
-            );
-            $storeElement->setRenderer($renderer);
-        }
-    }
-
-    /**
-     * Form post init
-     *
-     * @param \Magento\Framework\Data\Form $form
-     * @return $this
-     */
-    protected function _formPostInit($form)
-    {
-        $form->setAction(
-            $this->_adminhtmlData->getUrl('adminhtml/*/save', array('id' => $this->_getModel()->getId()))
-        );
-        return $this;
-    }
-
-    /**
-     * Get session data
-     *
-     * @return array
-     */
-    protected function _getSessionData()
-    {
-        if (is_null($this->_sessionData)) {
-            $this->_sessionData = $this->_backendSession->getData('urlrewrite_data', true);
-        }
-        return $this->_sessionData;
-    }
-
-    /**
-     * Get URL rewrite model instance
-     *
-     * @return \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    protected function _getModel()
-    {
-        if (!$this->hasData('url_rewrite')) {
-            $this->setUrlRewrite($this->_rewriteFactory->create());
-        }
-        return $this->getUrlRewrite();
-    }
-
-    /**
-     * Get request stores
-     *
-     * @return array
-     */
-    protected function _getAllStores()
-    {
-        if (is_null($this->_allStores)) {
-            $this->_allStores = $this->_systemStore->getStoreValuesForForm();
-        }
-
-        return $this->_allStores;
-    }
-
-    /**
-     * Get entity stores
-     *
-     * @return array
-     */
-    protected function _getEntityStores()
-    {
-        return $this->_getAllStores();
-    }
-
-    /**
-     * Get restricted stores list
-     * Stores should be filtered only if custom entity is specified.
-     * If we use custom rewrite, all stores are accepted.
-     *
-     * @return array
-     */
-    protected function _getRestrictedStoresList()
-    {
-        $stores = $this->_getAllStores();
-        $entityStores = $this->_getEntityStores();
-        $stores = $this->_getStoresListRestrictedByEntityStores($stores, $entityStores);
-
-        return $stores;
-    }
-
-    /**
-     * Get stores list restricted by entity stores
-     *
-     * @param array $stores
-     * @param array $entityStores
-     * @return array
-     */
-    private function _getStoresListRestrictedByEntityStores(array $stores, array $entityStores)
-    {
-        if ($this->_requireStoresFilter) {
-            foreach ($stores as $i => $store) {
-                if (isset($store['value']) && $store['value']) {
-                    $found = false;
-                    foreach ($store['value'] as $k => $v) {
-                        if (isset($v['value']) && in_array($v['value'], $entityStores)) {
-                            $found = true;
-                        } else {
-                            unset($stores[$i]['value'][$k]);
-                        }
-                    }
-                    if (!$found) {
-                        unset($stores[$i]);
-                    }
-                }
-            }
-        }
-
-        return $stores;
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Selector.php b/app/code/Magento/Backend/Block/Urlrewrite/Selector.php
deleted file mode 100644
index 46ce62f5674..00000000000
--- a/app/code/Magento/Backend/Block/Urlrewrite/Selector.php
+++ /dev/null
@@ -1,100 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Urlrewrite;
-
-/**
- * Modes selector for URL rewrites modes
- */
-class Selector extends \Magento\Framework\View\Element\Template
-{
-    /**
-     * List of available modes from source model
-     * key => label
-     *
-     * @var array
-     */
-    protected $_modes;
-
-    /**
-     * @var string
-     */
-    protected $_template = 'urlrewrite/selector.phtml';
-
-    /**
-     * Set block template and get available modes
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_modes = array(
-            'category' => __('For category'),
-            'product' => __('For product'),
-            'cms_page' => __('For CMS page'),
-            'id' => __('Custom')
-        );
-    }
-
-    /**
-     * Available modes getter
-     *
-     * @return array
-     */
-    public function getModes()
-    {
-        return $this->_modes;
-    }
-
-    /**
-     * Label getter
-     *
-     * @return string
-     */
-    public function getSelectorLabel()
-    {
-        return __('Create URL Rewrite:');
-    }
-
-    /**
-     * Check whether selection is in specified mode
-     *
-     * @param string $mode
-     * @return bool
-     */
-    public function isMode($mode)
-    {
-        return $this->getRequest()->has($mode);
-    }
-
-    /**
-     * Get default mode
-     *
-     * @return string
-     */
-    public function getDefaultMode()
-    {
-        $keys = array_keys($this->_modes);
-        return array_shift($keys);
-    }
-}
diff --git a/app/code/Magento/Backend/Block/Widget/Context.php b/app/code/Magento/Backend/Block/Widget/Context.php
index 8ffce8ce307..9596a04f3e3 100644
--- a/app/code/Magento/Backend/Block/Widget/Context.php
+++ b/app/code/Magento/Backend/Block/Widget/Context.php
@@ -39,6 +39,11 @@ class Context extends \Magento\Backend\Block\Template\Context
      */
     protected $buttonToolbar;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\View\LayoutInterface $layout
@@ -70,6 +75,7 @@ class Context extends \Magento\Backend\Block\Template\Context
      * @param \Magento\Framework\Code\NameBuilder $nameBuilder
      * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
      * @param Button\ToolbarInterface $toolbar
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -97,6 +103,7 @@ class Context extends \Magento\Backend\Block\Template\Context
         \Magento\Framework\View\TemplateEnginePool $enginePool,
         \Magento\Framework\App\State $appState,
         \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\View\Page\Config $pageConfig,
         \Magento\Framework\AuthorizationInterface $authorization,
         \Magento\Backend\Model\Session $backendSession,
         \Magento\Framework\Math\Random $mathRandom,
@@ -129,6 +136,7 @@ class Context extends \Magento\Backend\Block\Template\Context
             $enginePool,
             $appState,
             $storeManager,
+            $pageConfig,
             $authorization,
             $backendSession,
             $mathRandom,
diff --git a/app/code/Magento/Backend/Block/Widget/Grid.php b/app/code/Magento/Backend/Block/Widget/Grid.php
index 3cade6d445f..84f1156aaf8 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid.php
@@ -132,13 +132,6 @@ class Grid extends \Magento\Backend\Block\Widget
      */
     protected $_varTotals;
 
-    /**
-     * RSS list
-     *
-     * @var \Magento\Framework\Object[]
-     */
-    protected $_rssLists = array();
-
     /**
      * @var string
      */
@@ -201,12 +194,6 @@ class Grid extends \Magento\Backend\Block\Widget
         );
 
         $this->setData('use_ajax', $this->hasData('use_ajax') ? (bool)$this->getData('use_ajax') : false);
-
-        if ($this->hasData('rssList') && is_array($this->getData('rssList'))) {
-            foreach ($this->getData('rssList') as $item) {
-                $this->addRssList($item['url'], $item['label']);
-            }
-        }
     }
 
     /**
@@ -697,42 +684,6 @@ class Grid extends \Magento\Backend\Block\Widget
         return $this;
     }
 
-    /**
-     * Retrieve rss lists types
-     *
-     * @return \Magento\Framework\Object[]|false
-     */
-    public function getRssLists()
-    {
-        return empty($this->_rssLists) ? false : $this->_rssLists;
-    }
-
-    /**
-     * Add new rss list to grid
-     *
-     * @param   string $url
-     * @param   string $label
-     * @return  $this
-     */
-    public function addRssList($url, $label)
-    {
-        $this->_rssLists[] = new \Magento\Framework\Object(
-            array('url' => $this->getUrl($url, array('_nosecret' => true)), 'label' => $label)
-        );
-        return $this;
-    }
-
-    /**
-     * Clear rss list in grid
-     *
-     * @return  $this
-     */
-    public function clearRss()
-    {
-        $this->_rssLists = array();
-        return $this;
-    }
-
     /**
      * Check whether grid container should be displayed
      *
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Date.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Date.php
index 2347f088675..39b5fe89c57 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Date.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Date.php
@@ -57,17 +57,6 @@ class Date extends \Magento\Backend\Block\Widget\Grid\Column\Filter\AbstractFilt
         parent::__construct($context, $resourceHelper, $data);
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function _prepareLayout()
-    {
-        if ($head = $this->getLayout()->getBlock('head')) {
-            $head->setCanLoadCalendarJs(true);
-        }
-        return $this;
-    }
-
     /**
      * @return string
      */
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/AbstractRenderer.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/AbstractRenderer.php
index b38adef9876..ebd0aae1102 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/AbstractRenderer.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/AbstractRenderer.php
@@ -24,14 +24,12 @@
 namespace Magento\Backend\Block\Widget\Grid\Column\Renderer;
 
 use Magento\Backend\Block\Widget\Grid\Column;
+use Magento\Framework\Object;
 
 /**
  * Backend grid item abstract renderer
- *
- * @author     Magento Core Team <core@magentocommerce.com>
  */
-abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock implements
-    \Magento\Backend\Block\Widget\Grid\Column\Renderer\RendererInterface
+abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock implements RendererInterface
 {
     /**
      * @var int
@@ -64,10 +62,10 @@ abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock imp
     /**
      * Renders grid column
      *
-     * @param   \Magento\Framework\Object $row
+     * @param   Object $row
      * @return  string
      */
-    public function render(\Magento\Framework\Object $row)
+    public function render(Object $row)
     {
         if ($this->getColumn()->getEditable()) {
             $value = $this->_getValue($row);
@@ -82,19 +80,19 @@ abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock imp
     /**
      * Render column for export
      *
-     * @param \Magento\Framework\Object $row
+     * @param Object $row
      * @return string
      */
-    public function renderExport(\Magento\Framework\Object $row)
+    public function renderExport(Object $row)
     {
         return $this->render($row);
     }
 
     /**
-     * @param \Magento\Framework\Object $row
+     * @param Object $row
      * @return mixed
      */
-    protected function _getValue(\Magento\Framework\Object $row)
+    protected function _getValue(Object $row)
     {
         if ($getter = $this->getColumn()->getGetter()) {
             if (is_string($getter)) {
@@ -108,10 +106,10 @@ abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock imp
     }
 
     /**
-     * @param \Magento\Framework\Object $row
+     * @param Object $row
      * @return string
      */
-    public function _getInputValueElement(\Magento\Framework\Object $row)
+    public function _getInputValueElement(Object $row)
     {
         return '<input type="text" class="input-text ' .
             $this->getColumn()->getValidateClass() .
@@ -124,10 +122,10 @@ abstract class AbstractRenderer extends \Magento\Backend\Block\AbstractBlock imp
     }
 
     /**
-     * @param \Magento\Framework\Object $row
+     * @param Object $row
      * @return mixed
      */
-    protected function _getInputValue(\Magento\Framework\Object $row)
+    protected function _getInputValue(Object $row)
     {
         return $this->_getValue($row);
     }
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Concat.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Concat.php
index aa528c9a2de..535ac81f38a 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Concat.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Concat.php
@@ -39,14 +39,24 @@ class Concat extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstract
      */
     public function render(\Magento\Framework\Object $row)
     {
-        $dataArr = array();
-        foreach ($this->getColumn()->getIndex() as $index) {
-            if ($data = $row->getData($index)) {
+        $dataArr = [];
+        $column = $this->getColumn();
+        $methods = $column->getGetter() ?: $column->getIndex();
+        foreach ($methods as $method) {
+            if ($column->getGetter()
+                && is_callable([$row, $method])
+                && substr_compare('get', $method, 1, 3) !== 0
+            ) {
+                $data = call_user_func([$row, $method]);
+            } else {
+                $data = $row->getData($method);
+            }
+            if (strlen($data) > 0) {
                 $dataArr[] = $data;
             }
         }
-        $data = join($this->getColumn()->getSeparator(), $dataArr);
-        // TODO run column type renderer
+        $data = implode($column->getSeparator(), $dataArr);
+
         return $data;
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php
index 65bade9c886..1d5f788a1a4 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php
@@ -52,10 +52,6 @@ class Save extends \Magento\Backend\Controller\Adminhtml\System\Account
         )->setEmail(
             strtolower($this->getRequest()->getParam('email', false))
         );
-        if ($password !== '') {
-            $user->setPassword($password);
-            $user->setPasswordConfirmation($passwordConfirmation);
-        }
 
         if ($this->_objectManager->get('Magento\Framework\Locale\Validator')->isValid($interfaceLocale)) {
             $user->setInterfaceLocale($interfaceLocale);
@@ -65,13 +61,28 @@ class Save extends \Magento\Backend\Controller\Adminhtml\System\Account
                 $interfaceLocale
             );
         }
-
+        /** Before updating admin user data, ensure that password of current admin user is entered and is correct */
+        $currentUserPasswordField = \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD;
+        $currentUserPassword = $this->getRequest()->getParam($currentUserPasswordField);
+        $isCurrentUserPasswordValid = !empty($currentUserPassword) && is_string($currentUserPassword);
         try {
+            if (!($isCurrentUserPasswordValid && $user->verifyIdentity($currentUserPassword))) {
+                throw new \Magento\Backend\Model\Auth\Exception(
+                    __('You have entered an invalid password for current user.')
+                );
+            }
+            if ($password !== '') {
+                $user->setPassword($password);
+                $user->setPasswordConfirmation($passwordConfirmation);
+            }
             $user->save();
             $user->sendPasswordResetNotificationEmail();
             $this->messageManager->addSuccess(__('The account has been saved.'));
         } catch (\Magento\Framework\Model\Exception $e) {
             $this->messageManager->addMessages($e->getMessages());
+            if ($e->getMessage()) {
+                $this->messageManager->addError($e->getMessage());
+            }
         } catch (\Exception $e) {
             $this->messageManager->addError(__('An error occurred while saving account.'));
         }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php
index 842c6df2ba9..e434d543c56 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php
@@ -35,7 +35,6 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\System\Design
 
         $this->_view->loadLayout();
         $this->_setActiveMenu('Magento_Backend::system_design_schedule');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
 
         $id = (int)$this->getRequest()->getParam('id');
         $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface');
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php
deleted file mode 100644
index 8ac8b5ac9d1..00000000000
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php
+++ /dev/null
@@ -1,262 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
-
-use Magento\Catalog\Model\Category;
-use Magento\Catalog\Model\Product;
-use Magento\Framework\Model\Exception;
-
-class Save extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
-{
-    /**
-     * Call before save urlrewrite handlers
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function _onUrlRewriteSaveBefore($model)
-    {
-        $this->_handleCatalogUrlRewrite($model);
-        $this->_handleCmsPageUrlRewrite($model);
-    }
-
-    /**
-     * Call after save urlrewrite handlers
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function _onUrlRewriteSaveAfter($model)
-    {
-        $this->_handleCmsPageUrlRewriteSave($model);
-    }
-
-    /**
-     * Override urlrewrite data, basing on current category and product
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     * @throws Exception
-     */
-    protected function _handleCatalogUrlRewrite($model)
-    {
-        $product = $this->_getInitializedProduct($model);
-        $category = $this->_getInitializedCategory($model);
-
-        if ($product || $category) {
-            /** @var $catalogUrlModel \Magento\Catalog\Model\Url */
-            $catalogUrlModel = $this->_objectManager->get('Magento\Catalog\Model\Url');
-            $idPath = $catalogUrlModel->generatePath('id', $product, $category);
-            $model->setIdPath($idPath);
-
-            // if redirect specified try to find friendly URL
-            $generateTarget = true;
-            if ($this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->hasRedirectOptions($model)) {
-                /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
-                $rewriteResource = $this->_objectManager->create('Magento\Catalog\Model\Resource\Url');
-                /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-                $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
-                if (!$rewrite) {
-                    if ($product) {
-                        throw new Exception(
-                            __('Chosen product does not associated with the chosen store or category.')
-                        );
-                    } else {
-                        throw new Exception(__('Chosen category does not associated with the chosen store.'));
-                    }
-                } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
-                    $model->setTargetPath($rewrite->getRequestPath());
-                    $generateTarget = false;
-                }
-            }
-            if ($generateTarget) {
-                $model->setTargetPath($catalogUrlModel->generatePath('target', $product, $category));
-            }
-        }
-    }
-
-    /**
-     * Get product instance applicable for generatePath
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return Product|null
-     */
-    protected function _getInitializedProduct($model)
-    {
-        /** @var $product Product */
-        $product = $this->_getProduct();
-        if ($product->getId()) {
-            $model->setProductId($product->getId());
-        } else {
-            $product = null;
-        }
-
-        return $product;
-    }
-
-    /**
-     * Override URL rewrite data, basing on current CMS page
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function _handleCmsPageUrlRewrite($model)
-    {
-        /** @var $cmsPage \Magento\Cms\Model\Page */
-        $cmsPage = $this->_getCmsPage();
-        if (!$cmsPage->getId()) {
-            return;
-        }
-
-        /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsPageUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
-        $idPath = $cmsPageUrlRewrite->generateIdPath($cmsPage);
-        $model->setIdPath($idPath);
-
-        // if redirect specified try to find friendly URL
-        $generateTarget = true;
-        if ($model->getId()
-            && $this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->hasRedirectOptions($model)
-        ) {
-            /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
-            $rewriteResource = $this->_objectManager->create('Magento\Catalog\Model\Resource\Url');
-            /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-            $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
-            if (!$rewrite) {
-                throw new Exception(__('Chosen cms page does not associated with the chosen store.'));
-            } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
-                $model->setTargetPath($rewrite->getRequestPath());
-                $generateTarget = false;
-            }
-        }
-
-        if ($generateTarget) {
-            $model->setTargetPath($cmsPageUrlRewrite->generateTargetPath($cmsPage));
-        }
-    }
-
-    /**
-     * Save CMS page URL rewrite additional information
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function _handleCmsPageUrlRewriteSave($model)
-    {
-        /** @var $cmsPage \Magento\Cms\Model\Page */
-        $cmsPage = $this->_getCmsPage();
-        if (!$cmsPage->getId()) {
-            return;
-        }
-
-        /** @var $cmsRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
-        $cmsRewrite->load($model->getId(), 'url_rewrite_id');
-        if (!$cmsRewrite->getId()) {
-            $cmsRewrite->setUrlRewriteId($model->getId());
-            $cmsRewrite->setCmsPageId($cmsPage->getId());
-            $cmsRewrite->save();
-        }
-    }
-
-    /**
-     * Get category instance applicable for generatePath
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return Category|null
-     */
-    protected function _getInitializedCategory($model)
-    {
-        /** @var $category Category */
-        $category = $this->_getCategory();
-        if ($category->getId()) {
-            $model->setCategoryId($category->getId());
-        } else {
-            $category = null;
-        }
-        return $category;
-    }
-
-    /**
-     * Urlrewrite save action
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        if ($data = $this->getRequest()->getPost()) {
-            /** @var $session \Magento\Backend\Model\Session */
-            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-            try {
-                // set basic urlrewrite data
-                /** @var $model \Magento\UrlRewrite\Model\UrlRewrite */
-                $model = $this->_getUrlRewrite();
-
-                // Validate request path
-                $requestPath = $this->getRequest()->getParam('request_path');
-                $this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->validateRequestPath($requestPath);
-
-                // Proceed and save request
-                $model->setIdPath(
-                    $this->getRequest()->getParam('id_path')
-                )->setTargetPath(
-                    $this->getRequest()->getParam('target_path')
-                )->setOptions(
-                    $this->getRequest()->getParam('options')
-                )->setDescription(
-                    $this->getRequest()->getParam('description')
-                )->setRequestPath(
-                    $requestPath
-                );
-
-                if (!$model->getId()) {
-                    $model->setIsSystem(0);
-                }
-                if (!$model->getIsSystem()) {
-                    $model->setStoreId($this->getRequest()->getParam('store_id', 0));
-                }
-
-                $this->_onUrlRewriteSaveBefore($model);
-
-                // save and redirect
-                $model->save();
-
-                $this->_onUrlRewriteSaveAfter($model);
-
-                $this->messageManager->addSuccess(__('The URL Rewrite has been saved.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $session->setUrlrewriteData($data);
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.'));
-                $session->setUrlrewriteData($data);
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-}
diff --git a/app/code/Magento/Backend/Model/Config/Backend/Cookie/Domain.php b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Domain.php
new file mode 100644
index 00000000000..60f950e8a7d
--- /dev/null
+++ b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Domain.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+use Magento\Framework\App\Config\Value;
+
+/**
+ * Backend model for domain config value
+ */
+class Domain extends \Magento\Framework\App\Config\Value
+{
+    /** @var \Magento\Framework\Session\Config\Validator\CookieDomainValidator */
+    protected $configValidator;
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
+     * @param \Magento\Framework\Session\Config\Validator\CookieDomainValidator $configValidator
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\App\Config\ScopeConfigInterface $config,
+        \Magento\Framework\Session\Config\Validator\CookieDomainValidator $configValidator,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
+        array $data = array()
+    ) {
+        $this->configValidator = $configValidator;
+        parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
+    }
+
+    /**
+     * Validate a domain name value
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    protected function _beforeSave()
+    {
+        $value = $this->getValue();
+
+        // Empty value is treated valid and will be handled when read the value out
+        if (!empty($value) && !$this->configValidator->isValid($value)) {
+            $msg = __('Invalid domain name: ' . join('; ', $this->configValidator->getMessages()));
+            throw new \Magento\Framework\Model\Exception($msg);
+        }
+    }
+}
diff --git a/app/code/Magento/Backend/Model/Config/Backend/Cookie/Lifetime.php b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Lifetime.php
new file mode 100644
index 00000000000..157942607d5
--- /dev/null
+++ b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Lifetime.php
@@ -0,0 +1,73 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+use Magento\Framework\App\Config\Value;
+
+/**
+ * Backend model for domain config value
+ */
+class Lifetime extends \Magento\Framework\App\Config\Value
+{
+    /** @var  \Magento\Framework\Session\Config\Validator\CookieLifetimeValidator */
+    protected $configValidator;
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
+     * @param \Magento\Framework\Session\Config\Validator\CookieLifetimeValidator $configValidator
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\App\Config\ScopeConfigInterface $config,
+        \Magento\Framework\Session\Config\Validator\CookieLifetimeValidator $configValidator,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
+        array $data = array()
+    ) {
+        $this->configValidator = $configValidator;
+        parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
+    }
+
+    /**
+     * Validate a domain name value
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    protected function _beforeSave()
+    {
+        $value = $this->getValue();
+
+        if (!empty($value) && !$this->configValidator->isValid($value)) {
+            $msg = __('Invalid cookie lifetime: ' . join('; ', $this->configValidator->getMessages()));
+            throw new \Magento\Framework\Model\Exception($msg);
+        }
+    }
+}
diff --git a/app/code/Magento/Backend/Model/Config/Backend/Cookie/Path.php b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Path.php
new file mode 100644
index 00000000000..731f2f37aab
--- /dev/null
+++ b/app/code/Magento/Backend/Model/Config/Backend/Cookie/Path.php
@@ -0,0 +1,72 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+use Magento\Framework\App\Config\Value;
+
+/**
+ * Backend model for domain config value
+ */
+class Path extends \Magento\Framework\App\Config\Value
+{
+    /** @var \Magento\Framework\Session\Config\Validator\CookiePathValidator */
+    protected $configValidator;
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
+     * @param \Magento\Framework\Session\Config\Validator\CookiePathValidator $configValidator
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\App\Config\ScopeConfigInterface $config,
+        \Magento\Framework\Session\Config\Validator\CookiePathValidator $configValidator,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
+        array $data = array()
+    ) {
+        $this->configValidator = $configValidator;
+        parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
+    }
+
+    /**
+     * Validate a domain name value
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    protected function _beforeSave()
+    {
+        $value = $this->getValue();
+
+        if (!empty($value) && !$this->configValidator->isValid($value)) {
+            throw new \Magento\Framework\Model\Exception(__('Invalid cookie path'));
+        }
+    }
+}
diff --git a/app/code/Magento/Backend/Model/Config/Backend/Currency/AbstractCurrency.php b/app/code/Magento/Backend/Model/Config/Backend/Currency/AbstractCurrency.php
index 92057cbee81..8c309cbdd37 100644
--- a/app/code/Magento/Backend/Model/Config/Backend/Currency/AbstractCurrency.php
+++ b/app/code/Magento/Backend/Model/Config/Backend/Currency/AbstractCurrency.php
@@ -75,7 +75,11 @@ abstract class AbstractCurrency extends \Magento\Framework\App\Config\Value
         if ($this->getData('groups/options/fields/allow/inherit')) {
             return explode(
                 ',',
-                (string)$this->_config->getValue('currency/options/allow', $this->getScope(), $this->getScopeId())
+                (string)$this->_config->getValue(
+                    \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW,
+                    $this->getScope(),
+                    $this->getScopeId()
+                )
             );
         }
         return $this->getData('groups/options/fields/allow/value');
diff --git a/app/code/Magento/Backend/AdminConfig.php b/app/code/Magento/Backend/Model/Session/AdminConfig.php
similarity index 90%
rename from app/code/Magento/Backend/AdminConfig.php
rename to app/code/Magento/Backend/Model/Session/AdminConfig.php
index 691cbb9d72a..919d3100b5e 100644
--- a/app/code/Magento/Backend/AdminConfig.php
+++ b/app/code/Magento/Backend/Model/Session/AdminConfig.php
@@ -23,7 +23,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend;
+namespace Magento\Backend\Model\Session;
 
 use Magento\Backend\App\Area\FrontNameResolver;
 use Magento\Framework\Session\Config;
@@ -46,6 +46,7 @@ class AdminConfig extends Config
     protected $frontNameResolver;
 
     /**
+     * @param \Magento\Framework\ValidatorFactory $validatorFactory
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\Stdlib\String $stringHelper
      * @param \Magento\Framework\App\RequestInterface $request
@@ -60,6 +61,7 @@ class AdminConfig extends Config
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
+        \Magento\Framework\ValidatorFactory $validatorFactory,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\Stdlib\String $stringHelper,
         \Magento\Framework\App\RequestInterface $request,
@@ -73,6 +75,7 @@ class AdminConfig extends Config
         $sessionName = self::SESSION_NAME_ADMIN
     ) {
         parent::__construct(
+            $validatorFactory,
             $scopeConfig,
             $stringHelper,
             $request,
@@ -85,9 +88,7 @@ class AdminConfig extends Config
         );
 
         $this->frontNameResolver = $frontNameResolver;
-
-        $baseUrl = $this->_httpRequest->getBaseUrl();
-        $adminPath = $this->extractAdminPath($baseUrl);
+        $adminPath = $this->extractAdminPath();
         $this->setCookiePath($adminPath);
         $this->setName($sessionName);
     }
@@ -95,16 +96,11 @@ class AdminConfig extends Config
     /**
      * Determine the admin path
      *
-     * @param string $baseUrl
      * @return string
-     * @throws \InvalidArgumentException
      */
-    private function extractAdminPath($baseUrl)
+    private function extractAdminPath()
     {
-        if (!is_string($baseUrl)) {
-            throw new \InvalidArgumentException('Cookie path is not a string.');
-        }
-
+        $baseUrl = $this->_httpRequest->getBaseUrl();
         $adminPath = $this->frontNameResolver->getFrontName();
 
         if (!substr($baseUrl, -1) || ('/' != substr($baseUrl, -1))) {
diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json
index 94aebf551db..6381f36e6cd 100644
--- a/app/code/Magento/Backend/composer.json
+++ b/app/code/Magento/Backend/composer.json
@@ -3,28 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-reports": "0.1.0-alpha96",
-        "magento/module-catalog-search": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-user": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-backup": "0.1.0-alpha96",
-        "magento/module-email": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-url-rewrite": "0.1.0-alpha96",
-        "magento/module-translation": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-reports": "0.1.0-alpha97",
+        "magento/module-catalog-search": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-user": "0.1.0-alpha97",
+        "magento/module-backup": "0.1.0-alpha97",
+        "magento/module-email": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-translation": "0.1.0-alpha97",
+        "magento/module-require-js": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index 20b2078fd44..77a925ea493 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -36,7 +36,7 @@
     <preference for="Magento\Framework\App\Response\Http\FileFactory" type="Magento\Backend\App\Response\Http\FileFactory" />
     <preference for="Magento\Framework\App\View" type="Magento\Backend\Model\View" />
     <preference for="Magento\Framework\Model\ActionValidator\RemoveAction" type="Magento\Framework\Model\ActionValidator\RemoveAction\Allowed" />
-    <preference for="Magento\Framework\Session\Config\ConfigInterface" type="Magento\Backend\AdminConfig" />
+    <preference for="Magento\Framework\Session\Config\ConfigInterface" type="Magento\Backend\Model\Session\AdminConfig" />
     <type name="Magento\Backend\App\Action\Context">
         <arguments>
             <argument name="helper" xsi:type="object">Magento\Backend\Helper\Data</argument>
@@ -93,10 +93,10 @@
             <argument name="locale" xsi:type="object">Magento\Backend\Model\Locale\Resolver\Proxy</argument>
         </arguments>
     </type>
-    <type name="Magento\Backend\AdminConfig">
+    <type name="Magento\Backend\Model\Session\AdminConfig">
         <arguments>
             <argument name="lifetimePath" xsi:type="const">Magento\Backend\Model\Auth\Session::XML_PATH_SESSION_LIFETIME</argument>
-            <argument name="sessionName" xsi:type="const">Magento\Backend\AdminConfig::SESSION_NAME_ADMIN</argument>
+            <argument name="sessionName" xsi:type="const">Magento\Backend\Model\Session\AdminConfig::SESSION_NAME_ADMIN</argument>
         </arguments>
     </type>
 </config>
diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml
index 5314894c083..db577f8e588 100644
--- a/app/code/Magento/Backend/etc/adminhtml/system.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/system.xml
@@ -589,16 +589,21 @@
                 <label>Default Cookie Settings</label>
                 <field id="cookie_lifetime" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Cookie Lifetime</label>
+                    <backend_model>Magento\Backend\Model\Config\Backend\Cookie\Lifetime</backend_model>
                 </field>
                 <field id="cookie_path" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Cookie Path</label>
+                    <backend_model>Magento\Backend\Model\Config\Backend\Cookie\Path</backend_model>
                 </field>
                 <field id="cookie_domain" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Cookie Domain</label>
-                    <backend_model>Magento\Backend\Model\Config\Backend\Domain</backend_model>
+                    <backend_model>Magento\Backend\Model\Config\Backend\Cookie\Domain</backend_model>
                 </field>
                 <field id="cookie_httponly" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Use HTTP Only</label>
+                    <comment>
+                        <![CDATA[<strong style="color:red">Warning</strong>:  Do not set to "No". User security could be compromised.]]>
+                    </comment>
                     <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                 </field>
                 <field id="cookie_restriction" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0">
diff --git a/app/code/Magento/Backend/etc/config.xml b/app/code/Magento/Backend/etc/config.xml
index 1a88e36aea2..fc72289ab27 100644
--- a/app/code/Magento/Backend/etc/config.xml
+++ b/app/code/Magento/Backend/etc/config.xml
@@ -40,13 +40,6 @@
             </dashboard>
         </system>
         <general>
-            <file>
-                <sitemap_generate_valid_paths>
-                    <available>
-                        <any_path>/*/sitemap.xml</any_path>
-                    </available>
-                </sitemap_generate_valid_paths>
-            </file>
             <validator_data>
                 <input_types>
                     <price>price</price>
diff --git a/app/code/Magento/Backend/etc/module.xml b/app/code/Magento/Backend/etc/module.xml
index b969c2fe61d..11c99dcde03 100644
--- a/app/code/Magento/Backend/etc/module.xml
+++ b/app/code/Magento/Backend/etc/module.xml
@@ -40,12 +40,11 @@
             <module name="Magento_Sales"/>
             <module name="Magento_Catalog"/>
             <module name="Magento_User"/>
-            <module name="Magento_Cms"/>
             <module name="Magento_Backup"/>
             <module name="Magento_Email"/>
             <module name="Magento_Customer"/>
-            <module name="Magento_UrlRewrite"/>
             <module name="Magento_Translation"/>
+            <module name="Magento_RequireJs"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Backend/i18n/de_DE.csv b/app/code/Magento/Backend/i18n/de_DE.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/de_DE.csv
+++ b/app/code/Magento/Backend/i18n/de_DE.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/en_US.csv
+++ b/app/code/Magento/Backend/i18n/en_US.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/es_ES.csv b/app/code/Magento/Backend/i18n/es_ES.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/es_ES.csv
+++ b/app/code/Magento/Backend/i18n/es_ES.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/fr_FR.csv b/app/code/Magento/Backend/i18n/fr_FR.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/fr_FR.csv
+++ b/app/code/Magento/Backend/i18n/fr_FR.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/nl_NL.csv b/app/code/Magento/Backend/i18n/nl_NL.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/nl_NL.csv
+++ b/app/code/Magento/Backend/i18n/nl_NL.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/pt_BR.csv b/app/code/Magento/Backend/i18n/pt_BR.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/pt_BR.csv
+++ b/app/code/Magento/Backend/i18n/pt_BR.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/i18n/zh_CN.csv b/app/code/Magento/Backend/i18n/zh_CN.csv
index 42d4d718f5d..7a956dbcdcf 100644
--- a/app/code/Magento/Backend/i18n/zh_CN.csv
+++ b/app/code/Magento/Backend/i18n/zh_CN.csv
@@ -273,8 +273,8 @@ Synchronizing...,Synchronizing...
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
 "You deleted the custom variable.","You deleted the custom variable."
-"URL Redirects","URL Redirects"
-"[New/Edit] URL Redirect","[New/Edit] URL Redirect"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
 "An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
 "Chosen product does not associated with the chosen store or category.","Chosen product does not associated with the chosen store or category."
diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_denied.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_denied.xml
index 8d967323d27..6d4251833ec 100644
--- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_denied.xml
+++ b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_denied.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+<page layout="admin-1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="content">
         <block class="Magento\Backend\Block\Denied" name="content.denied" template="admin/access_denied.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_config_edit.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_config_edit.xml
index d405b9690c2..a6e2c069477 100644
--- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_config_edit.xml
+++ b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_system_config_edit.xml
@@ -24,7 +24,6 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head"/>
     <referenceContainer name="js">
         <block class="Magento\Backend\Block\Template" template="Magento_Backend::system/config/js.phtml"/>
         <block class="Magento\Backend\Block\Template" template="Magento_Backend::system/shipping/applicable_country.phtml"/>
diff --git a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_urlrewrite_index.xml b/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_urlrewrite_index.xml
deleted file mode 100644
index c6557a289d3..00000000000
--- a/app/code/Magento/Backend/view/adminhtml/layout/adminhtml_urlrewrite_index.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceContainer name="content">
-        <block class="Magento\Backend\Block\Urlrewrite" name="adminhtml.block.urlrewrite.grid.container">
-            <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.urlrewrite.grid" as="grid">
-                <arguments>
-                    <argument name="id" xsi:type="string">urlrewriteGrid</argument>
-                    <argument name="dataSource" xsi:type="object">Magento\UrlRewrite\Model\Resource\UrlRewrite\Collection</argument>
-                    <argument name="default_sort" xsi:type="string">url_rewrite_id</argument>
-                </arguments>
-                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="adminhtml.urlrewrite.grid.columnSet">
-                    <arguments>
-                        <argument name="rowUrl" xsi:type="array">
-                            <item name="path" xsi:type="string">adminhtml/*/edit</item>
-                            <item name="extraParamsTemplate" xsi:type="array">
-                                <item name="id" xsi:type="string">getId</item>
-                            </item>
-                        </argument>
-                    </arguments>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="url_rewrite_id">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">ID</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">url_rewrite_id</argument>
-                            <argument name="index" xsi:type="string">url_rewrite_id</argument>
-                            <argument name="column_css_class" xsi:type="string">col-id</argument>
-                            <argument name="header_css_class" xsi:type="string">col-id</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="store_id">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Store View</argument>
-                            <argument name="type" xsi:type="string">store</argument>
-                            <argument name="id" xsi:type="string">store_id</argument>
-                            <argument name="index" xsi:type="string">store_id</argument>
-                            <argument name="store_view" xsi:type="string">true</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="is_system">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Type</argument>
-                            <argument name="type" xsi:type="string">options</argument>
-                            <argument name="id" xsi:type="string">is_system</argument>
-                            <argument name="index" xsi:type="string">is_system</argument>
-                            <argument name="options" xsi:type="array">
-                                <item name="system" xsi:type="array">
-                                    <item name="value" xsi:type="string">1</item>
-                                    <item name="label" xsi:type="string" translate="true">System</item>
-                                </item>
-                                <item name="custom" xsi:type="array">
-                                    <item name="value" xsi:type="string">0</item>
-                                    <item name="label" xsi:type="string" translate="true">Custom</item>
-                                </item>
-                            </argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="id_path">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">ID Path</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">id_path</argument>
-                            <argument name="index" xsi:type="string">id_path</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="request_path">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Request Path</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">request_path</argument>
-                            <argument name="index" xsi:type="string">request_path</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="target_path">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Target Path</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">target_path</argument>
-                            <argument name="index" xsi:type="string">target_path</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="options">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Options</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">options</argument>
-                            <argument name="index" xsi:type="string">options</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="actions">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Action</argument>
-                            <argument name="sortable" xsi:type="string">0</argument>
-                            <argument name="filter" xsi:type="string">0</argument>
-                            <argument name="type" xsi:type="string">action</argument>
-                            <argument name="id" xsi:type="string">actions</argument>
-                            <argument name="index" xsi:type="string">url_rewrite_id</argument>
-                            <argument name="actions" xsi:type="array">
-                                <item name="view_action" xsi:type="array">
-                                    <item name="caption" xsi:type="string" translate="true">Edit</item>
-                                    <item name="url" xsi:type="array">
-                                        <item name="base" xsi:type="string">adminhtml/*/edit</item>
-                                    </item>
-                                    <item name="field" xsi:type="string">id</item>
-                                </item>
-                            </argument>
-                        </arguments>
-                    </block>
-                </block>
-            </block>
-        </block>
-    </referenceContainer>
-</page>
diff --git a/app/code/Magento/Backend/view/adminhtml/layout/default.xml b/app/code/Magento/Backend/view/adminhtml/layout/default.xml
index cc535e0a52c..e7d7e18610e 100644
--- a/app/code/Magento/Backend/view/adminhtml/layout/default.xml
+++ b/app/code/Magento/Backend/view/adminhtml/layout/default.xml
@@ -24,6 +24,34 @@
  */
 -->
 <page layout="admin-1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <head>
+        <title>Magento Admin</title>
+        <link src="prototype/prototype.js"/>
+        <link src="prototype/window.js"/>
+        <link src="scriptaculous/builder.js"/>
+        <link src="scriptaculous/effects.js"/>
+        <link src="lib/ccard.js"/>
+        <link src="prototype/validation.js"/>
+        <link src="varien/js.js"/>
+        <link src="mage/adminhtml/varienLoader.js"/>
+        <link src="mage/adminhtml/tools.js"/>
+        <link src="lib/ds-sleight.js" ie_condition="lt IE 7" defer="defer"/>
+        <css src="mage/calendar.css"/>
+        <link src="requirejs/require.js"/>
+        <link src="mage/requirejs/resolver.js"/>
+        <link src="jquery/jquery-1.8.2.js"/>
+        <link src="mage/jquery-no-conflict.js"/>
+        <link src="app-config.js"/>
+        <link src="extjs/ext-tree.js"/>
+        <link src="extjs/ext-tree-checkbox.js"/>
+        <css src="extjs/resources/css/ext-all.css"/>
+        <css src="extjs/resources/css/ytheme-magento.css"/>
+        <link src="Magento_Rule::rules.js"/>
+    </head>
+    <body>
+        <attribute name="id" value="html-body" />
+    </body>
+    <block name="require.js" class="Magento\Backend\Block\Page\RequireJs" template="Magento_Backend::page/js/require_js.phtml" />
     <referenceContainer name="global.notices">
         <block class="Magento\Backend\Block\Page\Notices" name="global_notices" as="global_notices" template="page/notices.phtml"/>
     </referenceContainer>
@@ -87,154 +115,11 @@
         <block class="Magento\Framework\View\Element\Template" name="page.loader" template="Magento_Backend::admin/loader.phtml" after="-"/>
     </referenceContainer>
 
-    <block class="Magento\Backend\Block\Page\Head" name="head" as="head" template="page/head.phtml">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Magento Admin</argument>
-        </action>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-prototype-js">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/prototype.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-window-js">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/window.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="scriptaculous-builder-js">
-            <arguments>
-                <argument name="file" xsi:type="string">scriptaculous/builder.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="scriptaculous-effects-js">
-            <arguments>
-                <argument name="file" xsi:type="string">scriptaculous/effects.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="lib-ccard-js">
-            <arguments>
-                <argument name="file" xsi:type="string">lib/ccard.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-validation-js">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/validation.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="varien-js-js">
-            <arguments>
-                <argument name="file" xsi:type="string">varien/js.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-adminhtml-varienloader-js">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/adminhtml/varienLoader.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-adminhtml-tools-js">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/adminhtml/tools.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="lib-ds-sleight-js">
-            <arguments>
-                <argument name="file" xsi:type="string">lib/ds-sleight.js</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string">defer</item>
-                    <item name="ie_condition" xsi:type="string">lt IE 7</item>
-                </argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-calendar-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/calendar.css</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                </argument>
-            </arguments>
-        </block>
-
-        <block class="Magento\Theme\Block\Html\Head\Script" name="requirejs">
-            <arguments>
-                <argument name="file" xsi:type="string">requirejs/require.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="mage-requirejs-resolver">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/requirejs/resolver.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="app-config" after="jquery">
-            <arguments>
-                <argument name="file" xsi:type="string">app-config.js</argument>
-            </arguments>
-        </block>
-        <!-- /**
-        TODO: remove jQuery. jQuery could be loaded through RequireJS. But only in case ALL MODULES ARE AMD MODULES.
-        Detail: http://requirejs.org/docs/jquery.html#noconflictmap
-        */ -->
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery" after="requirejs">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/jquery-1.8.2.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-no-conflict" after="jquery">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/jquery-no-conflict.js</argument>
-            </arguments>
-        </block>
-
-        <block class="Magento\Theme\Block\Html\Head\Script" name="extjs-ext-tree-js">
-            <arguments>
-                <argument name="file" xsi:type="string">extjs/ext-tree.js</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                    <item name="ie_condition" xsi:type="string"/>
-                    <item name="flag_name" xsi:type="string">can_load_ext_js</item>
-                </argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="extjs-ext-tree-checkbox-js">
-            <arguments>
-                <argument name="file" xsi:type="string">extjs/ext-tree-checkbox.js</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                    <item name="ie_condition" xsi:type="string"/>
-                    <item name="flag_name" xsi:type="string">can_load_ext_js</item>
-                </argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="extjs-resources-css-ext-all-css">
-            <arguments>
-                <argument name="file" xsi:type="string">extjs/resources/css/ext-all.css</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                    <item name="ie_condition" xsi:type="string"/>
-                    <item name="flag_name" xsi:type="string">can_load_ext_js</item>
-                </argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="extjs-resources-css-ytheme-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">extjs/resources/css/ytheme-magento.css</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                    <item name="ie_condition" xsi:type="string"/>
-                    <item name="flag_name" xsi:type="string">can_load_ext_js</item>
-                </argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-adminhtml-promo-rules-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Rule::rules.js</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string"/>
-                    <item name="ie_condition" xsi:type="string"/>
-                    <item name="flag_name" xsi:type="string">can_load_rules_js</item>
-                </argument>
-            </arguments>
-        </block>
+    <referenceContainer name="after.body.start">
+        <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/>
+        <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/>
+        <block class="Magento\Framework\View\Element\Template" name="head.scripts" template="Magento_Backend::page/js/head_scripts.phtml"/>
         <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Backend::page/js/components.phtml"/>
         <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="Magento_Backend::page/js/calendar.phtml"/>
-    </block>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Backend/view/adminhtml/layout/editor.xml b/app/code/Magento/Backend/view/adminhtml/layout/editor.xml
index f5552723b99..0e1ab8be92d 100644
--- a/app/code/Magento/Backend/view/adminhtml/layout/editor.xml
+++ b/app/code/Magento/Backend/view/adminhtml/layout/editor.xml
@@ -24,24 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-backend-js-bootstrap-editor-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Backend::js/bootstrap/editor.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="prototype-windows-themes-default-css">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/windows/themes/default.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_Backend::js/bootstrap/editor.js"/>
+        <css src="prototype/windows/themes/default.css"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
 </page>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/admin/page.phtml b/app/code/Magento/Backend/view/adminhtml/templates/admin/page.phtml
new file mode 100644
index 00000000000..e95aabc891a
--- /dev/null
+++ b/app/code/Magento/Backend/view/adminhtml/templates/admin/page.phtml
@@ -0,0 +1,77 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php /** @var $this \Magento\Backend\Block\Page */ ?>
+<!doctype html>
+<html lang="<?php echo $this->getLang() ?>" class="no-js">
+
+<head>
+    <?php echo $this->getChildHtml('head') ?>
+</head>
+
+<body id="html-body"<?php echo $this->getBodyClass() ? ' class="' . $this->getBodyClass() . '"' : ''; ?> data-container="body" data-mage-init='{"loaderAjax":{},"loader":{}}'>
+    <div class="page-wrapper">
+        <?php echo $this->getChildHtml('notification_window'); ?>
+        <?php echo $this->getChildHtml('global_notices') ?>
+        <div class="page-header-wrapper">
+            <?php echo $this->getChildHtml('header') ?>
+        </div>
+        <?php echo $this->getChildHtml('menu') ?>
+        <?php echo $this->getChildHtml('notifications'); ?>
+
+        <section class="page-content" id="anchor-content">
+            <?php echo $this->getChildHtml('main-top'); ?>
+            <div id="messages" data-container-for="messages" class="messages">
+                <?php echo $this->getLayout()->getMessagesBlock()->getGroupedHtml() ?>
+            </div>
+            <?php echo $this->getChildHtml('page_main_actions'); ?>
+            <?php if($this->getChildHtml('left')): ?>
+                <div id="page:main-container" class="<?php echo $this->getContainerCssClass() ?> col-2-left-layout">
+                    <div class="main-col" id="content">
+                        <?php echo $this->getChildHtml('content') ?>
+                    </div>
+
+                    <div class="side-col" id="page:left">
+                        <?php echo $this->getChildHtml('left') ?>
+                    </div>
+                </div>
+            <?php else: ?>
+                <div id="page:main-container" class="col-1-layout">
+                    <?php echo $this->getChildHtml('content') ?>
+                </div>
+            <?php endif; ?>
+        </section>
+
+        <?php echo $this->getChildHtml('js') ?>
+        <div class="page-footer-wrapper">
+            <?php echo $this->getChildHtml('footer') ?>
+        </div>
+    </div>
+    <?php echo $this->getChildHtml('before_body_end') ?>
+    <!-- TODO: remove this popup after refactoring of "varienLoader.js" file -->
+    <div class="loading-old" id="loading-mask" style="display:none;">
+        <div class="loader" id="loading_mask_loader"><p><?php echo __('Please wait...') ?></p></div>
+    </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/admin/popup.phtml b/app/code/Magento/Backend/view/adminhtml/templates/admin/popup.phtml
deleted file mode 100644
index 679bccef887..00000000000
--- a/app/code/Magento/Backend/view/adminhtml/templates/admin/popup.phtml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php /*{
-    "label":"Root page layout",
-    "type":"Magento\Framework\View\Element\Template",
-    "children":{
-        "header":{ "label":"Header", "type":"Magento\Backend\Block\Page\Header" },
-        "menu":{ "label":"Top navigation", "type":"Magento\Backend\Block\Menu" },
-        "breadcrumbs":{ "label":"Breadcrumbs", "type":"Magento\Backend\Block\Widget\Breadcrumbs" },
-        "content":{ "label":"Content block", "type":"Magento\Framework\View\Element\Template" },
-        "left":{ "label":"Left navigation", "type":"Magento\Framework\View\Element\Template" },
-        "footer":{ "label":"Footer", "type":"Magento\Backend\Block\Page\Footer" }
-    },
-    "vars":{}
-}*/ ?>
-<!doctype html>
-<html lang="<?php echo $this->getLang() ?>" class="no-js">
-<head>
-<?php echo $this->getChildHtml('head') ?>
-</head>
-<body id="html-body"<?php echo $this->getBodyClass()?' class="'.$this->getBodyClass().'"':'' ?>>
-<div class="wrapper-popup">
-    <div class="middle" id="anchor-content">
-        <div id="page:main-container">
-        <?php if($this->getChildHtml('left')): ?>
-            <div class="col-2-left-layout<?php echo $this->getContainerCssClass() ?>" id="page:container">
-                <div id="page:left" class="side-col">
-                    <?php echo $this->getChildHtml('left') ?>
-                </div>
-                <div class="main-col" id="content">
-                    <div class="main-col-inner">
-                        <div id="messages" data-container-for="messages"><?php echo $this->getLayout()->getMessagesBlock()->getGroupedHtml() ?></div>
-                        <?php echo $this->getChildHtml('content') ?>
-                    </div>
-                </div>
-            </div>
-      <?php else: ?>
-          <div id="messages" data-container-for="messages"><?php echo $this->getLayout()->getMessagesBlock()->getGroupedHtml() ?></div>
-          <?php echo $this->getChildHtml('content') ?>
-      <?php endif; ?>
-         </div>
-    </div>
-    <?php if($this->getChildHtml('footer')): ?>
-    <div class="footer">
-        <?php echo $this->getChildHtml('footer') ?>
-    </div>
-    <?php endif; ?>
-    <?php echo $this->getChildHtml('js') ?>
-
-    <!-- TODO: remove this popup after refactoring of "varienLoader.js" file -->
-    <div class="loading-old" id="loading-mask" style="display:none;">
-        <div class="loader" id="loading_mask_loader"><?php echo __('Please wait...') ?></div>
-    </div>
-</div>
-<?php echo $this->getChildHtml('before_body_end') ?>
-</body>
-</html>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/head.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/head.phtml
deleted file mode 100644
index 96007f399a5..00000000000
--- a/app/code/Magento/Backend/view/adminhtml/templates/page/head.phtml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-
-/** @var $this \Magento\Theme\Block\Html\Head */
-?>
-<meta http-equiv="X-UA-Compatible" content="IE=edge" >
-<meta http-equiv="Content-Type" content="<?php echo $this->getContentType() ?>"/>
-<title><?php echo htmlspecialchars(html_entity_decode($this->getTitle())) ?></title>
-<link rel="icon" href="<?php echo $this->getViewFileUrl('Magento_Theme::favicon.ico') ?>" type="image/x-icon"/>
-<link rel="shortcut icon" href="<?php echo $this->getViewFileUrl('Magento_Theme::favicon.ico') ?>" type="image/x-icon"/>
-
-<script type="text/javascript">
-    var BLANK_URL = '<?php echo $this->getViewFileUrl('blank.html') ?>';
-    var BLANK_IMG = '<?php echo $this->getViewFileUrl('spacer.gif') ?>';
-    var BASE_URL = '<?php echo $this->getUrl('*') ?>';
-    var FORM_KEY = '<?php echo $this->getFormKey() ?>';
-    var require = {
-        "baseUrl": "<?php echo $this->getViewFileUrl('/') ?>",
-    	"paths": {
-            "jquery/ui": "jquery/jquery-ui-1.9.2",
-            "mage/components": "mage/backend/components"
-        }
-    };
-</script>
-
-<?php echo $this->getCssJsHtml() ?>
-
-<?php if($this->getCanLoadExtJs()): ?>
-<script type="text/javascript">
-    Ext.BLANK_IMAGE_URL = BLANK_IMG;
-    Ext.UpdateManager.defaults.loadScripts = false;
-    Ext.UpdateManager.defaults.disableCaching = true;
-</script>
-<?php endif; ?>
-
-<?php if($this->getCanLoadTinyMce()): // TinyMCE is broken when loaded through index.php ?>
-<script type="text/javascript" src="<?php echo $this->getViewFileUrl('tiny_mce/tiny_mce_src.js') ?>"></script>
-<?php endif; ?>
-
-<script type="text/javascript">
-    Fieldset.addToPrefix(<?php echo $this->helper('Magento\Backend\Helper\Data')->getCurrentUserId() ?>);
-</script>
-
-<?php echo $this->getChildHtml('components'); ?>
-<?php echo $this->getChildHtml('calendar'); ?>
-<?php echo $this->getChildHtml('optional_zip_countries'); ?>
-<?php echo $this->getTranslatorScript(); ?>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/js/head_scripts.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/js/head_scripts.phtml
new file mode 100644
index 00000000000..cc0cfcffc91
--- /dev/null
+++ b/app/code/Magento/Backend/view/adminhtml/templates/page/js/head_scripts.phtml
@@ -0,0 +1,35 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<script type="text/javascript">
+    Ext.BLANK_IMAGE_URL = BLANK_IMG;
+    Ext.UpdateManager.defaults.loadScripts = false;
+    Ext.UpdateManager.defaults.disableCaching = true;
+</script>
+
+<script type="text/javascript" src="<?php echo $this->getViewFileUrl('tiny_mce/tiny_mce_src.js') ?>"></script>
+
+<script type="text/javascript">
+    Fieldset.addToPrefix(<?php echo $this->helper('Magento\Backend\Helper\Data')->getCurrentUserId() ?>);
+</script>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/js/require_js.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/js/require_js.phtml
new file mode 100644
index 00000000000..45dd53a4171
--- /dev/null
+++ b/app/code/Magento/Backend/view/adminhtml/templates/page/js/require_js.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<script type="text/javascript">
+    var BLANK_URL = '<?php echo $this->getViewFileUrl('blank.html') ?>';
+    var BLANK_IMG = '<?php echo $this->getViewFileUrl('spacer.gif') ?>';
+    var BASE_URL = '<?php echo $this->getUrl('*') ?>';
+    var FORM_KEY = '<?php echo $this->getFormKey() ?>';
+    var require = {
+        "baseUrl": "<?php echo $this->getViewFileUrl('/') ?>",
+        "paths": {
+            "jquery/ui": "jquery/jquery-ui-1.9.2",
+            "mage/components": "mage/backend/components"
+        }
+    };
+</script>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/selector.phtml b/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/selector.phtml
deleted file mode 100644
index eb0b392d151..00000000000
--- a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/selector.phtml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-
-/**
- * Urlrewrites edit mode selector
- *
- * @see \Magento\Backend\Block\Urlrewrite\Selector
- */
-?>
-<div class="form-inline">
-    <fieldset class="fieldset" data-ui-id="urlrewrite-type-selector">
-        <div class="field field-url-rewrite-option-select">
-            <label for="url-rewrite-option-select" class="label"><?php echo $this->getSelectorLabel() ?></label>
-            <div class="control">
-                <?php $url = $this->helper('Magento\Backend\Helper\Data')->getUrl('adminhtml/*/*')?>
-                <select id="url-rewrite-option-select" class="select" onchange="window.location = this.value;">
-                <?php foreach ($this->getModes() as $mode => $label): ?>
-                    <option <?php echo ($this->isMode($mode) ? 'selected="selected" ' :'' ) ?>value="<?php echo $url . $mode ?>"><?php echo $label ?></option>
-                <?php endforeach; ?>
-                </select>
-            </div>
-        </div>
-    </fieldset>
-</div>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml
index 341baadcf83..dec1f99a778 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml
@@ -142,11 +142,8 @@ $numColumns = sizeof($this->getColumns());
                         <?php else: ?>
                             <span class="action-next disabled"><span><?php echo __('Next page') ?></span></span>
                         <?php endif; ?>
-                        <?php if ($this->getRssLists()): ?>
-                            <?php foreach ($this->getRssLists() as $_rss): ?>
-                                <a href="<?php echo $_rss->getUrl() ?>"
-                                   class="link-feed"><?php echo $_rss->getLabel() ?></a>
-                            <?php endforeach ?>
+                        <?php if ($this->getChildBlock('grid.bottom.links')): ?>
+                            <?php echo $this->getChildHtml('grid.bottom.links') ?>
                         <?php endif; ?>
                     </div>
                 <?php endif ?>
@@ -184,7 +181,6 @@ $numColumns = sizeof($this->getColumns());
             <?php echo $this->getChildBlock('grid.massaction')->getJavaScript() ?>
             <?php endif ?>
             <?php echo $this->getAdditionalJavaScript(); ?>
-    
         });
 </script>
 <?php endif; ?>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml
index 09c70ed4b89..10a18d448ea 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml
@@ -233,11 +233,8 @@ $numColumns = sizeof($this->getColumns());
                 <?php else: ?>
                     <span class="action-next disabled"><span><?php echo __('Next page') ?></span></span>
                 <?php endif; ?>
-                <?php if ($this->getRssLists()): ?>
-                    <?php foreach ($this->getRssLists() as $_rss): ?>
-                        <a href="<?php echo $_rss->getUrl() ?>"
-                           class="link-feed"><?php echo $_rss->getLabel() ?></a>
-                    <?php endforeach ?>
+                <?php if ($this->getChildBlock('grid.bottom.links')): ?>
+                    <?php echo $this->getChildHtml('grid.bottom.links') ?>
                 <?php endif; ?>
             </div>
         <?php endif ?>
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
index 964bb7274b0..94c7927e5c1 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
@@ -127,7 +127,7 @@ class Rollback extends \Magento\Backup\Controller\Adminhtml\Index
 
             $backupManager->rollback();
 
-            $helper->invalidateCache()->invalidateIndexer();
+            $helper->invalidateCache();
 
             $adminSession = $this->_getSession();
             $adminSession->destroy();
diff --git a/app/code/Magento/Backup/Helper/Data.php b/app/code/Magento/Backup/Helper/Data.php
index eb046555cd9..4b38d04e4f3 100644
--- a/app/code/Magento/Backup/Helper/Data.php
+++ b/app/code/Magento/Backup/Helper/Data.php
@@ -45,13 +45,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_cacheTypeList;
 
-    /**
-     * Index resource process collection factory
-     *
-     * @var \Magento\Index\Model\Resource\Process\CollectionFactory
-     */
-    protected $_processFactory;
-
     /**
      * Construct
      *
@@ -59,20 +52,17 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Framework\App\Filesystem $filesystem
      * @param \Magento\Framework\AuthorizationInterface $authorization
      * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
-     * @param \Magento\Index\Model\Resource\Process\CollectionFactory $processFactory
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
         \Magento\Framework\App\Filesystem $filesystem,
         \Magento\Framework\AuthorizationInterface $authorization,
-        \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
-        \Magento\Index\Model\Resource\Process\CollectionFactory $processFactory
+        \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
     ) {
         parent::__construct($context);
         $this->_authorization = $authorization;
         $this->_filesystem = $filesystem;
         $this->_cacheTypeList = $cacheTypeList;
-        $this->_processFactory = $processFactory;
     }
 
     /**
@@ -261,19 +251,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this;
     }
 
-    /**
-     * Invalidate Indexer
-     *
-     * @return $this
-     */
-    public function invalidateIndexer()
-    {
-        foreach ($this->_processFactory->create() as $process) {
-            $process->changeStatus(\Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX);
-        }
-        return $this;
-    }
-
     /**
      * Creates backup's display name from it's name
      *
diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json
index 4eed44f1c19..ee63f6d2344 100644
--- a/app/code/Magento/Backup/composer.json
+++ b/app/code/Magento/Backup/composer.json
@@ -3,16 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/module-index": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Backup/etc/module.xml b/app/code/Magento/Backup/etc/module.xml
index 66ccd9178cb..1cc6eb52a3b 100644
--- a/app/code/Magento/Backup/etc/module.xml
+++ b/app/code/Magento/Backup/etc/module.xml
@@ -34,7 +34,6 @@
             <module name="Magento_Core"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Cron"/>
-            <module name="Magento_Index"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php b/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
index c7593e533c9..c13df9a9af2 100644
--- a/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
+++ b/app/code/Magento/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
@@ -21,7 +21,6 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
 namespace Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab;
 
 /**
@@ -154,40 +153,6 @@ class Attributes extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attri
                 )
             );
         }
-
-        $mapEnabled = $this->getForm()->getElement('msrp_enabled');
-        if ($mapEnabled && $this->getCanEditPrice() !== false) {
-            $mapEnabled->setAfterElementHtml(
-                '<script type="text/javascript">' .
-                "
-                function changePriceTypeMap() {
-                    if ($('price_type').value == " .
-                \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC .
-                ") {
-                        $('msrp_enabled').setValue(" .
-                \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_NO .
-                ");
-                        $('msrp_enabled').disable();
-                        $('msrp_display_actual_price_type').setValue(" .
-                \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price::TYPE_USE_CONFIG .
-                ");
-                        $('msrp_display_actual_price_type').disable();
-                        $('msrp').setValue('');
-                        $('msrp').disable();
-                    } else {
-                        $('msrp_enabled').enable();
-                        $('msrp_display_actual_price_type').enable();
-                        $('msrp').enable();
-                    }
-                }
-                document.observe('dom:loaded', function() {
-                    $('price_type').observe('change', changePriceTypeMap);
-                    changePriceTypeMap();
-                });
-                " .
-                '</script>'
-            );
-        }
     }
 
     /**
diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
index e9438dd2a5c..929edba7102 100644
--- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
+++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
@@ -56,13 +56,6 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
      */
     protected $_options;
 
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_item';
-
     /**
      * Catalog product
      *
@@ -231,7 +224,6 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
                 }
                 // break the reference with the last element
 
-                $canApplyMAP = false;
                 $bundleOptionPriceAmount = $currentProduct->getPriceInfo()->getPrice('bundle_option')
                     ->getOptionSelectionAmount($selectionItem);
                 $priceInclTax = $bundleOptionPriceAmount->getValue();
@@ -247,7 +239,7 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
                     'name' => $selectionItem->getName(),
                     'plusDisposition' => 0,
                     'minusDisposition' => 0,
-                    'canApplyMAP' => $canApplyMAP
+                    'canApplyMsrp' => false
                 );
 
                 $selection['price'] = $this->_taxData->displayPriceIncludingTax()
@@ -311,7 +303,6 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
                 ->getValue(),
             'includeTax' => $this->_taxData->priceIncludesTax() ? 'true' : 'false',
             'isFixedPrice' => $isFixedPrice,
-            //'isMAPAppliedDirectly' => $this->_catalogData->canApplyMsrp($this->getProduct(), null, false)
         );
 
         $config['finalPrice'] = $this->_taxData->displayPriceIncludingTax()
diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php
index 9b202cfc27d..c1d30c9cf4c 100644
--- a/app/code/Magento/Bundle/Model/Product/Type.php
+++ b/app/code/Magento/Bundle/Model/Product/Type.php
@@ -358,13 +358,6 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
         }
 
         if ($product->getPriceType() == Price::PRICE_TYPE_DYNAMIC) {
-            $product->setData(
-                'msrp_enabled',
-                \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_NO
-            );
-            $product->unsetData('msrp');
-            $product->unsetData('msrp_display_actual_price_type');
-
             /** unset product custom options for dynamic price */
             if ($product->hasData('product_options')) {
                 $product->unsetData('product_options');
@@ -1146,55 +1139,6 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
         );
     }
 
-    /**
-     * Check if Minimum Advertise Price is enabled at least in one option
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param int $visibility
-     * @return bool|null
-     */
-    public function isMapEnabledInOptions($product, $visibility = null)
-    {
-        /**
-         * @TODO: In order to clarify is MAP enabled for product we can check associated products.
-         * Commented for future improvements.
-         */
-        /*
-        $collection = $this->getUsedProductCollection($product);
-        $helper = $this->_catalogData;
-
-        $result = null;
-        $parentVisibility = $product->getMsrpDisplayActualPriceType();
-        if ($parentVisibility === null) {
-            $parentVisibility = $helper->getMsrpDisplayActualPriceType();
-        }
-        $visibilities = array($parentVisibility);
-        foreach ($collection as $item) {
-            if ($helper->canApplyMsrp($item)) {
-                $productVisibility = $item->getMsrpDisplayActualPriceType();
-                if ($productVisibility === null) {
-                    $productVisibility = $helper->getMsrpDisplayActualPriceType();
-                }
-                $visibilities[] = $productVisibility;
-                $result = true;
-            }
-        }
-
-        if ($result && $visibility !== null) {
-            if ($visibilities) {
-                $maxVisibility = max($visibilities);
-                $result = $result && $maxVisibility == $visibility;
-            } else {
-                $result = false;
-            }
-        }
-
-        return $result;
-        */
-
-        return null;
-    }
-
     /**
      * Delete data specific for Bundle product type
      *
diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json
index 4f6e16b7f09..b7e4ac63c1c 100644
--- a/app/code/Magento/Bundle/composer.json
+++ b/app/code/Magento/Bundle/composer.json
@@ -3,25 +3,24 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-catalog-rule": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-gift-message": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
-        "magento/module-webapi": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-catalog-rule": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-gift-message": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/module-webapi": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml
index 8b75bdd1c75..15c5089db1c 100644
--- a/app/code/Magento/Bundle/etc/di.xml
+++ b/app/code/Magento/Bundle/etc/di.xml
@@ -69,7 +69,6 @@
                 <item name="tier_price" xsi:type="string">Magento\Bundle\Pricing\Price\TierPrice</item>
                 <item name="group_price" xsi:type="string">Magento\Bundle\Pricing\Price\GroupPrice</item>
                 <item name="special_price" xsi:type="string">Magento\Bundle\Pricing\Price\SpecialPrice</item>
-                <item name="msrp_price" xsi:type="string">Magento\Catalog\Pricing\Price\MsrpPrice</item>
                 <item name="custom_option_price" xsi:type="string">Magento\Catalog\Pricing\Price\CustomOptionPrice</item>
                 <item name="base_price" xsi:type="string">Magento\Catalog\Pricing\Price\BasePrice</item>
                 <item name="configured_price" xsi:type="string">Magento\Bundle\Pricing\Price\ConfiguredPrice</item>
diff --git a/app/code/Magento/Bundle/etc/module.xml b/app/code/Magento/Bundle/etc/module.xml
index 3af545dbed1..a6a663bb9fd 100644
--- a/app/code/Magento/Bundle/etc/module.xml
+++ b/app/code/Magento/Bundle/etc/module.xml
@@ -41,7 +41,6 @@
             <module name="Magento_CatalogRule"/>
             <module name="Magento_Eav"/>
             <module name="Magento_GiftMessage"/>
-            <module name="Magento_Theme"/>
             <module name="Magento_Webapi"/>
         </depends>
     </module>
diff --git a/app/code/Magento/Bundle/view/adminhtml/layout/catalog_product_bundle.xml b/app/code/Magento/Bundle/view/adminhtml/layout/catalog_product_bundle.xml
index 811f019a726..97536c08297 100644
--- a/app/code/Magento/Bundle/view/adminhtml/layout/catalog_product_bundle.xml
+++ b/app/code/Magento/Bundle/view/adminhtml/layout/catalog_product_bundle.xml
@@ -24,13 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-bundle-css-bundle-product-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Bundle::css/bundle-product.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_Bundle::css/bundle-product.css"/>
+    </head>
     <referenceBlock name="product_tabs">
         <action method="addTab">
             <argument name="name" xsi:type="string">bundle</argument>
diff --git a/app/code/Magento/Bundle/view/base/templates/product/price/final_price.phtml b/app/code/Magento/Bundle/view/base/templates/product/price/final_price.phtml
index a0d3c734fc2..d57ca331e3b 100644
--- a/app/code/Magento/Bundle/view/base/templates/product/price/final_price.phtml
+++ b/app/code/Magento/Bundle/view/base/templates/product/price/final_price.phtml
@@ -41,14 +41,14 @@ $finalPriceModel = $this->getPrice();
     <?php if ($this->showRangePrice()): ?>
         <p class="price-from">
             <?php echo $this->renderAmount($finalPriceModel->getMinimalPrice(), [
-                'display_label'     => __('From:'),
+                'display_label'     => __('From'),
                 'price_id'          => $this->getPriceId('from-'),
                 'include_container' => true
             ]); ?>
         </p>
         <p class="price-to">
             <?php echo $this->renderAmount($finalPriceModel->getMaximalPrice(), [
-                'display_label'     => __('To:'),
+                'display_label'     => __('To'),
                 'price_id'          => $this->getPriceId('to-'),
                 'include_container' => true
             ]); ?>
diff --git a/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml b/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml
index 34e8c9fe1eb..31c442f0030 100644
--- a/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml
+++ b/app/code/Magento/Bundle/view/frontend/layout/catalog_product_view_type_bundle.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="value" xsi:type="string">type-bundle</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="type-bundle"/>
+    </body>
     <referenceBlock name="product.info">
         <block class="Magento\Catalog\Block\Product\View" name="bundle.summary" as="form_top" template="Magento_Bundle::catalog/product/view/summary.phtml">
             <block class="Magento\Catalog\Pricing\Render" name="product.price.render.bundle.customization">
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index 86facba5ec5..4ae84418b00 100644
--- a/app/code/Magento/Captcha/composer.json
+++ b/app/code/Magento/Captcha/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
index 8effff1b9a9..75321b025c7 100644
--- a/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
@@ -38,7 +38,6 @@
         </block>
     </referenceContainer>
     <referenceContainer name="form.billing.additional.info">
-        <referenceBlock name="head" />
         <block class="Magento\Captcha\Block\Captcha" name="captcha.guest.checkout">
             <action method="setFormId">
                 <argument name="formId" xsi:type="string">guest_checkout</argument>
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
index 84e61bf939b..72bb3dc9f96 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit/Form.php
@@ -75,14 +75,6 @@ class Form extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
      */
     protected function _prepareLayout()
     {
-        //if ($head = $this->getLayout()->getBlock('head')) {
-        //    $head->addChild(
-        //        'magento-adminhtml-catalog-category-edit-js',
-        //        'Magento\Theme\Block\Html\Head\Script',
-        //        array('file' => 'Magento_Catalog::catalog/category/edit.js')
-        //    );
-        //}
-
         $category = $this->getCategory();
         $categoryId = (int)$category->getId();
         // 0 when we create category, otherwise some value for editing category
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Attributes.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
index 359f6d2acd2..362fb2bbf0d 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
@@ -32,29 +32,6 @@ namespace Magento\Catalog\Block\Adminhtml\Category\Tab;
 
 class Attributes extends \Magento\Backend\Block\Widget\Form\Generic
 {
-    /**
-     * @var \Magento\Cms\Model\Wysiwyg\Config
-     */
-    protected $_wysiwygConfig;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig,
-        array $data = array()
-    ) {
-        $this->_wysiwygConfig = $wysiwygConfig;
-        parent::__construct($context, $registry, $formFactory, $data);
-    }
-
     /**
      * Retrieve Category object
      *
@@ -76,19 +53,6 @@ class Attributes extends \Magento\Backend\Block\Widget\Form\Generic
         $this->setShowGlobalIcon(true);
     }
 
-    /**
-     * Load Wysiwyg on demand and Prepare layout
-     *
-     * @return void
-     */
-    protected function _prepareLayout()
-    {
-        parent::_prepareLayout();
-        if ($this->_wysiwygConfig->isEnabled()) {
-            $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
-        }
-    }
-
     /**
      * Prepare form before rendering HTML
      *
@@ -133,28 +97,6 @@ class Attributes extends \Magento\Backend\Block\Widget\Form\Generic
 
         $this->_setFieldset($attributes, $fieldset);
 
-        foreach ($attributes as $attribute) {
-            /* @var $attribute \Magento\Eav\Model\Entity\Attribute */
-            if ($attribute->getAttributeCode() == 'url_key') {
-                if ($this->getCategory()->getLevel() == 1) {
-                    $fieldset->removeField('url_key');
-                    $fieldset->addField(
-                        'url_key',
-                        'hidden',
-                        array('name' => 'url_key', 'value' => $this->getCategory()->getUrlKey())
-                    );
-                } else {
-                    $form->getElement(
-                        'url_key'
-                    )->setRenderer(
-                        $this->getLayout()->createBlock(
-                            'Magento\Catalog\Block\Adminhtml\Form\Renderer\Attribute\Urlkey'
-                        )
-                    );
-                }
-            }
-        }
-
         if ($this->getCategory()->getLevel() == 1) {
             $fieldset->removeField('custom_use_parent_settings');
         } else {
@@ -188,7 +130,6 @@ class Attributes extends \Magento\Backend\Block\Widget\Form\Generic
 
         $form->setFieldNameSuffix('general');
         $this->setForm($form);
-
         return parent::_prepareForm();
     }
 
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/General.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/General.php
deleted file mode 100644
index 5f20894e654..00000000000
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tab/General.php
+++ /dev/null
@@ -1,143 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Category edit general tab
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Catalog\Block\Adminhtml\Category\Tab;
-
-class General extends \Magento\Catalog\Block\Adminhtml\Form
-{
-    /**
-     * @var array|null
-     */
-    protected $_category;
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setShowGlobalIcon(true);
-    }
-
-    /**
-     * @return array|null
-     */
-    public function getCategory()
-    {
-        if (!$this->_category) {
-            $this->_category = $this->_coreRegistry->registry('category');
-        }
-        return $this->_category;
-    }
-
-    /**
-     * @return void
-     */
-    public function _prepareLayout()
-    {
-        parent::_prepareLayout();
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create();
-        $form->setHtmlIdPrefix('_general');
-        $form->setDataObject($this->getCategory());
-
-        $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('General Information')));
-
-        if (!$this->getCategory()->getId()) {
-            //            $fieldset->addField('path', 'select', array(
-            //                'name'  => 'path',
-            //                'label' => __('Parent Category'),
-            //                'value' => base64_decode($this->getRequest()->getParam('parent')),
-            //                'values'=> $this->_getParentCategoryOptions(),
-            //                //'required' => true,
-            //                //'class' => 'required-entry'
-            //                ),
-            //                'name'
-            //            );
-            $parentId = $this->getRequest()->getParam('parent');
-            if (!$parentId) {
-                $parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
-            }
-            $fieldset->addField('path', 'hidden', array('name' => 'path', 'value' => $parentId));
-        } else {
-            $fieldset->addField('id', 'hidden', array('name' => 'id', 'value' => $this->getCategory()->getId()));
-            $fieldset->addField('path', 'hidden', array('name' => 'path', 'value' => $this->getCategory()->getPath()));
-        }
-
-        $this->_setFieldset($this->getCategory()->getAttributes(true), $fieldset);
-
-        if ($this->getCategory()->getId()) {
-            if ($this->getCategory()->getLevel() == 1) {
-                $fieldset->removeField('url_key');
-                $fieldset->addField(
-                    'url_key',
-                    'hidden',
-                    array('name' => 'url_key', 'value' => $this->getCategory()->getUrlKey())
-                );
-            }
-        }
-
-        $form->addValues($this->getCategory()->getData());
-
-        $form->setFieldNameSuffix('general');
-        $this->setForm($form);
-    }
-
-    /**
-     * @return array
-     */
-    protected function _getAdditionalElementTypes()
-    {
-        return array('image' => 'Magento\Catalog\Block\Adminhtml\Category\Helper\Image');
-    }
-
-    /**
-     * @param array|null $node
-     * @param array &$options
-     * @return array
-     */
-    protected function _getParentCategoryOptions($node = null, &$options = array())
-    {
-        if (is_null($node)) {
-            $node = $this->getRoot();
-        }
-
-        if ($node) {
-            $options[] = array(
-                'value' => $node->getPathId(),
-                'label' => str_repeat('&nbsp;', max(0, 3 * $node->getLevel())) . $this->escapeHtml($node->getName())
-            );
-
-            foreach ($node->getChildren() as $child) {
-                $this->_getParentCategoryOptions($child, $options);
-            }
-        }
-        return $options;
-    }
-}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
index 660b6418de2..47185ec7550 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
@@ -31,52 +31,6 @@ namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Tab;
 
 class Attributes extends \Magento\Catalog\Block\Adminhtml\Form
 {
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
-
-    /**
-     * @var \Magento\Cms\Model\Wysiwyg\Config
-     */
-    protected $_wysiwygConfig;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig,
-        \Magento\Catalog\Helper\Data $catalogData,
-        array $data = array()
-    ) {
-        $this->_wysiwygConfig = $wysiwygConfig;
-        $this->_catalogData = $catalogData;
-        parent::__construct($context, $registry, $formFactory, $data);
-    }
-
-    /**
-     * Load Wysiwyg on demand and prepare layout
-     *
-     * @return void
-     */
-    protected function _prepareLayout()
-    {
-        parent::_prepareLayout();
-        if ($this->_catalogData->isModuleEnabled('Magento_Cms') && $this->_wysiwygConfig->isEnabled()) {
-            $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
-        }
-    }
-
     /**
      * Prepare attributes form
      *
@@ -108,13 +62,6 @@ class Attributes extends \Magento\Catalog\Block\Adminhtml\Form
 
             $this->_setFieldset($attributes, $fieldset, array('gallery'));
 
-            $urlKey = $form->getElement('url_key');
-            if ($urlKey) {
-                $urlKey->setRenderer(
-                    $this->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Form\Renderer\Attribute\Urlkey')
-                );
-            }
-
             $tierPrice = $form->getElement('tier_price');
             if ($tierPrice) {
                 $tierPrice->setRenderer(
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php
index 81a22bbbdd4..ce2854d0bc7 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php
@@ -224,7 +224,6 @@ class Tabs extends \Magento\Backend\Block\Widget\Tabs
 
             /**
              * Do not change this tab id
-             * @see \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tabs
              */
             if ($this->getChildBlock('customer_options')) {
                 $this->addTab('customer_options', 'customer_options');
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php
index 4f9c130e5f2..8efc7787b88 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php
@@ -81,7 +81,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
      * @param \Magento\Catalog\Model\Product\Visibility $visibility
      * @param \Magento\Catalog\Helper\Data $catalogData
      * @param array $data
-     * 
+     *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -383,8 +383,9 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
             )
         );
 
-        if ($this->_catalogData->isModuleEnabled('Magento_Rss')) {
-            $this->addRssList('rss/catalog/notifystock', __('Notify Low Stock RSS'));
+        $block = $this->getLayout()->getBlock('grid.bottom.links');
+        if ($block) {
+            $this->setChild('grid.bottom.links', $block);
         }
 
         return parent::_prepareColumns();
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Price.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Price.php
index 8c8845c7688..fb9d07a155e 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Price.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Price.php
@@ -37,7 +37,7 @@ class Price extends \Magento\Framework\Data\Form\Element\Text
     protected $_taxData;
 
     /**
-     * @var Magneto_Core_Model_StoreManager
+     * @var \Magento\Framework\StoreManagerInterface
      */
     protected $_storeManager;
 
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Rss/Grid/Link.php b/app/code/Magento/Catalog/Block/Adminhtml/Rss/Grid/Link.php
new file mode 100644
index 00000000000..59207a10453
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Rss/Grid/Link.php
@@ -0,0 +1,97 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Adminhtml\Rss\Grid;
+
+/**
+ * Class Link
+ * @package Magento\Review\Block\Adminhtml\Grid\Rss
+ */
+class Link extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'rss/grid/link.phtml';
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _construct()
+    {
+        $this->setId('grid.rss.link');
+    }
+
+    /**
+     * @return string
+     */
+    public function getLink()
+    {
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
+    }
+
+    /**
+     * @return string
+     */
+    public function getLabel()
+    {
+        return __('Notify Low Stock RSS');
+    }
+
+    /**
+     * Check whether status notification is allowed
+     *
+     * @return bool
+     */
+    public function isRssAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * @return string
+     */
+    protected function getLinkParams()
+    {
+        return array('type' => 'notifystock');
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Rss/NotifyStock.php b/app/code/Magento/Catalog/Block/Adminhtml/Rss/NotifyStock.php
new file mode 100644
index 00000000000..1f32d404274
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Rss/NotifyStock.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Adminhtml\Rss;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class NotifyStock
+ * @package Magento\Catalog\Block\Adminhtml\Rss
+ */
+class NotifyStock extends \Magento\Backend\Block\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NotifyStock
+     */
+    protected $rssModel;
+
+    /**
+     * @param \Magento\Backend\Block\Context $context
+     * @param \Magento\Catalog\Model\Rss\Product\NotifyStock $rssModel
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Context $context,
+        \Magento\Catalog\Model\Rss\Product\NotifyStock $rssModel,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        $this->rssModel = $rssModel;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->setCacheKey('rss_catalog_notifystock');
+        parent::_construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRssData()
+    {
+        $newUrl = $this->rssUrlBuilder->getUrl(array('_secure' => true, '_nosecret' => true, 'type' => 'notifystock'));
+        $title = __('Low Stock Products');
+        $data = array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+
+        foreach ($this->rssModel->getProductsCollection() as $item) {
+            /* @var $item \Magento\Catalog\Model\Product */
+            $url = $this->getUrl(
+                'catalog/product/edit',
+                array('id' => $item->getId(), '_secure' => true, '_nosecret' => true)
+            );
+            $qty = 1 * $item->getQty();
+            $description = __('%1 has reached a quantity of %2.', $item->getName(), $qty);
+            $data['entries'][] = array('title' => $item->getName(), 'link' => $url, 'description' => $description);
+        }
+
+        return $data;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCacheLifetime()
+    {
+        return 600;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFeeds()
+    {
+        return array();
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Breadcrumbs.php b/app/code/Magento/Catalog/Block/Breadcrumbs.php
index 40faf651acf..87b4e3f84cb 100644
--- a/app/code/Magento/Catalog/Block/Breadcrumbs.php
+++ b/app/code/Magento/Catalog/Block/Breadcrumbs.php
@@ -90,9 +90,7 @@ class Breadcrumbs extends \Magento\Framework\View\Element\Template
                 $title[] = $breadcrumb['label'];
             }
 
-            if ($headBlock = $this->getLayout()->getBlock('head')) {
-                $headBlock->setTitle(join($this->getTitleSeparator(), array_reverse($title)));
-            }
+            $this->pageConfig->setTitle(join($this->getTitleSeparator(), array_reverse($title)));
         }
         return parent::_prepareLayout();
     }
diff --git a/app/code/Magento/Catalog/Block/Category/Rss/Link.php b/app/code/Magento/Catalog/Block/Category/Rss/Link.php
new file mode 100644
index 00000000000..a9c1b0d6d2a
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Category/Rss/Link.php
@@ -0,0 +1,104 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Category\Rss;
+
+/**
+ * Class Link
+ * @package Magento\Catalog\Block\Category\Rss
+ */
+class Link extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry = null;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param \Magento\Framework\Registry $registry
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        \Magento\Framework\Registry $registry,
+        array $data = array()
+    ) {
+        $this->registry = $registry;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return string
+     */
+    public function isRssAllowed()
+    {
+        return $this->_scopeConfig->getValue('rss/catalog/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+    }
+
+    /**
+     * @return string
+     */
+    public function getLabel()
+    {
+        return __('Subscribe to RSS Feed');
+    }
+
+    /**
+     * @return string
+     */
+    protected function getLinkParams()
+    {
+        return array(
+            'type' => 'category',
+            'cid' => $this->registry->registry('current_category')->getId(),
+            'store_id' => $this->_storeManager->getStore()->getId()
+        );
+    }
+
+    /**
+     * @return bool
+     */
+    public function isTopCategory()
+    {
+        return $this->registry->registry('current_category')->getLevel() == 2;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLink()
+    {
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Category/View.php b/app/code/Magento/Catalog/Block/Category/View.php
index c9963e8e4c5..fc94a7f9d07 100644
--- a/app/code/Magento/Catalog/Block/Category/View.php
+++ b/app/code/Magento/Catalog/Block/Category/View.php
@@ -21,14 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Catalog\Block\Category;
 
 /**
- * Category View block
- *
- * @author      Magento Core Team <core@magentocommerce.com>
+ * Class View
+ * @package Magento\Catalog\Block\Category
  */
-namespace Magento\Catalog\Block\Category;
-
 class View extends \Magento\Framework\View\Element\Template implements \Magento\Framework\View\Block\IdentityInterface
 {
     /**
@@ -79,42 +77,27 @@ class View extends \Magento\Framework\View\Element\Template implements \Magento\
 
         $this->getLayout()->createBlock('Magento\Catalog\Block\Breadcrumbs');
 
-        $headBlock = $this->getLayout()->getBlock('head');
         $category = $this->getCurrentCategory();
-        if ($headBlock && $category) {
+        if ($category) {
             $title = $category->getMetaTitle();
             if ($title) {
-                $headBlock->setTitle($title);
+                $this->pageConfig->setTitle($title);
             }
             $description = $category->getMetaDescription();
             if ($description) {
-                $headBlock->setDescription($description);
+                $this->pageConfig->setDescription($description);
             }
             $keywords = $category->getMetaKeywords();
             if ($keywords) {
-                $headBlock->setKeywords($keywords);
+                $this->pageConfig->setKeywords($keywords);
             }
-            //@todo: move canonical link to separate block
-            if ($this->_categoryHelper->canUseCanonicalTag() && !$headBlock->getChildBlock(
-                'magento-page-head-category-canonical-link'
-            )
-            ) {
-                $headBlock->addChild(
-                    'magento-page-head-category-canonical-link',
-                    'Magento\Theme\Block\Html\Head\Link',
-                    array(
-                        'url' => $category->getUrl(),
-                        'properties' => array('attributes' => array('rel' => 'canonical'))
-                    )
+            if ($this->_categoryHelper->canUseCanonicalTag()) {
+                $this->pageConfig->addRemotePageAsset(
+                    $category->getUrl(),
+                    ['attributes' => ['rel' => 'canonical']]
                 );
             }
-            /**
-             * want to show rss feed in the url
-             */
-            if ($this->isRssCatalogEnable() && $this->isTopCategory()) {
-                $title = __('%1 RSS Feed', $this->getCurrentCategory()->getName());
-                $headBlock->addRss($title, $this->getRssLink());
-            }
+
             $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
             if ($pageMainTitle) {
                 $pageMainTitle->setPageTitle($this->getCurrentCategory()->getName());
@@ -124,36 +107,6 @@ class View extends \Magento\Framework\View\Element\Template implements \Magento\
         return $this;
     }
 
-    /**
-     * @return string
-     */
-    public function isRssCatalogEnable()
-    {
-        return $this->_scopeConfig->getValue('rss/catalog/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
-    }
-
-    /**
-     * @return bool
-     */
-    public function isTopCategory()
-    {
-        return $this->getCurrentCategory()->getLevel() == 2;
-    }
-
-    /**
-     * @return string
-     */
-    public function getRssLink()
-    {
-        return $this->_urlBuilder->getUrl(
-            'rss/catalog/category',
-            array(
-                'cid' => $this->getCurrentCategory()->getId(),
-                'store_id' => $this->_storeManager->getStore()->getId()
-            )
-        );
-    }
-
     /**
      * @return string
      */
diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
index 850ae06b709..910efe75478 100644
--- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
+++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php
@@ -23,10 +23,7 @@
  */
 namespace Magento\Catalog\Block\Product;
 
-/**
- * Catalog Product Abstract Block
- */
-abstract class AbstractProduct extends \Magento\Framework\View\Element\Template
+class AbstractProduct extends \Magento\Framework\View\Element\Template
 {
     /**
      * @var array
@@ -54,13 +51,6 @@ abstract class AbstractProduct extends \Magento\Framework\View\Element\Template
      */
     protected $_columnCountLayoutDepend = array();
 
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp';
-
     /**
      * Core registry
      *
diff --git a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php
index 26bd2557ff1..22319f9b4d3 100644
--- a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php
+++ b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php
@@ -60,13 +60,6 @@ class ListCompare extends \Magento\Catalog\Block\Product\Compare\AbstractCompare
      */
     protected $_customerId = null;
 
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_noform';
-
     /**
      * @var \Magento\Framework\App\Http\Context
      */
@@ -159,10 +152,7 @@ class ListCompare extends \Magento\Catalog\Block\Product\Compare\AbstractCompare
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Products Comparison List') . ' - ' . $headBlock->getDefaultTitle());
-        }
+        $this->pageConfig->setTitle(__('Products Comparison List') . ' - ' . $this->pageConfig->getDefaultTitle());
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Catalog/Block/Product/Context.php b/app/code/Magento/Catalog/Block/Product/Context.php
index fe22dcc23b0..ae4512a6651 100644
--- a/app/code/Magento/Catalog/Block/Product/Context.php
+++ b/app/code/Magento/Catalog/Block/Product/Context.php
@@ -83,6 +83,11 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      */
     protected $stockItemService;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\View\LayoutInterface $layout
@@ -118,6 +123,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      * @param \Magento\Catalog\Helper\Image $imageHelper
      * @param ReviewRendererInterface $reviewRenderer
      * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -145,6 +151,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
         \Magento\Framework\View\TemplateEnginePool $enginePool,
         \Magento\Framework\App\State $appState,
         \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\View\Page\Config $pageConfig,
         \Magento\Catalog\Model\Config $catalogConfig,
         \Magento\Framework\Registry $registry,
         \Magento\Tax\Helper\Data $taxHelper,
@@ -191,7 +198,8 @@ class Context extends \Magento\Framework\View\Element\Template\Context
             $viewFileSystem,
             $enginePool,
             $appState,
-            $storeManager
+            $storeManager,
+            $pageConfig
         );
     }
 
diff --git a/app/code/Magento/Catalog/Block/Product/Gallery.php b/app/code/Magento/Catalog/Block/Product/Gallery.php
index 1e28695837e..d303bad8442 100644
--- a/app/code/Magento/Catalog/Block/Product/Gallery.php
+++ b/app/code/Magento/Catalog/Block/Product/Gallery.php
@@ -60,10 +60,7 @@ class Gallery extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle($this->getProduct()->getMetaTitle());
-        }
+        $this->pageConfig->setTitle($this->getProduct()->getMetaTitle());
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php
index 9b45812607a..360951799f9 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php
@@ -29,13 +29,6 @@ namespace Magento\Catalog\Block\Product\ProductList;
 
 class Crosssell extends \Magento\Catalog\Block\Product\AbstractProduct
 {
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_item';
-
     /**
      * Crosssell item collection
      *
diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
index c66550e7a76..46ade087a85 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
@@ -33,13 +33,6 @@ use Magento\Framework\View\Element\AbstractBlock;
  */
 class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements \Magento\Framework\View\Block\IdentityInterface
 {
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_noform';
-
     /**
      * @var Collection
      */
diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php
index 02128fd204a..96ee027397a 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php
@@ -33,13 +33,6 @@ use Magento\Framework\View\Element\AbstractBlock;
  */
 class Upsell extends \Magento\Catalog\Block\Product\AbstractProduct implements \Magento\Framework\View\Block\IdentityInterface
 {
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_noform';
-
     /**
      * @var int
      */
diff --git a/app/code/Magento/Catalog/Block/Product/View.php b/app/code/Magento/Catalog/Block/Product/View.php
index b23ad04e278..7a134829dec 100644
--- a/app/code/Magento/Catalog/Block/Product/View.php
+++ b/app/code/Magento/Catalog/Block/Product/View.php
@@ -31,14 +31,6 @@ use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
  */
 class View extends AbstractProduct implements \Magento\Framework\View\Block\IdentityInterface
 {
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     * @deprecated
-     */
-    protected $_mapRenderer = 'msrp_item';
-
     /**
      * Magento string lib
      *
@@ -141,39 +133,31 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
         if (!$product) {
             return parent::_prepareLayout();
         }
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $title = $product->getMetaTitle();
-            if ($title) {
-                $headBlock->setTitle($title);
-            }
-            $keyword = $product->getMetaKeyword();
-            $currentCategory = $this->_coreRegistry->registry('current_category');
-            if ($keyword) {
-                $headBlock->setKeywords($keyword);
-            } elseif ($currentCategory) {
-                $headBlock->setKeywords($product->getName());
-            }
-            $description = $product->getMetaDescription();
-            if ($description) {
-                $headBlock->setDescription($description);
-            } else {
-                $headBlock->setDescription($this->string->substr($product->getDescription(), 0, 255));
-            }
-            //@todo: move canonical link to separate block
-            $childBlockName = 'magento-page-head-product-canonical-link';
-            if ($this->_productHelper->canUseCanonicalTag() && !$headBlock->getChildBlock($childBlockName)) {
-                $params = array('_ignore_category' => true);
-                $headBlock->addChild(
-                    $childBlockName,
-                    'Magento\Theme\Block\Html\Head\Link',
-                    array(
-                        'url' => $product->getUrlModel()->getUrl($product, $params),
-                        'properties' => array('attributes' => array('rel' => 'canonical'))
-                    )
-                );
-            }
+
+        $title = $product->getMetaTitle();
+        if ($title) {
+            $this->pageConfig->setTitle($title);
+        }
+        $keyword = $product->getMetaKeyword();
+        $currentCategory = $this->_coreRegistry->registry('current_category');
+        if ($keyword) {
+            $this->pageConfig->setKeywords($keyword);
+        } elseif ($currentCategory) {
+            $this->pageConfig->setKeywords($product->getName());
         }
+        $description = $product->getMetaDescription();
+        if ($description) {
+            $this->pageConfig->setDescription($description);
+        } else {
+            $this->pageConfig->setDescription($this->string->substr($product->getDescription(), 0, 255));
+        }
+        if ($this->_productHelper->canUseCanonicalTag()) {
+            $this->pageConfig->addRemotePageAsset(
+                $product->getUrlModel()->getUrl($product, ['_ignore_category' => true]),
+                ['attributes' => array('rel' => 'canonical')]
+            );
+        }
+
         $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
         if ($pageMainTitle) {
             $pageMainTitle->setPageTitle($product->getName());
diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php
index 3369bd4238f..7a5dff4af47 100644
--- a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php
+++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Date.php
@@ -64,17 +64,6 @@ class Date extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions
         parent::__construct($context, $coreHelper, $catalogData, $data);
     }
 
-    /**
-     * @return AbstractBlock
-     */
-    protected function _prepareLayout()
-    {
-        if ($head = $this->getLayout()->getBlock('head')) {
-            $head->setCanLoadCalendarJs(true);
-        }
-        return parent::_prepareLayout();
-    }
-
     /**
      * Use JS calendar settings
      *
diff --git a/app/code/Magento/Catalog/Block/Rss/Category.php b/app/code/Magento/Catalog/Block/Rss/Category.php
new file mode 100644
index 00000000000..e9ca79966f6
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Rss/Category.php
@@ -0,0 +1,266 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class Category
+ * @package Magento\Catalog\Block\Rss
+ */
+class Category extends \Magento\Framework\View\Element\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Catalog\Model\CategoryFactory
+     */
+    protected $categoryFactory;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Category
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Http\Context $httpContext
+     * @param \Magento\Catalog\Helper\Data $catalogData
+     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
+     * @param \Magento\Catalog\Model\Rss\Category $rssModel
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param \Magento\Catalog\Helper\Image $imageHelper
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Http\Context $httpContext,
+        \Magento\Catalog\Helper\Data $catalogData,
+        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
+        \Magento\Catalog\Model\Rss\Category $rssModel,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        \Magento\Catalog\Helper\Image $imageHelper,
+        \Magento\Customer\Model\Session $customerSession,
+        array $data = array()
+    ) {
+        $this->imageHelper = $imageHelper;
+        $this->categoryFactory = $categoryFactory;
+        $this->customerSession = $customerSession;
+        $this->rssModel = $rssModel;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        $this->storeManager = $context->getStoreManager();
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->setCacheKey(
+            'rss_catalog_category_'
+            . $this->getRequest()->getParam('cid') . '_'
+            . $this->getStoreId() . '_'
+            . $this->customerSession->getId()
+        );
+        parent::_construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRssData()
+    {
+        $category = $this->categoryFactory->create();
+        $category->load($this->getRequest()->getParam('cid'));
+        if ($category->getId()) {
+            $category->setIsAnchor(true);
+            $newUrl = $category->getUrl();
+            $title = $category->getName();
+            $data = array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+
+            /** @var $product \Magento\Catalog\Model\Product */
+            foreach ($this->rssModel->getProductCollection($category, $this->getStoreId()) as $product) {
+                $product->setAllowedInRss(true);
+                $product->setAllowedPriceInRss(true);
+
+                $this->_eventManager->dispatch('rss_catalog_category_xml_callback', array('product' => $product));
+
+                if (!$product->getAllowedInRss()) {
+                    continue;
+                }
+
+                $description = '
+                    <table><tr>
+                        <td><a href="%s"><img src="%s" border="0" align="left" height="75" width="75"></a></td>
+                        <td  style="text-decoration:none;">%s %s</td>
+                    </tr></table>
+                ';
+
+                $description = sprintf(
+                    $description,
+                    $product->getProductUrl(),
+                    $this->imageHelper->init($product, 'thumbnail')->resize(75, 75),
+                    $product->getDescription(),
+                    $product->getAllowedPriceInRss() ? $this->renderPriceHtml($product) : ''
+                );
+
+                $data['entries'][] = array(
+                    'title' => $product->getName(),
+                    'link' => $product->getProductUrl(),
+                    'description' => $description
+                );
+            }
+        } else {
+            $data = array(
+                'title' => 'Category Not Found',
+                'description' => 'Category Not Found',
+                'link' => $this->getUrl(''),
+                'charset' => 'UTF-8'
+            );
+        }
+
+        return $data;
+    }
+
+    /**
+     * Get rendered price html
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return string
+     */
+    protected function renderPriceHtml(\Magento\Catalog\Model\Product $product)
+    {
+        /** @var \Magento\Framework\Pricing\Render $priceRender */
+        $priceRender = $this->getLayout()->getBlock('product.price.render.default');
+        if (!$priceRender) {
+            $priceRender = $this->getLayout()->createBlock(
+                'Magento\Framework\Pricing\Render',
+                'product.price.render.default',
+                array('data' => array('price_render_handle' => 'catalog_product_prices'))
+            );
+        }
+
+        $price = '';
+        if ($priceRender) {
+            $price = $priceRender->render(
+                \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
+                $product,
+                array(
+                    'display_minimal_price'  => true,
+                    'use_link_for_as_low_as' => true,
+                    'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST
+                )
+            );
+        }
+
+        return $price;
+    }
+
+    /**
+     * @return int
+     */
+    protected function getStoreId()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        if ($storeId == null) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+        return $storeId;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCacheLifetime()
+    {
+        return 600;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag('rss/catalog/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        $result = array();
+        if ($this->isAllowed()) {
+            /** @var $category \Magento\Catalog\Model\Category */
+            $category = $this->categoryFactory->create();
+            $treeModel = $category->getTreeModel()->loadNode($this->storeManager->getStore()->getRootCategoryId());
+            $nodes = $treeModel->loadChildren()->getChildren();
+
+            $nodeIds = array();
+            foreach ($nodes as $node) {
+                $nodeIds[] = $node->getId();
+            }
+
+            /* @var $collection \Magento\Catalog\Model\Resource\Category\Collection */
+            $collection = $category->getResourceCollection();
+            $collection->addIdFilter($nodeIds)
+                ->addAttributeToSelect('url_key')
+                ->addAttributeToSelect('name')
+                ->addAttributeToSelect('is_anchor')
+                ->addAttributeToFilter('is_active', 1)
+                ->addAttributeToSort('name')
+                ->load();
+
+            $feeds = array();
+            foreach ($collection as $category) {
+                $feeds[] = array(
+                    'label' => $category->getName(),
+                    'link' => $this->rssUrlBuilder->getUrl(array('type' => 'category', 'cid' => $category->getId()))
+                );
+            }
+            $result = array('group' => 'Categories', 'feeds' => $feeds);
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Rss/Product/NewProducts.php b/app/code/Magento/Catalog/Block/Rss/Product/NewProducts.php
new file mode 100644
index 00000000000..e249f0a016c
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Rss/Product/NewProducts.php
@@ -0,0 +1,218 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss\Product;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class NewProducts
+ * @package Magento\Catalog\Block\Rss\Product
+ */
+class NewProducts extends \Magento\Framework\View\Element\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Catalog\Helper\Image
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NewProducts
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Catalog\Helper\Image $imageHelper
+     * @param \Magento\Catalog\Model\Rss\Product\NewProducts $rssModel
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Catalog\Helper\Image $imageHelper,
+        \Magento\Catalog\Model\Rss\Product\NewProducts $rssModel,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->imageHelper = $imageHelper;
+        $this->rssModel = $rssModel;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        $this->storeManager = $context->getStoreManager();
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->setCacheKey('rss_catalog_new_products_store_' . $this->getStoreId());
+        parent::_construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag('rss/catalog/new', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRssData()
+    {
+        $storeModel = $this->storeManager->getStore($this->getStoreId());
+        $newUrl = $this->rssUrlBuilder->getUrl(array('store_id' => $this->getStoreId(), 'type' => 'new_products'));
+        $title = __('New Products from %1', $storeModel->getFrontendName());
+        $lang = $this->_scopeConfig->getValue(
+            'general/locale/code',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $storeModel
+        );
+        $data = array(
+            'title' => $title,
+            'description' => $title,
+            'link' => $newUrl,
+            'charset' => 'UTF-8',
+            'language' => $lang
+        );
+
+        foreach ($this->rssModel->getProductsCollection($this->getStoreId()) as $item) {
+            /** @var $item \Magento\Catalog\Model\Product */
+            $item->setAllowedInRss(true);
+            $item->setAllowedPriceInRss(true);
+
+            $this->_eventManager->dispatch('rss_catalog_new_xml_callback', array(
+                'row' => $item->getData(),
+                'product' => $item
+            ));
+
+            if (!$item->getAllowedInRss()) {
+                continue;
+            }
+
+            $allowedPriceInRss = $item->getAllowedPriceInRss();
+            $description ='
+                <table><tr>
+                <td><a href="%s"><img src="%s" border="0" align="left" height="75" width="75"></a></td>
+                <td style="text-decoration:none;">%s %s</td>
+                </tr></table>
+            ';
+            $description = sprintf(
+                $description,
+                $item->getProductUrl(),
+                $this->imageHelper->init($item, 'thumbnail')->resize(75, 75),
+                $item->getDescription(),
+                $allowedPriceInRss ? $this->renderPriceHtml($item) : ''
+            );
+
+            $data['entries'][] = array(
+                'title' => $item->getName(),
+                'link' => $item->getProductUrl(),
+                'description' => $description
+            );
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return int
+     */
+    protected function getStoreId()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        if ($storeId == null) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+        return $storeId;
+    }
+
+    /**
+     * Get rendered price html
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return string
+     */
+    protected function renderPriceHtml(\Magento\Catalog\Model\Product $product)
+    {
+        /** @var \Magento\Framework\Pricing\Render $priceRender */
+        $priceRender = $this->getLayout()->getBlock('product.price.render.default');
+        if (!$priceRender) {
+            $priceRender = $this->getLayout()->createBlock(
+                'Magento\Framework\Pricing\Render',
+                'product.price.render.default',
+                array('data' => array('price_render_handle' => 'catalog_product_prices'))
+            );
+        }
+        $price = '';
+        if ($priceRender) {
+            $price = $priceRender->render(
+                \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
+                $product,
+                array(
+                    'display_minimal_price'  => true,
+                    'use_link_for_as_low_as' => true,
+                    'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST
+                )
+            );
+        }
+
+        return $price;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCacheLifetime()
+    {
+        return 600;
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        $data = array();
+        if ($this->isAllowed()) {
+            $url = $this->rssUrlBuilder->getUrl(array('type' => 'new_products'));
+            $data = array('label' => __('New Products'), 'link' => $url);
+        }
+
+        return $data;
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Rss/Product/Special.php b/app/code/Magento/Catalog/Block/Rss/Product/Special.php
new file mode 100644
index 00000000000..cab115dbe86
--- /dev/null
+++ b/app/code/Magento/Catalog/Block/Rss/Product/Special.php
@@ -0,0 +1,267 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss\Product;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class Special
+ * @package Magento\Catalog\Block\Rss\Product
+ */
+class Special extends \Magento\Framework\View\Element\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Framework\Pricing\PriceCurrencyInterface
+     */
+    protected $priceCurrency;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Catalog\Helper\Output
+     */
+    protected $outputHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\Special
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Http\Context
+     */
+    protected $httpContext;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Http\Context $httpContext
+     * @param \Magento\Catalog\Helper\Image $imageHelper
+     * @param \Magento\Catalog\Helper\Output $outputHelper
+     * @param \Magento\Catalog\Helper\Data $catalogHelper
+     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
+     * @param \Magento\Catalog\Model\Rss\Product\Special $rssModel
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Http\Context $httpContext,
+        \Magento\Catalog\Helper\Image $imageHelper,
+        \Magento\Catalog\Helper\Output $outputHelper,
+        \Magento\Catalog\Helper\Data $catalogHelper,
+        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
+        \Magento\Catalog\Model\Rss\Product\Special $rssModel,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->outputHelper = $outputHelper;
+        $this->imageHelper = $imageHelper;
+        $this->rssModel = $rssModel;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        $this->priceCurrency = $priceCurrency;
+        $this->catalogHelper = $catalogHelper;
+        $this->httpContext = $httpContext;
+        $this->storeManager = $context->getStoreManager();
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->setCacheKey('rss_catalog_special_' . $this->getStoreId() . '_' . $this->getCustomerGroupId());
+        parent::_construct();
+    }
+
+    /**
+     * @return string
+     */
+    public function getRssData()
+    {
+        $newUrl = $this->rssUrlBuilder->getUrl(array('type' => 'special_products', 'store_id' => $this->getStoreId()));
+        $title = __('%1 - Special Products', $this->storeManager->getStore()->getFrontendName());
+        $lang = $this->_scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+
+        $data = array(
+            'title' => $title,
+            'description' => $title,
+            'link' => $newUrl,
+            'charset' => 'UTF-8',
+            'language' => $lang
+        );
+
+        $currentDate = new \Magento\Framework\Stdlib\DateTime\Date();
+        foreach ($this->rssModel->getProductsCollection($this->getStoreId(), $this->getCustomerGroupId()) as $item) {
+            /** @var $item \Magento\Catalog\Model\Product */
+            $item->setAllowedInRss(true);
+            $item->setAllowedPriceInRss(true);
+
+            $this->_eventManager->dispatch('rss_catalog_special_xml_callback', array(
+                'row' => $item->getData(),
+                'product' => $item
+            ));
+
+            if (!$item->getAllowedInRss()) {
+                continue;
+            }
+
+            $item->setUseSpecial(false);
+            if ($item->getSpecialToDate() && $item->getFinalPrice() <= $item->getSpecialPrice() &&
+                $item->getAllowedPriceInRss()
+            ) {
+                $compareDate = $currentDate->compareDate(
+                    $item->getSpecialToDate(),
+                    \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT
+                );
+                if (-1 === $compareDate || 0 === $compareDate) {
+                    $item->setUseSpecial(true);
+                }
+            }
+            $data['entries'][] = $this->getEntryData($item);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $item
+     * @return array
+     */
+    protected function getEntryData(\Magento\Catalog\Model\Product $item)
+    {
+        $description = '
+            <table><tr>
+                <td><a href="%s"><img src="%s" alt="" border="0" align="left" height="75" width="75" /></a></td>
+                <td style="text-decoration:none;">%s %s</td>
+            </tr></table>
+        ';
+
+        $specialPrice = '';
+        if ($item->getAllowedPriceInRss()) {
+            if ($this->catalogHelper->canApplyMsrp($item)) {
+                $specialPrice = '<br/><a href="' . $item->getProductUrl() . '">' . __('Click for price') . '</a>';
+            } else {
+                $special = '';
+                if ($item->getUseSpecial()) {
+                    $special = '<br />' . __('Special Expires On: %1', $this->formatDate(
+                        $item->getSpecialToDate(),
+                        \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM
+                    ));
+                }
+                $specialPrice = sprintf(
+                    '<p>%s %s%s</p>',
+                    __('Price: %1', $this->priceCurrency->convertAndFormat($item->getPrice())),
+                    __('Special Price: %1', $this->priceCurrency->convertAndFormat($item->getFinalPrice())),
+                    $special
+                );
+            }
+        }
+        $description = sprintf(
+            $description,
+            $item->getProductUrl(),
+            $this->imageHelper->init($item, 'thumbnail')->resize(75, 75),
+            $this->outputHelper->productAttribute($item, $item->getDescription(), 'description'),
+            $specialPrice
+        );
+
+        return array(
+            'title' => $item->getName(),
+            'link' => $item->getProductUrl(),
+            'description' => $description
+        );
+    }
+
+    /**
+     * Get store id
+     *
+     * @return int
+     */
+    protected function getStoreId()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        if ($storeId == null) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+        return $storeId;
+    }
+
+    /**
+     * Get customer group id
+     *
+     * @return int
+     */
+    protected function getCustomerGroupId()
+    {
+        $customerGroupId =   (int) $this->getRequest()->getParam('cid');
+        if ($customerGroupId == null) {
+            $customerGroupId = $this->httpContext->getValue(\Magento\Customer\Helper\Data::CONTEXT_GROUP);
+        }
+        return $customerGroupId;
+    }
+
+    /**
+     * Check if RSS feed allowed
+     *
+     * @return mixed
+     */
+    public function isAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag('rss/catalog/special', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCacheLifetime()
+    {
+        return 600;
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        $data = array();
+        if ($this->isAllowed()) {
+            $url = $this->rssUrlBuilder->getUrl(array('type' => 'special_products'));
+            $data = array('label' => __('Special Products'), 'link' => $url);
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Widget/Link.php b/app/code/Magento/Catalog/Block/Widget/Link.php
index 19616864587..2d94f12ab8c 100644
--- a/app/code/Magento/Catalog/Block/Widget/Link.php
+++ b/app/code/Magento/Catalog/Block/Widget/Link.php
@@ -29,6 +29,10 @@
  */
 namespace Magento\Catalog\Block\Widget;
 
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+
 class Link extends \Magento\Framework\View\Element\Html\Link implements \Magento\Widget\Block\BlockInterface
 {
     /**
@@ -52,60 +56,81 @@ class Link extends \Magento\Framework\View\Element\Html\Link implements \Magento
     protected $_anchorText;
 
     /**
-     * Url rewrite
+     * Url finder for category
      *
-     * @var \Magento\UrlRewrite\Model\Resource\UrlRewrite
+     * @var UrlFinderInterface
      */
-    protected $_urlRewrite;
+    protected $urlFinder;
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite
+     * @param UrlFinderInterface $urlFinder
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite,
-        array $data = array()
+        UrlFinderInterface $urlFinder,
+        array $data = []
     ) {
-        $this->_urlRewrite = $urlRewrite;
         parent::__construct($context, $data);
+        $this->urlFinder = $urlFinder;
     }
 
     /**
      * Prepare url using passed id path and return it
      * or return false if path was not found in url rewrites.
      *
+     * @throws \RuntimeException
      * @return string|false
      */
     public function getHref()
     {
-        if (!$this->_href) {
+        if ($this->_href === null) {
+            if (!$this->getData('id_path')) {
+                throw new \RuntimeException('Parameter id_path is not set.');
+            }
+            $rewriteData = $this->parseIdPath($this->getData('id_path'));
 
-            if ($this->hasStoreId()) {
-                $store = $this->_storeManager->getStore($this->getStoreId());
-            } else {
-                $store = $this->_storeManager->getStore();
+            $href = false;
+            $store = $this->hasStoreId() ? $this->_storeManager->getStore($this->getStoreId())
+                : $this->_storeManager->getStore();
+            $filterData = [
+                UrlRewrite::ENTITY_ID => $rewriteData[1],
+                UrlRewrite::ENTITY_TYPE => $rewriteData[0],
+                UrlRewrite::STORE_ID => $store->getId(),
+            ];
+            if (!empty($rewriteData[2]) && $rewriteData[0] == ProductUrlRewriteGenerator::ENTITY_TYPE) {
+                $filterData[UrlRewrite::METADATA]['category_id'] = $rewriteData[2];
             }
+            $rewrite = $this->urlFinder->findOneByData($filterData);
+
+            if ($rewrite) {
+                $href = $store->getUrl('', ['_direct' => $rewrite->getRequestPath()]);
 
-            /* @var $store \Magento\Store\Model\Store */
-            $href = "";
-            if ($this->getData('id_path')) {
-                $href = $this->_urlRewrite->getRequestPathByIdPath($this->getData('id_path'), $store);
-                if (!$href) {
-                    return false;
+                if (strpos($href, '___store') === false) {
+                    $href .= (strpos($href, '?') === false ? '?' : '&') . '___store=' . $store->getCode();
                 }
             }
-
-            $this->_href = $store->getUrl('', array('_direct' => $href));
+            $this->_href = $href;
         }
+        return $this->_href;
+    }
 
-        if (strpos($this->_href, "___store") === false) {
-            $symbol = strpos($this->_href, "?") === false ? "?" : "&";
-            $this->_href = $this->_href . $symbol . "___store=" . $store->getCode();
-        }
+    /**
+     * Parse id_path
+     *
+     * @param string $idPath
+     * @throws \RuntimeException
+     * @return array
+     */
+    protected function parseIdPath($idPath)
+    {
+        $rewriteData = explode('/', $idPath);
 
-        return $this->_href;
+        if (!isset($rewriteData[0]) || !isset($rewriteData[1])) {
+            throw new \RuntimeException('Wrong id_path structure.');
+        }
+        return $rewriteData;
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
index 366d0e3b898..6f5e2e20a67 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
@@ -110,7 +110,6 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Category
 
         $this->_view->loadLayout();
         $this->_setActiveMenu('Magento_Catalog::catalog_categories');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true)->setContainerCssClass('catalog-categories');
 
         $this->_addBreadcrumb(__('Manage Catalog Categories'), __('Manage Categories'));
 
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
index e6f3378323a..5c2292e8201 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
@@ -74,6 +74,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category
                 }
                 $parentCategory = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($parentId);
                 $category->setPath($parentCategory->getPath());
+                $category->setParentId($parentId);
             }
 
             /**
@@ -86,14 +87,6 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Category
                 }
             }
 
-            /**
-             * Create Permanent Redirect for old URL key
-             */
-            // && $category->getOrigData('url_key') != $category->getData('url_key')
-            if ($category->getId() && isset($data['general']['url_key_create_redirect'])) {
-                $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
-            }
-
             $category->setAttributeSetId($category->getDefaultAttributeSetId());
 
             if (isset($data['category_products']) && !$category->getProductsReadonly()) {
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php
index 8bcf964d191..07eedf8cc69 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php
@@ -183,8 +183,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribut
 
                 $this->messageManager->addNotice(
                     __(
-                        'Please refresh "Catalog URL Rewrites" and "Product Attributes" in System -> ' .
-                        '<a href="%1">Index Management</a>.',
+                        'Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.',
                         $this->getUrl('adminhtml/process/list')
                     )
                 );
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php
index fb4fcbb3ef6..bcd2261590d 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php
@@ -81,8 +81,6 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
                 );
         }
 
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
         $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
         if ($block) {
             $block->setStoreId($product->getStoreId());
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
index 9dc472ea172..7941ca0787b 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
@@ -108,13 +108,6 @@ class Helper
             $product->setWebsiteIds(array($this->storeManager->getStore(true)->getWebsite()->getId()));
         }
 
-        /**
-         * Create Permanent Redirect for old URL key
-         */
-        if ($product->getId() && isset($productData['url_key_create_redirect'])) {
-            $product->setData('save_rewrites_history', (bool)$productData['url_key_create_redirect']);
-        }
-
         /**
          * Check "Use Default Value" checkboxes values
          */
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
index 089cbd41384..dc97a9da9ce 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
@@ -91,8 +91,6 @@ class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product
             $this->_setActiveMenu('Magento_Catalog::catalog_products');
         }
 
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
         $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
         if ($block) {
             $block->setStoreId($product->getStoreId());
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php
index 8dac12620e5..071db65a981 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php
@@ -51,8 +51,6 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Set
 
         $this->_view->loadLayout();
         $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
         $this->_addBreadcrumb(__('Catalog'), __('Catalog'));
         $this->_addBreadcrumb(__('Manage Product Sets'), __('Manage Product Sets'));
 
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php
index 418720fa8d7..4df2a960cec 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php
@@ -74,8 +74,6 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Search
 
         $this->_title->add($id ? $model->getQueryText() : __('New Search'));
 
-        $this->_view->getLayout()->getBlock('head')->setCanLoadRulesJs(true);
-
         $this->_view->getLayout()->getBlock(
             'adminhtml.catalog.search.edit'
         )->setData(
diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php
index 12a68a4b630..ef119e611cb 100644
--- a/app/code/Magento/Catalog/Controller/Category/View.php
+++ b/app/code/Magento/Catalog/Controller/Category/View.php
@@ -59,6 +59,9 @@ class View extends \Magento\Framework\App\Action\Action
      */
     protected $_storeManager;
 
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
@@ -66,6 +69,7 @@ class View extends \Magento\Framework\App\Action\Action
      * @param \Magento\Catalog\Model\Session $catalogSession
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
@@ -73,13 +77,15 @@ class View extends \Magento\Framework\App\Action\Action
         \Magento\Catalog\Model\Design $catalogDesign,
         \Magento\Catalog\Model\Session $catalogSession,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\StoreManagerInterface $storeManager
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
     ) {
         $this->_storeManager = $storeManager;
         $this->_categoryFactory = $categoryFactory;
         $this->_catalogDesign = $catalogDesign;
         $this->_catalogSession = $catalogSession;
         $this->_coreRegistry = $coreRegistry;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
         parent::__construct($context);
     }
 
@@ -176,7 +182,7 @@ class View extends \Magento\Framework\App\Action\Action
             $this->_view->generateLayoutBlocks();
 
             $pageConfig->addBodyClass('page-products')
-                ->addBodyClass('categorypath-' . $category->getUrlPath())
+                ->addBodyClass('categorypath-' . $this->categoryUrlPathGenerator->getUrlPath($category))
                 ->addBodyClass('category-' . $category->getUrlKey());
 
             $this->_view->getLayout()->initMessages();
diff --git a/app/code/Magento/Catalog/Helper/Catalog.php b/app/code/Magento/Catalog/Helper/Catalog.php
index f5d49df403c..7f2638a4492 100644
--- a/app/code/Magento/Catalog/Helper/Catalog.php
+++ b/app/code/Magento/Catalog/Helper/Catalog.php
@@ -30,16 +30,6 @@ namespace Magento\Catalog\Helper;
  */
 class Catalog extends \Magento\Framework\App\Helper\AbstractHelper
 {
-    /**
-     * Config path to valid file paths
-     */
-    const XML_PATH_PUBLIC_FILES_VALID_PATHS = 'general/file/public_files_valid_paths';
-
-    /**
-     * Config path to sitemap valid paths
-     */
-    const XML_PATH_SITEMAP_VALID_PATHS = 'general/file/sitemap_generate_valid_paths';
-
     /**
      * Attribute Tab block name for product edit
      *
@@ -118,17 +108,4 @@ class Catalog extends \Magento\Framework\App\Helper\AbstractHelper
         $this->_categoryAttributeTabBlock = $attributeTabBlock;
         return $this;
     }
-
-    /**
-     * Get list valid paths for generate a sitemap XML file
-     *
-     * @return array
-     */
-    public function getSitemapValidPaths()
-    {
-        return array_merge(
-            $this->_scopeConfig->getValue(self::XML_PATH_SITEMAP_VALID_PATHS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE),
-            $this->_scopeConfig->getValue(self::XML_PATH_PUBLIC_FILES_VALID_PATHS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
-        );
-    }
 }
diff --git a/app/code/Magento/Catalog/Helper/Category.php b/app/code/Magento/Catalog/Helper/Category.php
index 99e5a25df2e..c698ec9a2cd 100644
--- a/app/code/Magento/Catalog/Helper/Category.php
+++ b/app/code/Magento/Catalog/Helper/Category.php
@@ -34,8 +34,6 @@ use Magento\Store\Model\Store;
  */
 class Category extends AbstractHelper
 {
-    const XML_PATH_CATEGORY_URL_SUFFIX = 'catalog/seo/category_url_suffix';
-
     const XML_PATH_USE_CATEGORY_CANONICAL_TAG = 'catalog/seo/category_canonical_tag';
 
     const XML_PATH_CATEGORY_ROOT_ID = 'catalog/category/root_id';
@@ -47,13 +45,6 @@ class Category extends AbstractHelper
      */
     protected $_storeCategories = array();
 
-    /**
-     * Cache for category rewrite suffix
-     *
-     * @var array
-     */
-    protected $_categoryUrlSuffix = array();
-
     /**
      * Scope config
      *
@@ -184,53 +175,6 @@ class Category extends AbstractHelper
         return true;
     }
 
-    /**
-     * Retrieve category rewrite suffix for store
-     *
-     * @param int $storeId
-     * @return string
-     */
-    public function getCategoryUrlSuffix($storeId = null)
-    {
-        if (is_null($storeId)) {
-            $storeId = $this->_storeManager->getStore()->getId();
-        }
-
-        if (!isset($this->_categoryUrlSuffix[$storeId])) {
-            $this->_categoryUrlSuffix[$storeId] = $this->_scopeConfig->getValue(
-                self::XML_PATH_CATEGORY_URL_SUFFIX,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                $storeId
-            );
-        }
-        return $this->_categoryUrlSuffix[$storeId];
-    }
-
-    /**
-     * Retrieve clear url for category as parent
-     *
-     * @param string $urlPath
-     * @param bool $slash
-     * @param int $storeId
-     * @return string
-     */
-    public function getCategoryUrlPath($urlPath, $slash = false, $storeId = null)
-    {
-        if (!$this->getCategoryUrlSuffix($storeId)) {
-            return $urlPath;
-        }
-
-        if ($slash) {
-            $regexp = '#(' . preg_quote($this->getCategoryUrlSuffix($storeId), '#') . ')/$#i';
-            $replace = '/';
-        } else {
-            $regexp = '#(' . preg_quote($this->getCategoryUrlSuffix($storeId), '#') . ')$#i';
-            $replace = '';
-        }
-
-        return preg_replace($regexp, $replace, $urlPath);
-    }
-
     /**
      * Check if <link rel="canonical"> can be used for category
      *
diff --git a/app/code/Magento/Catalog/Helper/Data.php b/app/code/Magento/Catalog/Helper/Data.php
index 1e21a3a8de9..aa81392fb0a 100644
--- a/app/code/Magento/Catalog/Helper/Data.php
+++ b/app/code/Magento/Catalog/Helper/Data.php
@@ -23,13 +23,10 @@
  */
 namespace Magento\Catalog\Helper;
 
-use Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder;
 use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder as QuoteDetailsItemBuilder;
 use Magento\Tax\Service\V1\Data\TaxClassKey;
-use Magento\Tax\Service\V1\Data\TaxClassKeyBuilder;
-use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
 use Magento\Customer\Model\Address\Converter as AddressConverter;
 use Magento\Customer\Model\Session as CustomerSession;
 use Magento\Tax\Model\Config;
@@ -45,27 +42,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
 
     const XML_PATH_PRICE_SCOPE = 'catalog/price/scope';
 
-    const XML_PATH_SEO_SAVE_HISTORY = 'catalog/seo/save_rewrites_history';
-
     const CONFIG_USE_STATIC_URLS = 'cms/wysiwyg/use_static_urls_in_catalog';
 
     const CONFIG_PARSE_URL_DIRECTIVES = 'catalog/frontend/parse_url_directives';
 
     const XML_PATH_DISPLAY_PRODUCT_COUNT = 'catalog/layered_navigation/display_product_count';
 
-    /**
-     * Minimum advertise price constants
-     */
-    const XML_PATH_MSRP_ENABLED = 'sales/msrp/enabled';
-
-    const XML_PATH_MSRP_DISPLAY_ACTUAL_PRICE_TYPE = 'sales/msrp/display_price_type';
-
-    const XML_PATH_MSRP_APPLY_TO_ALL = 'sales/msrp/apply_for_all';
-
-    const XML_PATH_MSRP_EXPLANATION_MESSAGE = 'sales/msrp/explanation_message';
-
-    const XML_PATH_MSRP_EXPLANATION_MESSAGE_WHATS_THIS = 'sales/msrp/explanation_message_whats_this';
-
     /**
      * Cache context
      */
@@ -84,13 +66,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_categoryPath;
 
-    /**
-     * Array of product types that MAP enabled
-     *
-     * @var array
-     */
-    protected $_mapApplyToProductType = null;
-
     /**
      * Currently selected store ID if applicable
      *
@@ -157,13 +132,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_categoryFactory;
 
-    /**
-     * Eav attribute factory
-     *
-     * @var \Magento\Catalog\Model\Resource\Eav\AttributeFactory
-     */
-    protected $_eavAttributeFactory;
-
     /**
      * Template filter factory
      *
@@ -171,11 +139,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_templateFilterFactory;
 
-    /**
-     * @var \Magento\Framework\Escaper
-     */
-    protected $_escaper;
-
     /**
      * Tax class key builder
      *
@@ -232,7 +195,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
 
     /**
      * @param \Magento\Framework\App\Helper\Context $context
-     * @param \Magento\Catalog\Model\Resource\Eav\AttributeFactory $eavAttributeFactory
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Framework\StoreManagerInterface $storeManager
@@ -243,7 +205,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Catalog\Model\Template\Filter\Factory $templateFilterFactory
-     * @param \Magento\Framework\Escaper $escaper
      * @param string $templateFilterModel
      * @param TaxClassKeyBuilder $taxClassKeyBuilder
      * @param Config $taxConfig
@@ -256,7 +217,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
-        \Magento\Catalog\Model\Resource\Eav\AttributeFactory $eavAttributeFactory,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         \Magento\Framework\StoreManagerInterface $storeManager,
@@ -267,7 +227,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Catalog\Model\Template\Filter\Factory $templateFilterFactory,
-        \Magento\Framework\Escaper $escaper,
         $templateFilterModel,
         \Magento\Tax\Service\V1\Data\TaxClassKeyBuilder $taxClassKeyBuilder,
         \Magento\Tax\Model\Config $taxConfig,
@@ -278,7 +237,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         AddressConverter $addressConverter,
         PriceCurrencyInterface $priceCurrency
     ) {
-        $this->_eavAttributeFactory = $eavAttributeFactory;
         $this->_categoryFactory = $categoryFactory;
         $this->_productFactory = $productFactory;
         $this->_storeManager = $storeManager;
@@ -290,7 +248,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         $this->_scopeConfig = $scopeConfig;
         $this->_coreRegistry = $coreRegistry;
         $this->_templateFilterModel = $templateFilterModel;
-        $this->_escaper = $escaper;
         $this->_taxClassKeyBuilder = $taxClassKeyBuilder;
         $this->_taxConfig = $taxConfig;
         $this->_quoteDetailsBuilder = $quoteDetailsBuilder;
@@ -466,21 +423,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->getPriceScope() == self::PRICE_SCOPE_GLOBAL;
     }
 
-    /**
-     * Indicate whether to save URL Rewrite History or not (create redirects to old URLs)
-     *
-     * @param int $storeId Store View
-     * @return bool
-     */
-    public function shouldSaveUrlRewritesHistory($storeId = null)
-    {
-        return $this->_scopeConfig->isSetFlag(
-            self::XML_PATH_SEO_SAVE_HISTORY,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $storeId
-        );
-    }
-
     /**
      * Check if the store is configured to use static URLs for media
      *
@@ -519,187 +461,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->_templateFilterFactory->create($this->_templateFilterModel);
     }
 
-    /**
-     * Check if Minimum Advertised Price is enabled
-     *
-     * @return bool
-     */
-    public function isMsrpEnabled()
-    {
-        return (bool)$this->_scopeConfig->getValue(
-            self::XML_PATH_MSRP_ENABLED,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $this->_storeId
-        );
-    }
-
-    /**
-     * Return MAP display actual type
-     *
-     * @return null|string
-     */
-    public function getMsrpDisplayActualPriceType()
-    {
-        return $this->_scopeConfig->getValue(
-            self::XML_PATH_MSRP_DISPLAY_ACTUAL_PRICE_TYPE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $this->_storeId
-        );
-    }
-
-    /**
-     * Check if MAP apply to all products
-     *
-     * @return bool
-     */
-    public function isMsrpApplyToAll()
-    {
-        return (bool) $this->_scopeConfig->getValue(
-            self::XML_PATH_MSRP_APPLY_TO_ALL,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $this->_storeId
-        );
-    }
-
-    /**
-     * Return MAP explanation message
-     *
-     * @return string
-     */
-    public function getMsrpExplanationMessage()
-    {
-        return $this->_escaper->escapeHtml(
-            $this->_scopeConfig->getValue(
-                self::XML_PATH_MSRP_EXPLANATION_MESSAGE,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                $this->_storeId
-            ),
-            array('b', 'br', 'strong', 'i', 'u', 'p', 'span')
-        );
-    }
-
-    /**
-     * Return MAP explanation message for "Whats This" window
-     *
-     * @return string
-     */
-    public function getMsrpExplanationMessageWhatsThis()
-    {
-        return $this->_escaper->escapeHtml(
-            $this->_scopeConfig->getValue(
-                self::XML_PATH_MSRP_EXPLANATION_MESSAGE_WHATS_THIS,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                $this->_storeId
-            ),
-            array('b', 'br', 'strong', 'i', 'u', 'p', 'span')
-        );
-    }
-
-    /**
-     * Check if can apply Minimum Advertise price to product
-     * in specific visibility
-     *
-     * @param int|\Magento\Catalog\Model\Product $product
-     * @param int $visibility Check displaying price in concrete place (by default generally)
-     * @param bool $checkAssociatedItems
-     * @return bool
-     */
-    public function canApplyMsrp($product, $visibility = null, $checkAssociatedItems = true)
-    {
-        if (!$this->isMsrpEnabled()) {
-            return false;
-        }
-
-        if (is_numeric($product)) {
-            /** @var \Magento\Catalog\Model\Product $product */
-            $product = $this->_productFactory->create()->setStoreId(
-                $this->_storeManager->getStore()->getId()
-            )->load(
-                $product
-            );
-        }
-
-        if (!$this->canApplyMsrpToProductType($product)) {
-            return false;
-        }
-
-        $result = $product->getMsrpEnabled();
-        if ($result == Type\Enabled::MSRP_ENABLE_USE_CONFIG) {
-            $result = $this->isMsrpApplyToAll();
-        }
-
-        if (!$product->hasMsrpEnabled() && $this->isMsrpApplyToAll()) {
-            $result = true;
-        }
-
-        if ($result && $visibility !== null) {
-            $productVisibility = $product->getMsrpDisplayActualPriceType();
-            if ($productVisibility == Type\Price::TYPE_USE_CONFIG) {
-                $productVisibility = $this->getMsrpDisplayActualPriceType();
-            }
-            $result = $productVisibility == $visibility;
-        }
-
-        if ($product->getTypeInstance()->isComposite($product)
-            && $checkAssociatedItems
-            && (!$result || $visibility !== null)
-        ) {
-            $resultInOptions = $product->getTypeInstance()->isMapEnabledInOptions($product, $visibility);
-            if ($resultInOptions !== null) {
-                $result = $resultInOptions;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Check whether MAP applied to product Product Type
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return bool
-     */
-    public function canApplyMsrpToProductType($product)
-    {
-        if ($this->_mapApplyToProductType === null) {
-            /** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */
-            $attribute = $this->_eavAttributeFactory->create()->loadByCode(
-                \Magento\Catalog\Model\Product::ENTITY,
-                'msrp_enabled'
-            );
-            $this->_mapApplyToProductType = $attribute->getApplyTo();
-        }
-        return empty($this->_mapApplyToProductType) || in_array($product->getTypeId(), $this->_mapApplyToProductType);
-    }
-
-    /**
-     * Get MAP message for price
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return string
-     */
-    public function getMsrpPriceMessage($product)
-    {
-        $message = "";
-        if ($this->canApplyMsrp($product, Type::TYPE_IN_CART)) {
-            $message = __('To see product price, add this item to your cart. You can always remove it later.');
-        } elseif ($this->canApplyMsrp($product, Type::TYPE_BEFORE_ORDER_CONFIRM)) {
-            $message = __('See price before order confirmation.');
-        }
-        return $message;
-    }
-
-    /**
-     * Check is product need gesture to show price
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return bool
-     */
-    public function isShowPriceOnGesture($product)
-    {
-        return $this->canApplyMsrp($product, Type::TYPE_ON_GESTURE);
-    }
-
     /**
      * Whether to display items count for each filter option
      * @param int $storeId Store view ID
@@ -720,10 +481,10 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param   \Magento\Catalog\Model\Product $product
      * @param   float $price inputted product price
      * @param   bool $includingTax return price include tax flag
-     * @param   null|Address $shippingAddress
-     * @param   null|Address $billingAddress
+     * @param   null|\Magento\Customer\Model\Address\AbstractAddress $shippingAddress
+     * @param   null|\Magento\Customer\Model\Address\AbstractAddress $billingAddress
      * @param   null|int $ctc customer tax class
-     * @param   null|string|bool|int|Store $store
+     * @param   null|string|bool|int|\Magento\Store\Model\Store $store
      * @param   bool $priceIncludesTax flag what price parameter contain tax
      * @param   bool $roundPrice
      * @return  float
diff --git a/app/code/Magento/Catalog/Helper/Product.php b/app/code/Magento/Catalog/Helper/Product.php
index 4be9078942e..85348d3ebd4 100644
--- a/app/code/Magento/Catalog/Helper/Product.php
+++ b/app/code/Magento/Catalog/Helper/Product.php
@@ -31,8 +31,6 @@ use Magento\Store\Model\Store;
  */
 class Product extends \Magento\Core\Helper\Url
 {
-    const XML_PATH_PRODUCT_URL_SUFFIX = 'catalog/seo/product_url_suffix';
-
     const XML_PATH_PRODUCT_URL_USE_CATEGORY = 'catalog/seo/product_use_categories';
 
     const XML_PATH_USE_PRODUCT_CANONICAL_TAG = 'catalog/seo/product_canonical_tag';
@@ -46,13 +44,6 @@ class Product extends \Magento\Core\Helper\Url
      */
     protected $_skipSaleableCheck = false;
 
-    /**
-     * Cache for product rewrite suffix
-     *
-     * @var array
-     */
-    protected $_productUrlSuffix = array();
-
     /**
      * @var array
      */
@@ -328,28 +319,6 @@ class Product extends \Magento\Core\Helper\Url
         return $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility();
     }
 
-    /**
-     * Retrieve product rewrite sufix for store
-     *
-     * @param int $storeId
-     * @return string
-     */
-    public function getProductUrlSuffix($storeId = null)
-    {
-        if (is_null($storeId)) {
-            $storeId = $this->_storeManager->getStore()->getId();
-        }
-
-        if (!isset($this->_productUrlSuffix[$storeId])) {
-            $this->_productUrlSuffix[$storeId] = $this->_scopeConfig->getValue(
-                self::XML_PATH_PRODUCT_URL_SUFFIX,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                $storeId
-            );
-        }
-        return $this->_productUrlSuffix[$storeId];
-    }
-
     /**
      * Check if <link rel="canonical"> can be used for product
      *
diff --git a/app/code/Magento/Catalog/Helper/Product/View.php b/app/code/Magento/Catalog/Helper/Product/View.php
index db0a65704c0..e9ee09ceaa9 100644
--- a/app/code/Magento/Catalog/Helper/Product/View.php
+++ b/app/code/Magento/Catalog/Helper/Product/View.php
@@ -79,6 +79,9 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $messageManager;
 
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Catalog\Model\Session $catalogSession
@@ -87,6 +90,7 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Framework\App\ViewInterface $view
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
      * @param array $messageGroups
      */
     public function __construct(
@@ -97,6 +101,7 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Framework\App\ViewInterface $view,
         \Magento\Framework\Message\ManagerInterface $messageManager,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
         array $messageGroups = array()
     ) {
         $this->_catalogSession = $catalogSession;
@@ -106,6 +111,7 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper
         $this->_view = $view;
         $this->messageGroups = $messageGroups;
         $this->messageManager = $messageManager;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
         parent::__construct($context);
     }
 
@@ -179,7 +185,7 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper
         }
         $pageConfig->addBodyClass('product-' . $product->getUrlKey());
         if ($currentCategory instanceof \Magento\Catalog\Model\Category) {
-            $pageConfig->addBodyClass('categorypath-' . $currentCategory->getUrlPath())
+            $pageConfig->addBodyClass('categorypath-' . $this->categoryUrlPathGenerator->getUrlPath($currentCategory))
                 ->addBodyClass('category-' . $currentCategory->getUrlKey());
         }
 
diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php
index bc0ec4c791e..f367d9e74d8 100644
--- a/app/code/Magento/Catalog/Model/Category.php
+++ b/app/code/Magento/Catalog/Model/Category.php
@@ -23,15 +23,23 @@
  */
 namespace Magento\Catalog\Model;
 
+use Magento\Framework\Profiler;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+
 /**
  * Catalog category
  *
- * @method setAffectedProductIds(array $productIds)
+ * @method Category setAffectedProductIds(array $productIds)
  * @method array getAffectedProductIds()
- * @method setMovedCategoryId(array $productIds)
+ * @method Category setMovedCategoryId(array $productIds)
  * @method int getMovedCategoryId()
- * @method setAffectedCategoryIds(array $categoryIds)
+ * @method Category setAffectedCategoryIds(array $categoryIds)
  * @method array getAffectedCategoryIds()
+ * @method string getUrlKey()
+ * @method Category setUrlKey(string $urlKey)
+ * @method Category setUrlPath(string $urlPath)
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  */
@@ -147,13 +155,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
      */
     protected $_storeCollectionFactory;
 
-    /**
-     * Url rewrite factory
-     *
-     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
-     */
-    protected $_urlRewriteFactory;
-
     /**
      * Category factory
      *
@@ -178,33 +179,34 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
      */
     protected $flatIndexer;
 
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $indexIndexer;
-
     /**
      * @var \Magento\Indexer\Model\IndexerInterface
      */
     protected $productIndexer;
 
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param \Magento\Catalog\Model\Resource\Category\Tree $categoryTreeResource
-     * @param \Magento\Catalog\Model\Resource\Category\TreeFactory $categoryTreeFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory
+     * @param Resource\Category\Tree $categoryTreeResource
+     * @param Resource\Category\TreeFactory $categoryTreeFactory
+     * @param CategoryFactory $categoryFactory
      * @param \Magento\Store\Model\Resource\Store\CollectionFactory $storeCollectionFactory
      * @param \Magento\Framework\UrlInterface $url
-     * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory
-     * @param \Magento\Catalog\Model\Config $catalogConfig
-     * @param \Magento\Index\Model\Indexer $indexIndexer
+     * @param Resource\Product\CollectionFactory $productCollectionFactory
+     * @param Config $catalogConfig
      * @param \Magento\Framework\Filter\FilterManager $filter
      * @param Indexer\Category\Flat\State $flatState
      * @param \Magento\Indexer\Model\IndexerInterface $flatIndexer
      * @param \Magento\Indexer\Model\IndexerInterface $productIndexer
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
+     * @param UrlFinderInterface $urlFinder
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
@@ -216,16 +218,16 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
         \Magento\Catalog\Model\Resource\Category\Tree $categoryTreeResource,
         \Magento\Catalog\Model\Resource\Category\TreeFactory $categoryTreeFactory,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory,
         \Magento\Store\Model\Resource\Store\CollectionFactory $storeCollectionFactory,
         \Magento\Framework\UrlInterface $url,
         \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory,
         \Magento\Catalog\Model\Config $catalogConfig,
-        \Magento\Index\Model\Indexer $indexIndexer,
         \Magento\Framework\Filter\FilterManager $filter,
         Indexer\Category\Flat\State $flatState,
         \Magento\Indexer\Model\IndexerInterface $flatIndexer,
         \Magento\Indexer\Model\IndexerInterface $productIndexer,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
+        UrlFinderInterface $urlFinder,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
@@ -233,16 +235,16 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
         $this->_treeModel = $categoryTreeResource;
         $this->_categoryTreeFactory = $categoryTreeFactory;
         $this->_categoryFactory = $categoryFactory;
-        $this->_urlRewriteFactory = $urlRewriteFactory;
         $this->_storeCollectionFactory = $storeCollectionFactory;
         $this->_url = $url;
         $this->_productCollectionFactory = $productCollectionFactory;
         $this->_catalogConfig = $catalogConfig;
-        $this->indexIndexer = $indexIndexer;
         $this->productIndexer = $productIndexer;
         $this->filter = $filter;
         $this->flatState = $flatState;
         $this->flatIndexer = $flatIndexer;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+        $this->urlFinder = $urlFinder;
         parent::__construct($context, $registry, $storeManager, $resource, $resourceCollection, $data);
     }
 
@@ -262,6 +264,16 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
         }
     }
 
+    /**
+     * Get flat resource model flag
+     *
+     * @return bool
+     */
+    public function getUseFlatResource()
+    {
+        return $this->_useFlatResource;
+    }
+
     /**
      * Return flat indexer object
      *
@@ -298,19 +310,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
         return $this->_url;
     }
 
-    /**
-     * Get url rewrite model
-     *
-     * @return \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    public function getUrlRewrite()
-    {
-        if (!$this->_urlRewrite) {
-            $this->_urlRewrite = $this->_urlRewriteFactory->create();
-        }
-        return $this->_urlRewrite;
-    }
-
     /**
      * Retrieve category tree model
      *
@@ -396,7 +395,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
             throw $e;
         }
         $this->_eventManager->dispatch('category_move', $eventParams);
-        $this->indexIndexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
         if ($this->flatState->isFlatEnabled() && !$this->getFlatIndexer()->isScheduled()) {
             $this->getFlatIndexer()->reindexList(array($this->getId(), $oldParentId, $parentId));
         }
@@ -559,31 +557,27 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
     public function getUrl()
     {
         $url = $this->_getData('url');
-        if (is_null($url)) {
-            \Magento\Framework\Profiler::start('REWRITE: ' . __METHOD__, array('group' => 'REWRITE', 'method' => __METHOD__));
-
+        if ($url === null) {
+            Profiler::start('REWRITE: ' . __METHOD__, array('group' => 'REWRITE', 'method' => __METHOD__));
             if ($this->hasData('request_path') && $this->getRequestPath() != '') {
                 $this->setData('url', $this->getUrlInstance()->getDirectUrl($this->getRequestPath()));
-                \Magento\Framework\Profiler::stop('REWRITE: ' . __METHOD__);
+                Profiler::stop('REWRITE: ' . __METHOD__);
                 return $this->getData('url');
             }
 
-            $rewrite = $this->getUrlRewrite();
-            if ($this->getStoreId()) {
-                $rewrite->setStoreId($this->getStoreId());
-            }
-            $idPath = 'category/' . $this->getId();
-            $rewrite->loadByIdPath($idPath);
-
-            if ($rewrite->getId()) {
+            $rewrite = $this->urlFinder->findOneByData([
+                UrlRewrite::ENTITY_ID => $this->getId(),
+                UrlRewrite::ENTITY_TYPE => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+                UrlRewrite::STORE_ID => $this->getStoreId(),
+            ]);
+            if ($rewrite) {
                 $this->setData('url', $this->getUrlInstance()->getDirectUrl($rewrite->getRequestPath()));
-                \Magento\Framework\Profiler::stop('REWRITE: ' . __METHOD__);
+                Profiler::stop('REWRITE: ' . __METHOD__);
                 return $this->getData('url');
             }
 
-            \Magento\Framework\Profiler::stop('REWRITE: ' . __METHOD__);
-
             $this->setData('url', $this->getCategoryIdUrl());
+            Profiler::stop('REWRITE: ' . __METHOD__);
             return $this->getData('url');
         }
         return $url;
@@ -596,10 +590,10 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
      */
     public function getCategoryIdUrl()
     {
-        \Magento\Framework\Profiler::start('REGULAR: ' . __METHOD__, array('group' => 'REGULAR', 'method' => __METHOD__));
+        Profiler::start('REGULAR: ' . __METHOD__, array('group' => 'REGULAR', 'method' => __METHOD__));
         $urlKey = $this->getUrlKey() ? $this->getUrlKey() : $this->formatUrlKey($this->getName());
         $url = $this->getUrlInstance()->getUrl('catalog/category/view', array('s' => $urlKey, 'id' => $this->getId()));
-        \Magento\Framework\Profiler::stop('REGULAR: ' . __METHOD__);
+        Profiler::stop('REGULAR: ' . __METHOD__);
         return $url;
     }
 
@@ -631,30 +625,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
         return $url;
     }
 
-    /**
-     * Retrieve URL path
-     *
-     * @return string
-     */
-    public function getUrlPath()
-    {
-        $path = $this->getData('url_path');
-        if ($path) {
-            return $path;
-        }
-
-        $path = $this->getUrlKey();
-
-        if ($this->getParentId()) {
-            $parentPath = $this->_categoryFactory->create()->load($this->getParentId())->getCategoryPath();
-            $path = $parentPath . '/' . $path;
-        }
-
-        $this->setUrlPath($path);
-
-        return $path;
-    }
-
     /**
      * Get parent category object
      *
@@ -1055,7 +1025,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements \Magento\
     protected function _afterSave()
     {
         $result = parent::_afterSave();
-        $this->indexIndexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
         $this->_getResource()->addCommitCallback(array($this, 'reindex'));
         return $result;
     }
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroup.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroup.php
index cac8406b519..5e11522d526 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroup.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroup.php
@@ -28,23 +28,39 @@ use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
 class CustomerGroup extends AbstractPlugin
 {
     /**
+     * Invalidate the indexer after the group is created.
+     *
      * @param CustomerGroupServiceInterface $subject
      * @param string                        $result
      * @return string
-     *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function afterSaveGroup(CustomerGroupServiceInterface $subject, $result)
+    public function afterCreateGroup(CustomerGroupServiceInterface $subject, $result)
     {
         $this->invalidateIndexer();
         return $result;
     }
 
     /**
+     * Invalidate the indexer after the group is updated.
+     *
      * @param CustomerGroupServiceInterface $subject
      * @param string                        $result
      * @return string
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterUpdateGroup(CustomerGroupServiceInterface $subject, $result)
+    {
+        $this->invalidateIndexer();
+        return $result;
+    }
+
+    /**
+     * Invalidate the indexer after the group is deleted.
      *
+     * @param CustomerGroupServiceInterface $subject
+     * @param string                        $result
+     * @return string
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function afterDeleteGroup(CustomerGroupServiceInterface $subject, $result)
diff --git a/app/code/Magento/Catalog/Model/Indexer/Url.php b/app/code/Magento/Catalog/Model/Indexer/Url.php
deleted file mode 100644
index 0a1dd8dc3a2..00000000000
--- a/app/code/Magento/Catalog/Model/Indexer/Url.php
+++ /dev/null
@@ -1,302 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Indexer;
-
-/**
- * Catalog url rewrites index model.
- * Responsibility for system actions:
- *  - Product save (changed assigned categories list, assigned websites or url key)
- *  - Category save (changed assigned products list, category move, changed url key)
- *  - Store save (new store creation, changed store group) - require reindex all data
- *  - Store group save (changed root category or group website) - require reindex all data
- *  - Seo config settings change - require reindex all data
- */
-class Url extends \Magento\Index\Model\Indexer\AbstractIndexer
-{
-    /**
-     * Data key for matching result to be saved in
-     */
-    const EVENT_MATCH_RESULT_KEY = 'catalog_url_match_result';
-
-    /**
-     * Index math: product save, category save, store save
-     * store group save, config save
-     *
-     * @var array
-     */
-    protected $_matchedEntities = array(
-        \Magento\Catalog\Model\Product::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Catalog\Model\Category::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Store\Model\Store::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Store\Model\Group::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Framework\App\Config\ValueInterface::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE)
-    );
-
-    /**
-     * Related Config Settings
-     *
-     * @var array
-     */
-    protected $_relatedConfigSettings = array(
-        \Magento\Catalog\Helper\Category::XML_PATH_CATEGORY_URL_SUFFIX,
-        \Magento\Catalog\Helper\Product::XML_PATH_PRODUCT_URL_SUFFIX,
-        \Magento\Catalog\Helper\Product::XML_PATH_PRODUCT_URL_USE_CATEGORY
-    );
-
-    /**
-     * Catalog url
-     *
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_catalogUrl;
-
-    /**
-     * Catalog url1
-     *
-     * @var \Magento\Catalog\Model\Resource\Url
-     */
-    protected $_catalogResourceUrl;
-
-    /**
-     * Constructor
-     *
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Catalog\Model\Resource\UrlFactory $catalogResourceUrlFactory
-     * @param \Magento\Catalog\Model\Url $catalogUrl
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Model\Resource\UrlFactory $catalogResourceUrlFactory,
-        \Magento\Catalog\Model\Url $catalogUrl,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        $this->_catalogResourceUrl = $catalogResourceUrlFactory->create();
-        $this->_catalogUrl = $catalogUrl;
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-    }
-
-    /**
-     * Get Indexer name
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return __('Catalog URL Rewrites');
-    }
-
-    /**
-     * Get Indexer description
-     *
-     * @return string
-     */
-    public function getDescription()
-    {
-        return __('Index product and categories URL Redirects');
-    }
-
-    /**
-     * Check if event can be matched by process.
-     * Overwrote for specific config save, store and store groups save matching
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return bool
-     */
-    public function matchEvent(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
-            return $data[self::EVENT_MATCH_RESULT_KEY];
-        }
-
-        $entity = $event->getEntity();
-        if ($entity == \Magento\Store\Model\Store::ENTITY) {
-            $store = $event->getDataObject();
-            if ($store && ($store->isObjectNew() || $store->dataHasChangedFor('group_id'))) {
-                $result = true;
-            } else {
-                $result = false;
-            }
-        } else {
-            if ($entity == \Magento\Store\Model\Group::ENTITY) {
-                /** @var \Magento\Store\Model\Group $storeGroup */
-                $storeGroup = $event->getDataObject();
-                $hasDataChanges = $storeGroup && ($storeGroup->dataHasChangedFor(
-                    'root_category_id'
-                ) || $storeGroup->dataHasChangedFor(
-                    'website_id'
-                ));
-                if ($storeGroup && !$storeGroup->isObjectNew() && $hasDataChanges) {
-                    $result = true;
-                } else {
-                    $result = false;
-                }
-            } else {
-                if ($entity == \Magento\Framework\App\Config\ValueInterface::ENTITY) {
-                    $configData = $event->getDataObject();
-                    if ($configData && in_array($configData->getPath(), $this->_relatedConfigSettings)) {
-                        $result = $configData->isValueChanged();
-                    } else {
-                        $result = false;
-                    }
-                } else {
-                    $result = parent::matchEvent($event);
-                }
-            }
-        }
-
-        $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
-
-        return $result;
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerEvent(\Magento\Index\Model\Event $event)
-    {
-        $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
-        $entity = $event->getEntity();
-        switch ($entity) {
-            case \Magento\Catalog\Model\Product::ENTITY:
-                $this->_registerProductEvent($event);
-                break;
-
-            case \Magento\Catalog\Model\Category::ENTITY:
-                $this->_registerCategoryEvent($event);
-                break;
-
-            case \Magento\Store\Model\Store::ENTITY:
-            case \Magento\Store\Model\Store::ENTITY:
-            case \Magento\Framework\App\Config\ValueInterface::ENTITY:
-                $process = $event->getProcess();
-                $process->changeStatus(\Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX);
-                break;
-        }
-        return $this;
-    }
-
-    /**
-     * Register event data during product save process
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _registerProductEvent(\Magento\Index\Model\Event $event)
-    {
-        $product = $event->getDataObject();
-        $dataChange = $product->dataHasChangedFor(
-            'url_key'
-        ) || $product->getIsChangedCategories() || $product->getIsChangedWebsites();
-
-        if (!$product->getExcludeUrlRewrite() && $dataChange) {
-            $event->addNewData('rewrite_product_ids', array($product->getId()));
-        }
-    }
-
-    /**
-     * Register event data during category save process
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _registerCategoryEvent(\Magento\Index\Model\Event $event)
-    {
-        $category = $event->getDataObject();
-        if (!$category->getInitialSetupFlag() && $category->getLevel() > 1) {
-            if ($category->dataHasChangedFor('url_key') || $category->getIsChangedProductList()) {
-                $event->addNewData('rewrite_category_ids', array($category->getId()));
-            }
-            /**
-             * Check if category has another affected category ids (category move result)
-             */
-            if ($category->getAffectedCategoryIds()) {
-                $event->addNewData('rewrite_category_ids', $category->getAffectedCategoryIds());
-            }
-        }
-    }
-
-    /**
-     * Process event
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _processEvent(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (!empty($data['catalog_url_reindex_all'])) {
-            $this->reindexAll();
-        }
-
-        // Force rewrites history saving
-        $dataObject = $event->getDataObject();
-        if ($dataObject instanceof \Magento\Framework\Object && $dataObject->hasData('save_rewrites_history')) {
-            $this->_catalogUrl->setShouldSaveRewritesHistory($dataObject->getData('save_rewrites_history'));
-        }
-
-        if (isset($data['rewrite_product_ids'])) {
-            $this->_catalogUrl->clearStoreInvalidRewrites();
-            // Maybe some products were moved or removed from website
-            foreach ($data['rewrite_product_ids'] as $productId) {
-                $this->_catalogUrl->refreshProductRewrite($productId);
-            }
-        }
-        if (isset($data['rewrite_category_ids'])) {
-            $this->_catalogUrl->clearStoreInvalidRewrites();
-            // Maybe some categories were moved
-            foreach ($data['rewrite_category_ids'] as $categoryId) {
-                $this->_catalogUrl->refreshCategoryRewrite($categoryId, null, true, true);
-            }
-        }
-    }
-
-    /**
-     * Rebuild all index data
-     *
-     * @return void
-     * @throws \Exception
-     */
-    public function reindexAll()
-    {
-        $this->_catalogResourceUrl->beginTransaction();
-        try {
-            $this->_catalogUrl->refreshRewrites();
-            $this->_catalogResourceUrl->commit();
-        } catch (\Exception $e) {
-            $this->_catalogResourceUrl->rollBack();
-            throw $e;
-        }
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Observer.php b/app/code/Magento/Catalog/Model/Observer.php
index 9bf515157cd..8ef26b5e73b 100644
--- a/app/code/Magento/Catalog/Model/Observer.php
+++ b/app/code/Magento/Catalog/Model/Observer.php
@@ -44,13 +44,6 @@ class Observer
      */
     protected $_catalogCategory;
 
-    /**
-     * Index indexer
-     *
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexIndexer;
-
     /**
      * Catalog layer
      *
@@ -79,13 +72,6 @@ class Observer
      */
     protected $_categoryResource;
 
-    /**
-     * Url factory
-     *
-     * @var \Magento\Catalog\Model\UrlFactory
-     */
-    protected $_urlFactory;
-
     /**
      * Factory for product resource
      *
@@ -94,35 +80,29 @@ class Observer
     protected $_productResourceFactory;
 
     /**
-     * @param \Magento\Catalog\Model\UrlFactory $urlFactory
      * @param \Magento\Catalog\Model\Resource\Category $categoryResource
      * @param \Magento\Catalog\Model\Resource\Product $catalogProduct
      * @param \Magento\Framework\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Model\Layer\Category $catalogLayer
-     * @param \Magento\Index\Model\Indexer $indexIndexer
      * @param \Magento\Catalog\Helper\Category $catalogCategory
      * @param \Magento\Catalog\Helper\Data $catalogData
      * @param Indexer\Category\Flat\State $categoryFlatState
      * @param \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory
      */
     public function __construct(
-        \Magento\Catalog\Model\UrlFactory $urlFactory,
         \Magento\Catalog\Model\Resource\Category $categoryResource,
         \Magento\Catalog\Model\Resource\Product $catalogProduct,
         \Magento\Framework\StoreManagerInterface $storeManager,
         \Magento\Catalog\Model\Layer\Category $catalogLayer,
-        \Magento\Index\Model\Indexer $indexIndexer,
         \Magento\Catalog\Helper\Category $catalogCategory,
         \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
         \Magento\Catalog\Model\Resource\ProductFactory $productResourceFactory
     ) {
-        $this->_urlFactory = $urlFactory;
         $this->_categoryResource = $categoryResource;
         $this->_catalogProduct = $catalogProduct;
         $this->_storeManager = $storeManager;
         $this->_catalogLayer = $catalogLayer;
-        $this->_indexIndexer = $indexIndexer;
         $this->_catalogCategory = $catalogCategory;
         $this->_catalogData = $catalogData;
         $this->categoryFlatConfig = $categoryFlatState;
@@ -184,7 +164,7 @@ class Observer
             $categoryNode = new \Magento\Framework\Data\Tree\Node($categoryData, 'id', $tree, $parentCategoryNode);
             $parentCategoryNode->addChild($categoryNode);
 
-            if ($this->categoryFlatConfig->isFlatEnabled()) {
+            if ($this->categoryFlatConfig->isFlatEnabled() && $category->getUseFlatResource()) {
                 $subcategories = (array)$category->getChildrenNodes();
             } else {
                 $subcategories = $category->getChildren();
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 6bae0cd6270..5ac4bd524d1 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -29,15 +29,18 @@ use Magento\Framework\Object\IdentityInterface;
 /**
  * Catalog product model
  *
- * @method \Magento\Catalog\Model\Product setHasError(bool $value)
+ * @method Product setHasError(bool $value)
  * @method null|bool getHasError()
- * @method \Magento\Catalog\Model\Product setTypeId(string $typeId)
- * @method \Magento\Catalog\Model\Product setAssociatedProductIds(array $productIds)
+ * @method Product setTypeId(string $typeId)
+ * @method Product setAssociatedProductIds(array $productIds)
  * @method array getAssociatedProductIds()
- * @method \Magento\Catalog\Model\Product setNewVariationsAttributeSetId(int $value)
+ * @method Product setNewVariationsAttributeSetId(int $value)
  * @method int getNewVariationsAttributeSetId()
  * @method int getPriceType
- * @method \Magento\Catalog\Model\Resource\Product\Collection getCollection()
+ * @method Resource\Product\Collection getCollection()
+ * @method string getUrlKey()
+ * @method Product setUrlKey(string $urlKey)
+ * @method Product setRequestPath(string $requestPath)
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  */
@@ -112,11 +115,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
      */
     protected static $_url;
 
-    /**
-     * @var string
-     */
-    protected static $_urlRewrite;
-
     /**
      * @var array
      */
@@ -181,13 +179,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
      */
     protected $_catalogProductType;
 
-    /**
-     * Index indexer
-     *
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexIndexer;
-
     /**
      * Catalog product media config
      *
@@ -282,7 +273,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
      * @param Product\Visibility $catalogProductVisibility
      * @param Product\Attribute\Source\Status $catalogProductStatus
      * @param Product\Media\Config $catalogProductMediaConfig
-     * @param \Magento\Index\Model\Indexer $indexIndexer
      * @param Product\Type $catalogProductType
      * @param \Magento\Catalog\Helper\Image $catalogImage
      * @param \Magento\Catalog\Helper\Data $catalogData
@@ -312,7 +302,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
         \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus,
         \Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig,
-        \Magento\Index\Model\Indexer $indexIndexer,
         Product\Type $catalogProductType,
         \Magento\Catalog\Helper\Image $catalogImage,
         \Magento\Catalog\Helper\Data $catalogData,
@@ -334,7 +323,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         $this->_catalogProductVisibility = $catalogProductVisibility;
         $this->_catalogProductStatus = $catalogProductStatus;
         $this->_catalogProductMediaConfig = $catalogProductMediaConfig;
-        $this->_indexIndexer = $indexIndexer;
         $this->_catalogProductType = $catalogProductType;
         $this->_catalogImage = $catalogImage;
         $this->_catalogData = $catalogData;
@@ -755,7 +743,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
 
         $result = parent::_afterSave();
 
-        $this->_indexIndexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
         $this->_getResource()->addCommitCallback(array($this, 'reindex'));
         $this->reloadPriceInfo();
         return $result;
@@ -830,7 +817,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
     protected function _beforeDelete()
     {
         $this->cleanCache();
-        $this->_indexIndexer->logEvent($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_DELETE);
         return parent::_beforeDelete();
     }
 
@@ -844,7 +830,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         $this->reindex();
         $this->_productPriceIndexerProcessor->reindexRow($this->getId());
         parent::_afterDeleteCommit();
-        $this->_indexIndexer->indexEvents(self::ENTITY, \Magento\Index\Model\Event::TYPE_DELETE);
     }
 
     /**
@@ -1517,17 +1502,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         return $this->getUrlModel()->formatUrlKey($str);
     }
 
-    /**
-     * Retrieve Product Url Path (include category)
-     *
-     * @param \Magento\Catalog\Model\Category $category
-     * @return string
-     */
-    public function getUrlPath($category = null)
-    {
-        return $this->getUrlModel()->getUrlPath($this, $category);
-    }
-
     /**
      * Save current attribute with code $code and assign new value
      *
diff --git a/app/code/Magento/Catalog/Model/Product/Action.php b/app/code/Magento/Catalog/Model/Product/Action.php
index 7eb6cd23108..6a77bc1cb88 100644
--- a/app/code/Magento/Catalog/Model/Product/Action.php
+++ b/app/code/Magento/Catalog/Model/Product/Action.php
@@ -30,13 +30,6 @@ namespace Magento\Catalog\Model\Product;
  */
 class Action extends \Magento\Framework\Model\AbstractModel
 {
-    /**
-     * Index indexer
-     *
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexIndexer;
-
     /**
      * Product website factory
      *
@@ -63,7 +56,6 @@ class Action extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Catalog\Model\Product\WebsiteFactory $productWebsiteFactory
-     * @param \Magento\Index\Model\Indexer $indexIndexer
      * @param \Magento\Indexer\Model\IndexerInterface $categoryIndexer
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor
@@ -75,7 +67,6 @@ class Action extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Catalog\Model\Product\WebsiteFactory $productWebsiteFactory,
-        \Magento\Index\Model\Indexer $indexIndexer,
         \Magento\Indexer\Model\IndexerInterface $categoryIndexer,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
@@ -84,7 +75,6 @@ class Action extends \Magento\Framework\Model\AbstractModel
         array $data = array()
     ) {
         $this->_productWebsiteFactory = $productWebsiteFactory;
-        $this->_indexIndexer = $indexIndexer;
         $this->categoryIndexer = $categoryIndexer;
         $this->_eavConfig = $eavConfig;
         $this->_productEavIndexerProcessor = $productEavIndexerProcessor;
@@ -148,12 +138,6 @@ class Action extends \Magento\Framework\Model\AbstractModel
             $this->_productEavIndexerProcessor->reindexList(array_unique($productIds));
         }
 
-        // register mass action indexer event
-        $this->_indexIndexer->processEntityAction(
-            $this,
-            \Magento\Catalog\Model\Product::ENTITY,
-            \Magento\Index\Model\Event::TYPE_MASS_ACTION
-        );
         if (!$this->getCategoryIndexer()->isScheduled()) {
             $this->getCategoryIndexer()->reindexList(array_unique($productIds));
         }
@@ -215,12 +199,6 @@ class Action extends \Magento\Framework\Model\AbstractModel
             array('product_ids' => array_unique($productIds), 'website_ids' => $websiteIds, 'action_type' => $type)
         );
 
-        // register mass action indexer event
-        $this->_indexIndexer->processEntityAction(
-            $this,
-            \Magento\Catalog\Model\Product::ENTITY,
-            \Magento\Index\Model\Event::TYPE_MASS_ACTION
-        );
         if (!$this->getCategoryIndexer()->isScheduled()) {
             $this->getCategoryIndexer()->reindexList(array_unique($productIds));
         }
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Msrp.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Msrp.php
deleted file mode 100644
index 5e66b632aa3..00000000000
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Msrp.php
+++ /dev/null
@@ -1,78 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Product\Attribute\Backend;
-
-/**
- * Product attribute for `Apply MAP` enable/disable option
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Msrp extends \Magento\Catalog\Model\Product\Attribute\Backend\Boolean
-{
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
-
-    /**
-     * Constructor
-     *
-     * @param \Magento\Framework\Logger $logger
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     */
-    public function __construct(\Magento\Framework\Logger $logger, \Magento\Catalog\Helper\Data $catalogData)
-    {
-        $this->_catalogData = $catalogData;
-        parent::__construct($logger);
-    }
-
-    /**
-     * Disable MAP if it's bundle with dynamic price type
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return $this
-     */
-    public function beforeSave($product)
-    {
-        if (!$product instanceof \Magento\Catalog\Model\Product ||
-            $product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE ||
-            $product->getPriceType() != \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC
-        ) {
-            return parent::beforeSave($product);
-        }
-
-        parent::beforeSave($product);
-        $attributeCode = $this->getAttribute()->getName();
-        $value = $product->getData($attributeCode);
-        if (empty($value)) {
-            $value = $this->_catalogData->isMsrpApplyToAll();
-        }
-        if ($value) {
-            $product->setData($attributeCode, 0);
-        }
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Urlkey.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Urlkey.php
deleted file mode 100644
index 5779ffbda70..00000000000
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Urlkey.php
+++ /dev/null
@@ -1,53 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Product\Attribute\Backend;
-
-/**
- * Product url key attribute backend
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Urlkey extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
-{
-    /**
-     * @param \Magento\Framework\Object $object
-     * @return $this
-     */
-    public function beforeSave($object)
-    {
-        $attributeName = $this->getAttribute()->getName();
-
-        $urlKey = $object->getData($attributeName);
-        if ($urlKey === false) {
-            return $this;
-        }
-        if ($urlKey == '') {
-            $urlKey = $object->getName();
-        }
-
-        $object->setData($attributeName, $object->formatUrlKey($urlKey));
-
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php
deleted file mode 100644
index 177277dcb6a..00000000000
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php
+++ /dev/null
@@ -1,128 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Source model for 'msrp_enabled' product attribute
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type;
-
-use Magento\Framework\DB\Ddl\Table;
-
-class Enabled extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
-{
-    /**
-     * Enable MAP
-     */
-    const MSRP_ENABLE_YES = 1;
-
-    /**
-     * Disable MAP
-     */
-    const MSRP_ENABLE_NO = 0;
-
-    /**
-     * Get value from the store configuration settings
-     */
-    const MSRP_ENABLE_USE_CONFIG = 2;
-
-    /**
-     * Core data
-     *
-     * @var \Magento\Core\Helper\Data
-     */
-    protected $_coreData = null;
-
-    /**
-     * Entity attribute factory
-     *
-     * @var \Magento\Eav\Model\Resource\Entity\AttributeFactory
-     */
-    protected $_entityAttributeFactory;
-
-    /**
-     * Construct
-     *
-     * @param \Magento\Eav\Model\Resource\Entity\AttributeFactory $entityAttributeFactory
-     * @param \Magento\Core\Helper\Data $coreData
-     */
-    public function __construct(
-        \Magento\Eav\Model\Resource\Entity\AttributeFactory $entityAttributeFactory,
-        \Magento\Core\Helper\Data $coreData
-    ) {
-        $this->_entityAttributeFactory = $entityAttributeFactory;
-        $this->_coreData = $coreData;
-    }
-
-    /**
-     * Retrieve all attribute options
-     *
-     * @return array
-     */
-    public function getAllOptions()
-    {
-        if (!$this->_options) {
-            $this->_options = array(
-                array('label' => __('Yes'), 'value' => self::MSRP_ENABLE_YES),
-                array('label' => __('No'), 'value' => self::MSRP_ENABLE_NO),
-                array('label' => __('Use config'), 'value' => self::MSRP_ENABLE_USE_CONFIG)
-            );
-        }
-        return $this->_options;
-    }
-
-    /**
-     * Retrieve flat column definition
-     *
-     * @return array
-     */
-    public function getFlatColumns()
-    {
-        $attributeCode = $this->getAttribute()->getAttributeCode();
-
-        return [
-            $attributeCode => [
-                'unsigned' => false,
-                'default' => null,
-                'extra' => null,
-                'type' => Table::TYPE_SMALLINT,
-                'length' => 1,
-                'nullable' => true,
-                'comment' => $attributeCode . ' column',
-            ],
-        ];
-    }
-
-    /**
-     * Retrieve Select For Flat Attribute update
-     *
-     * @param int $store
-     * @return \Magento\Framework\DB\Select|null
-     */
-    public function getFlatUpdateSelect($store)
-    {
-        return $this->_entityAttributeFactory->create()->getFlatUpdateSelect($this->getAttribute(), $store);
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php
index b1e256f59a5..8513ba3b996 100644
--- a/app/code/Magento/Catalog/Model/Product/Copier.php
+++ b/app/code/Magento/Catalog/Model/Product/Copier.php
@@ -25,6 +25,8 @@
  */
 namespace Magento\Catalog\Model\Product;
 
+use Magento\UrlRewrite\Model\Storage\DuplicateEntryException;
+
 class Copier
 {
     /**
@@ -71,7 +73,19 @@ class Copier
         $duplicate->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
 
         $this->copyConstructor->build($product, $duplicate);
-        $duplicate->save();
+        $isDuplicateSaved = false;
+        do {
+            $urlKey = $duplicate->getUrlKey();
+            $urlKey = preg_match('/(.*)-(\d+)$/', $urlKey, $matches)
+                ? $matches[1] . '-' . ($matches[2] + 1)
+                : $urlKey . '-1';
+            $duplicate->setUrlKey($urlKey);
+            try {
+                $duplicate->save();
+                $isDuplicateSaved = true;
+            } catch (DuplicateEntryException $e) {
+            }
+        } while (!$isDuplicateSaved);
 
         $product->getOptionInstance()->duplicate($product->getId(), $duplicate->getId());
         $product->getResource()->duplicate($product->getId(), $duplicate->getId());
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index 232a6ecd2c9..865a7f2ee4f 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -1035,18 +1035,6 @@ abstract class AbstractType
         return $errors;
     }
 
-    /**
-     * Check if Minimum advertise price is enabled at least in one option
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param int $visibility
-     * @return bool
-     */
-    public function isMapEnabledInOptions($product, $visibility = null)
-    {
-        return false;
-    }
-
     /**
      * Determine presence of weight for product type
      *
@@ -1078,4 +1066,13 @@ abstract class AbstractType
     {
         return array();
     }
+
+    /**
+     * @param \Magento\Catalog\Model\Product\Type\AbstractType $product
+     * @return array
+     */
+    public function getAssociatedProducts($product)
+    {
+        return [];
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Catalog/Model/Product/Url.php b/app/code/Magento/Catalog/Model/Product/Url.php
index 45268641301..5e78cb58145 100644
--- a/app/code/Magento/Catalog/Model/Product/Url.php
+++ b/app/code/Magento/Catalog/Model/Product/Url.php
@@ -30,10 +30,11 @@
  */
 namespace Magento\Catalog\Model\Product;
 
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+
 class Url extends \Magento\Framework\Object
 {
-    const CACHE_TAG = 'url_rewrite';
-
     /**
      * Static URL instance
      *
@@ -41,13 +42,6 @@ class Url extends \Magento\Framework\Object
      */
     protected $_url;
 
-    /**
-     * Static URL Rewrite Instance
-     *
-     * @var \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    protected $_urlRewrite;
-
     /**
      * @var \Magento\Framework\Filter\FilterManager
      */
@@ -72,33 +66,40 @@ class Url extends \Magento\Framework\Object
      */
     protected $_sidResolver;
 
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
     /**
-     * Construct
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory
      * @param \Magento\Framework\UrlInterface $url
      * @param \Magento\Framework\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Helper\Category $catalogCategory
      * @param \Magento\Framework\Filter\FilterManager $filter
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
+     * @param \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator
+     * @param UrlFinderInterface $urlFinder
      * @param array $data
      */
     public function __construct(
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory,
         \Magento\Framework\UrlInterface $url,
         \Magento\Framework\StoreManagerInterface $storeManager,
         \Magento\Catalog\Helper\Category $catalogCategory,
         \Magento\Framework\Filter\FilterManager $filter,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
+        \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator,
+        UrlFinderInterface $urlFinder,
         array $data = array()
     ) {
-        $this->_urlRewrite = $urlRewriteFactory->create();
+        parent::__construct($data);
         $this->_url = $url;
         $this->_storeManager = $storeManager;
         $this->_catalogCategory = $catalogCategory;
         $this->filter = $filter;
         $this->_sidResolver = $sidResolver;
-        parent::__construct($data);
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->urlFinder = $urlFinder;
     }
 
     /**
@@ -111,16 +112,6 @@ class Url extends \Magento\Framework\Object
         return $this->_url;
     }
 
-    /**
-     * Retrieve URL Rewrite Instance
-     *
-     * @return \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    public function getUrlRewrite()
-    {
-        return $this->_urlRewrite;
-    }
-
     /**
      * 'no_selection' shouldn't be a valid image attribute value
      *
@@ -180,29 +171,6 @@ class Url extends \Magento\Framework\Object
         return $this->filter->translitUrl($str);
     }
 
-    /**
-     * Retrieve Product Url path (with category if exists)
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param \Magento\Catalog\Model\Category $category
-     *
-     * @return string
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function getUrlPath($product, $category = null)
-    {
-        $path = $product->getData('url_path');
-
-        if (is_null($category)) {
-            /** @todo get default category */
-            return $path;
-        } elseif (!$category instanceof \Magento\Catalog\Model\Category) {
-            throw new \Magento\Framework\Model\Exception('Invalid category object supplied');
-        }
-
-        return $this->_catalogCategory->getCategoryUrlPath($category->getUrlPath()) . '/' . $path;
-    }
-
     /**
      * Retrieve Product URL using UrlDataObject
      *
@@ -230,13 +198,16 @@ class Url extends \Magento\Framework\Object
         } else {
             $requestPath = $product->getRequestPath();
             if (empty($requestPath) && $requestPath !== false) {
-                $idPath = sprintf('product/%d', $product->getEntityId());
+                $filterData = [
+                    UrlRewrite::ENTITY_ID => $product->getId(),
+                    UrlRewrite::ENTITY_TYPE => \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::ENTITY_TYPE,
+                    UrlRewrite::STORE_ID => $storeId,
+                ];
                 if ($categoryId) {
-                    $idPath = sprintf('%s/%d', $idPath, $categoryId);
+                    $filterData[UrlRewrite::METADATA]['category_id'] = $categoryId;
                 }
-                $rewrite = $this->getUrlRewrite();
-                $rewrite->setStoreId($storeId)->loadByIdPath($idPath);
-                if ($rewrite->getId()) {
+                $rewrite = $this->urlFinder->findOneByData($filterData);
+                if ($rewrite) {
                     $requestPath = $rewrite->getRequestPath();
                     $product->setRequestPath($requestPath);
                 } else {
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Collection.php b/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
index 8fbd5653951..5333a105b01 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Collection.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Catalog\Model\Resource\Category;
 
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
 /**
  * Category resource collection
  *
@@ -322,15 +324,15 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
      */
     public function joinUrlRewrite()
     {
-        $storeId = $this->_storeManager->getStore()->getId();
         $this->joinTable(
-            'core_url_rewrite',
-            'category_id=entity_id',
-            array('request_path'),
-            "{{table}}.is_system=1" .
-            " AND {{table}}.product_id IS NULL" .
-            " AND {{table}}.store_id='{$storeId}'" .
-            " AND id_path LIKE 'category/%'",
+            'url_rewrite',
+            'entity_id = entity_id',
+            ['request_path'],
+            sprintf(
+                '{{table}}.is_autogenerated = 1 AND {{table}}.store_id = %d AND {{table}}.entity_type = \'%s\'',
+                $this->_storeManager->getStore()->getId(),
+                CategoryUrlRewriteGenerator::ENTITY_TYPE
+            ),
             'left'
         );
         return $this;
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Flat.php b/app/code/Magento/Catalog/Model/Resource/Category/Flat.php
index 51515557a69..adfe857270c 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Flat.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Flat.php
@@ -23,12 +23,14 @@
  */
 namespace Magento\Catalog\Model\Resource\Category;
 
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
 /**
  * Category flat model
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  */
-class Flat extends \Magento\Index\Model\Resource\AbstractResource
+class Flat extends \Magento\Indexer\Model\Resource\AbstractResource
 {
     /**
      * Store id
@@ -268,19 +270,12 @@ class Flat extends \Magento\Index\Model\Resource\AbstractResource
                 'is_anchor'
             )
         )->joinLeft(
-            array('url_rewrite' => $this->getTable('core_url_rewrite')),
-            'url_rewrite.category_id=main_table.entity_id AND url_rewrite.is_system=1 AND ' . $_conn->quoteInto(
-                'url_rewrite.product_id IS NULL AND url_rewrite.store_id=? AND ',
-                $storeId
-            ) . $_conn->prepareSqlCondition(
-                'url_rewrite.id_path',
-                array('like' => 'category/%')
-            ),
-            array('request_path' => 'url_rewrite.request_path')
-        )->where(
-            'main_table.is_active = ?',
-            '1'
-        );
+            ['url_rewrite' => $this->getTable('url_rewrite')],
+            'url_rewrite.entity_id = main_table.entity_id AND url_rewrite.is_autogenerated = 1'
+            . $_conn->quoteInto(' AND url_rewrite.store_id = ?', $storeId)
+            . $_conn->quoteInto(' AND url_rewrite.entity_type = ?', CategoryUrlRewriteGenerator::ENTITY_TYPE),
+            ['request_path' => 'url_rewrite.request_path']
+        )->where('main_table.is_active = 1');
 
         if (false == $skipMenuFilter) {
             $select->where('main_table.include_in_menu = ?', '1');
@@ -526,15 +521,11 @@ class Flat extends \Magento\Index\Model\Resource\AbstractResource
             array('main_table' => $this->getMainStoreTable($category->getStoreId())),
             array('main_table.entity_id', 'main_table.name')
         )->joinLeft(
-            array('url_rewrite' => $this->getTable('core_url_rewrite')),
-            'url_rewrite.category_id=main_table.entity_id AND url_rewrite.is_system=1 AND ' . $read->quoteInto(
-                'url_rewrite.product_id IS NULL AND url_rewrite.store_id=? AND ',
-                $category->getStoreId()
-            ) . $read->prepareSqlCondition(
-                'url_rewrite.id_path',
-                array('like' => 'category/%')
-            ),
-            array('request_path' => 'url_rewrite.request_path')
+            ['url_rewrite' => $this->getTable('url_rewrite')],
+            'url_rewrite.entity_id = main_table.entity_id AND url_rewrite.is_autogenerated = 1'
+            . $read->quoteInto(' AND url_rewrite.store_id = ?', $category->getStoreId())
+            . $read->quoteInto(' AND url_rewrite.entity_type = ?', CategoryUrlRewriteGenerator::ENTITY_TYPE),
+            ['request_path' => 'url_rewrite.request_path']
         )->where(
             'main_table.entity_id IN (?)',
             array_reverse(explode(',', $category->getPathInStore()))
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php b/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
index e91e35d297d..48b5b3b14d8 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
@@ -23,6 +23,7 @@
  */
 namespace Magento\Catalog\Model\Resource\Category\Flat;
 
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
 use Magento\Core\Model\EntityFactory;
 use Magento\Framework\Event\ManagerInterface;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
@@ -335,20 +336,14 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function addUrlRewriteToResult()
     {
-        $storeId = $this->_storeManager->getStore()->getId();
+        $connection = $this->getConnection();
+
         $this->getSelect()->joinLeft(
-            array('url_rewrite' => $this->getTable('core_url_rewrite')),
-            'url_rewrite.category_id=main_table.entity_id AND url_rewrite.is_system=1 ' .
-            'AND url_rewrite.product_id IS NULL' .
-            ' AND ' .
-            $this->getConnection()->quoteInto(
-                'url_rewrite.store_id=?',
-                $storeId
-            ) . ' AND ' . $this->getConnection()->quoteInto(
-                'url_rewrite.id_path LIKE ?',
-                'category/%'
-            ),
-            array('request_path')
+            ['url_rewrite' => $this->getTable('url_rewrite')],
+            'url_rewrite.entity_id = main_table.entity_id AND url_rewrite.is_autogenerated = 1'
+            . $connection->quoteInto(' AND url_rewrite.store_id = ?', $this->_storeManager->getStore()->getId())
+            . $connection->quoteInto(' AND url_rewrite.entity_type = ?', CategoryUrlRewriteGenerator::ENTITY_TYPE),
+            ['request_path']
         );
         return $this;
     }
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Backend/Urlkey.php b/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Backend/Urlkey.php
deleted file mode 100644
index a3d7d895269..00000000000
--- a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Backend/Urlkey.php
+++ /dev/null
@@ -1,83 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Resource\Product\Attribute\Backend;
-
-/**
- * Product url key attribute backend
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Urlkey extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
-{
-    /**
-     * Catalog url
-     *
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_catalogUrl;
-
-    /**
-     * @param \Magento\Framework\Logger $logger
-     * @param \Magento\Catalog\Model\Url $catalogUrl
-     */
-    public function __construct(\Magento\Framework\Logger $logger, \Magento\Catalog\Model\Url $catalogUrl)
-    {
-        $this->_catalogUrl = $catalogUrl;
-        parent::__construct($logger);
-    }
-
-    /**
-     * Before save
-     *
-     * @param \Magento\Framework\Object $object
-     * @return $this
-     */
-    public function beforeSave($object)
-    {
-        $attributeName = $this->getAttribute()->getName();
-
-        $urlKey = $object->getData($attributeName);
-        if ($urlKey == '') {
-            $urlKey = $object->getName();
-        }
-
-        $object->setData($attributeName, $object->formatUrlKey($urlKey));
-
-        return $this;
-    }
-
-    /**
-     * Refresh product rewrites
-     *
-     * @param \Magento\Framework\Object $object
-     * @return $this
-     */
-    public function afterSave($object)
-    {
-        if ($object->dataHasChangedFor($this->getAttribute()->getName())) {
-            $this->_catalogUrl->refreshProductRewrites(null, $object, true);
-        }
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
index ac7b011b7e9..bad88547c50 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
@@ -25,8 +25,6 @@ namespace Magento\Catalog\Model\Resource\Product\Attribute;
 
 /**
  * Catalog product EAV additional attribute resource collection
- *
- * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Collection
 {
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
index a4a2f008a56..ffc76618132 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
@@ -24,6 +24,7 @@
 namespace Magento\Catalog\Model\Resource\Product;
 
 use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
 use Magento\Store\Model\Store;
 use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
 
@@ -622,7 +623,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
     protected function _afterLoad()
     {
         if ($this->_addUrlRewrite) {
-            $this->_addUrlRewrite($this->_urlRewriteCategory);
+            $this->_addUrlRewrite();
         }
 
         $this->_prepareUrlDataObject();
@@ -1223,13 +1224,12 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
     public function joinUrlRewrite()
     {
         $this->joinTable(
-            'core_url_rewrite',
-            'entity_id=entity_id',
-            array('request_path'),
-            '{{table}}.type = ' . \Magento\UrlRewrite\Model\UrlRewrite::TYPE_PRODUCT,
+            'url_rewrite',
+            'entity_id = entity_id',
+            ['request_path'],
+            '{{table}}.entity_type = \'' . ProductUrlRewriteGenerator::ENTITY_TYPE . '\'',
             'left'
         );
-
         return $this;
     }
 
@@ -1272,34 +1272,31 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
         foreach ($this->getItems() as $item) {
             $productIds[] = $item->getEntityId();
         }
-        if (!count($productIds)) {
+        if (!$productIds) {
             return;
         }
 
-        $select = $this->getConnection()->select()->from(
-            $this->getTable('core_url_rewrite'),
-            array('product_id', 'request_path')
-        )->where(
-            'store_id = ?',
-            $this->_storeManager->getStore()->getId()
-        )->where(
-            'is_system = ?',
-            1
-        )->where(
-            'category_id = ? OR category_id IS NULL',
-            $this->_urlRewriteCategory
-        )->where(
-            'product_id IN(?)',
-            $productIds
-        )->order(
-            'category_id ' . self::SORT_ORDER_DESC
-        );
+        $select = $this->getConnection()
+            ->select()
+            ->from(array('u' => $this->getTable('url_rewrite')), ['u.entity_id', 'u.request_path'])
+            ->where('u.store_id = ?', $this->_storeManager->getStore()->getId())
+            ->where('u.is_autogenerated = 1')
+            ->where('u.entity_type = ?', ProductUrlRewriteGenerator::ENTITY_TYPE)
+            ->where('u.entity_id IN(?)', $productIds);
+
+        if ($this->_urlRewriteCategory) {
+            $select->joinInner(
+                array('cu' => $this->getTable('catalog_url_rewrite_product_category')),
+                'u.url_rewrite_id=cu.url_rewrite_id'
+            )->where('cu.category_id IN (?)', $this->_urlRewriteCategory);
+        }
+
         // more priority is data with category id
         $urlRewrites = array();
 
         foreach ($this->getConnection()->fetchAll($select) as $row) {
-            if (!isset($urlRewrites[$row['product_id']])) {
-                $urlRewrites[$row['product_id']] = $row['request_path'];
+            if (!isset($urlRewrites[$row['entity_id']])) {
+                $urlRewrites[$row['entity_id']] = $row['request_path'];
             }
         }
 
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/AbstractIndexer.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/AbstractIndexer.php
index 5d3504ac6e5..53623343c71 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/AbstractIndexer.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/AbstractIndexer.php
@@ -28,7 +28,7 @@ namespace Magento\Catalog\Model\Resource\Product\Indexer;
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-abstract class AbstractIndexer extends \Magento\Index\Model\Resource\AbstractResource
+abstract class AbstractIndexer extends \Magento\Indexer\Model\Resource\AbstractResource
 {
     /**
      * Eav config
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav.php
deleted file mode 100644
index 1ee96001d44..00000000000
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav.php
+++ /dev/null
@@ -1,233 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Resource\Product\Indexer;
-
-/**
- * Catalog Product Eav Indexer Resource Model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Eav extends AbstractIndexer
-{
-    /**
-     * EAV Indexers by type
-     *
-     * @var array
-     */
-    protected $_types;
-
-    /**
-     * Eav source factory
-     *
-     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory
-     */
-    protected $_eavSourceFactory;
-
-    /**
-     * Eav decimal factory
-     *
-     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory
-     */
-    protected $_eavDecimalFactory;
-
-    /**
-     * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Eav\Model\Config $eavConfig
-     * @param \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory
-     * @param \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory $eavSourceFactory
-     */
-    public function __construct(
-        \Magento\Framework\App\Resource $resource,
-        \Magento\Eav\Model\Config $eavConfig,
-        \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory,
-        \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory $eavSourceFactory
-    ) {
-        $this->_eavDecimalFactory = $eavDecimalFactory;
-        $this->_eavSourceFactory = $eavSourceFactory;
-        parent::__construct($resource, $eavConfig);
-    }
-
-    /**
-     * Define main index table
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('catalog_product_index_eav', 'entity_id');
-    }
-
-    /**
-     * Retrieve array of EAV type indexers
-     *
-     * @return array
-     */
-    public function getIndexers()
-    {
-        if (is_null($this->_types)) {
-            $this->_types = array(
-                'source' => $this->_eavSourceFactory->create(),
-                'decimal' => $this->_eavDecimalFactory->create()
-            );
-        }
-
-        return $this->_types;
-    }
-
-    /**
-     * Retrieve indexer instance by type
-     *
-     * @param string $type
-     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function getIndexer($type)
-    {
-        $indexers = $this->getIndexers();
-        if (!isset($indexers[$type])) {
-            throw new \Magento\Framework\Model\Exception(__('We found an unknown EAV indexer type "%1".', $type));
-        }
-        return $indexers[$type];
-    }
-
-    /**
-     * Process product save.
-     * Method is responsible for index support
-     * when product was saved and assigned categories was changed.
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function catalogProductSave(\Magento\Index\Model\Event $event)
-    {
-        $productId = $event->getEntityPk();
-        $data = $event->getNewData();
-
-        /**
-         * Check if filterable attribute values were updated
-         */
-        if (!isset($data['reindex_eav'])) {
-            return $this;
-        }
-
-        foreach ($this->getIndexers() as $indexer) {
-            /** @var $indexer \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav */
-            $indexer->reindexEntities($productId);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Process Product Delete
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function catalogProductDelete(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['reindex_eav_parent_ids'])) {
-            return $this;
-        }
-
-        foreach ($this->getIndexers() as $indexer) {
-            /** @var $indexer \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav */
-            $indexer->reindexEntities($data['reindex_eav_parent_ids']);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Process Product Mass Update
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function catalogProductMassAction(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['reindex_eav_product_ids'])) {
-            return $this;
-        }
-
-        foreach ($this->getIndexers() as $indexer) {
-            /** @var $indexer \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav */
-            $indexer->reindexEntities($data['reindex_eav_product_ids']);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Process Catalog Eav Attribute Save
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function catalogEavAttributeSave(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['reindex_attribute'])) {
-            return $this;
-        }
-
-        $indexer = $this->getIndexer($data['attribute_index_type']);
-
-        $indexer->reindexAttribute($event->getEntityPk(), !empty($data['is_indexable']));
-
-        return $this;
-    }
-
-    /**
-     * Rebuild all index data
-     *
-     * @return $this
-     */
-    public function reindexAll()
-    {
-        $this->useIdxTable(true);
-        foreach ($this->getIndexers() as $indexer) {
-            /** @var $indexer \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav */
-            $indexer->reindexAll();
-        }
-
-        return $this;
-    }
-
-    /**
-     * Retrieve temporary source index table name
-     *
-     * @param string $table
-     * @return string
-     */
-    public function getIdxTable($table = null)
-    {
-        if ($this->useIdxTable()) {
-            return $this->getTable('catalog_product_index_eav_idx');
-        }
-        return $this->getTable('catalog_product_index_eav_tmp');
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
index a20e8e47f7d..61a90878123 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
@@ -654,16 +654,6 @@ class DefaultPrice extends \Magento\Catalog\Model\Resource\Product\Indexer\Abstr
         return $this->getTable('catalog_product_index_group_price');
     }
 
-    /**
-     * Register data required by product type process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    public function registerEvent(\Magento\Index\Model\Event $event)
-    {
-    }
-
     /**
      * Retrieve temporary index table name
      *
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/PriceInterface.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/PriceInterface.php
index 0272277aa35..a25802e63d0 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/PriceInterface.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/PriceInterface.php
@@ -44,12 +44,4 @@ interface PriceInterface
      * @return $this
      */
     public function reindexEntity($entityIds);
-
-    /**
-     * Register data required by product type process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    public function registerEvent(\Magento\Index\Model\Event $event);
 }
diff --git a/app/code/Magento/Catalog/Model/Resource/Setup.php b/app/code/Magento/Catalog/Model/Resource/Setup.php
index 9578a85612b..3dd73ed183e 100644
--- a/app/code/Magento/Catalog/Model/Resource/Setup.php
+++ b/app/code/Magento/Catalog/Model/Resource/Setup.php
@@ -34,13 +34,6 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
      */
     protected $_categoryFactory;
 
-    /**
-     * Indexer model factory
-     *
-     * @var \Magento\Index\Model\IndexerFactory
-     */
-    protected $_indexerFactory;
-
     /**
      * Attribute resource model factory
      *
@@ -54,7 +47,6 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
      * @param \Magento\Framework\App\CacheInterface $cache
      * @param \Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory $attrGroupCollectionFactory
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\Index\Model\IndexerFactory $indexerFactory
      * @param Eav\AttributeFactory $eavAttributeResourceFactory
      * @param string $moduleName
      * @param string $connectionName
@@ -65,13 +57,11 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
         \Magento\Framework\App\CacheInterface $cache,
         \Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory $attrGroupCollectionFactory,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Index\Model\IndexerFactory $indexerFactory,
         \Magento\Catalog\Model\Resource\Eav\AttributeFactory $eavAttributeResourceFactory,
         $moduleName = 'Magento_Catalog',
         $connectionName = \Magento\Framework\Module\Updater\SetupInterface::DEFAULT_SETUP_CONNECTION
     ) {
         $this->_categoryFactory = $categoryFactory;
-        $this->_indexerFactory = $indexerFactory;
         $this->_eavAttributeResourceFactory = $eavAttributeResourceFactory;
         parent::__construct(
             $context,
@@ -138,16 +128,6 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
                         'group' => 'General Information'
                     ),
-                    'url_key' => array(
-                        'type' => 'varchar',
-                        'label' => 'URL Key',
-                        'input' => 'text',
-                        'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Urlkey',
-                        'required' => false,
-                        'sort_order' => 3,
-                        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
-                        'group' => 'General Information'
-                    ),
                     'description' => array(
                         'type' => 'text',
                         'label' => 'Description',
@@ -262,14 +242,6 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'visible' => false,
                         'group' => 'General Information'
                     ),
-                    'url_path' => array(
-                        'type' => 'varchar',
-                        'required' => false,
-                        'sort_order' => 17,
-                        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
-                        'visible' => false,
-                        'group' => 'General Information'
-                    ),
                     'custom_design' => array(
                         'type' => 'varchar',
                         'label' => 'Custom Design',
@@ -541,7 +513,7 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'label' => 'Meta Title',
                         'input' => 'text',
                         'required' => false,
-                        'sort_order' => 1,
+                        'sort_order' => 20,
                         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
                         'group' => 'Meta Information'
                     ),
@@ -550,7 +522,7 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'label' => 'Meta Keywords',
                         'input' => 'textarea',
                         'required' => false,
-                        'sort_order' => 2,
+                        'sort_order' => 30,
                         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
                         'group' => 'Meta Information'
                     ),
@@ -561,7 +533,7 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'required' => false,
                         'note' => 'Maximum 255 chars',
                         'class' => 'validate-length maximum-length-255',
-                        'sort_order' => 3,
+                        'sort_order' => 40,
                         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
                         'group' => 'Meta Information'
                     ),
@@ -679,23 +651,6 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                         'searchable' => true,
                         'used_in_product_listing' => true
                     ),
-                    'url_key' => array(
-                        'type' => 'varchar',
-                        'label' => 'URL Key',
-                        'input' => 'text',
-                        'backend' => 'Magento\Catalog\Model\Product\Attribute\Backend\Urlkey',
-                        'required' => false,
-                        'sort_order' => 10,
-                        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
-                        'used_in_product_listing' => true
-                    ),
-                    'url_path' => array(
-                        'type' => 'varchar',
-                        'required' => false,
-                        'sort_order' => 11,
-                        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
-                        'visible' => false
-                    ),
                     'minimal_price' => array(
                         'type' => 'decimal',
                         'label' => 'Minimal Price',
diff --git a/app/code/Magento/Catalog/Model/Resource/Url.php b/app/code/Magento/Catalog/Model/Resource/Url.php
index 18e90d9608e..3c04c8fa034 100644
--- a/app/code/Magento/Catalog/Model/Resource/Url.php
+++ b/app/code/Magento/Catalog/Model/Resource/Url.php
@@ -28,6 +28,8 @@ namespace Magento\Catalog\Model\Resource;
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+
 class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
 {
     /**
@@ -134,7 +136,7 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     protected function _construct()
     {
-        $this->_init('core_url_rewrite', 'url_rewrite_id');
+        $this->_init('url_rewrite', 'url_rewrite_id');
     }
 
     /**
@@ -164,333 +166,6 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $this->_catalogCategory;
     }
 
-    /**
-     * Retrieve rewrite by idPath
-     *
-     * @param string $idPath
-     * @param int $storeId
-     * @return \Magento\Framework\Object|false
-     */
-    public function getRewriteByIdPath($idPath, $storeId)
-    {
-        $adapter = $this->_getReadAdapter();
-        $select = $adapter->select()->from(
-            $this->getMainTable()
-        )->where(
-            'store_id = :store_id'
-        )->where(
-            'id_path = :id_path'
-        );
-        $bind = array('store_id' => (int)$storeId, 'id_path' => $idPath);
-        $row = $adapter->fetchRow($select, $bind);
-
-        if (!$row) {
-            return false;
-        }
-        $rewrite = new \Magento\Framework\Object($row);
-        $rewrite->setIdFieldName($this->getIdFieldName());
-
-        return $rewrite;
-    }
-
-    /**
-     * Retrieve rewrite by requestPath
-     *
-     * @param string $requestPath
-     * @param int $storeId
-     * @return \Magento\Framework\Object|false
-     */
-    public function getRewriteByRequestPath($requestPath, $storeId)
-    {
-        $adapter = $this->_getWriteAdapter();
-        $select = $adapter->select()->from(
-            $this->getMainTable()
-        )->where(
-            'store_id = :store_id'
-        )->where(
-            'request_path = :request_path'
-        );
-        $bind = array('request_path' => $requestPath, 'store_id' => (int)$storeId);
-        $row = $adapter->fetchRow($select, $bind);
-
-        if (!$row) {
-            return false;
-        }
-        $rewrite = new \Magento\Framework\Object($row);
-        $rewrite->setIdFieldName($this->getIdFieldName());
-
-        return $rewrite;
-    }
-
-    /**
-     * Get last used increment part of rewrite request path
-     *
-     * @param string $prefix
-     * @param string $suffix
-     * @param int $storeId
-     * @return int
-     */
-    public function getLastUsedRewriteRequestIncrement($prefix, $suffix, $storeId)
-    {
-        $adapter = $this->_getWriteAdapter();
-        $requestPathField = new \Zend_Db_Expr($adapter->quoteIdentifier('request_path'));
-
-        //select increment part of request path and cast expression to integer
-        $expression = $adapter->getSubstringSql(
-            $requestPathField,
-            strlen($prefix) + 1,
-            $adapter->getLengthSql($requestPathField) . ' - ' . strlen($prefix) . ' - ' . strlen($suffix)
-        );
-        $urlIncrementPartExpression = new \Zend_Db_Expr("CAST({$expression} AS SIGNED)");
-        $select = $adapter->select()->from(
-            $this->getMainTable(),
-            new \Zend_Db_Expr('MAX(' . $urlIncrementPartExpression . ')')
-        )->where(
-            'store_id = :store_id'
-        )->where(
-            'request_path LIKE :request_path'
-        )->where(
-            $adapter->prepareSqlCondition(
-                'request_path',
-                array('regexp' => '^' . preg_quote($prefix) . '[0-9]*' . preg_quote($suffix) . '$')
-            )
-        );
-        $bind = array('store_id' => (int)$storeId, 'request_path' => $prefix . '%' . $suffix);
-
-        return (int)$adapter->fetchOne($select, $bind);
-    }
-
-    /**
-     * Validate array of request paths. Return first not used path in case if validations passed
-     *
-     * @param array $paths
-     * @param int $storeId
-     * @return bool|string
-     */
-    public function checkRequestPaths($paths, $storeId)
-    {
-        $adapter = $this->_getWriteAdapter();
-        $select = $adapter->select()->from(
-            $this->getMainTable(),
-            'request_path'
-        )->where(
-            'store_id = :store_id'
-        )->where(
-            'request_path IN (?)',
-            $paths
-        );
-        $data = $adapter->fetchCol($select, array('store_id' => $storeId));
-        $paths = array_diff($paths, $data);
-        if (empty($paths)) {
-            return false;
-        }
-        reset($paths);
-
-        return current($paths);
-    }
-
-    /**
-     * Prepare rewrites for condition
-     *
-     * @param int $storeId
-     * @param int|array $categoryIds
-     * @param int|array $productIds
-     * @return array
-     */
-    public function prepareRewrites($storeId, $categoryIds = null, $productIds = null)
-    {
-        $rewrites = array();
-        $adapter = $this->_getWriteAdapter();
-        $select = $adapter->select()->from(
-            $this->getMainTable()
-        )->where(
-            'store_id = :store_id'
-        )->where(
-            'is_system = ?',
-            1
-        );
-        $bind = array('store_id' => $storeId);
-        if ($categoryIds === null) {
-            $select->where('category_id IS NULL');
-        } elseif ($categoryIds) {
-            $catIds = is_array($categoryIds) ? $categoryIds : array($categoryIds);
-
-            // Check maybe we request products and root category id is within categoryIds,
-            // it's a separate case because root category products are stored with NULL categoryId
-            if ($productIds) {
-                $addNullCategory = in_array($this->getStores($storeId)->getRootCategoryId(), $catIds);
-            } else {
-                $addNullCategory = false;
-            }
-
-            // Compose optimal condition
-            if ($addNullCategory) {
-                $select->where('category_id IN(?) OR category_id IS NULL', $catIds);
-            } else {
-                $select->where('category_id IN(?)', $catIds);
-            }
-        }
-
-        if ($productIds === null) {
-            $select->where('product_id IS NULL');
-        } elseif ($productIds) {
-            $select->where('product_id IN(?)', $productIds);
-        }
-
-        $rowSet = $adapter->fetchAll($select, $bind);
-
-        foreach ($rowSet as $row) {
-            $rewrite = new \Magento\Framework\Object($row);
-            $rewrite->setIdFieldName($this->getIdFieldName());
-            $rewrites[$rewrite->getIdPath()] = $rewrite;
-        }
-
-        return $rewrites;
-    }
-
-    /**
-     * Save rewrite URL
-     *
-     * @param array $rewriteData
-     * @param int|\Magento\Framework\Object $rewrite
-     * @return $this
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function saveRewrite($rewriteData, $rewrite)
-    {
-        $adapter = $this->_getWriteAdapter();
-        try {
-            $adapter->insertOnDuplicate($this->getMainTable(), $rewriteData);
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-            throw new \Magento\Framework\Model\Exception(__('Something went wrong saving the URL rewite.'));
-        }
-
-        if ($rewrite && $rewrite->getId()) {
-            if ($rewriteData['request_path'] != $rewrite->getRequestPath()) {
-                // Update existing rewrites history and avoid chain redirects
-                $where = array('target_path = ?' => $rewrite->getRequestPath());
-                if ($rewrite->getStoreId()) {
-                    $where['store_id = ?'] = (int)$rewrite->getStoreId();
-                }
-                $adapter->update($this->getMainTable(), array('target_path' => $rewriteData['request_path']), $where);
-            }
-        }
-        unset($rewriteData);
-
-        return $this;
-    }
-
-    /**
-     * Saves rewrite history
-     *
-     * @param array $rewriteData
-     * @return $this
-     */
-    public function saveRewriteHistory($rewriteData)
-    {
-        $rewriteData = new \Magento\Framework\Object($rewriteData);
-        // check if rewrite exists with save request_path
-        $rewrite = $this->getRewriteByRequestPath($rewriteData->getRequestPath(), $rewriteData->getStoreId());
-        if ($rewrite === false) {
-            // create permanent redirect
-            $this->_getWriteAdapter()->insert($this->getMainTable(), $rewriteData->getData());
-        }
-
-        return $this;
-    }
-
-    /**
-     * Save category attribute
-     *
-     * @param \Magento\Framework\Object $category
-     * @param string $attributeCode
-     * @return $this
-     */
-    public function saveCategoryAttribute(\Magento\Framework\Object $category, $attributeCode)
-    {
-        $adapter = $this->_getWriteAdapter();
-        if (!isset($this->_categoryAttributes[$attributeCode])) {
-            $attribute = $this->getCategoryModel()->getResource()->getAttribute($attributeCode);
-
-            $this->_categoryAttributes[$attributeCode] = array(
-                'entity_type_id' => $attribute->getEntityTypeId(),
-                'attribute_id' => $attribute->getId(),
-                'table' => $attribute->getBackend()->getTable(),
-                'is_global' => $attribute->getIsGlobal()
-            );
-            unset($attribute);
-        }
-
-        $attributeTable = $this->_categoryAttributes[$attributeCode]['table'];
-
-        $attributeData = array(
-            'entity_type_id' => $this->_categoryAttributes[$attributeCode]['entity_type_id'],
-            'attribute_id' => $this->_categoryAttributes[$attributeCode]['attribute_id'],
-            'store_id' => $category->getStoreId(),
-            'entity_id' => $category->getId(),
-            'value' => $category->getData($attributeCode)
-        );
-
-        if ($this->_categoryAttributes[$attributeCode]['is_global'] || $category->getStoreId() == 0) {
-            $attributeData['store_id'] = 0;
-        }
-
-        $select = $adapter->select()->from(
-            $attributeTable
-        )->where(
-            'entity_type_id = ?',
-            (int)$attributeData['entity_type_id']
-        )->where(
-            'attribute_id = ?',
-            (int)$attributeData['attribute_id']
-        )->where(
-            'store_id = ?',
-            (int)$attributeData['store_id']
-        )->where(
-            'entity_id = ?',
-            (int)$attributeData['entity_id']
-        );
-
-        $row = $adapter->fetchRow($select);
-        $whereCond = array('value_id = ?' => $row['value_id']);
-        if ($row) {
-            $adapter->update($attributeTable, $attributeData, $whereCond);
-        } else {
-            $adapter->insert($attributeTable, $attributeData);
-        }
-
-        if ($attributeData['store_id'] != 0) {
-            $attributeData['store_id'] = 0;
-            $select = $adapter->select()->from(
-                $attributeTable
-            )->where(
-                'entity_type_id = ?',
-                (int)$attributeData['entity_type_id']
-            )->where(
-                'attribute_id = ?',
-                (int)$attributeData['attribute_id']
-            )->where(
-                'store_id = ?',
-                (int)$attributeData['store_id']
-            )->where(
-                'entity_id = ?',
-                (int)$attributeData['entity_id']
-            );
-
-            $row = $adapter->fetchRow($select);
-            if ($row) {
-                $whereCond = array('value_id = ?' => $row['value_id']);
-                $adapter->update($attributeTable, $attributeData, $whereCond);
-            } else {
-                $adapter->insert($attributeTable, $attributeData);
-            }
-        }
-        unset($attributeData);
-
-        return $this;
-    }
-
     /**
      * Retrieve category attributes
      *
@@ -583,97 +258,6 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $attributes;
     }
 
-    /**
-     * Save product attribute
-     *
-     * @param \Magento\Framework\Object $product
-     * @param string $attributeCode
-     * @return $this
-     */
-    public function saveProductAttribute(\Magento\Framework\Object $product, $attributeCode)
-    {
-        $adapter = $this->_getWriteAdapter();
-        if (!isset($this->_productAttributes[$attributeCode])) {
-            $attribute = $this->productResource->getAttribute($attributeCode);
-
-            $this->_productAttributes[$attributeCode] = array(
-                'entity_type_id' => $attribute->getEntityTypeId(),
-                'attribute_id' => $attribute->getId(),
-                'table' => $attribute->getBackend()->getTable(),
-                'is_global' => $attribute->getIsGlobal()
-            );
-            unset($attribute);
-        }
-
-        $attributeTable = $this->_productAttributes[$attributeCode]['table'];
-
-        $attributeData = array(
-            'entity_type_id' => $this->_productAttributes[$attributeCode]['entity_type_id'],
-            'attribute_id' => $this->_productAttributes[$attributeCode]['attribute_id'],
-            'store_id' => $product->getStoreId(),
-            'entity_id' => $product->getId(),
-            'value' => $product->getData($attributeCode)
-        );
-
-        if ($this->_productAttributes[$attributeCode]['is_global'] || $product->getStoreId() == 0) {
-            $attributeData['store_id'] = 0;
-        }
-
-        $select = $adapter->select()->from(
-            $attributeTable
-        )->where(
-            'entity_type_id = ?',
-            (int)$attributeData['entity_type_id']
-        )->where(
-            'attribute_id = ?',
-            (int)$attributeData['attribute_id']
-        )->where(
-            'store_id = ?',
-            (int)$attributeData['store_id']
-        )->where(
-            'entity_id = ?',
-            (int)$attributeData['entity_id']
-        );
-
-        $row = $adapter->fetchRow($select);
-        if ($row) {
-            $whereCond = array('value_id = ?' => $row['value_id']);
-            $adapter->update($attributeTable, $attributeData, $whereCond);
-        } else {
-            $adapter->insert($attributeTable, $attributeData);
-        }
-
-        if ($attributeData['store_id'] != 0) {
-            $attributeData['store_id'] = 0;
-            $select = $adapter->select()->from(
-                $attributeTable
-            )->where(
-                'entity_type_id = ?',
-                (int)$attributeData['entity_type_id']
-            )->where(
-                'attribute_id = ?',
-                (int)$attributeData['attribute_id']
-            )->where(
-                'store_id = ?',
-                (int)$attributeData['store_id']
-            )->where(
-                'entity_id = ?',
-                (int)$attributeData['entity_id']
-            );
-
-            $row = $adapter->fetchRow($select);
-            if ($row) {
-                $whereCond = array('value_id = ?' => $row['value_id']);
-                $adapter->update($attributeTable, $attributeData, $whereCond);
-            } else {
-                $adapter->insert($attributeTable, $attributeData);
-            }
-        }
-        unset($attributeData);
-
-        return $this;
-    }
-
     /**
      * Retrieve product attribute
      *
@@ -932,127 +516,6 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $this->_getCategories($categoryIds, $storeId);
     }
 
-    /**
-     * Retrieve category child data objects
-     *
-     * @param \Magento\Framework\Object $category
-     * @return \Magento\Framework\Object
-     */
-    public function loadCategoryChilds(\Magento\Framework\Object $category)
-    {
-        if ($category->getId() === null || $category->getStoreId() === null) {
-            return $category;
-        }
-
-        $categories = $this->_getCategories(null, $category->getStoreId(), $category->getPath() . '/');
-        $category->setChilds(array());
-        foreach ($categories as $child) {
-            if (!is_array($child->getChilds())) {
-                $child->setChilds(array());
-            }
-            if ($child->getParentId() == $category->getId()) {
-                $category->setChilds($category->getChilds() + array($child->getId() => $child));
-            } else {
-                if (isset($categories[$child->getParentId()])) {
-                    if (!is_array($categories[$child->getParentId()]->getChilds())) {
-                        $categories[$child->getParentId()]->setChilds(array());
-                    }
-                    $categories[$child->getParentId()]->setChilds(
-                        $categories[$child->getParentId()]->getChilds() + array($child->getId() => $child)
-                    );
-                }
-            }
-        }
-        $category->setAllChilds($categories);
-
-        return $category;
-    }
-
-    /**
-     * Retrieves all children ids of root category tree
-     * Actually this routine can be used to get children ids of any category, not only root.
-     * But as far as result is cached in memory, it's not recommended to do so.
-     *
-     * @param string $categoryId
-     * @param string $categoryPath
-     * @param bool $includeStart
-     * @return \Magento\Framework\Object
-     */
-    public function getRootChildrenIds($categoryId, $categoryPath, $includeStart = true)
-    {
-        if (!isset($this->_rootChildrenIds[$categoryId])) {
-            // Select all descedant category ids
-            $adapter = $this->_getReadAdapter();
-            $select = $adapter->select()->from(
-                array($this->getTable('catalog_category_entity')),
-                array('entity_id')
-            )->where(
-                'path LIKE ?',
-                $categoryPath . '/%'
-            );
-
-            $categoryIds = array();
-            $rowSet = $adapter->fetchAll($select);
-            foreach ($rowSet as $row) {
-                $categoryIds[$row['entity_id']] = $row['entity_id'];
-            }
-            $this->_rootChildrenIds[$categoryId] = $categoryIds;
-        }
-
-        $categoryIds = $this->_rootChildrenIds[$categoryId];
-        if ($includeStart) {
-            $categoryIds[$categoryId] = $categoryId;
-        }
-        return $categoryIds;
-    }
-
-    /**
-     * Retrieve category parent path
-     *
-     * @param \Magento\Framework\Object $category
-     * @return string
-     */
-    public function getCategoryParentPath(\Magento\Framework\Object $category)
-    {
-        $store = $this->_storeManager->getStore($category->getStoreId());
-
-        if ($category->getId() == $store->getRootCategoryId()) {
-            return '';
-        } elseif ($category->getParentId() == 1 || $category->getParentId() == $store->getRootCategoryId()) {
-            return '';
-        }
-
-        $parentCategory = $this->getCategory($category->getParentId(), $store->getId());
-        return $parentCategory->getUrlPath() . '/';
-    }
-
-    /**
-     * Retrieve product ids by category
-     *
-     * @param \Magento\Framework\Object|int $category
-     * @return array
-     */
-    public function getProductIdsByCategory($category)
-    {
-        if ($category instanceof \Magento\Framework\Object) {
-            $categoryId = $category->getId();
-        } else {
-            $categoryId = $category;
-        }
-        $adapter = $this->_getReadAdapter();
-        $select = $adapter->select()->from(
-            $this->getTable('catalog_category_product'),
-            array('product_id')
-        )->where(
-            'category_id = :category_id'
-        )->order(
-            'product_id'
-        );
-        $bind = array('category_id' => $categoryId);
-
-        return $adapter->fetchCol($select, $bind);
-    }
-
     /**
      * Retrieve Product data objects
      *
@@ -1161,217 +624,6 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $this->_getProducts(null, $storeId, $lastEntityId, $lastEntityId);
     }
 
-    /**
-     * Retrieve Product data objects in category
-     *
-     * @param \Magento\Framework\Object $category
-     * @param int &$lastEntityId
-     * @return array
-     */
-    public function getProductsByCategory(\Magento\Framework\Object $category, &$lastEntityId)
-    {
-        $productIds = $this->getProductIdsByCategory($category);
-        if (!$productIds) {
-            return array();
-        }
-        return $this->_getProducts($productIds, $category->getStoreId(), $lastEntityId, $lastEntityId);
-    }
-
-    /**
-     * Find and remove unused products rewrites - a case when products were moved away from the category
-     * (either to other category or deleted), so rewrite "category_id-product_id" is invalid
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function clearCategoryProduct($storeId)
-    {
-        $adapter = $this->_getWriteAdapter();
-        $select = $adapter->select()->from(
-            array('tur' => $this->getMainTable()),
-            $this->getIdFieldName()
-        )->joinLeft(
-            array('tcp' => $this->getTable('catalog_category_product')),
-            'tur.category_id = tcp.category_id AND tur.product_id = tcp.product_id',
-            array()
-        )->where(
-            'tur.store_id = :store_id'
-        )->where(
-            'tur.category_id IS NOT NULL'
-        )->where(
-            'tur.product_id IS NOT NULL'
-        )->where(
-            'tcp.category_id IS NULL'
-        );
-        $rewriteIds = $adapter->fetchCol($select, array('store_id' => $storeId));
-        if ($rewriteIds) {
-            $where = array($this->getIdFieldName() . ' IN(?)' => $rewriteIds);
-            $adapter->delete($this->getMainTable(), $where);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Remove unused rewrites for product - called after we created all needed rewrites for product and
-     * know the categories where the product is contained ($excludeCategoryIds),
-     * so we can remove all invalid product rewrites that have other category ids
-     *
-     * Notice: this routine is not identical to clearCategoryProduct(), because after checking all categories
-     * this one removes rewrites for product still contained within categories.
-     *
-     * @param int $productId Product entity Id
-     * @param int $storeId Store Id for rewrites
-     * @param array $excludeCategoryIds Array of category Ids that should be skipped
-     * @return $this
-     */
-    public function clearProductRewrites($productId, $storeId, $excludeCategoryIds = array())
-    {
-        $where = array('product_id = ?' => $productId, 'store_id = ?' => $storeId);
-
-        if (!empty($excludeCategoryIds)) {
-            $where['category_id NOT IN (?)'] = $excludeCategoryIds;
-            // If there's at least one category to skip, also skip root category, because product belongs to website
-            $where[] = 'category_id IS NOT NULL';
-        }
-
-        $this->_getWriteAdapter()->delete($this->getMainTable(), $where);
-
-        return $this;
-    }
-
-    /**
-     * Finds and deletes all old category and category/product rewrites for store
-     * left from the times when categories/products belonged to store
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function clearStoreCategoriesInvalidRewrites($storeId)
-    {
-        // Form a list of all current store categories ids
-        $store = $this->getStores($storeId);
-        $rootCategoryId = $store->getRootCategoryId();
-        if (!$rootCategoryId) {
-            return $this;
-        }
-        $categoryIds = $this->getRootChildrenIds($rootCategoryId, $store->getRootCategoryPath());
-
-        // Remove all store catalog rewrites that are for some category or cartegory/product not within store categories
-        $where = array(
-            'store_id = ?' => $storeId,
-            'category_id IS NOT NULL', // For sure check that it's a catalog rewrite
-            'category_id NOT IN (?)' => $categoryIds
-        );
-
-        $this->_getWriteAdapter()->delete($this->getMainTable(), $where);
-
-        return $this;
-    }
-
-    /**
-     * Finds and deletes product rewrites (that are not assigned to any category) for store
-     * left from the times when product was assigned to this store's website and now is not assigned
-     *
-     * Notice: this routine is different from clearProductRewrites() and clearCategoryProduct() because
-     * it handles direct rewrites to product without defined category (category_id IS NULL) whilst that routines
-     * handle only product rewrites within categories
-     *
-     * @param int $storeId
-     * @param int|array|null $productId
-     * @return $this
-     */
-    public function clearStoreProductsInvalidRewrites($storeId, $productId = null)
-    {
-        $store = $this->getStores($storeId);
-        $adapter = $this->_getReadAdapter();
-        $bind = array('website_id' => (int)$store->getWebsiteId(), 'store_id' => (int)$storeId);
-        $select = $adapter->select()->from(
-            array('rewrite' => $this->getMainTable()),
-            $this->getIdFieldName()
-        )->joinLeft(
-            array('website' => $this->getTable('catalog_product_website')),
-            'rewrite.product_id = website.product_id AND website.website_id = :website_id',
-            array()
-        )->where(
-            'rewrite.store_id = :store_id'
-        )->where(
-            'rewrite.category_id IS NULL'
-        );
-        if ($productId) {
-            $select->where('rewrite.product_id IN (?)', $productId);
-        } else {
-            $select->where('rewrite.product_id IS NOT NULL');
-        }
-        $select->where('website.website_id IS NULL');
-
-        $rewriteIds = $adapter->fetchCol($select, $bind);
-        if ($rewriteIds) {
-            $where = array($this->getIdFieldName() . ' IN(?)' => $rewriteIds);
-            $this->_getWriteAdapter()->delete($this->getMainTable(), $where);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Clear store invalid rewrites
-     *
-     * Finds and deletes old rewrites for store
-     * a) category rewrites left from the times when store had some other root category
-     * b) product rewrites left from products that once belonged to this site, but then deleted or just removed from website
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function clearStoreInvalidRewrites($storeId)
-    {
-        $this->clearStoreCategoriesInvalidRewrites($storeId);
-        $this->clearStoreProductsInvalidRewrites($storeId);
-        return $this;
-    }
-
-    /**
-     * Delete rewrites for associated to category products
-     *
-     * @param int $categoryId
-     * @param array|int|null $productIds
-     * @return $this
-     */
-    public function deleteCategoryProductRewrites($categoryId, $productIds)
-    {
-        $this->deleteCategoryProductStoreRewrites($categoryId, $productIds);
-        return $this;
-    }
-
-    /**
-     * Delete URL rewrites for category products of specific store
-     *
-     * @param int $categoryId
-     * @param array|int|null $productIds
-     * @param null|int $storeId
-     * @return $this
-     */
-    public function deleteCategoryProductStoreRewrites($categoryId, $productIds = null, $storeId = null)
-    {
-        // Notice that we don't include category_id = NULL in case of root category,
-        // because product removed from all categories but assigned to store's website is still
-        // assumed to be in root cat. Unassigned products must be removed by other routine.
-        $condition = array('category_id = ?' => $categoryId);
-        if (empty($productIds)) {
-            $condition[] = 'product_id IS NOT NULL';
-        } else {
-            $condition['product_id IN (?)'] = $productIds;
-        }
-
-        if ($storeId !== null) {
-            $condition['store_id IN(?)'] = $storeId;
-        }
-
-        $this->_getWriteAdapter()->delete($this->getMainTable(), $condition);
-        return $this;
-    }
-
     /**
      * Get rewrite by product store
      *
@@ -1399,9 +651,14 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
             array('i' => $this->getTable('catalog_category_product_index')),
             array('product_id', 'store_id', 'visibility')
         )->joinLeft(
-            array('r' => $this->getMainTable()),
-            'i.product_id = r.product_id AND i.store_id=r.store_id AND r.category_id IS NULL',
+            array('u' => $this->getMainTable()),
+            'i.product_id = u.entity_id AND i.store_id = u.store_id'
+            . ' AND u.entity_type = "' . ProductUrlRewriteGenerator::ENTITY_TYPE . '"',
             array('request_path')
+        )->joinLeft(
+            array('r' => $this->getTable('catalog_url_rewrite_product_category')),
+            'u.url_rewrite_id = r.url_rewrite_id AND r.category_id is NULL',
+            array()
         );
 
         $bind = array();
@@ -1431,74 +688,4 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
 
         return $result;
     }
-
-    /**
-     * Find and return final id path by request path
-     * Needed for permanent redirect old URLs.
-     *
-     * @param string $requestPath
-     * @param int $storeId
-     * @param array &$_checkedPaths internal variable to prevent infinite loops.
-     * @return string|bool
-     */
-    public function findFinalTargetPath($requestPath, $storeId, &$_checkedPaths = array())
-    {
-        if (in_array($requestPath, $_checkedPaths)) {
-            return false;
-        }
-
-        $_checkedPaths[] = $requestPath;
-
-        $select = $this->_getWriteAdapter()->select()->from(
-            $this->getMainTable(),
-            array('target_path', 'id_path')
-        )->where(
-            'store_id = ?',
-            $storeId
-        )->where(
-            'request_path = ?',
-            $requestPath
-        );
-
-        $row = $this->_getWriteAdapter()->fetchRow($select);
-        if ($row) {
-            $idPath = $this->findFinalTargetPath($row['target_path'], $storeId, $_checkedPaths);
-            if (!$idPath) {
-                return $row['id_path'];
-            } else {
-                return $idPath;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Delete rewrite path record from the database.
-     *
-     * @param string $requestPath
-     * @param int $storeId
-     * @return void
-     */
-    public function deleteRewrite($requestPath, $storeId)
-    {
-        $this->deleteRewriteRecord($requestPath, $storeId);
-    }
-
-    /**
-     * Delete rewrite path record from the database with RP checking.
-     *
-     * @param string $requestPath
-     * @param int $storeId
-     * @param bool $rp whether check rewrite option to be "Redirect = Permanent"
-     * @return void
-     */
-    public function deleteRewriteRecord($requestPath, $storeId, $rp = false)
-    {
-        $conditions = array('store_id = ?' => $storeId, 'request_path = ?' => $requestPath);
-        if ($rp) {
-            $conditions['options = ?'] = 'RP';
-        }
-        $this->_getWriteAdapter()->delete($this->getMainTable(), $conditions);
-    }
 }
diff --git a/app/code/Magento/Catalog/Model/Rss/Category.php b/app/code/Magento/Catalog/Model/Rss/Category.php
new file mode 100644
index 00000000000..9a7f34bbadf
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Rss/Category.php
@@ -0,0 +1,96 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss;
+
+/**
+ * Class Category
+ * @package Magento\Catalog\Model\Rss
+ */
+class Category
+{
+    /**
+     * @var \Magento\Catalog\Model\Layer
+     */
+    protected $catalogLayer;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\CollectionFactory
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Visibility
+     */
+    protected $visibility;
+
+    /**
+     * @param \Magento\Catalog\Model\Layer\Category $catalogLayer
+     * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $collectionFactory
+     * @param \Magento\Catalog\Model\Product\Visibility $visibility
+     */
+    public function __construct(
+        \Magento\Catalog\Model\Layer\Category $catalogLayer,
+        \Magento\Catalog\Model\Resource\Product\CollectionFactory $collectionFactory,
+        \Magento\Catalog\Model\Product\Visibility $visibility
+    ) {
+        $this->catalogLayer = $catalogLayer;
+        $this->collectionFactory = $collectionFactory;
+        $this->visibility = $visibility;
+    }
+
+
+    /**
+     * @param \Magento\Catalog\Model\Category $category
+     * @param int $storeId
+     * @return $this
+     */
+    public function getProductCollection(\Magento\Catalog\Model\Category $category, $storeId)
+    {
+        /** @var $layer \Magento\Catalog\Model\Layer */
+        $layer = $this->catalogLayer->setStore($storeId);
+        $collection = $category->getResourceCollection();
+        $collection->addAttributeToSelect('url_key')
+            ->addAttributeToSelect('name')
+            ->addAttributeToSelect('is_anchor')
+            ->addAttributeToFilter('is_active', 1)
+            ->addIdFilter($category->getChildren())
+            ->load();
+        /** @var $productCollection \Magento\Catalog\Model\Resource\Product\Collection */
+        $productCollection = $this->collectionFactory->create();
+
+        $currentCategory = $layer->setCurrentCategory($category);
+        $layer->prepareProductCollection($productCollection);
+        $productCollection->addCountToCategories($collection);
+
+        $category->getProductCollection()->setStoreId($storeId);
+
+        $products = $currentCategory->getProductCollection()
+            ->addAttributeToSort('updated_at', 'desc')
+            ->setVisibility($this->visibility->getVisibleInCatalogIds())
+            ->setCurPage(1)
+            ->setPageSize(50);
+
+        return $products;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Rss/Product/NewProducts.php b/app/code/Magento/Catalog/Model/Rss/Product/NewProducts.php
new file mode 100644
index 00000000000..b0b1c27cf52
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Rss/Product/NewProducts.php
@@ -0,0 +1,119 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+/**
+ * Class NewProducts
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class NewProducts
+{
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Visibility
+     */
+    protected $visibility;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
+     */
+    protected $localeDate;
+
+    /**
+     * @param \Magento\Catalog\Model\ProductFactory $productFactory
+     * @param \Magento\Catalog\Model\Product\Visibility $visibility
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     */
+    public function __construct(
+        \Magento\Catalog\Model\ProductFactory $productFactory,
+        \Magento\Catalog\Model\Product\Visibility $visibility,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+    ) {
+        $this->productFactory = $productFactory;
+        $this->visibility = $visibility;
+        $this->localeDate = $localeDate;
+    }
+
+
+    /**
+     * @param int $storeId
+     * @return \Magento\Catalog\Model\Resource\Product\Collection
+     */
+    public function getProductsCollection($storeId)
+    {
+        /** @var $product \Magento\Catalog\Model\Product */
+        $product = $this->productFactory->create();
+        $todayStartOfDayDate = $this->localeDate->date()->setTime('00:00:00')
+            ->toString(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT);
+
+        $todayEndOfDayDate = $this->localeDate->date()->setTime('23:59:59')
+            ->toString(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT);
+        /** @var $products \Magento\Catalog\Model\Resource\Product\Collection */
+        $products = $product->getResourceCollection();
+        $products->setStoreId($storeId);
+        $products->addStoreFilter()->addAttributeToFilter(
+            'news_from_date',
+            array(
+                'or' => array(
+                    0 => array('date' => true, 'to' => $todayEndOfDayDate),
+                    1 => array('is' => new \Zend_Db_Expr('null'))
+                )
+            ),
+            'left'
+        )->addAttributeToFilter(
+            'news_to_date',
+            array(
+                'or' => array(
+                    0 => array('date' => true, 'from' => $todayStartOfDayDate),
+                    1 => array('is' => new \Zend_Db_Expr('null'))
+                )
+            ),
+            'left'
+        )->addAttributeToFilter(array(
+            array('attribute' => 'news_from_date', 'is' => new \Zend_Db_Expr('not null')),
+            array('attribute' => 'news_to_date', 'is' => new \Zend_Db_Expr('not null'))
+        ))->addAttributeToSort('news_from_date', 'desc')
+        ->addAttributeToSelect(array('name', 'short_description', 'description'), 'inner')
+        ->addAttributeToSelect(
+            array(
+                'price',
+                'special_price',
+                'special_from_date',
+                'special_to_date',
+                'msrp_enabled',
+                'msrp_display_actual_price_type',
+                'msrp',
+                'thumbnail'
+            ),
+            'left'
+        )->applyFrontendPriceLimitations();
+        $products->setVisibility($this->visibility->getVisibleInCatalogIds());
+
+        return $products;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Rss/Product/NotifyStock.php b/app/code/Magento/Catalog/Model/Rss/Product/NotifyStock.php
new file mode 100644
index 00000000000..5f5bb0f4bac
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Rss/Product/NotifyStock.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+/**
+ * Class NotifyStock
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class NotifyStock extends \Magento\Framework\Model\AbstractModel
+{
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Resource\StockFactory
+     */
+    protected $stockFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Attribute\Source\Status
+     */
+    protected $productStatus;
+
+    /**
+     * Application Event Dispatcher
+     *
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * @param \Magento\Catalog\Model\ProductFactory $productFactory
+     * @param \Magento\CatalogInventory\Model\Resource\StockFactory $stockFactory
+     * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     */
+    public function __construct(
+        \Magento\Catalog\Model\ProductFactory $productFactory,
+        \Magento\CatalogInventory\Model\Resource\StockFactory $stockFactory,
+        \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
+        \Magento\Framework\Event\ManagerInterface $eventManager
+    ) {
+        $this->productFactory = $productFactory;
+        $this->stockFactory = $stockFactory;
+        $this->productStatus = $productStatus;
+        $this->eventManager = $eventManager;
+    }
+
+
+    /**
+     * @return \Magento\Catalog\Model\Resource\Product\Collection
+     */
+    public function getProductsCollection()
+    {
+        /* @var $product \Magento\Catalog\Model\Product */
+        $product = $this->productFactory->create();
+        /* @var $collection \Magento\Catalog\Model\Resource\Product\Collection */
+        $collection = $product->getCollection();
+        /** @var $resourceStock \Magento\CatalogInventory\Model\Resource\Stock */
+        $resourceStock = $this->stockFactory->create();
+        $resourceStock->addLowStockFilter(
+            $collection,
+            array('qty', 'notify_stock_qty', 'low_stock_date', 'use_config' => 'use_config_notify_stock_qty')
+        );
+        $collection->addAttributeToSelect('name', true)
+            ->addAttributeToFilter('status', array('in' => $this->productStatus->getVisibleStatusIds()))
+            ->setOrder('low_stock_date');
+
+        $this->eventManager->dispatch(
+            'rss_catalog_notify_stock_collection_select',
+            array('collection' => $collection)
+        );
+        return $collection;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Rss/Product/Special.php b/app/code/Magento/Catalog/Model/Rss/Product/Special.php
new file mode 100644
index 00000000000..dd823ae3e0e
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Rss/Product/Special.php
@@ -0,0 +1,89 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+/**
+ * Class Special
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class Special
+{
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @param \Magento\Catalog\Model\ProductFactory $productFactory
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        \Magento\Catalog\Model\ProductFactory $productFactory,
+        \Magento\Framework\StoreManagerInterface $storeManager
+    ) {
+        $this->productFactory = $productFactory;
+        $this->storeManager = $storeManager;
+    }
+
+
+    /**
+     * @param int $storeId
+     * @param int $customerGroupId
+     * @return \Magento\Catalog\Model\Resource\Product\Collection
+     */
+    public function getProductsCollection($storeId, $customerGroupId)
+    {
+        $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId();
+
+        /** @var $product \Magento\Catalog\Model\Product */
+        $product = $this->productFactory->create();
+        $product->setStoreId($storeId);
+
+        $collection = $product->getResourceCollection()
+            ->addPriceDataFieldFilter('%s < %s', array('final_price', 'price'))
+            ->addPriceData($customerGroupId, $websiteId)
+            ->addAttributeToSelect(
+                array(
+                    'name',
+                    'short_description',
+                    'description',
+                    'price',
+                    'thumbnail',
+                    'special_price',
+                    'special_to_date',
+                    'msrp_enabled',
+                    'msrp_display_actual_price_type',
+                    'msrp'
+                ),
+                'left'
+            )->addAttributeToSort('name', 'asc');
+
+        return $collection;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/Suffix.php b/app/code/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/Suffix.php
index a76d76197dc..a86383cc8cf 100644
--- a/app/code/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/Suffix.php
+++ b/app/code/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/Suffix.php
@@ -27,35 +27,58 @@
  */
 namespace Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite;
 
+use Magento\Framework\App\Resource;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
+use Magento\UrlRewrite\Model\Storage\DbStorage;
+use Magento\Store\Model\ScopeInterface;
+
 class Suffix extends \Magento\Framework\App\Config\Value
 {
-    /**
-     * Core url rewrite
-     *
-     * @var \Magento\UrlRewrite\Helper\UrlRewrite
-     */
-    protected $_coreUrlRewrite = null;
+    /** @var \Magento\UrlRewrite\Helper\UrlRewrite */
+    protected $urlRewriteHelper;
+
+    /** @var \Magento\Framework\StoreManagerInterface */
+    protected $storeManager;
+
+    /** @var \Magento\UrlRewrite\Model\UrlFinderInterface */
+    protected $urlFinder;
+
+    /** @var \Magento\Framework\DB\Adapter\AdapterInterface */
+    protected $connection;
 
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
-     * @param \Magento\UrlRewrite\Helper\UrlRewrite $coreUrlRewrite
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param \Magento\UrlRewrite\Helper\UrlRewrite $urlRewriteHelper
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Resource $appResource
+     * @param \Magento\UrlRewrite\Model\UrlFinderInterface $urlFinder
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\App\Config\ScopeConfigInterface $config,
-        \Magento\UrlRewrite\Helper\UrlRewrite $coreUrlRewrite,
+        \Magento\UrlRewrite\Helper\UrlRewrite $urlRewriteHelper,
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Resource $appResource,
+        \Magento\UrlRewrite\Model\UrlFinderInterface $urlFinder,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
     ) {
-        $this->_coreUrlRewrite = $coreUrlRewrite;
         parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
+        $this->urlRewriteHelper = $urlRewriteHelper;
+        $this->connection = $appResource->getConnection(Resource::DEFAULT_WRITE_RESOURCE);
+        $this->urlFinder = $urlFinder;
+        $this->storeManager = $storeManager;
     }
 
     /**
@@ -65,7 +88,87 @@ class Suffix extends \Magento\Framework\App\Config\Value
      */
     protected function _beforeSave()
     {
-        $this->_coreUrlRewrite->validateSuffix($this->getValue());
+        $this->urlRewriteHelper->validateSuffix($this->getValue());
         return $this;
     }
+
+    /**
+     * @return $this
+     */
+    protected function _afterSave()
+    {
+        if ($this->isValueChanged()) {
+            $this->updateSuffixForUrlRewrites();
+        }
+        return parent::_afterSave();
+    }
+
+    /**
+     * Update suffix for url rewrites
+     *
+     * @return $this
+     */
+    protected function updateSuffixForUrlRewrites()
+    {
+        $map = [
+            ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX => ProductUrlRewriteGenerator::ENTITY_TYPE,
+            CategoryUrlPathGenerator::XML_PATH_CATEGORY_URL_SUFFIX => CategoryUrlRewriteGenerator::ENTITY_TYPE
+        ];
+        if (!isset($map[$this->getPath()])) {
+            return $this;
+        }
+        $dataFilter = [UrlRewrite::ENTITY_TYPE => $map[$this->getPath()]];
+        $storesIds = $this->getStoreIds();
+        if ($storesIds) {
+            $dataFilter[UrlRewrite::STORE_ID] = $storesIds;
+        }
+        $entities = $this->urlFinder->findAllByData($dataFilter);
+        $oldSuffixPattern = '~' . preg_quote($this->getOldValue()). '$~';
+        $suffix = $this->getValue();
+        foreach ($entities as $urlRewrite) {
+            $bind = $urlRewrite->getIsAutogenerated()
+                ? [UrlRewrite::REQUEST_PATH => preg_replace($oldSuffixPattern, $suffix, $urlRewrite->getRequestPath())]
+                : [UrlRewrite::TARGET_PATH => preg_replace($oldSuffixPattern, $suffix, $urlRewrite->getTargetPath())];
+            $this->connection->update(
+                DbStorage::TABLE_NAME,
+                $bind,
+                $this->connection->quoteIdentifier(UrlRewrite::URL_REWRITE_ID) . ' = ' . $urlRewrite->getUrlRewriteId()
+            );
+        }
+        return $this;
+    }
+
+    /**
+     * @return array|null
+     */
+    protected function getStoreIds()
+    {
+        if ($this->getScope() == 'stores') {
+            $storeIds = [$this->getScopeId()];
+        } elseif ($this->getScope() == 'websites') {
+            $website = $this->storeManager->getWebsite($this->getScopeId());
+            $storeIds = array_keys($website->getStoreIds());
+            $storeIds = array_diff($storeIds, $this->getOverrideStoreIds($storeIds));
+        } else {
+            $storeIds = array_keys($this->storeManager->getStores());
+            $storeIds = array_diff($storeIds, $this->getOverrideStoreIds($storeIds));
+        }
+        return $storeIds;
+    }
+
+    /**
+     * @param array $storeIds
+     * @return array
+     */
+    protected function getOverrideStoreIds($storeIds)
+    {
+        $excludeIds = [];
+        foreach ($storeIds as $storeId) {
+            $suffix = $this->_config->getValue($this->getPath(), ScopeInterface::SCOPE_STORE, $storeId);
+            if ($suffix != $this->getOldValue()) {
+                $excludeIds[] = $storeId;
+            }
+        }
+        return $excludeIds;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Url.php b/app/code/Magento/Catalog/Model/Url.php
deleted file mode 100644
index fbd489bce82..00000000000
--- a/app/code/Magento/Catalog/Model/Url.php
+++ /dev/null
@@ -1,1045 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Catalog url model
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Catalog\Model;
-
-class Url
-{
-    /**
-     * Number of characters allowed to be in URL path
-     *
-     * @var int
-     */
-    const MAX_REQUEST_PATH_LENGTH = 240;
-
-    /**
-     * Number of characters allowed to be in URL path
-     * after MAX_REQUEST_PATH_LENGTH number of characters
-     *
-     * @var int
-     */
-    const ALLOWED_REQUEST_PATH_OVERFLOW = 10;
-
-    /**
-     * Resource model
-     *
-     * @var \Magento\Catalog\Model\Resource\Url
-     */
-    protected $_resourceModel;
-
-    /**
-     * Categories cache for products
-     *
-     * @var array
-     */
-    protected $_categories = array();
-
-    /**
-     * Store root categories cache
-     *
-     * @var array
-     */
-    protected $_rootCategories = array();
-
-    /**
-     * Rewrite cache
-     *
-     * @var array
-     */
-    protected $_rewrites = array();
-
-    /**
-     * Current url rewrite rule
-     *
-     * @var \Magento\Framework\Object
-     */
-    protected $_rewrite;
-
-    /**
-     * Cache for product rewrite suffix
-     *
-     * @var array
-     */
-    protected $_productUrlSuffix = array();
-
-    /**
-     * Cache for category rewrite suffix
-     *
-     * @var array
-     */
-    protected $_categoryUrlSuffix = array();
-
-    /**
-     * Flag to overwrite config settings for Catalog URL rewrites history maintainance
-     *
-     * @var bool
-     */
-    protected $_saveRewritesHistory = null;
-
-    /**
-     * Singleton of category model for building URL path
-     *
-     * @var \Magento\Catalog\Model\Category
-     */
-    protected static $_categoryForUrlPath;
-
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
-
-    /**
-     * Catalog product
-     *
-     * @var \Magento\Catalog\Helper\Product
-     */
-    protected $_catalogProduct = null;
-
-    /**
-     * Catalog category
-     *
-     * @var \Magento\Catalog\Helper\Category
-     */
-    protected $_catalogCategory = null;
-
-    /**
-     * Category factory
-     *
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * Url factory
-     *
-     * @var \Magento\Catalog\Model\Resource\UrlFactory
-     */
-    protected $_urlFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Url
-     */
-    protected $productUrl;
-
-    /**
-     * @param Resource\UrlFactory $urlFactory
-     * @param CategoryFactory $categoryFactory
-     * @param \Magento\Catalog\Helper\Category $catalogCategory
-     * @param \Magento\Catalog\Helper\Product $catalogProduct
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param Product\Url $productUrl
-     */
-    public function __construct(
-        \Magento\Catalog\Model\Resource\UrlFactory $urlFactory,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Catalog\Helper\Category $catalogCategory,
-        \Magento\Catalog\Helper\Product $catalogProduct,
-        \Magento\Catalog\Helper\Data $catalogData,
-        Product\Url $productUrl
-    ) {
-        $this->_urlFactory = $urlFactory;
-        $this->_categoryFactory = $categoryFactory;
-        $this->_catalogCategory = $catalogCategory;
-        $this->_catalogProduct = $catalogProduct;
-        $this->_catalogData = $catalogData;
-        $this->productUrl = $productUrl;
-    }
-
-    /**
-     * Adds url_path property for non-root category - to ensure that url path is not empty.
-     *
-     * Sometimes attribute 'url_path' can be empty, because url_path hasn't been generated yet,
-     * in this case category is loaded with empty url_path and we should generate it manually.
-     *
-     * @param \Magento\Framework\Object $category
-     * @return void
-     */
-    protected function _addCategoryUrlPath($category)
-    {
-        if (!$category instanceof \Magento\Framework\Object || $category->getUrlPath()) {
-            return;
-        }
-
-        // This routine is not intended to be used with root categories,
-        // but handle 'em gracefully - ensure them to have empty path.
-        if ($category->getLevel() <= 1) {
-            $category->setUrlPath('');
-            return;
-        }
-
-        if (self::$_categoryForUrlPath === null) {
-            self::$_categoryForUrlPath = $this->_categoryFactory->create();
-        }
-
-        // Generate url_path
-        $urlPath = self::$_categoryForUrlPath->setData($category->getData())->getUrlPath();
-        $category->setUrlPath($urlPath);
-    }
-
-    /**
-     * Retrieve stores array or store model
-     *
-     * @param int $storeId
-     * @return \Magento\Store\Model\Store|\Magento\Store\Model\Store[]
-     */
-    public function getStores($storeId = null)
-    {
-        return $this->getResource()->getStores($storeId);
-    }
-
-    /**
-     * Retrieve resource model
-     *
-     * @return \Magento\Catalog\Model\Resource\Url
-     */
-    public function getResource()
-    {
-        if (is_null($this->_resourceModel)) {
-            $this->_resourceModel = $this->_urlFactory->create();
-        }
-        return $this->_resourceModel;
-    }
-
-    /**
-     * Retrieve Category model singleton
-     *
-     * @return \Magento\Catalog\Model\Category
-     */
-    public function getCategoryModel()
-    {
-        return $this->getResource()->getCategoryModel();
-    }
-
-    /**
-     * Returns store root category, uses caching for it
-     *
-     * @param int $storeId
-     * @return \Magento\Framework\Object
-     */
-    public function getStoreRootCategory($storeId)
-    {
-        if (!array_key_exists($storeId, $this->_rootCategories)) {
-            $category = null;
-            $store = $this->getStores($storeId);
-            if ($store) {
-                $rootCategoryId = $store->getRootCategoryId();
-                $category = $this->getResource()->getCategory($rootCategoryId, $storeId);
-            }
-            $this->_rootCategories[$storeId] = $category;
-        }
-        return $this->_rootCategories[$storeId];
-    }
-
-    /**
-     * Setter for $_saveRewritesHistory
-     * Force Rewrites History save bypass config settings
-     *
-     * @param bool $flag
-     * @return $this
-     */
-    public function setShouldSaveRewritesHistory($flag)
-    {
-        $this->_saveRewritesHistory = (bool)$flag;
-        return $this;
-    }
-
-    /**
-     * Indicate whether to save URL Rewrite History or not (create redirects to old URLs)
-     *
-     * @param int $storeId Store View
-     * @return bool
-     */
-    public function getShouldSaveRewritesHistory($storeId = null)
-    {
-        if ($this->_saveRewritesHistory !== null) {
-            return $this->_saveRewritesHistory;
-        }
-        return $this->_catalogData->shouldSaveUrlRewritesHistory($storeId);
-    }
-
-    /**
-     * Refresh all rewrite urls for some store or for all stores
-     * Used to make full reindexing of url rewrites
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function refreshRewrites($storeId = null)
-    {
-        if (is_null($storeId)) {
-            foreach ($this->getStores() as $store) {
-                $this->refreshRewrites($store->getId());
-            }
-            return $this;
-        }
-
-        $this->clearStoreInvalidRewrites($storeId);
-        $this->refreshCategoryRewrite($this->getStores($storeId)->getRootCategoryId(), $storeId, false, false);
-        $this->refreshProductRewrites($storeId);
-        $this->getResource()->clearCategoryProduct($storeId);
-
-        return $this;
-    }
-
-    /**
-     * Refresh category rewrite
-     *
-     * @param \Magento\Framework\Object $category
-     * @param string $parentPath
-     * @param bool $refreshProducts
-     * @param bool $changeRequestPath
-     * @return $this
-     */
-    protected function _refreshCategoryRewrites(
-        \Magento\Framework\Object $category,
-        $parentPath = null,
-        $refreshProducts = true,
-        $changeRequestPath = false
-    ) {
-        if ($category->getId() != $this->getStores($category->getStoreId())->getRootCategoryId()) {
-            if ($category->getUrlKey() == '') {
-                $urlKey = $this->getCategoryModel()->formatUrlKey($category->getName());
-            } else {
-                $urlKey = $this->getCategoryModel()->formatUrlKey($category->getUrlKey());
-            }
-
-            $idPath = $this->generatePath('id', null, $category);
-            $targetPath = $this->generatePath('target', null, $category);
-            $requestPath = $this->getCategoryRequestPath($category, $parentPath, $changeRequestPath);
-
-            $rewriteData = array(
-                'store_id' => $category->getStoreId(),
-                'category_id' => $category->getId(),
-                'product_id' => null,
-                'id_path' => $idPath,
-                'request_path' => $requestPath,
-                'target_path' => $targetPath,
-                'is_system' => 1
-            );
-
-            $this->getResource()->saveRewrite($rewriteData, $this->_rewrite);
-
-            if ($this->getShouldSaveRewritesHistory($category->getStoreId())) {
-                $this->_saveRewriteHistory($rewriteData, $this->_rewrite);
-            }
-
-            if ($category->getUrlKey() != $urlKey) {
-                $category->setUrlKey($urlKey);
-                $this->getResource()->saveCategoryAttribute($category, 'url_key');
-            }
-            if ($category->getUrlPath() != $requestPath) {
-                $category->setUrlPath($requestPath);
-                $this->getResource()->saveCategoryAttribute($category, 'url_path');
-            }
-        } else {
-            if ($category->getUrlPath() != '') {
-                $category->setUrlPath('');
-                $this->getResource()->saveCategoryAttribute($category, 'url_path');
-            }
-        }
-
-        if ($refreshProducts) {
-            $this->_refreshCategoryProductRewrites($category);
-        }
-
-        foreach ($category->getChilds() as $child) {
-            $this->_refreshCategoryRewrites(
-                $child,
-                $category->getUrlPath() . '/',
-                $refreshProducts,
-                $changeRequestPath
-            );
-        }
-
-        return $this;
-    }
-
-    /**
-     * Refresh product rewrite
-     *
-     * @param \Magento\Framework\Object $product
-     * @param \Magento\Framework\Object $category
-     * @return $this
-     */
-    protected function _refreshProductRewrite(\Magento\Framework\Object $product, \Magento\Framework\Object $category)
-    {
-        if ($category->getId() == $category->getPath()) {
-            return $this;
-        }
-        if ($product->getUrlKey() == '') {
-            $urlKey = $this->productUrl->formatUrlKey($product->getName());
-        } else {
-            $urlKey = $this->productUrl->formatUrlKey($product->getUrlKey());
-        }
-
-        $idPath = $this->generatePath('id', $product, $category);
-        $targetPath = $this->generatePath('target', $product, $category);
-        $requestPath = $this->getProductRequestPath($product, $category);
-
-        $categoryId = null;
-        $updateKeys = true;
-        if ($category->getLevel() > 1) {
-            $categoryId = $category->getId();
-            $updateKeys = false;
-        }
-
-        $rewriteData = array(
-            'store_id' => $category->getStoreId(),
-            'category_id' => $categoryId,
-            'product_id' => $product->getId(),
-            'id_path' => $idPath,
-            'request_path' => $requestPath,
-            'target_path' => $targetPath,
-            'is_system' => 1
-        );
-
-        $this->getResource()->saveRewrite($rewriteData, $this->_rewrite);
-
-        if ($this->getShouldSaveRewritesHistory($category->getStoreId())) {
-            $this->_saveRewriteHistory($rewriteData, $this->_rewrite);
-        }
-
-        if ($updateKeys && $product->getUrlKey() != $urlKey) {
-            $product->setUrlKey($urlKey);
-            $this->getResource()->saveProductAttribute($product, 'url_key');
-        }
-        if ($updateKeys && $product->getUrlPath() != $requestPath) {
-            $product->setUrlPath($requestPath);
-            $this->getResource()->saveProductAttribute($product, 'url_path');
-        }
-
-        return $this;
-    }
-
-    /**
-     * Refresh products for category
-     *
-     * @param \Magento\Framework\Object $category
-     * @return $this
-     */
-    protected function _refreshCategoryProductRewrites(\Magento\Framework\Object $category)
-    {
-        $originalRewrites = $this->_rewrites;
-        $process = true;
-        $lastEntityId = 0;
-        $firstIteration = true;
-        while ($process == true) {
-            $products = $this->getResource()->getProductsByCategory($category, $lastEntityId);
-            if (!$products) {
-                if ($firstIteration) {
-                    $this->getResource()->deleteCategoryProductStoreRewrites(
-                        $category->getId(),
-                        array(),
-                        $category->getStoreId()
-                    );
-                }
-                $process = false;
-                break;
-            }
-
-            // Prepare rewrites for generation
-            $rootCategory = $this->getStoreRootCategory($category->getStoreId());
-            $categoryIds = array($category->getId(), $rootCategory->getId());
-            $this->_rewrites = $this->getResource()->prepareRewrites(
-                $category->getStoreId(),
-                $categoryIds,
-                array_keys($products)
-            );
-
-            foreach ($products as $product) {
-                // Product always must have rewrite in root category
-                $this->_refreshProductRewrite($product, $rootCategory);
-                $this->_refreshProductRewrite($product, $category);
-            }
-            $firstIteration = false;
-            unset($products);
-        }
-        $this->_rewrites = $originalRewrites;
-        return $this;
-    }
-
-    /**
-     * Refresh category and children rewrites
-     * Called when reindexing all rewrites and as a reaction on category change that affects rewrites
-     *
-     * @param int $categoryId
-     * @param int|null $storeId
-     * @param bool $refreshProducts
-     * @param bool $changeRequestPath
-     * @return $this
-     */
-    public function refreshCategoryRewrite(
-        $categoryId,
-        $storeId = null,
-        $refreshProducts = true,
-        $changeRequestPath = false
-    ) {
-        if (is_null($storeId)) {
-            foreach ($this->getStores() as $store) {
-                $this->refreshCategoryRewrite($categoryId, $store->getId(), $refreshProducts, $changeRequestPath);
-            }
-            return $this;
-        }
-
-        $category = $this->getResource()->getCategory($categoryId, $storeId);
-        if (!$category) {
-            return $this;
-        }
-
-        // Load all childs and refresh all categories
-        $category = $this->getResource()->loadCategoryChilds($category);
-        $categoryIds = array($category->getId());
-        if ($category->getAllChilds()) {
-            $categoryIds = array_merge($categoryIds, array_keys($category->getAllChilds()));
-        }
-        $this->_rewrites = $this->getResource()->prepareRewrites($storeId, $categoryIds);
-        $this->_refreshCategoryRewrites($category, null, $refreshProducts, $changeRequestPath);
-
-        unset($category);
-        $this->_rewrites = array();
-
-        return $this;
-    }
-
-    /**
-     * Refresh product rewrite urls for one store or all stores
-     * Called as a reaction on product change that affects rewrites
-     *
-     * @param int $productId
-     * @param int|null $storeId
-     * @return $this
-     */
-    public function refreshProductRewrite($productId, $storeId = null)
-    {
-        if (is_null($storeId)) {
-            foreach ($this->getStores() as $store) {
-                $this->refreshProductRewrite($productId, $store->getId());
-            }
-            return $this;
-        }
-
-        $product = $this->getResource()->getProduct($productId, $storeId);
-        if ($product) {
-            $store = $this->getStores($storeId);
-            $storeRootCategoryId = $store->getRootCategoryId();
-
-            // List of categories the product is assigned to, filtered by being within the store's categories root
-            $categories = $this->getResource()->getCategories($product->getCategoryIds(), $storeId);
-            $this->_rewrites = $this->getResource()->prepareRewrites($storeId, '', $productId);
-
-            // Add rewrites for all needed categories
-            // If product is assigned to any of store's categories -
-            // we also should use store root category to create root product url rewrite
-            if (!isset($categories[$storeRootCategoryId])) {
-                $categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
-            }
-
-            // Create product url rewrites
-            foreach ($categories as $category) {
-                $this->_refreshProductRewrite($product, $category);
-            }
-
-            // Remove all other product rewrites created earlier for this store - they're invalid now
-            $excludeCategoryIds = array_keys($categories);
-            $this->getResource()->clearProductRewrites($productId, $storeId, $excludeCategoryIds);
-
-            unset($categories);
-            unset($product);
-        } else {
-            // Product doesn't belong to this store - clear all its url rewrites including root one
-            $this->getResource()->clearProductRewrites($productId, $storeId, array());
-        }
-
-        return $this;
-    }
-
-    /**
-     * Refresh all product rewrites for designated store
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function refreshProductRewrites($storeId)
-    {
-        $this->_categories = array();
-        $storeRootCategoryId = $this->getStores($storeId)->getRootCategoryId();
-        $storeRootCategoryPath = $this->getStores($storeId)->getRootCategoryPath();
-        $this->_categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
-
-        $lastEntityId = 0;
-        $process = true;
-
-        while ($process == true) {
-            $products = $this->getResource()->getProductsByStore($storeId, $lastEntityId);
-            if (!$products) {
-                $process = false;
-                break;
-            }
-
-            $this->_rewrites = $this->getResource()->prepareRewrites($storeId, false, array_keys($products));
-
-            $loadCategories = array();
-            foreach ($products as $product) {
-                foreach ($product->getCategoryIds() as $categoryId) {
-                    if (!isset($this->_categories[$categoryId])) {
-                        $loadCategories[$categoryId] = $categoryId;
-                    }
-                }
-            }
-
-            if ($loadCategories) {
-                foreach ($this->getResource()->getCategories($loadCategories, $storeId) as $category) {
-                    $this->_categories[$category->getId()] = $category;
-                }
-            }
-
-            foreach ($products as $product) {
-                $this->_refreshProductRewrite($product, $this->_categories[$storeRootCategoryId]);
-                foreach ($product->getCategoryIds() as $categoryId) {
-                    if ($categoryId != $storeRootCategoryId && isset($this->_categories[$categoryId])) {
-                        if (strpos($this->_categories[$categoryId]['path'], $storeRootCategoryPath . '/') !== 0) {
-                            continue;
-                        }
-                        $this->_refreshProductRewrite($product, $this->_categories[$categoryId]);
-                    }
-                }
-            }
-
-            unset($products);
-            $this->_rewrites = array();
-        }
-
-        $this->_categories = array();
-        return $this;
-    }
-
-    /**
-     * Deletes old rewrites for store, left from the times when store had some other root category
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function clearStoreInvalidRewrites($storeId = null)
-    {
-        if (is_null($storeId)) {
-            foreach ($this->getStores() as $store) {
-                $this->clearStoreInvalidRewrites($store->getId());
-            }
-            return $this;
-        }
-
-        $this->getResource()->clearStoreInvalidRewrites($storeId);
-        return $this;
-    }
-
-    /**
-     * Get requestPath that was not used yet
-     *
-     * Will try to get unique path by adding -1 -2 etc. between url_key and optional url_suffix
-     *
-     * @param int $storeId
-     * @param string $requestPath
-     * @param string $idPath
-     * @param string $urlKey
-     * @return string
-     */
-    public function getUnusedPath($storeId, $requestPath, $idPath, $urlKey)
-    {
-        if (strpos($idPath, 'product') !== false) {
-            $suffix = $this->getProductUrlSuffix($storeId);
-        } else {
-            $suffix = $this->getCategoryUrlSuffix($storeId);
-        }
-        if (empty($requestPath)) {
-            $requestPath = '-';
-        } elseif ($requestPath == $suffix) {
-            $requestPath = '-' . $suffix;
-        }
-
-        /**
-         * Validate maximum length of request path
-         */
-        if (strlen($requestPath) > self::MAX_REQUEST_PATH_LENGTH + self::ALLOWED_REQUEST_PATH_OVERFLOW) {
-            $requestPath = substr($requestPath, 0, self::MAX_REQUEST_PATH_LENGTH);
-        }
-
-        if (isset($this->_rewrites[$idPath])) {
-            $this->_rewrite = $this->_rewrites[$idPath];
-            if ($this->_rewrites[$idPath]->getRequestPath() == $requestPath) {
-                return $requestPath;
-            }
-        } else {
-            $this->_rewrite = null;
-        }
-
-        $rewrite = $this->getResource()->getRewriteByRequestPath($requestPath, $storeId);
-        if ($rewrite && $rewrite->getId()) {
-            if ($rewrite->getIdPath() == $idPath) {
-                $this->_rewrite = $rewrite;
-                return $requestPath;
-            }
-            // match request_url {$urlKey}(-12)(.html) pattern
-            $match = array();
-            $suffix = preg_quote($suffix);
-            $quotedUrlKey = preg_quote($urlKey);
-            $regularExpression = "#(?P<urlKey>{$quotedUrlKey})(\\-(?P<copyNum>[0-9]+))?(?P<suffix>{$suffix})?\$#i";
-            if (!preg_match($regularExpression, $requestPath, $match)) {
-                return $this->getUnusedPath($storeId, '-', $idPath, $urlKey);
-            }
-            $match['urlKey'] = $match['urlKey'] . '-';
-            $match['suffix'] = isset($match['suffix']) ? $match['suffix'] : '';
-
-            $lastRequestPath = $this->getResource()->getLastUsedRewriteRequestIncrement(
-                $match['urlKey'],
-                $match['suffix'],
-                $storeId
-            );
-            if ($lastRequestPath) {
-                $match['copyNum'] = $lastRequestPath;
-            }
-            return $match['urlKey'] . (isset($match['copyNum']) ? $match['copyNum'] + 1 : '1') . $match['suffix'];
-        } else {
-            return $requestPath;
-        }
-    }
-
-    /**
-     * Retrieve product rewrite sufix for store
-     *
-     * @param int $storeId
-     * @return string
-     */
-    public function getProductUrlSuffix($storeId)
-    {
-        return $this->_catalogProduct->getProductUrlSuffix($storeId);
-    }
-
-    /**
-     * Retrieve category rewrite sufix for store
-     *
-     * @param int $storeId
-     * @return string
-     */
-    public function getCategoryUrlSuffix($storeId)
-    {
-        return $this->_catalogCategory->getCategoryUrlSuffix($storeId);
-    }
-
-    /**
-     * Get unique category request path
-     *
-     * @param \Magento\Framework\Object $category
-     * @param string $parentPath
-     * @param bool $changeRequestPath
-     * @return string
-     */
-    public function getCategoryRequestPath($category, $parentPath, $changeRequestPath = false)
-    {
-        $storeId = $category->getStoreId();
-        $idPath = $this->generatePath('id', null, $category);
-        $categoryUrlSuffix = $this->getCategoryUrlSuffix($storeId);
-        $pathSuffix = '(\-[0-9]+)?';
-        if (isset($this->_rewrites[$idPath])) {
-            $this->_rewrite = $this->_rewrites[$idPath];
-            $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath();
-        }
-
-        if ($category->getUrlKey() == '') {
-            $urlKey = $this->getCategoryModel()->formatUrlKey($category->getName());
-        } else {
-            $urlKey = $this->getCategoryModel()->formatUrlKey($category->getUrlKey());
-        }
-
-        if (null === $parentPath) {
-            $parentPath = $this->getResource()->getCategoryParentPath($category);
-        } elseif ($parentPath == '/') {
-            $parentPath = '';
-        }
-        $parentPath = $this->_catalogCategory->getCategoryUrlPath($parentPath, true, $storeId);
-
-        $requestPath = $parentPath . $urlKey;
-        if ($changeRequestPath) {
-            $pathSuffix = '';
-        }
-        $regexp = '/^' . preg_quote($requestPath, '/') . $pathSuffix . preg_quote($categoryUrlSuffix, '/') . '$/i';
-        if (isset($existingRequestPath) && preg_match($regexp, $existingRequestPath)) {
-            return $existingRequestPath;
-        }
-
-        $fullPath = $requestPath . $categoryUrlSuffix;
-        if ($this->_deleteOldTargetPath($fullPath, $idPath, $storeId)) {
-            return $requestPath;
-        }
-
-        return $this->getUnusedPath($storeId, $fullPath, $this->generatePath('id', null, $category), $urlKey);
-    }
-
-    /**
-     * Check if current generated request path is one of the old paths
-     *
-     * @param string $requestPath
-     * @param string $idPath
-     * @param int $storeId
-     * @return bool
-     */
-    protected function _deleteOldTargetPath($requestPath, $idPath, $storeId)
-    {
-        $finalOldTargetPath = $this->getResource()->findFinalTargetPath($requestPath, $storeId);
-        if ($finalOldTargetPath && $finalOldTargetPath == $idPath) {
-            $this->getResource()->deleteRewriteRecord($requestPath, $storeId, true);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Get unique product request path
-     *
-     * @param   \Magento\Framework\Object $product
-     * @param   \Magento\Framework\Object $category
-     * @return  string
-     */
-    public function getProductRequestPath($product, $category)
-    {
-        if ($product->getUrlKey() == '') {
-            $urlKey = $this->productUrl->formatUrlKey($product->getName());
-        } else {
-            $urlKey = $this->productUrl->formatUrlKey($product->getUrlKey());
-        }
-        $storeId = $category->getStoreId();
-        $suffix = $this->getProductUrlSuffix($storeId);
-        $idPath = $this->generatePath('id', $product, $category);
-        /**
-         * Prepare product base request path
-         */
-        if ($category->getLevel() > 1) {
-            // To ensure, that category has path either from attribute or generated now
-            $this->_addCategoryUrlPath($category);
-            $categoryUrl = $this->_catalogCategory->getCategoryUrlPath($category->getUrlPath(), false, $storeId);
-            $requestPath = $categoryUrl . '/' . $urlKey;
-        } else {
-            $requestPath = $urlKey;
-        }
-
-        if (strlen($requestPath) > self::MAX_REQUEST_PATH_LENGTH + self::ALLOWED_REQUEST_PATH_OVERFLOW) {
-            $requestPath = substr($requestPath, 0, self::MAX_REQUEST_PATH_LENGTH);
-        }
-
-        $this->_rewrite = null;
-        /**
-         * Check $requestPath should be unique
-         */
-        if (isset($this->_rewrites[$idPath])) {
-            $this->_rewrite = $this->_rewrites[$idPath];
-            $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath();
-
-            $regexp = '/^' . preg_quote($requestPath, '/') . '(\-[0-9]+)?' . preg_quote($suffix, '/') . '$/i';
-            if (preg_match($regexp, $existingRequestPath)) {
-                return $existingRequestPath;
-            }
-
-            $existingRequestPath = preg_replace('/' . preg_quote($suffix, '/') . '$/', '', $existingRequestPath);
-            /**
-             * Check if existing request past can be used
-             */
-            if ($product->getUrlKey() == '' && !empty($requestPath) && strpos($existingRequestPath, $requestPath) === 0
-            ) {
-                $existingRequestPath = preg_replace(
-                    '/^' . preg_quote($requestPath, '/') . '/',
-                    '',
-                    $existingRequestPath
-                );
-                if (preg_match('#^-([0-9]+)$#i', $existingRequestPath)) {
-                    return $this->_rewrites[$idPath]->getRequestPath();
-                }
-            }
-
-            $fullPath = $requestPath . $suffix;
-            if ($this->_deleteOldTargetPath($fullPath, $idPath, $storeId)) {
-                return $fullPath;
-            }
-        }
-        /**
-         * Check 2 variants: $requestPath and $requestPath . '-' . $productId
-         */
-        $validatedPath = $this->getResource()->checkRequestPaths(
-            array($requestPath . $suffix, $requestPath . '-' . $product->getId() . $suffix),
-            $storeId
-        );
-
-        if ($validatedPath) {
-            return $validatedPath;
-        }
-        /**
-         * Use unique path generator
-         */
-        return $this->getUnusedPath($storeId, $requestPath . $suffix, $idPath, $urlKey);
-    }
-
-    /**
-     * Generate either id path, request path or target path for product and/or category
-     *
-     * For generating id or system path, either product or category is required
-     * For generating request path - category is required
-     * $parentPath used only for generating category path
-     *
-     * @param string $type
-     * @param \Magento\Framework\Object $product
-     * @param \Magento\Framework\Object $category
-     * @param string $parentPath
-     * @return string
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function generatePath($type = 'target', $product = null, $category = null, $parentPath = null)
-    {
-        if (!$product && !$category) {
-            throw new \Magento\Framework\Model\Exception(__('Please specify either a category or a product, or both.'));
-        }
-
-        // generate id_path
-        if ('id' === $type) {
-            if (!$product) {
-                return 'category/' . $category->getId();
-            }
-            if ($category && $category->getLevel() > 1) {
-                return 'product/' . $product->getId() . '/' . $category->getId();
-            }
-            return 'product/' . $product->getId();
-        }
-
-        // generate request_path
-        if ('request' === $type) {
-            // for category
-            if (!$product) {
-                if ($category->getUrlKey() == '') {
-                    $urlKey = $this->getCategoryModel()->formatUrlKey($category->getName());
-                } else {
-                    $urlKey = $this->getCategoryModel()->formatUrlKey($category->getUrlKey());
-                }
-
-                $categoryUrlSuffix = $this->getCategoryUrlSuffix($category->getStoreId());
-                if (null === $parentPath) {
-                    $parentPath = $this->getResource()->getCategoryParentPath($category);
-                } elseif ($parentPath == '/') {
-                    $parentPath = '';
-                }
-                $parentPath = $this->_catalogCategory->getCategoryUrlPath($parentPath, true, $category->getStoreId());
-
-                return $this->getUnusedPath(
-                    $category->getStoreId(),
-                    $parentPath . $urlKey . $categoryUrlSuffix,
-                    $this->generatePath('id', null, $category),
-                    $urlKey
-                );
-            }
-
-            // for product & category
-            if (!$category) {
-                throw new \Magento\Framework\Model\Exception(
-                    __('A category object is required for determining the product request path.')
-                );
-            }
-
-            if ($product->getUrlKey() == '') {
-                $urlKey = $this->productUrl->formatUrlKey($product->getName());
-            } else {
-                $urlKey = $this->productUrl->formatUrlKey($product->getUrlKey());
-            }
-            $productUrlSuffix = $this->getProductUrlSuffix($category->getStoreId());
-            if ($category->getLevel() > 1) {
-                // To ensure, that category has url path either from attribute or generated now
-                $this->_addCategoryUrlPath($category);
-                $categoryUrl = $this->_catalogCategory->getCategoryUrlPath(
-                    $category->getUrlPath(),
-                    false,
-                    $category->getStoreId()
-                );
-                return $this->getUnusedPath(
-                    $category->getStoreId(),
-                    $categoryUrl . '/' . $urlKey . $productUrlSuffix,
-                    $this->generatePath('id', $product, $category),
-                    $urlKey
-                );
-            }
-
-            // for product only
-            return $this->getUnusedPath(
-                $category->getStoreId(),
-                $urlKey . $productUrlSuffix,
-                $this->generatePath('id', $product),
-                $urlKey
-            );
-        }
-
-        // generate target_path
-        if (!$product) {
-            return 'catalog/category/view/id/' . $category->getId();
-        }
-        if ($category && $category->getLevel() > 1) {
-            return 'catalog/product/view/id/' . $product->getId() . '/category/' . $category->getId();
-        }
-        return 'catalog/product/view/id/' . $product->getId();
-    }
-
-    /**
-     * Return unique string based on the time in microseconds.
-     *
-     * @return string
-     */
-    public function generateUniqueIdPath()
-    {
-        return str_replace('.', '_', uniqid(\Magento\Framework\Math\Random::getRandomNumber(), true));
-    }
-
-    /**
-     * Create Custom URL Rewrite for old product/category URL after url_key changed
-     * It will perform permanent redirect from old URL to new URL
-     *
-     * @param array $rewriteData New rewrite data
-     * @param \Magento\Framework\Object $rewrite Rewrite model
-     * @return $this
-     */
-    protected function _saveRewriteHistory($rewriteData, $rewrite)
-    {
-        if ($rewrite instanceof \Magento\Framework\Object && $rewrite->getId()) {
-            $rewriteData['target_path'] = $rewriteData['request_path'];
-            $rewriteData['request_path'] = $rewrite->getRequestPath();
-            $rewriteData['id_path'] = $this->generateUniqueIdPath();
-            $rewriteData['is_system'] = 0;
-            $rewriteData['options'] = 'RP';
-            // Redirect = Permanent
-            $this->getResource()->saveRewriteHistory($rewriteData);
-        }
-
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Catalog/Pricing/Render.php b/app/code/Magento/Catalog/Pricing/Render.php
index 80c7a931d4d..a1ce65ffab0 100644
--- a/app/code/Magento/Catalog/Pricing/Render.php
+++ b/app/code/Magento/Catalog/Pricing/Render.php
@@ -35,7 +35,6 @@ use Magento\Framework\Pricing\Render as PricingRender;
  *
  * @method string getPriceRender()
  * @method string getPriceTypeCode()
- * @method string getDisplayMsrpHelpMessage()
  */
 class Render extends Template
 {
diff --git a/app/code/Magento/Catalog/Pricing/Render/ConfiguredPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/ConfiguredPriceBox.php
index 4bba39b6d45..4edb1a3037b 100644
--- a/app/code/Magento/Catalog/Pricing/Render/ConfiguredPriceBox.php
+++ b/app/code/Magento/Catalog/Pricing/Render/ConfiguredPriceBox.php
@@ -38,7 +38,7 @@ class ConfiguredPriceBox extends FinalPriceBox
      */
     protected function _prepareLayout()
     {
-        /** @var $price \Magento\Bundle\Pricing\Price\ConfiguredPrice */
+        /** @var $price \Magento\Catalog\Pricing\Price\ConfiguredPrice */
         $price = $this->getPrice();
         /** @var $renderBlock \Magento\Catalog\Pricing\Render */
         $renderBlock = $this->getRenderBlock();
diff --git a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
index 4941a5bf974..a0c10b1f211 100644
--- a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
+++ b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
@@ -25,7 +25,7 @@
 namespace Magento\Catalog\Pricing\Render;
 
 use Magento\Framework\Pricing\Render\PriceBox as BasePriceBox;
-use Magento\Catalog\Pricing\Price\MsrpPrice;
+use Magento\Msrp\Pricing\Price\MsrpPrice;
 use Magento\Framework\Pricing\Render;
 use Magento\Catalog\Pricing\Price;
 
@@ -52,8 +52,9 @@ class FinalPriceBox extends BasePriceBox
             return $this->wrapResult($result);
         }
 
-        //Renders MAP price in case it is enabled
-        if ($msrpPriceType->canApplyMsrp($this->getSaleableItem())) {
+        //Renders MSRP in case it is enabled
+        $product = $this->getSaleableItem();
+        if ($msrpPriceType->canApplyMsrp($product) && $msrpPriceType->isMinimalPriceLessMsrp($product)) {
             /** @var BasePriceBox $msrpBlock */
             $msrpBlock = $this->rendererPool->createPriceRender(
                 MsrpPrice::PRICE_CODE,
@@ -92,7 +93,7 @@ class FinalPriceBox extends BasePriceBox
         return $this->renderAmount(
             $price->getMinimalPrice(),
             [
-                'display_label'     => __('As low as:'),
+                'display_label'     => __('As low as'),
                 'price_id'          => $id,
                 'include_container' => false,
                 'skip_adjustments' => true
diff --git a/app/code/Magento/Catalog/Pricing/Render/PriceBox.php b/app/code/Magento/Catalog/Pricing/Render/PriceBox.php
index 1909902f18a..cd812a098d1 100644
--- a/app/code/Magento/Catalog/Pricing/Render/PriceBox.php
+++ b/app/code/Magento/Catalog/Pricing/Render/PriceBox.php
@@ -36,7 +36,6 @@ use Magento\Framework\Math\Random;
  *
  * @method string getPriceElementIdPrefix()
  * @method string getIdSuffix()
- * @method string getDisplayMsrpHelpMessage()
  */
 class PriceBox extends PriceBoxRender
 {
diff --git a/app/code/Magento/Catalog/Service/V1/Product/TierPriceService.php b/app/code/Magento/Catalog/Service/V1/Product/TierPriceService.php
index e00443d1f8a..51f3a20764c 100644
--- a/app/code/Magento/Catalog/Service/V1/Product/TierPriceService.php
+++ b/app/code/Magento/Catalog/Service/V1/Product/TierPriceService.php
@@ -93,7 +93,6 @@ class TierPriceService implements TierPriceServiceInterface
     public function set($productSku, $customerGroupId, \Magento\Catalog\Service\V1\Data\Product\TierPrice $price)
     {
         $product = $this->productRepository->get($productSku, true);
-        $customerGroup = $this->customerGroupService->getGroup($customerGroupId);
 
         $tierPrices = $product->getData('tier_price');
         $websiteId = 0;
@@ -119,7 +118,7 @@ class TierPriceService implements TierPriceServiceInterface
         if (!$found) {
             $mappedCustomerGroupId = 'all' == $customerGroupId
                 ? \Magento\Customer\Service\V1\CustomerGroupServiceInterface::CUST_GROUP_ALL
-                : $customerGroup->getId();
+                : $this->customerGroupService->getGroup($customerGroupId)->getId();
 
             $tierPrices[] = array(
                 'cust_group' => $mappedCustomerGroupId,
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index fc9c4e764d0..5a75b0a230d 100644
--- a/app/code/Magento/Catalog/composer.json
+++ b/app/code/Magento/Catalog/composer.json
@@ -3,33 +3,33 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-index": "0.1.0-alpha96",
-        "magento/module-indexer": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-log": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-bundle": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-catalog-rule": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-catalog-search": "0.1.0-alpha96",
-        "magento/module-product-alert": "0.1.0-alpha96",
-        "magento/module-url-rewrite": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-indexer": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-log": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-msrp": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-catalog-rule": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-catalog-search": "0.1.0-alpha97",
+        "magento/module-product-alert": "0.1.0-alpha97",
+        "magento/module-url-rewrite": "0.1.0-alpha97",
+        "magento/module-catalog-url-rewrite": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.20-1.6.0.0.21.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.20-1.6.0.0.21.php
index 088a9af2438..f8656fc6134 100644
--- a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.20-1.6.0.0.21.php
+++ b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.20-1.6.0.0.21.php
@@ -94,7 +94,6 @@ $attributesOrder = array(
     ),
     //Autosettings tab
     'short_description' => array($autosettingsTabName => 0, 'is_required' => 0),
-    'url_key' => array($autosettingsTabName => 10),
     'visibility' => array($autosettingsTabName => 20, 'is_required' => 0),
     'news_from_date' => array($autosettingsTabName => 30),
     'news_to_date' => array($autosettingsTabName => 40),
diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.23-1.6.0.0.24.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.23-1.6.0.0.24.php
index faa56ca88e5..eaa6c462be4 100644
--- a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.23-1.6.0.0.24.php
+++ b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.23-1.6.0.0.24.php
@@ -45,20 +45,6 @@ $this->updateAttribute(
     'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight'
 );
 
-$this->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_enabled',
-    'frontend_input_renderer',
-    'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp\Enabled'
-);
-
-$this->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_display_actual_price_type',
-    'frontend_input_renderer',
-    'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp\Price'
-);
-
 $this->updateAttribute(
     \Magento\Catalog\Model\Category::ENTITY,
     'available_sort_by',
diff --git a/app/code/Magento/Rss/Controller/Index/Nofeed.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.28-1.6.0.0.29.php
similarity index 58%
rename from app/code/Magento/Rss/Controller/Index/Nofeed.php
rename to app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.28-1.6.0.0.29.php
index ed76be54cf7..7c64beec968 100644
--- a/app/code/Magento/Rss/Controller/Index/Nofeed.php
+++ b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.28-1.6.0.0.29.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,17 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Index;
+/** @var $this \Magento\Catalog\Model\Resource\Setup */
+$oldTabName = 'Search Optimization';
+$newTabName = 'Search Engine Optimization';
+$entityTypeId = $this->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY);
+$attributeSetId = $this->getAttributeSetId($entityTypeId, 'Default');
+$groupId = $this->getAttributeGroupId($entityTypeId, $attributeSetId, $oldTabName);
 
-class Nofeed extends \Magento\Rss\Controller\Index
-{
-    /**
-     * Display feed not found message
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $this->_rssHelper->sendEmptyRssFeed($this->getResponse());
-    }
-}
+$this->updateAttributeGroup($entityTypeId, $attributeSetId, $groupId, 'attribute_group_name', $newTabName);
+$this->updateAttributeGroup(
+    $entityTypeId,
+    $attributeSetId,
+    $groupId,
+    'attribute_group_code',
+    preg_replace('/[^a-z0-9]+/', '-', strtolower($newTabName))
+);
diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.3-1.6.0.0.4.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.3-1.6.0.0.4.php
deleted file mode 100644
index 23be7a82149..00000000000
--- a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.3-1.6.0.0.4.php
+++ /dev/null
@@ -1,54 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-$installer = $this;
-/** @var $installer \Magento\Catalog\Model\Resource\Setup */
-
-$installer->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_enabled',
-    'source_model',
-    'Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled'
-);
-
-$installer->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_enabled',
-    'default_value',
-    \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_USE_CONFIG
-);
-
-$installer->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_display_actual_price_type',
-    'source_model',
-    'Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price'
-);
-
-$installer->updateAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_display_actual_price_type',
-    'default_value',
-    \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price::TYPE_USE_CONFIG
-);
diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.5-1.6.0.0.6.php b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.5-1.6.0.0.6.php
index 18554e203a0..9e29094ab1c 100644
--- a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.5-1.6.0.0.6.php
+++ b/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.5-1.6.0.0.6.php
@@ -25,10 +25,6 @@
 /** @var $installer \Magento\Catalog\Model\Resource\Setup */
 $installer = $this;
 
-$installer->updateAttribute(\Magento\Catalog\Model\Product::ENTITY, 'url_key', 'frontend_label', 'URL Key');
-
-$installer->updateAttribute(\Magento\Catalog\Model\Category::ENTITY, 'url_key', 'frontend_label', 'URL Key');
-
 $installer->updateAttribute(
     \Magento\Catalog\Model\Product::ENTITY,
     'options_container',
diff --git a/app/code/Magento/Catalog/etc/acl.xml b/app/code/Magento/Catalog/etc/acl.xml
index d7e16006409..eaffab7aab3 100644
--- a/app/code/Magento/Catalog/etc/acl.xml
+++ b/app/code/Magento/Catalog/etc/acl.xml
@@ -33,11 +33,6 @@
                         <resource id="Magento_Catalog::categories" title="Categories" sortOrder="20" />
                     </resource>
                 </resource>
-                <resource id="Magento_Adminhtml::marketing">
-                    <resource id="Magento_Adminhtml::marketing_seo">
-                        <resource id="Magento_Catalog::urlrewrite" title="URL Redirects" sortOrder="20" />
-                    </resource>
-                </resource>
                 <resource id="Magento_Adminhtml::stores">
                     <resource id="Magento_Adminhtml::stores_settings">
                         <resource id="Magento_Adminhtml::config">
diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml
index b838bdd88f2..59df420f658 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/di.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml
@@ -76,4 +76,11 @@
             <argument name="frontendUrlBuilder" xsi:type="object">Magento\Framework\Url</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
+        <arguments>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="notifystock" xsi:type="string">Magento\Catalog\Block\Adminhtml\Rss\NotifyStock</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/etc/adminhtml/menu.xml b/app/code/Magento/Catalog/etc/adminhtml/menu.xml
index cd0ab536830..f8989dca2f8 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/menu.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/menu.xml
@@ -30,7 +30,6 @@
         <add id="Magento_Catalog::catalog_categories" title="Categories" module="Magento_Catalog" sortOrder="20" parent="Magento_Catalog::inventory" action="catalog/category/" resource="Magento_Catalog::categories"/>
         <add id="Magento_Catalog::catalog_attributes_attributes" title="Product" module="Magento_Catalog" sortOrder="30" parent="Magento_Backend::stores_attributes" action="catalog/product_attribute/" resource="Magento_Catalog::attributes_attributes"/>
         <add id="Magento_Catalog::catalog_attributes_sets" title="Product Template" module="Magento_Catalog" sortOrder="40" parent="Magento_Backend::stores_attributes" action="catalog/product_set/" resource="Magento_Catalog::sets"/>
-        <add id="Magento_Catalog::catalog_urlrewrite" title="URL Redirects" module="Magento_Catalog" sortOrder="20" parent="Magento_Backend::marketing_seo" action="adminhtml/urlrewrite/index" resource="Magento_Catalog::urlrewrite"/>
 
         <add id="Magento_Catalog::inventory" title="Inventory" module="Magento_Catalog" sortOrder="10" parent="Magento_Catalog::catalog" dependsOnModule="Magento_Catalog" resource="Magento_Catalog::catalog"/>
     </menu>
diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml
index 4d7523f5d05..8b1997ae903 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/system.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml
@@ -115,26 +115,7 @@
                 </field>
             </group>
             <group id="seo" translate="label" type="text" sortOrder="500" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Search Engine Optimizations</label>
-                <field id="category_url_suffix" translate="label comment" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Category URL Suffix</label>
-                    <backend_model>Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite\Suffix</backend_model>
-                    <comment>You need to refresh the cache.</comment>
-                </field>
-                <field id="product_url_suffix" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Product URL Suffix</label>
-                    <backend_model>Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite\Suffix</backend_model>
-                    <comment>You need to refresh the cache.</comment>
-                </field>
-                <field id="product_use_categories" translate="label" type="select" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Use Categories Path for Product URLs</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                    <backend_model>Magento\Catalog\Model\Config\Backend\Seo\Product</backend_model>
-                </field>
-                <field id="save_rewrites_history" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Create Permanent Redirect for URLs if URL Key Changed</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
+                <label>Search Engine Optimization</label>
                 <field id="title_separator" translate="label" type="text" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Page Title Separator</label>
                 </field>
@@ -218,29 +199,20 @@
                 </field>
             </group>
         </section>
-        <section id="sales">
-            <group id="msrp" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0">
-                <label>Minimum Advertised Price</label>
-                <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Enable MAP</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
-                <field id="apply_for_all" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Apply MAP (Default Value)</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                    <comment>
-                        <![CDATA[<strong style="color:red">Warning!</strong> Applying MAP by default will hide all product prices on the front end.]]>
-                    </comment>
-                </field>
-                <field id="display_price_type" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Display Actual Price</label>
-                    <source_model>Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type</source_model>
-                </field>
-                <field id="explanation_message" translate="label" type="textarea" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Default Popup Text Message</label>
-                </field>
-                <field id="explanation_message_whats_this" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Default "What's This" Text Message</label>
+        <section id="rss">
+            <group id="catalog" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Catalog</label>
+                <field id="new" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>New Products</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
+                </field>
+                <field id="special" translate="label" type="select" sortOrder="11" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Special Products</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
+                </field>
+                <field id="category" translate="label" type="select" sortOrder="14" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Top Level Category</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
                 </field>
             </group>
         </section>
diff --git a/app/code/Magento/Catalog/etc/catalog_attributes.xml b/app/code/Magento/Catalog/etc/catalog_attributes.xml
index d53e2b3a798..cbca919daff 100644
--- a/app/code/Magento/Catalog/etc/catalog_attributes.xml
+++ b/app/code/Magento/Catalog/etc/catalog_attributes.xml
@@ -26,12 +26,10 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Catalog/etc/catalog_attributes.xsd">
     <group name="catalog_category">
         <attribute name="name"/>
-        <attribute name="url_key"/>
         <attribute name="is_active"/>
     </group>
     <group name="catalog_product">
         <attribute name="name"/>
-        <attribute name="url_key"/>
         <attribute name="price"/>
         <attribute name="special_price"/>
         <attribute name="special_from_date"/>
diff --git a/app/code/Magento/Catalog/etc/config.xml b/app/code/Magento/Catalog/etc/config.xml
index 7b4d82ae76d..c469a96d446 100644
--- a/app/code/Magento/Catalog/etc/config.xml
+++ b/app/code/Magento/Catalog/etc/config.xml
@@ -74,14 +74,5 @@
                 </allowed_resources>
             </media_storage_configuration>
         </system>
-        <sales>
-            <msrp>
-                <enabled>0</enabled>
-                <apply_for_all>0</apply_for_all>
-                <display_price_type>1</display_price_type>
-                <explanation_message>Our price is lower than the manufacturer's "minimum advertised price." As a result, we cannot show you the price in catalog or the product page. &lt;br /&gt;&lt;br /&gt; You have no obligation to purchase the product once you know the price. You can simply remove the item from your cart.</explanation_message>
-                <explanation_message_whats_this>Our price is lower than the manufacturer's "minimum advertised price." As a result, we cannot show you the price in catalog or the product page. &lt;br /&gt;&lt;br /&gt; You have no obligation to purchase the product once you know the price. You can simply remove the item from your cart.</explanation_message_whats_this>
-            </msrp>
-        </sales>
     </default>
 </config>
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 455ad2b273b..d330ebfb2fb 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -104,9 +104,6 @@
                     <item name="special_from_date" xsi:type="string">special_from_date</item>
                     <item name="special_to_date" xsi:type="string">special_to_date</item>
                     <item name="website_ids" xsi:type="string">website_ids</item>
-                    <item name="msrp" xsi:type="string">msrp</item>
-                    <item name="msrp_enabled" xsi:type="string">msrp_enabled</item>
-                    <item name="msrp_display_actual_price_type" xsi:type="string">msrp_display_actual_price_type</item>
                     <item name="gift_wrapping_price" xsi:type="string">gift_wrapping_price</item>
                     <item name="tax_class_id" xsi:type="string">tax_class_id</item>
                 </item>
@@ -378,7 +375,6 @@
                 <item name="tier_price" xsi:type="string">Magento\Catalog\Pricing\Price\TierPrice</item>
                 <item name="group_price" xsi:type="string">Magento\Catalog\Pricing\Price\GroupPrice</item>
                 <item name="special_price" xsi:type="string">Magento\Catalog\Pricing\Price\SpecialPrice</item>
-                <item name="msrp_price" xsi:type="string">Magento\Catalog\Pricing\Price\MsrpPrice</item>
                 <item name="base_price" xsi:type="string">Magento\Catalog\Pricing\Price\BasePrice</item>
                 <item name="custom_option_price" xsi:type="string">Magento\Catalog\Pricing\Price\CustomOptionPrice</item>
                 <item name="configured_price" xsi:type="string">Magento\Catalog\Pricing\Price\ConfiguredPrice</item>
@@ -499,4 +495,15 @@
     <type name="Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock">
         <plugin name="showOutOfStockValueChanged" type="\Magento\Catalog\Model\Plugin\ShowOutOfStockConfig"/>
     </type>
+    <preference for="Magento\Catalog\Block\Category\Widget\Link" type="Magento\Catalog\Block\Widget\Link" />
+    <preference for="Magento\Catalog\Block\Product\Widget\Link" type="Magento\Catalog\Block\Widget\Link" />
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
+        <arguments>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="new_products" xsi:type="string">Magento\Catalog\Block\Rss\Product\NewProducts</item>
+                <item name="special_products" xsi:type="string">Magento\Catalog\Block\Rss\Product\Special</item>
+                <item name="category" xsi:type="string">Magento\Catalog\Block\Rss\Category</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/etc/eav_attributes.xml b/app/code/Magento/Catalog/etc/eav_attributes.xml
index 3ed356f546c..2f0d490cf19 100644
--- a/app/code/Magento/Catalog/etc/eav_attributes.xml
+++ b/app/code/Magento/Catalog/etc/eav_attributes.xml
@@ -29,9 +29,6 @@
             <field code="is_global" locked="true" />
             <field code="is_unique" locked="true" />
         </attribute>
-        <attribute code="url_key">
-            <field code="is_unique" locked="true" />
-        </attribute>
         <attribute code="status">
             <field code="is_filterable" locked="true" />
             <field code="is_filterable_in_search" locked="true" />
diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml
index 575f1f91c18..362c7d346fa 100644
--- a/app/code/Magento/Catalog/etc/module.xml
+++ b/app/code/Magento/Catalog/etc/module.xml
@@ -24,11 +24,10 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_Catalog" schema_version="1.6.0.0.28" active="true">
+    <module name="Magento_Catalog" schema_version="1.6.0.0.29" active="true">
         <sequence>
             <module name="Magento_Eav"/>
             <module name="Magento_Cms"/>
-            <module name="Magento_Index"/>
             <module name="Magento_Indexer"/>
             <module name="Magento_Customer"/>
         </sequence>
@@ -36,7 +35,6 @@
             <module name="Magento_Store"/>
             <module name="Magento_Eav"/>
             <module name="Magento_Cms"/>
-            <module name="Magento_Index"/>
             <module name="Magento_Indexer"/>
             <module name="Magento_Customer"/>
             <module name="Magento_Core"/>
@@ -47,14 +45,15 @@
             <module name="Magento_Widget"/>
             <module name="Magento_Wishlist"/>
             <module name="Magento_Tax"/>
-            <module name="Magento_Bundle"/>
             <module name="Magento_CatalogInventory"/>
             <module name="Magento_Directory"/>
             <module name="Magento_CatalogRule"/>
             <module name="Magento_Sales"/>
             <module name="Magento_CatalogSearch"/>
             <module name="Magento_ProductAlert"/>
+            <module name="Magento_CatalogUrlRewrite"/>
             <module name="Magento_UrlRewrite"/>
+            <module name="Magento_Msrp" />
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Catalog/i18n/de_DE.csv b/app/code/Magento/Catalog/i18n/de_DE.csv
index afcf15d94d3..5248fb6353e 100644
--- a/app/code/Magento/Catalog/i18n/de_DE.csv
+++ b/app/code/Magento/Catalog/i18n/de_DE.csv
@@ -255,7 +255,7 @@ Categories,Kategorien
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,Mitte
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Umschreibung der Katalog-URL"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv
index b90461bb4d0..5887784287b 100644
--- a/app/code/Magento/Catalog/i18n/en_US.csv
+++ b/app/code/Magento/Catalog/i18n/en_US.csv
@@ -255,7 +255,7 @@ Categories,Categories
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -340,8 +340,7 @@ Center,Center
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Catalog URL Rewrites"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/es_ES.csv b/app/code/Magento/Catalog/i18n/es_ES.csv
index c7f09578e43..d86c9b05058 100644
--- a/app/code/Magento/Catalog/i18n/es_ES.csv
+++ b/app/code/Magento/Catalog/i18n/es_ES.csv
@@ -255,7 +255,7 @@ Categories,Categorías
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,Centro
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Nueva versión de URL de Catálogo"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/fr_FR.csv b/app/code/Magento/Catalog/i18n/fr_FR.csv
index a066af4b25e..4c2595d01bf 100644
--- a/app/code/Magento/Catalog/i18n/fr_FR.csv
+++ b/app/code/Magento/Catalog/i18n/fr_FR.csv
@@ -255,7 +255,7 @@ Categories,catégories
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,Centrer
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Catalogue Réécritures URL"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/nl_NL.csv b/app/code/Magento/Catalog/i18n/nl_NL.csv
index 06558ec32e2..8a3940a19a4 100644
--- a/app/code/Magento/Catalog/i18n/nl_NL.csv
+++ b/app/code/Magento/Catalog/i18n/nl_NL.csv
@@ -255,7 +255,7 @@ Categories,Categoriën
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,Centrum
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Catalogus URL Herschrijvingen"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/pt_BR.csv b/app/code/Magento/Catalog/i18n/pt_BR.csv
index 406868b73d4..5717e8f7b64 100644
--- a/app/code/Magento/Catalog/i18n/pt_BR.csv
+++ b/app/code/Magento/Catalog/i18n/pt_BR.csv
@@ -255,7 +255,7 @@ Categories,Categorias
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,Centro
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites","Reedições da URL de Catálogo"
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/i18n/zh_CN.csv b/app/code/Magento/Catalog/i18n/zh_CN.csv
index 117d5863497..9a431375ea5 100644
--- a/app/code/Magento/Catalog/i18n/zh_CN.csv
+++ b/app/code/Magento/Catalog/i18n/zh_CN.csv
@@ -255,7 +255,7 @@ Categories,分类
 "A total of %1 record(s) have been updated.","A total of %1 record(s) have been updated."
 "Something went wrong while updating the product(s) status.","Something went wrong while updating the product(s) status."
 "Please make sure to define SKU values for all processed products.","Please make sure to define SKU values for all processed products."
-"Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>.","Please refresh ""Catalog URL Rewrites"" and ""Product Attributes"" in System -> ' '<a href=""%1"">Index Management</a>."
+"Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>.","Please refresh "Product EAV" in System -> <a href="%1">Index Management</a>."
 "A total of %1 record(s) were updated.","A total of %1 record(s) were updated."
 "Something went wrong while updating the product(s) attributes.","Something went wrong while updating the product(s) attributes."
 "Please select products for attributes update.","Please select products for attributes update."
@@ -341,8 +341,7 @@ Center,中心
 "Bad value was supplied.","Bad value was supplied."
 "The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module","The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes."" ""Currently there are %1\$d of them."" ""Please reduce the number of filterable/sortable attributes in order to use this module"
 "Unsupported product type ""%1"".","Unsupported product type ""%1""."
-"Catalog URL Rewrites",分类URL重写
-"Index product and categories URL Redirects","Index product and categories URL Redirects"
+"Index product and categories URL Rewrites","Index product and categories URL Rewrites"
 "The category must be an instance of \Magento\Catalog\Model\Category.","The category must be an instance of \Magento\Catalog\Model\Category."
 "Please correct the category.","Please correct the category."
 "The attribute model is not defined.","The attribute model is not defined."
@@ -562,7 +561,7 @@ Comma-separated.,Comma-separated.
 "Allow Dynamic Media URLs in Products and Categories","Allow Dynamic Media URLs in Products and Categories"
 "E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance.","E.g. {{media url=""path/to/image.jpg""}} {{skin url=""path/to/picture.gif""}}. Dynamic directives parsing impacts catalog performance."
 "Product Image Placeholders","Product Image Placeholders"
-"Search Engine Optimizations","Search Engine Optimizations"
+"Search Engine Optimization","Search Engine Optimization"
 "Category URL Suffix","Category URL Suffix"
 "You need to refresh the cache.","You need to refresh the cache."
 "Product URL Suffix","Product URL Suffix"
@@ -589,12 +588,7 @@ Watermark,Watermark
 "This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes.","This applies only to catalog products and categories. Media content will be inserted into the editor as a static URL. Media content is not updated if the system configuration base URL changes."
 "Minimum Advertised Price","Minimum Advertised Price"
 "Enable MAP","Enable MAP"
-"Apply MAP (Default Value)","Apply MAP (Default Value)"
-"
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    ","
-                        <strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.
-                    "
+"<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end.","<strong style=""color:red"">Warning!</strong> Applying MAP by default will hide all product prices on the front end."
 "Display Actual Price","Display Actual Price"
 "Default Popup Text Message","Default Popup Text Message"
 "Default ""What's This"" Text Message","Default ""What's This"" Text Message"
diff --git a/app/code/Magento/Catalog/sql/catalog_setup/install-1.6.0.0.0.php b/app/code/Magento/Catalog/sql/catalog_setup/install-1.6.0.0.0.php
index 034a5a1721f..f72a40e8768 100644
--- a/app/code/Magento/Catalog/sql/catalog_setup/install-1.6.0.0.0.php
+++ b/app/code/Magento/Catalog/sql/catalog_setup/install-1.6.0.0.0.php
@@ -3886,42 +3886,4 @@ $table = $installer->getConnection()->newTable(
 );
 $installer->getConnection()->createTable($table);
 
-/**
- * Modify core/url_rewrite table
- */
-$installer->getConnection()->addColumn(
-    $installer->getTable('core_url_rewrite'),
-    'category_id',
-    array(
-        'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-        'unsigned' => true,
-        'nullable' => true,
-        'comment' => 'Category Id'
-    )
-);
-$installer->getConnection()->addColumn(
-    $installer->getTable('core_url_rewrite'),
-    'product_id',
-    array(
-        'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-        'unsigned' => true,
-        'nullable' => true,
-        'comment' => 'Product Id'
-    )
-);
-$installer->getConnection()->addForeignKey(
-    $installer->getFkName('core_url_rewrite', 'category_id', 'catalog_category_entity', 'entity_id'),
-    $installer->getTable('core_url_rewrite'),
-    'category_id',
-    $installer->getTable('catalog_category_entity'),
-    'entity_id'
-);
-$installer->getConnection()->addForeignKey(
-    $installer->getFkName('core_url_rewrite', 'product_id', 'catalog_category_entity', 'entity_id'),
-    $installer->getTable('core_url_rewrite'),
-    'product_id',
-    $installer->getTable('catalog_product_entity'),
-    'entity_id'
-);
-
 $installer->endSetup();
diff --git a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_category_edit.xml b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_category_edit.xml
index 973318d8c40..9a49726e053 100644
--- a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_category_edit.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_category_edit.xml
@@ -25,18 +25,10 @@
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="editor"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-catalog-js-bootstrap-category-edit-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Catalog::js/bootstrap/category-edit.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <link src="Magento_Catalog::js/bootstrap/category-edit.js"/>
+    </head>
     <referenceContainer name="page.main.actions">
         <block class="Magento\Backend\Block\Store\Switcher" name="category.store.switcher" template="Magento_Backend::store/switcher.phtml">
             <!--<arguments>-->
@@ -60,5 +52,4 @@
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="catalog_category_page_head_components" template="Magento_Catalog::js/components.phtml"/>
     </referenceBlock>
-
 </page>
diff --git a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_index.xml b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_index.xml
index 081ab5359bc..4ee8fbba745 100644
--- a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_index.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_index.xml
@@ -44,4 +44,9 @@
     <referenceContainer name="content">
         <block class="Magento\Catalog\Block\Adminhtml\Product" name="products_list"/>
     </referenceContainer>
+    <referenceContainer name="product.grid">
+        <block class="Magento\Framework\View\Element\Text\ListText" name="grid.bottom.links">
+            <block class="Magento\Catalog\Block\Adminhtml\Rss\Grid\Link" name="grid.rss.link"/>
+        </block>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_new.xml b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_new.xml
index fffeacc4ff8..40c23d672cd 100644
--- a/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_new.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_new.xml
@@ -25,28 +25,12 @@
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="editor"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-adminhtml-catalog-category-selector-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Catalog::catalog/category-selector.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-catalog-product-product-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Catalog::product/product.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-catalog-js-bootstrap-product-new-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Catalog::js/bootstrap/product-new.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <css src="Magento_Catalog::catalog/category-selector.css"/>
+        <css src="Magento_Catalog::product/product.css"/>
+        <link src="Magento_Catalog::js/bootstrap/product-new.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Catalog\Block\Adminhtml\Product\Edit" name="product_edit">
             <container name="product-type-tabs" label="Tabs">
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
index 350f61365cc..698ead9021d 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/edit/form.phtml
@@ -52,14 +52,92 @@
     </div>
     <div id="category_tab_content"></div>
 </form>
+<div data-id="information-dialog-category" style="display: none;">
+    <span class="information-message"><?php echo __('This operation can take much time'); ?><span>
+</div>
 <script type="text/javascript">
-require(['jquery', "mage/mage"], function($){
+require(['jquery', 'jquery/ui', "mage/mage"], function($){
+    var mageDialog = (function($) {
+        var self = {dialogOpened: false, callback: [], needShow: false};
+
+        self.callback = {ok: [], cancel: []};
+        self.createDialog = function () {
+            var onEvent = function (type, dialog) {
+                self.callback[type].forEach(function(call) {
+                    call();
+                });
+                $(dialog).dialog( "close" );
+            };
+
+            self.dialog = $('[data-id="information-dialog-category"]').dialog({
+                autoOpen:   false,
+                modal:      true,
+                dialogClass: 'popup-window',
+                resizable: false,
+                title: $.mage.__('Warning message'),
+                buttons: [
+                    {text: $.mage.__('Ok'), click: function() { onEvent('ok', this); }},
+                    {text: $.mage.__('Cancel'), click: function() { onEvent('cancel', this); } }
+                ],
+                open: function () {
+                    self.dialogOpened = true;
+                    self.callback.ok.push(function() {
+                        self.needShow = false;
+                    });
+                },
+                close: function(event, ui) {
+                    $(this).dialog('destroy');
+                    self.dialogOpened = false;
+                    self.callback = {ok: [], cancel: []};
+                    delete self.dialog;
+                }
+            });
+        };
+
+        return {
+            needToShow: function() {
+                self.needShow = true &&
+                    !!$('[data-ui-id="tabs-tab-general-information-fieldset-element-hidden-general-id"]').length;
+                return this;
+            },
+            isNeedShow: function() {
+                return self.needShow;
+            },
+            onOk: function(call) {
+                self.callback.ok.push(call);
+                return this;
+            },
+            onCancel: function(call) {
+                self.callback.cancel.push(call);
+                return this;
+            },
+            show: function() {
+                if (self.dialog == undefined) {
+                    self.createDialog();
+                }
+                if (self.dialogOpened ==  false) {
+                    self.dialog.dialog('open');
+                }
+                return this;
+            }
+        };
+    })(jQuery);
+    $(document).on('change', '[data-ui-id="urlkeyrenderer-text-general-url-key"]', function() {
+        mageDialog.needToShow();
+    });
     $.mage.extend('categoryForm', 'form', 'Magento_Catalog/catalog/category/form');
     $('#category_edit_form')
         .mage('categoryForm', {refreshUrl: '<?php echo $this->getRefreshPathUrl() ?>'})
         .mage('validation', {submitHandler: function(form){
-            form.submit();
-            displayLoadingMask();
+            if (mageDialog.isNeedShow()) {
+                mageDialog.onOk(function() {
+                    form.submit();
+                    displayLoadingMask();
+                }).show();
+            } else {
+                form.submit();
+                displayLoadingMask();
+            }
         }});
 });
 
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
index 1643882c838..e721c3d5011 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml
@@ -44,9 +44,12 @@
         <div id="tree-div" style="width:100%; overflow:auto;"></div>
     </div>
 </div>
+<div data-id="information-dialog-tree" style="display: none;">
+    <span class="messages"><?php echo __('This operation can take much time'); ?><span>
+</div>
 <script type="text/javascript">
 var tree;
-require(["jquery", "prototype", "mage/adminhtml/form"], function(jQuery){
+require(["jquery", "jquery/ui", "prototype", "mage/adminhtml/form", "mage/translate"], function(jQuery){
 
 /**
  * Fix ext compatibility with prototype 1.6
@@ -394,6 +397,63 @@ function addNew(url, isRoot) {
     updateContent(url);
 }
 
+var mageDialog = (function($) {
+    var self = {dialogOpened: false, callback: []};
+
+    self.callback = {ok: [], cancel: []};
+    self.createDialog = function () {
+        var onEvent = function (type, dialog) {
+            self.callback[type].forEach(function(call) {
+                call();
+            });
+            $(dialog).dialog( "close" );
+        };
+        var _resetState = function() {
+            self.dialogOpened = false;
+            self.callback = {ok: [], cancel: []};
+            delete self.dialog;
+        };
+        self.dialog = $('[data-id="information-dialog-category"]').dialog({
+            autoOpen:   false,
+            modal:      true,
+            dialogClass: 'popup-window',
+            resizable: false,
+            title: $.mage.__('Warning message'),
+            buttons: [
+                {text: $.mage.__('Ok'), click: function() { onEvent('ok', this); }},
+                {text: $.mage.__('Cancel'), click: function() { onEvent('cancel', this); } }
+            ],
+            open: function () {
+                self.dialogOpened = true;
+            },
+            close: function(event, ui) {
+                $(this).dialog('destroy');
+                _resetState();
+            }
+        });
+    };
+
+    return {
+        onOk: function(call) {
+            self.callback.ok.push(call);
+            return this;
+        },
+        onCancel: function(call) {
+            self.callback.cancel.push(call);
+            return this;
+        },
+        show: function() {
+            if (self.dialog == undefined) {
+                self.createDialog();
+            }
+            if (self.dialogOpened ==  false) {
+                self.dialog.dialog('open');
+            }
+            return this;
+        }
+    };
+})(jQuery);
+
 function categoryMove(obj) {
     var data = {id:obj.dropNode.id, form_key:FORM_KEY};
 
@@ -455,17 +515,22 @@ function categoryMove(obj) {
         pd.push(encodeURIComponent(key), "=", encodeURIComponent(data[key]), "&");
     }
     pd.splice(pd.length - 1, 1);
-    new Ajax.Request(
+    mageDialog.onOk(function() {
+        new Ajax.Request(
             '<?php echo $this->getMoveUrl() ?>',
             {
                 method:'POST',
                 parameters:pd.join(""),
                 onSuccess:success,
-                onFailure:failure
+                onFailure: failure,
+                onCreate: function() { jQuery('body').loader('show'); },
+                onComplete: function() { jQuery('body').loader('hide'); }
             }
-    );
+        );
+    }).onCancel(function() {
+        reRenderTree();
+    }).show();
 }
-
     window.addNew = addNew;
 
 });
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
index 9f518c21062..4a36c8ff9b0 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
@@ -78,7 +78,7 @@ require([
     "mage/mage",
     "Magento_Catalog/catalog/type-switcher",
     "mage/backend/tabs",
-    "_"
+    "underscore"
 ], function($){
     var $form = $('[data-form=edit-product]');
     $form.data('typeSwitcher', new TypeSwitcher(<?php echo $this->getTypeSwitcherData();?>).bindAll());
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/rss/grid/link.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/rss/grid/link.phtml
new file mode 100644
index 00000000000..37559469d1c
--- /dev/null
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/rss/grid/link.phtml
@@ -0,0 +1,29 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+/** @var $this \Magento\Catalog\Block\Adminhtml\Rss\Grid\Link */
+?>
+<?php if ($this->isRssAllowed() && $this->getLink()): ?>
+<a href="<?php echo $this->getLink() ?>" class="link-feed"><?php echo $this->getLabel() ?></a>
+<?php endif; ?>
diff --git a/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml b/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml
index 41c1d2e3496..41e16a36ec4 100644
--- a/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml
+++ b/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml
@@ -45,10 +45,6 @@
                         <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\FinalPriceBox</item>
                         <item name="render_template" xsi:type="string">Magento_Catalog::product/price/final_price.phtml</item>
                     </item>
-                    <item name="msrp_price" xsi:type="array">
-                        <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\PriceBox</item>
-                        <item name="render_template" xsi:type="string">Magento_Catalog::product/price/msrp_price.phtml</item>
-                    </item>
                     <item name="custom_option_price" xsi:type="array">
                         <item name="amount_render_template" xsi:type="string">Magento_Catalog::product/price/amount/option.phtml</item>
                     </item>
diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/amount/default.phtml b/app/code/Magento/Catalog/view/base/templates/product/price/amount/default.phtml
index 7ef4ca3d468..3e99f4be3b1 100644
--- a/app/code/Magento/Catalog/view/base/templates/product/price/amount/default.phtml
+++ b/app/code/Magento/Catalog/view/base/templates/product/price/amount/default.phtml
@@ -29,16 +29,12 @@
     <?php if ($this->getDisplayLabel()): ?>
         <span class="price-label"><?php echo $this->getDisplayLabel(); ?></span>
     <?php endif; ?>
-    <span id="<?php echo $this->getPriceId() ?>"
-        <?php echo ($this->getPriceDisplayLabel()) ? 'data-label="' . $this->getPriceDisplayLabel() . '"' : '' ?>
-          class="price-wrapper <?php echo $this->getPriceWrapperCss();?>">
-        <span class="price">
-            <?php echo $this->convertAndFormatCurrency($this->getDisplayValue(), (bool) $this->getIncludeContainer()) ?>
-        </span>
+    <span<?php if ($this->getPriceId()): ?> id="<?php echo $this->getPriceId() ?>"<?php endif;?>
+        <?php echo ($this->getPriceDisplayLabel()) ? 'data-label="' . $this->getPriceDisplayLabel() . $this->getPriceDisplayInclExclTaxes() . '"' : '' ?>
+        class="price-wrapper <?php echo $this->getPriceWrapperCss(); ?>">
+        <?php echo $this->convertAndFormatCurrency($this->getDisplayValue(), (bool)$this->getIncludeContainer()) ?>
     </span>
     <?php if ($this->hasAdjustmentsHtml()): ?>
-        <span class="price-adjustments">
-            <?php echo $this->getAdjustmentsHtml() ?>
-        </span>
+        <?php echo $this->getAdjustmentsHtml() ?>
     <?php endif; ?>
 </span>
diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/configured_price.phtml b/app/code/Magento/Catalog/view/base/templates/product/price/configured_price.phtml
index 9eb83124fe9..e18efbf504c 100644
--- a/app/code/Magento/Catalog/view/base/templates/product/price/configured_price.phtml
+++ b/app/code/Magento/Catalog/view/base/templates/product/price/configured_price.phtml
@@ -28,7 +28,7 @@
 $configuredPrice = $this->getPrice();
 $priceLabel = ($this->getPriceLabel() !== null) 
 	? $this->getPriceLabel()
-	: __('Price as configured:');
+	: __('Price as configured');
 ?>
 <p class="price-as-configured">
     <?php echo $this->renderAmount($configuredPrice->getAmount(), [
diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/final_price.phtml b/app/code/Magento/Catalog/view/base/templates/product/price/final_price.phtml
index ab816ad2bee..d6617828223 100644
--- a/app/code/Magento/Catalog/view/base/templates/product/price/final_price.phtml
+++ b/app/code/Magento/Catalog/view/base/templates/product/price/final_price.phtml
@@ -33,26 +33,27 @@ $priceModel = $this->getPriceType('regular_price');
 
 /** @var \Magento\Catalog\Pricing\Price\FinalPrice $finalPriceModel */
 $finalPriceModel = $this->getPriceType('final_price');
+$idSuffix = $this->getIdSuffix() ? $this->getIdSuffix() : '';
 ?>
 <?php if ($this->hasSpecialPrice()): ?>
-    <p class="old-price">
+    <span class="old-price">
         <?php echo $this->renderAmount($priceModel->getAmount(), [
-            'display_label'     => __('Regular Price:'),
-            'price_id'          => $this->getPriceId('old-price-'),
+            'display_label'     => __('Regular Price'),
+            'price_id'          => $this->getPriceId('old-price-' . $idSuffix),
             'include_container' => true,
             'skip_adjustments'  => true
         ]); ?>
-    </p>
-    <p class="special-price">
+    </span>
+    <span class="special-price">
         <?php echo $this->renderAmount($finalPriceModel->getAmount(), [
-            'display_label'     => __('Special Price:'),
-            'price_id'          => $this->getPriceId('product-price-'),
-            'include_container' => false
+            'display_label'     => __('Special Price'),
+            'price_id'          => $this->getPriceId('product-price-' . $idSuffix),
+            'include_container' => true
         ]); ?>
-    </p>
+    </span>
 <?php else: ?>
     <?php echo $this->renderAmount($finalPriceModel->getAmount(), [
-        'price_id'          => $this->getPriceId('product-price-'),
+        'price_id'          => $this->getPriceId('product-price-' . $idSuffix),
         'include_container' => true
     ]); ?>
 <?php endif; ?>
diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/tier_prices.phtml b/app/code/Magento/Catalog/view/base/templates/product/price/tier_prices.phtml
index 3ca04fd21bd..e8ce065bc5e 100644
--- a/app/code/Magento/Catalog/view/base/templates/product/price/tier_prices.phtml
+++ b/app/code/Magento/Catalog/view/base/templates/product/price/tier_prices.phtml
@@ -33,12 +33,12 @@ $msrpShowOnGesture = $this->getPriceType('msrp_price')->isShowPriceOnGesture();
 $product = $this->getSaleableItem();
 ?>
 <?php if (count($tierPrices)) : ?>
-    <ul class="<?php echo ($this->hasListClass() ? $this->getListClass() : 'prices tier items'); ?>">
+    <ul class="<?php echo ($this->hasListClass() ? $this->getListClass() : 'prices-tier items'); ?>">
     <?php foreach ($tierPrices as $index => $price) : ?>
         <li class="item">
             <?php
                 $popupId = 'msrp-popup-' . $product->getId() . $this->getRandomString(20);
-                if ($msrpShowOnGesture):
+                if ($msrpShowOnGesture && $price['price']->getValue() < $product->getMsrp()):
                     $addToCartUrl = '';
                     if ($product->isSaleable()) {
                         $addToCartUrl = $this->helper('\Magento\Checkout\Helper\Cart')
@@ -88,8 +88,7 @@ $product = $this->getSaleableItem();
                     );
                 ?><?php echo __('each') ?>
                 <?php if ($this->getShowDetailedPrice() !== false): ?>
-                    <?php echo __('and') ?>&nbsp;<strong class="benefit">
-                        <?php echo __('save')?>
+                    <?php echo __('and') ?>&nbsp;<strong class="benefit"><?php echo __('save')?>
                         <span class="percent tier-<?php echo $index ?>"><?php echo $tierPriceModel->getSavePercent($price['price']) ?></span>%
                     </strong>
                 <?php endif ?>
@@ -105,7 +104,7 @@ $product = $this->getSaleableItem();
                 inputQty: '#qty',
                 productForm: '#product_addtocart_form'
             });
-                
+
         });
 </script>
     <?php endif;?>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
index 08cf14d41fb..bad8ca2a411 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml
@@ -94,5 +94,7 @@
             </arguments>
         </block>
     </referenceContainer>
-    <update handle="MAP_popup"/>
+    <referenceBlock name="page.main.title">
+        <block class="Magento\Catalog\Block\Category\Rss\Link" name="rss.link" template="Magento_Catalog::category/rss.phtml"/>
+    </referenceBlock>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_compare_index.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_compare_index.xml
index cfec4899079..51fcb229494 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_compare_index.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_compare_index.xml
@@ -32,5 +32,4 @@
     <referenceContainer name="content">
         <block class="Magento\Catalog\Block\Product\Compare\ListCompare" name="catalog.compare.list" template="product/compare/list.phtml"/>
     </referenceContainer>
-    <update handle="MAP_popup"/>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
index 5db60cf1e40..29b925aff48 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
@@ -38,13 +38,9 @@
             <argument name="add_attribute" xsi:type="string">itemscope itemtype="http://schema.org/Product"</argument>
         </arguments>
     </referenceBlock>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mage-gallery-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/gallery.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="mage/gallery.css"/>
+    </head>
     <update handle="page_calendar"/>
     <referenceContainer name="content">
         <container name="product.info.main" label="invisible" htmlTag="div" htmlClass="product-info-main" before="-">
@@ -63,7 +59,6 @@
                 <arguments>
                     <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                     <argument name="price_type_code" xsi:type="string">final_price</argument>
-                    <argument name="display_msrp_help_message" xsi:type="string">1</argument>
                     <argument name="zone" xsi:type="string">item_view</argument>
                 </arguments>
             </block>
@@ -71,7 +66,6 @@
                 <arguments>
                     <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                     <argument name="price_type_code" xsi:type="string">tier_price</argument>
-                    <argument name="display_msrp_help_message" xsi:type="string">1</argument>
                     <argument name="zone" xsi:type="string">item_view</argument>
                 </arguments>
             </block>
@@ -161,6 +155,4 @@
     <referenceBlock name="product.info.addtocart.additional">
         <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons.additional"/>
     </referenceBlock>
-    <update handle="MAP_popup"/>
-    <update handle="MAP_price_msrp_item"/>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/default.xml b/app/code/Magento/Catalog/view/frontend/layout/default.xml
index ea388d154c9..7a3714e07a6 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/default.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/default.xml
@@ -30,7 +30,7 @@
     <referenceContainer name="sidebar.additional">
         <block class="Magento\Catalog\Block\Product\Compare\Sidebar" name="catalog.compare.sidebar" template="product/compare/sidebar.phtml"/>
     </referenceContainer>
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Catalog::js/components.phtml"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Rss/view/frontend/templates/category/link.phtml b/app/code/Magento/Catalog/view/frontend/templates/category/rss.phtml
similarity index 82%
rename from app/code/Magento/Rss/view/frontend/templates/category/link.phtml
rename to app/code/Magento/Catalog/view/frontend/templates/category/rss.phtml
index 9ada24d0685..a936c6b4696 100644
--- a/app/code/Magento/Rss/view/frontend/templates/category/link.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/category/rss.phtml
@@ -22,6 +22,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php if($this->isRssCatalogEnable() && $this->isTopCategory()): ?>
-    <a href="<?php echo $this->getRssLink() ?>" class="action link rss"><span><?php echo __('Subscribe to RSS Feed') ?></span></a>
+<?php if($this->isRssAllowed() && $this->getLink() && $this->isTopCategory()): ?>
+    <a href="<?php echo $this->getLink() ?>" class="action link rss"><span><?php echo $this->getLabel() ?></span></a>
 <?php endif; ?>
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/price-option.js b/app/code/Magento/Catalog/view/frontend/web/js/price-option.js
index 8c2e1123367..4fc47ee2201 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/price-option.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/price-option.js
@@ -106,9 +106,12 @@ define([
                 var skipIds = [],
                     priceSelectors = [
                         '#product-price-' + this.options.priceConfig.productId,
+                        '#product-price-copy-' + this.options.priceConfig.productId,
                         '#bundle-price-' + this.options.priceConfig.productId,
                         '#price-including-tax-product-price-' + this.options.priceConfig.productId,
+                        '#price-including-tax-product-price-copy-' + this.options.priceConfig.productId,
                         '#price-excluding-tax-product-price-' + this.options.priceConfig.productId,
+                        '#price-excluding-tax-product-price-copy-' + this.options.priceConfig.productId,
                         '#old-price-' + this.options.priceConfig.productId
                     ],
                     getOptionPrices = this._getOptionPrices(),
diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json
index 225fc03887c..4e6aaa07908 100644
--- a/app/code/Magento/CatalogImportExport/composer.json
+++ b/app/code/Magento/CatalogImportExport/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-import-export": "0.1.0-alpha96",
-        "magento/module-indexer": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-import-export": "0.1.0-alpha97",
+        "magento/module-indexer": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json
index 47e034652f7..e377c3bbbe8 100644
--- a/app/code/Magento/CatalogInventory/composer.json
+++ b/app/code/Magento/CatalogInventory/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-indexer": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-indexer": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index 62c8429573b..3465c991d44 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -29,7 +29,6 @@
     <type name="Magento\CatalogInventory\Model\Observer">
         <arguments>
             <argument name="resourceStock" xsi:type="object">Magento\CatalogInventory\Model\Resource\Stock\Proxy</argument>
-            <argument name="indexer" xsi:type="object">Magento\Index\Model\Indexer\Proxy</argument>
             <argument name="stock" xsi:type="object">Magento\CatalogInventory\Model\Stock\Proxy</argument>
             <argument name="stockStatus" xsi:type="object">Magento\CatalogInventory\Model\Stock\Status\Proxy</argument>
             <argument name="catalogInventoryData" xsi:type="object">Magento\CatalogInventory\Helper\Data\Proxy</argument>
diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php
index 21290013144..9de82512439 100644
--- a/app/code/Magento/CatalogRule/Model/Rule.php
+++ b/app/code/Magento/CatalogRule/Model/Rule.php
@@ -124,11 +124,6 @@ class Rule extends \Magento\Rule\Model\AbstractModel
      */
     protected $_resourceIterator;
 
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
     /**
      * @var \Magento\Customer\Model\Session
      */
@@ -175,7 +170,6 @@ class Rule extends \Magento\Rule\Model\AbstractModel
      * @param \Magento\CatalogRule\Model\Rule\Action\CollectionFactory $actionCollectionFactory
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param \Magento\Index\Model\Indexer $indexer
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
      * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList
@@ -196,7 +190,6 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         \Magento\CatalogRule\Model\Rule\Action\CollectionFactory $actionCollectionFactory,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        \Magento\Index\Model\Indexer $indexer,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\CatalogRule\Helper\Data $catalogRuleData,
         \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList,
@@ -212,7 +205,6 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         $this->_actionCollectionFactory = $actionCollectionFactory;
         $this->_productFactory = $productFactory;
         $this->_resourceIterator = $resourceIterator;
-        $this->_indexer = $indexer;
         $this->_customerSession = $customerSession;
         $this->_catalogRuleData = $catalogRuleData;
         $this->_cacheTypesList = $cacheTypesList;
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index dae73d4f517..a6c09e071f1 100644
--- a/app/code/Magento/CatalogRule/composer.json
+++ b/app/code/Magento/CatalogRule/composer.json
@@ -3,18 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-rule": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-index": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-rule": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CatalogRule/etc/module.xml b/app/code/Magento/CatalogRule/etc/module.xml
index da7cd1f9cc1..5fda9f6e40c 100644
--- a/app/code/Magento/CatalogRule/etc/module.xml
+++ b/app/code/Magento/CatalogRule/etc/module.xml
@@ -35,7 +35,6 @@
             <module name="Magento_Rule"/>
             <module name="Magento_Catalog"/>
             <module name="Magento_Customer"/>
-            <module name="Magento_Index"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Eav"/>
         </depends>
diff --git a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
index 176f55a129e..144f368dd74 100644
--- a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
+++ b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
@@ -24,14 +24,6 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <action method="setCanLoadRulesJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-    </referenceBlock>
     <referenceContainer name="left">
         <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tabs" name="promo_catalog_edit_tabs">
             <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main" name="promo_catalog_edit_tab_main"/>
diff --git a/app/code/Magento/CatalogSearch/Block/Result.php b/app/code/Magento/CatalogSearch/Block/Result.php
index 9abe90169f5..b5c8637c134 100644
--- a/app/code/Magento/CatalogSearch/Block/Result.php
+++ b/app/code/Magento/CatalogSearch/Block/Result.php
@@ -92,8 +92,7 @@ class Result extends Template
     protected function _prepareLayout()
     {
         $title = $this->getSearchQueryText();
-        $this->getLayout()->getBlock('head')->setTitle($title);
-
+        $this->pageConfig->setTitle($title);
         // add Home breadcrumb
         $breadcrumbs = $this->getLayout()->getBlock('breadcrumbs');
         if ($breadcrumbs) {
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php
index 87c59349195..d0360c88f00 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php
@@ -151,10 +151,16 @@ class Full
      */
     protected $priceCurrency;
 
+    /**
+     * @var \Magento\Framework\Search\Request\Config
+     */
+    private $searchRequestConfig;
+
     /**
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Catalog\Model\Product\Type $catalogProductType
      * @param \Magento\Eav\Model\Config $eavConfig
+     * @param \Magento\Framework\Search\Request\Config $searchRequestConfig
      * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus
      * @param \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $productAttributeCollectionFactory
      * @param \Magento\CatalogSearch\Model\Resource\EngineProvider $engineProvider
@@ -172,6 +178,7 @@ class Full
         \Magento\Framework\App\Resource $resource,
         \Magento\Catalog\Model\Product\Type $catalogProductType,
         \Magento\Eav\Model\Config $eavConfig,
+        \Magento\Framework\Search\Request\Config $searchRequestConfig,
         \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus,
         \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $productAttributeCollectionFactory,
         \Magento\CatalogSearch\Model\Resource\EngineProvider $engineProvider,
@@ -188,6 +195,7 @@ class Full
         $this->resource = $resource;
         $this->catalogProductType = $catalogProductType;
         $this->eavConfig = $eavConfig;
+        $this->searchRequestConfig = $searchRequestConfig;
         $this->catalogProductStatus = $catalogProductStatus;
         $this->productAttributeCollectionFactory = $productAttributeCollectionFactory;
         $this->eventManager = $eventManager;
@@ -260,6 +268,7 @@ class Full
         foreach ($storeIds as $storeId) {
             $this->rebuildStoreIndex($storeId, $productIds);
         }
+        $this->searchRequestConfig->reset();
     }
 
     /**
diff --git a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php
new file mode 100644
index 00000000000..3286c2316ab
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php
@@ -0,0 +1,60 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogSearch\Model\Search;
+
+class ReaderPlugin
+{
+    /**
+     * @var \Magento\CatalogSearch\Model\Search\RequestGenerator
+     */
+    private $requestGenerator;
+
+    /**
+     * @param \Magento\CatalogSearch\Model\Search\RequestGenerator $requestGenerator
+     */
+    public function __construct(
+        \Magento\CatalogSearch\Model\Search\RequestGenerator $requestGenerator
+    ) {
+        $this->requestGenerator = $requestGenerator;
+    }
+
+    /**
+     * Merge reader's value with generated
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @param \Magento\Framework\Config\ReaderInterface $subject
+     * @param \Closure $proceed
+     * @param string $scope
+     * @return array
+     */
+    public function aroundRead(
+        \Magento\Framework\Config\ReaderInterface $subject,
+        \Closure $proceed,
+        $scope = null
+    ) {
+        $result = $proceed($scope);
+        $result = array_merge_recursive($result, $this->requestGenerator->generate());
+        return $result;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
new file mode 100644
index 00000000000..2ad1ef807b1
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
@@ -0,0 +1,163 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogSearch\Model\Search;
+
+class RequestGenerator
+{
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory
+     */
+    private $productAttributeCollectionFactory;
+
+    /**
+     * @param \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $productAttributeCollectionFactory
+     */
+    public function __construct(
+        \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $productAttributeCollectionFactory
+    ) {
+        $this->productAttributeCollectionFactory = $productAttributeCollectionFactory;
+    }
+
+    /**
+     * Generate dynamic fields requests
+     *
+     * @return array
+     */
+    public function generate()
+    {
+        $requests = [];
+        $requests['quick_search_container'] = $this->generateQuickSearchRequest();
+        $requests['advanced_search_container'] = $this->generateAdvancedSearchRequest();
+        return $requests;
+    }
+
+    /**
+     * Generate quick search request
+     *
+     * @return array
+     */
+    private function generateQuickSearchRequest()
+    {
+        $request = [];
+        foreach ($this->getSearchableAttributes() as $attribute) {
+            /** @var $attribute \Magento\Catalog\Model\Product\Attribute */
+            if (in_array($attribute->getAttributeCode(), ['price', 'sku'])) {
+                //same fields have special semantics
+                continue;
+            }
+            $request['queries']['quick_search_container']['match'][] = [
+                'field' => $attribute->getAttributeCode(),
+                'boost' => $attribute->getSearchWeight() ?: 1,
+            ];
+        }
+        return $request;
+    }
+
+    /**
+     * Generate advanced search request
+     *
+     * @return array
+     */
+    private function generateAdvancedSearchRequest()
+    {
+        $request = [];
+        foreach ($this->getSearchableAttributes() as $attribute) {
+            /** @var $attribute \Magento\Catalog\Model\Product\Attribute */
+            if (!$attribute->getIsVisibleInAdvancedSearch()) {
+                continue;
+            }
+            if (in_array($attribute->getAttributeCode(), ['price', 'sku'])) {
+                //same fields have special semantics
+                continue;
+            }
+
+            $queryName = $attribute->getAttributeCode() . '_query';
+            $request['queries']['advanced_search_container']['queryReference'][] = [
+                'clause' => 'should',
+                'ref' => $queryName,
+            ];
+            switch ($attribute->getBackendType()) {
+                case 'static':
+                    break;
+                case 'text':
+                case 'varchar':
+                    $request['queries'][$queryName] = [
+                        'name' => $queryName,
+                        'type' => 'matchQuery',
+                        'value' => '$' . $attribute->getAttributeCode() . '$',
+                        'match' => [
+                            [
+                                'field' => $attribute->getAttributeCode(),
+                                'boost' => $attribute->getSearchWeight() ?: 1,
+                            ]
+                        ]
+                    ];
+                    break;
+                case 'decimal':
+                case 'date':
+                    $filterName = $attribute->getAttributeCode() . '_filter';
+                    $request['queries'][$queryName] = [
+                        'name' => $queryName,
+                        'type' => 'filteredQuery',
+                        'filterReference' => [['ref' => $filterName]]
+                    ];
+                    $request['filters'][$filterName] = [
+                        'field' => $attribute->getAttributeCode(),
+                        'type' => 'rangeFilter',
+                        'from' => '$' . $attribute->getAttributeCode() . '.from$',
+                        'to' => '$' . $attribute->getAttributeCode() . '.to$',
+                    ];
+                    break;
+                default:
+                    $filterName = $attribute->getAttributeCode() . '_filter';
+                    $request['queries'][$queryName] = [
+                        'name' => $queryName,
+                        'type' => 'filteredQuery',
+                        'filterReference' => [['ref' => $filterName]]
+                    ];
+
+                    $request['filters'][$filterName] = [
+                        'type' => 'termFilter',
+                        'field' => $attribute->getAttributeCode(),
+                        'value' => '$' . $attribute->getAttributeCode() . '$',
+                    ];
+            }
+        }
+        return $request;
+    }
+
+    /**
+     * Retrieve searchable attributes
+     *
+     * @return \Traversable
+     */
+    protected function getSearchableAttributes()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Product\Attribute\Collection $productAttributes */
+        $productAttributes = $this->productAttributeCollectionFactory->create();
+        $productAttributes->addFieldToFilter('is_searchable', 1);
+
+        return $productAttributes;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 89ad0c2cc71..a9cc6a7815b 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-indexer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-indexer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml
index 8f314df6174..f1cfc63c177 100644
--- a/app/code/Magento/CatalogSearch/etc/di.xml
+++ b/app/code/Magento/CatalogSearch/etc/di.xml
@@ -72,4 +72,7 @@
             <argument name="entityId" xsi:type="object">Magento\Framework\Search\ProductEntityMetadata</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Search\Request\Config\FilesystemReader">
+        <plugin name="catalogSearchDynamicFields"  type="Magento\CatalogSearch\Model\Search\ReaderPlugin" />
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogSearch/etc/search_request.xml b/app/code/Magento/CatalogSearch/etc/search_request.xml
index f1c6ef3c362..ebb1d50ac89 100644
--- a/app/code/Magento/CatalogSearch/etc/search_request.xml
+++ b/app/code/Magento/CatalogSearch/etc/search_request.xml
@@ -23,19 +23,20 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Search/etc/search_request_merged.xsd">
+<requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Search/etc/search_request_merged.xsd">
     <request query="quick_search_container" index="product">
         <dimensions>
-            <dimension name="scope" value="%scope_placeholder%" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
-            <query xsi:type="matchQuery" name="quick_search_container">
-                <match field="name" value="$search_term" boost="1" />
-                <match field="sku" value="$search_term" boost="1" />
-                <match field="description" value="$search_term" boost="1" />
-                <match field="short_description" value="$search_term" boost="1" />
-                <match field="price" value="$search_term" boost="1" />
-                <match field="tax_class" value="$search_term" boost="1" />
+            <query xsi:type="matchQuery" value="$search_term" name="quick_search_container">
+                <match field="name" boost="1" />
+                <match field="sku" boost="1" />
+                <match field="description" boost="1" />
+                <match field="short_description" boost="1" />
+                <match field="price" boost="1" />
+                <match field="tax_class" boost="1" />
             </query>
         </queries>
         <from>10</from>
@@ -43,42 +44,25 @@
     </request>
     <request query="advanced_search_container" index="product">
         <dimensions>
-            <dimension name="scope" value="%scope_placeholder%" />
+            <dimension name="scope" value="default" />
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="advanced_search_container" boost="1">
-                <queryReference clause="should" ref="name_query" />
                 <queryReference clause="should" ref="sku_query" />
-                <queryReference clause="should" ref="description_query" />
-                <queryReference clause="should" ref="short_description_query" />
                 <queryReference clause="should" ref="price_query" />
-                <queryReference clause="should" ref="tax_class_query" />
             </query>
-            <query xsi:type="matchQuery" name="name_query">
-                <match field="name" value="$name" boost="1" />
-            </query>
-            <query xsi:type="filteredQuery" name="sku_query">
+            <query name="sku_query" xsi:type="filteredQuery">
                 <filterReference ref="sku_query_filter" />
             </query>
-            <query xsi:type="matchQuery" name="description_query">
-                <match field="description" value="$description" boost="1" />
-            </query>
-            <query xsi:type="matchQuery" name="short_description_query">
-                <match field="short_description" value="$short_description" boost="1" />
-            </query>
-            <query xsi:type="filteredQuery" name="price_query">
+            <query name="price_query" xsi:type="filteredQuery">
                 <filterReference ref="price_query_filter" />
             </query>
-            <query xsi:type="filteredQuery" name="tax_class_query">
-                <filterReference ref="tax_class_query_filter" />
-            </query>
         </queries>
         <filters>
             <filter xsi:type="termFilter" name="sku_query_filter" field="sku" value="$sku" />
             <filter xsi:type="rangeFilter" name="price_query_filter" field="price" from="$price_from" to="$price_to" />
-            <filter xsi:type="termFilter" name="tax_class_query_filter" field="tax_class" value="$tax_class" />
         </filters>
-        <from>10</from>
+        <from>0</from>
         <size>10</size>
     </request>
 </requests>
diff --git a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_index.xml b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_index.xml
index e85347f277e..6509820bcc0 100644
--- a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_index.xml
+++ b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_index.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Advanced Search</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Advanced Search</title>
+    </head>
     <update handle="page_calendar"/>
     <referenceContainer name="content">
         <block class="Magento\CatalogSearch\Block\Advanced\Form" name="catalogsearch_advanced_form" template="advanced/form.phtml"/>
diff --git a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_result.xml b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_result.xml
index b53ae3e2927..b640d14743c 100644
--- a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_result.xml
+++ b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_advanced_result.xml
@@ -24,16 +24,14 @@
  */
 -->
 <page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="class" value="page-products"/>
+    </body>
     <referenceBlock name="page.main.title">
         <action method="setPageTitle">
             <argument translate="true" name="title" xsi:type="string">Catalog Advanced Search</argument>
         </action>
     </referenceBlock>
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="class" xsi:type="string">page-products</argument>
-        </action>
-    </referenceBlock>
     <referenceContainer name="content">
         <block class="Magento\CatalogSearch\Block\Advanced\Result" name="catalogsearch_advanced_result" template="advanced/result.phtml">
             <block class="Magento\CatalogSearch\Block\SearchResult\ListProduct" name="search_result_list" template="product/list.phtml">
diff --git a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_result_index.xml b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_result_index.xml
index 6d62792a75e..f5862aa548d 100644
--- a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_result_index.xml
+++ b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_result_index.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="class" xsi:type="string">page-products</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="page-products"/>
+    </body>
     <referenceContainer name="content">
         <block class="Magento\CatalogSearch\Block\Result" name="search.result" template="result.phtml" cacheable="false">
             <block class="Magento\CatalogSearch\Block\SearchResult\ListProduct" name="search_result_list" template="product/list.phtml" cacheable="false">
diff --git a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_term_popular.xml b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_term_popular.xml
index 42b07876ccb..4f52660551d 100644
--- a/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_term_popular.xml
+++ b/app/code/Magento/CatalogSearch/view/frontend/layout/catalogsearch_term_popular.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Popular Search Terms</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Popular Search Terms</title>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\CatalogSearch\Block\Term" name="seo.searchterm" template="term.phtml" cacheable="false"/>
     </referenceContainer>
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Attribute/Urlkey.php b/app/code/Magento/CatalogUrlRewrite/Block/UrlKeyRenderer.php
similarity index 79%
rename from app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Attribute/Urlkey.php
rename to app/code/Magento/CatalogUrlRewrite/Block/UrlKeyRenderer.php
index 86754a2ac0a..3393aab3754 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Attribute/Urlkey.php
+++ b/app/code/Magento/CatalogUrlRewrite/Block/UrlKeyRenderer.php
@@ -21,23 +21,17 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\CatalogUrlRewrite\Block;
+
+use Magento\Store\Model\ScopeInterface;
 
 /**
  * Renderer for URL key input
  * Allows to manage and overwrite URL Rewrites History save settings
- *
- * @author     Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Catalog\Block\Adminhtml\Form\Renderer\Attribute;
-
-class Urlkey extends \Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset\Element
+class UrlKeyRenderer extends \Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset\Element
 {
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
+    const XML_PATH_SEO_SAVE_HISTORY = 'catalog/seo/save_rewrites_history';
 
     /**
      * @var \Magento\Framework\Data\Form\Element\Factory
@@ -47,17 +41,14 @@ class Urlkey extends \Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset\Ele
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Data\Form\Element\Factory $elementFactory
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
         \Magento\Framework\Data\Form\Element\Factory $elementFactory,
-        \Magento\Catalog\Helper\Data $catalogData,
         array $data = array()
     ) {
         $this->_elementFactory = $elementFactory;
-        $this->_catalogData = $catalogData;
         parent::__construct($context, $data);
     }
 
@@ -83,15 +74,16 @@ class Urlkey extends \Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset\Ele
         $data['html_id'] = $element->getHtmlId() . '_create_redirect';
         $data['label'] = __('Create Permanent Redirect for old URL');
         $data['value'] = $element->getValue();
-        $data['checked'] = $this->_catalogData->shouldSaveUrlRewritesHistory($storeId);
+        $data['checked'] = $this->_scopeConfig->isSetFlag(
+            self::XML_PATH_SEO_SAVE_HISTORY,
+            ScopeInterface::SCOPE_STORE,
+            $storeId
+        );
         /** @var \Magento\Framework\Data\Form\Element\Checkbox $checkbox */
         $checkbox = $this->_elementFactory->create('checkbox', array('data' => $data));
         $checkbox->setForm($element->getForm());
 
-        return parent::getElementHtml() .
-            '<br/>' .
-            $hidden->getElementHtml() .
-            $checkbox->getElementHtml() .
-            $checkbox->getLabelHtml();
+        return parent::getElementHtml() . '<br/>' . $hidden->getElementHtml() . $checkbox->getElementHtml()
+            . $checkbox->getLabelHtml();
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Helper/Data.php b/app/code/Magento/CatalogUrlRewrite/Helper/Data.php
deleted file mode 100644
index 098a731a8aa..00000000000
--- a/app/code/Magento/CatalogUrlRewrite/Helper/Data.php
+++ /dev/null
@@ -1,277 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\CatalogUrlRewrite\Helper;
-
-use Magento\Catalog\Helper\Category as CategoryHelper;
-use Magento\Catalog\Helper\Product as ProductHelper;
-use Magento\Catalog\Model\Category;
-use Magento\Catalog\Model\Product;
-use Magento\Eav\Model\Config;
-use Magento\Framework\App\Resource;
-use Magento\Store\Model\Store;
-use Magento\Framework\StoreManagerInterface;
-use Magento\UrlRedirect\Service\V1\Data\Converter;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewrite;
-
-/**
- * Helper Data
- */
-class Data
-{
-    /**
-     * Url slash
-     */
-    const URL_SLASH = '/';
-
-    /**
-     * @var \Magento\Eav\Model\Config
-     */
-    protected $eavConfig;
-
-    /**
-     * @var false|\Magento\Framework\DB\Adapter\AdapterInterface
-     */
-    protected $connection;
-
-    /**
-     * @var \Magento\Catalog\Helper\Product
-     */
-    protected $productHelper;
-
-    /**
-     * Store manager
-     *
-     * @var \Magento\Framework\StoreManagerInterface
-     */
-    protected $storeManager;
-
-    /**
-     * Catalog category helper
-     *
-     * @var CategoryHelper
-     */
-    protected $categoryHelper;
-
-    /**
-     * @var Converter
-     */
-    protected $converter;
-
-    /**
-     * @param Config $eavConfig
-     * @param Resource $resource
-     * @param \Magento\Catalog\Helper\Product $productHelper
-     * @param StoreManagerInterface $storeManager
-     * @param CategoryHelper $categoryHelper
-     * @param Converter $converter
-     */
-    public function __construct(
-        Config $eavConfig,
-        Resource $resource,
-        ProductHelper $productHelper,
-        StoreManagerInterface $storeManager,
-        CategoryHelper $categoryHelper,
-        Converter $converter
-    ) {
-        $this->eavConfig = $eavConfig;
-        $this->connection = $resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
-        $this->productHelper = $productHelper;
-        $this->storeManager = $storeManager;
-        $this->categoryHelper = $categoryHelper;
-        $this->converter = $converter;
-    }
-
-    /**
-     * If product saved on default store view, then need to check specific url_key for other stores
-     *
-     * @param int $storeId
-     * @param int $productId
-     * @return bool
-     */
-    public function isNeedCreateUrlRewrite($storeId, $productId)
-    {
-        $attribute = $this->eavConfig->getAttribute(Product::ENTITY, 'url_key');
-        $select = $this->connection->select()
-            ->from($attribute->getBackendTable(), 'store_id')
-            ->where('attribute_id = ?', $attribute->getId())
-            ->where('entity_id = ?', $productId);
-
-        return !in_array($storeId, $this->connection->fetchCol($select));
-    }
-
-    /**
-     * Whether the store is default
-     *
-     * @param int|null $storeId
-     * @return bool
-     */
-    public function isDefaultStore($storeId)
-    {
-        return null === $storeId || $storeId == Store::DEFAULT_STORE_ID;
-    }
-
-    /**
-     * Get canonical product url path
-     *
-     * @param Product $product
-     * @return string
-     */
-    public function getProductCanonicalUrlPath(Product $product)
-    {
-        return 'catalog/product/view/id/' . $product->getId();
-    }
-
-    /**
-     * Get canonical product url path with category
-     *
-     * @param Product $product
-     * @param Category $category
-     * @return string
-     */
-    public function getProductCanonicalUrlPathWithCategory(Product $product, Category $category)
-    {
-        return $this->getProductCanonicalUrlPath($product) . '/category/' . $category->getId();
-    }
-
-    /**
-     * Get product url key path
-     *
-     * @param Product $product
-     * @param int $storeId
-     * @return string
-     */
-    public function getProductUrlKeyPath(Product $product, $storeId)
-    {
-        return $product->getUrlModel()->getUrlPath($product) . $this->productHelper->getProductUrlSuffix($storeId);
-    }
-
-    /**
-     * Get product url key path with category
-     *
-     * @param Product $product
-     * @param Category $category
-     * @param int $storeId
-     * @return string
-     */
-    public function getProductUrlKeyPathWithCategory(Product $product, Category $category, $storeId)
-    {
-        return $product->getUrlModel()->getUrlPath($product, $category)
-            . $this->productHelper->getProductUrlSuffix($storeId);
-    }
-
-    /**
-     * Get canonical category url
-     *
-     * @param Category $category
-     * @return string
-     */
-    public function getCategoryCanonicalUrlPath(Category $category)
-    {
-        return 'catalog/category/view/id/' . $category->getId();
-    }
-
-    /**
-     * Get category url path
-     *
-     * @param Category $category
-     * @return string
-     */
-    public function getCategoryUrlKeyPath(Category $category)
-    {
-        return $category->getUrlPath();
-    }
-
-    /**
-     * Check is root category
-     *
-     * @param Category $category
-     * @return string
-     */
-    public function isRootCategory(Category $category)
-    {
-        $store = $this->storeManager->getStore($category->getStoreId());
-
-        return $category->getId() == $store->getRootCategoryId();
-    }
-
-    /**
-     * Generate category url key path
-     *
-     * @param \Magento\Catalog\Model\Category $category
-     * @return string
-     */
-    public function generateCategoryUrlKeyPath($category)
-    {
-        $parentPath = $this->categoryHelper->getCategoryUrlPath('', true, $category->getStoreId());
-
-        $urlKey = $category->getUrlKey() == ''
-            ? $category->formatUrlKey($category->getName()) : $category->formatUrlKey($category->getUrlKey());
-
-        return $parentPath . $urlKey;
-    }
-
-    /**
-     * Generate product url key path
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return string
-     */
-    public function generateProductUrlKeyPath($product)
-    {
-        $urlKey = $product->getUrlKey() == ''
-            ? $product->formatUrlKey($product->getName())
-            : $product->formatUrlKey($product->getUrlKey());
-
-        return $urlKey;
-    }
-
-    /**
-     * Create url rewrite object
-     *
-     * @param string $entityType
-     * @param int $entityId
-     * @param int $storeId
-     * @param string $requestPath
-     * @param string $targetPath
-     * @param string|null $redirectType Null or one of OptionProvider const
-     * @return UrlRewrite
-     */
-    public function createUrlRewrite(
-        $entityType,
-        $entityId,
-        $storeId,
-        $requestPath,
-        $targetPath,
-        $redirectType = null
-    ) {
-        return $this->converter->convertArrayToObject([
-            UrlRewrite::ENTITY_TYPE => $entityType,
-            UrlRewrite::ENTITY_ID => $entityId,
-            UrlRewrite::STORE_ID => $storeId,
-            UrlRewrite::REQUEST_PATH => $requestPath,
-            UrlRewrite::TARGET_PATH => $targetPath,
-            UrlRewrite::REDIRECT_TYPE => $redirectType,
-        ]);
-    }
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php
new file mode 100644
index 00000000000..5e9c7094839
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+
+class CanonicalUrlRewriteGenerator
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder $urlRewriteBuilder
+     */
+    public function __construct(
+        CategoryUrlPathGenerator $categoryUrlPathGenerator,
+        UrlRewriteBuilder $urlRewriteBuilder
+    ) {
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
+    }
+
+    /**
+     * Generate list based on store view
+     *
+     * @param int $storeId
+     * @param \Magento\Catalog\Model\Category $category
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generate($storeId, Category $category)
+    {
+        return [
+            $this->urlRewriteBuilder->setStoreId($storeId)
+                ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($category->getId())
+                ->setRequestPath($this->categoryUrlPathGenerator->getUrlPathWithSuffix($category, $storeId))
+                ->setTargetPath($this->categoryUrlPathGenerator->getCanonicalUrlPath($category))
+                ->create()
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProvider.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProvider.php
new file mode 100644
index 00000000000..9ce634e22c7
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProvider.php
@@ -0,0 +1,63 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\Catalog\Model\Category;
+
+class ChildrenCategoriesProvider
+{
+    /**
+     * @param \Magento\Catalog\Model\Category $category
+     * @param boolean $recursive
+     * @return \Magento\Catalog\Model\Category[]
+     */
+    public function getChildren(Category $category, $recursive = false)
+    {
+        return $category->getResourceCollection()
+            ->addAttributeToSelect('url_path')
+            ->addAttributeToSelect('url_key')
+            ->addAttributeToSelect('name')
+            ->addIdFilter($this->getChildrenIds($category, $recursive));
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Category $category
+     * @param boolean $recursive
+     * @return int[]
+     */
+    public function getChildrenIds(Category $category, $recursive = false)
+    {
+        $connection = $category->getResource()->getReadConnection();
+        $select = $connection->select()
+            ->from($category->getResource()->getEntityTable(), 'entity_id')
+            ->where($connection->quoteIdentifier('path') . ' LIKE :c_path');
+        $bind = ['c_path' => $category->getPath() . '/%'];
+        if (!$recursive) {
+            $select->where($connection->quoteIdentifier('level') . ' <= :c_level');
+            $bind['c_level'] = $category->getLevel() + 1;
+        }
+
+        return $connection->fetchCol($select, $bind);
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php
new file mode 100644
index 00000000000..95c88680f03
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory;
+
+class ChildrenUrlRewriteGenerator
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider */
+    protected $childrenCategoriesProvider;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory */
+    protected $categoryUrlRewriteGeneratorFactory;
+
+    /**
+     * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider $childrenCategoriesProvider
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory
+     */
+    public function __construct(
+        ChildrenCategoriesProvider $childrenCategoriesProvider,
+        CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory
+    ) {
+        $this->childrenCategoriesProvider = $childrenCategoriesProvider;
+        $this->categoryUrlRewriteGeneratorFactory = $categoryUrlRewriteGeneratorFactory;
+    }
+
+    /**
+     * Generate list of children urls
+     *
+     * @param int $storeId
+     * @param \Magento\Catalog\Model\Category $category
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generate($storeId, Category $category)
+    {
+        $urls = [];
+        foreach ($this->childrenCategoriesProvider->getChildren($category) as $childCategory) {
+            $childCategory->setStoreId($storeId);
+            $childCategory->setData('save_rewrites_history', $category->getData('save_rewrites_history'));
+            $urls = array_merge(
+                $urls,
+                $this->categoryUrlRewriteGeneratorFactory->create()->generate($childCategory)
+            );
+        }
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php
new file mode 100644
index 00000000000..b9c1ba4ecd5
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+
+class CurrentUrlRewritesRegenerator
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
+    /** @var \Magento\Catalog\Model\Category */
+    protected $category;
+
+    /**
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder $urlRewriteBuilder
+     * @param UrlFinderInterface $urlFinder
+     */
+    public function __construct(
+        CategoryUrlPathGenerator $categoryUrlPathGenerator,
+        UrlRewriteBuilder $urlRewriteBuilder,
+        UrlFinderInterface $urlFinder
+    ) {
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
+        $this->urlFinder = $urlFinder;
+    }
+
+    /**
+     * Generate list based on current url rewrites
+     *
+     * @param int $storeId
+     * @param \Magento\Catalog\Model\Category $category
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generate($storeId, Category $category)
+    {
+        $this->category = $category;
+
+        $currentUrlRewrites = $this->urlFinder->findAllByData(
+            [
+                UrlRewrite::STORE_ID => $storeId,
+                UrlRewrite::ENTITY_ID => $category->getId(),
+                UrlRewrite::ENTITY_TYPE => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            ]
+        );
+
+        $urlRewrites = [];
+        foreach ($currentUrlRewrites as $rewrite) {
+            if ($rewrite->getIsAutogenerated()) {
+                $urlRewrites = array_merge($urlRewrites, $this->generateForAutogenerated($rewrite, $storeId));
+            } else {
+                $urlRewrites = array_merge($urlRewrites, $this->generateForCustom($rewrite, $storeId));
+            }
+        }
+        return $urlRewrites;
+    }
+
+    /**
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite $url
+     * @param int $storeId
+     * @return array
+     */
+    protected function generateForAutogenerated($url, $storeId)
+    {
+        $urls = [];
+        if ($this->category->getData('save_rewrites_history')) {
+            $targetPath = $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId);
+            if ($url->getRequestPath() !== $targetPath) {
+                $urls[] = $this->urlRewriteBuilder
+                    ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
+                    ->setEntityId($this->category->getId())
+                    ->setRequestPath($url->getRequestPath())
+                    ->setTargetPath($targetPath)
+                    ->setRedirectType(OptionProvider::PERMANENT)
+                    ->setStoreId($storeId)
+                    ->setIsAutogenerated(0)
+                    ->create();
+            }
+        }
+        return $urls;
+    }
+
+    /**
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite $url
+     * @param int $storeId
+     * @return array
+     */
+    protected function generateForCustom($url, $storeId)
+    {
+        $urls = [];
+        $targetPath = !$url->getRedirectType()
+            ? $url->getTargetPath()
+            : $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId);
+        if ($url->getRequestPath() !== $targetPath) {
+            $urls[] = $this->urlRewriteBuilder
+                ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($this->category->getId())
+                ->setRequestPath($url->getRequestPath())
+                ->setTargetPath($targetPath)
+                ->setRedirectType($url->getRedirectType())
+                ->setStoreId($storeId)
+                ->setDescription($url->getDescription())
+                ->setIsAutogenerated(0)
+                ->setMetadata($url->getMetadata())
+                ->create();
+        }
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php
index c2387d36e4b..dd65243301f 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Observer.php
@@ -23,50 +23,61 @@
  */
 namespace Magento\CatalogUrlRewrite\Model\Category;
 
-use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper;
-use Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGeneratorInterface;
-use Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface;
+use Magento\Catalog\Model\Category;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
 use Magento\Framework\Event\Observer as EventObserver;
-use Magento\UrlRedirect\Service\V1\UrlSaveInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\CatalogUrlRewrite\Block\UrlKeyRenderer;
 
 class Observer
 {
-    /**
-     * @var CategoryUrlGeneratorInterface
-     */
-    protected $categoryUrlGenerator;
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider */
+    protected $childrenCategoriesProvider;
 
-    /**
-     * @var CategoryUrlGeneratorInterface
-     */
-    protected $productUrlGenerator;
+    /** @var CategoryUrlRewriteGenerator */
+    protected $categoryUrlRewriteGenerator;
 
-    /**
-     * @var UrlSaveInterface
-     */
-    protected $urlSave;
+    /** @var ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
 
-    /**
-     * @var CatalogUrlRewriteHelper
-     */
-    protected $catalogUrlRewriteHelper;
+    /** @var UrlPersistInterface */
+    protected $urlPersist;
+
+    /** @var ScopeConfigInterface */
+    protected $scopeConfig;
+
+    /** @var array */
+    protected $isSkippedProduct;
+
+    /** @var \Magento\Catalog\Model\Resource\Product\CollectionFactory */
+    protected $productCollectionFactory;
 
     /**
-     * @param CategoryUrlGeneratorInterface $categoryUrlGenerator
-     * @param ProductUrlGeneratorInterface $productUrlGenerator
-     * @param UrlSaveInterface $urlSave
-     * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper
+     * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider $childrenCategoriesProvider
+     * @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     * @param UrlPersistInterface $urlPersist
+     * @param ScopeConfigInterface $scopeConfig
+     * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory
      */
     public function __construct(
-        CategoryUrlGeneratorInterface $categoryUrlGenerator,
-        ProductUrlGeneratorInterface $productUrlGenerator,
-        UrlSaveInterface $urlSave,
-        CatalogUrlRewriteHelper $catalogUrlRewriteHelper
+        ChildrenCategoriesProvider $childrenCategoriesProvider,
+        CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator,
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator,
+        UrlPersistInterface $urlPersist,
+        ScopeConfigInterface $scopeConfig,
+        \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory
     ) {
-        $this->categoryUrlGenerator = $categoryUrlGenerator;
-        $this->productUrlGenerator = $productUrlGenerator;
-        $this->urlSave = $urlSave;
-        $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper;
+        $this->childrenCategoriesProvider = $childrenCategoriesProvider;
+        $this->categoryUrlRewriteGenerator = $categoryUrlRewriteGenerator;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+        $this->urlPersist = $urlPersist;
+        $this->scopeConfig = $scopeConfig;
+        $this->productCollectionFactory = $productCollectionFactory;
     }
 
     /**
@@ -77,26 +88,131 @@ class Observer
      */
     public function processUrlRewriteSaving(EventObserver $observer)
     {
-        /** @var \Magento\Catalog\Model\Category $category */
+        /** @var Category $category */
         $category = $observer->getEvent()->getCategory();
+        if ($category->getParentId() == Category::TREE_ROOT_ID) {
+            return;
+        }
+        if ($category->dataHasChangedFor('url_key') || $category->getIsChangedProductList()) {
+            $urlRewrites = array_merge(
+                $this->categoryUrlRewriteGenerator->generate($category),
+                $this->generateProductUrlRewrites($category)
+            );
+            $this->urlPersist->replace($urlRewrites);
+        }
+    }
 
-        if (!$this->catalogUrlRewriteHelper->isRootCategory($category)
-            && (!$category->getData('url_key') || $category->getOrigData('url_key') != $category->getData('url_key'))
-        ) {
-            $this->urlSave->save($this->categoryUrlGenerator->generate($category));
+    /**
+     * @param EventObserver $observer
+     * @return void
+     */
+    public function processUrlRewriteMoving(EventObserver $observer)
+    {
+        /** @var Category $category */
+        $category = $observer->getEvent()->getCategory();
+        if ($category->dataHasChangedFor('parent_id')) {
+            $saveRewritesHistory = $this->scopeConfig->isSetFlag(
+                UrlKeyRenderer::XML_PATH_SEO_SAVE_HISTORY,
+                ScopeInterface::SCOPE_STORE,
+                $category->getStoreId()
+            );
+            $category->setData('save_rewrites_history', $saveRewritesHistory);
+            $urlRewrites = array_merge(
+                $this->categoryUrlRewriteGenerator->generate($category),
+                $this->generateProductUrlRewrites($category)
+            );
+            $this->deleteCategoryRewritesForChildren($category);
+            $this->urlPersist->replace($urlRewrites);
+        }
+    }
 
-            $products = $category->getProductCollection()
+    /**
+     * Generate url rewrites for products assigned to category
+     *
+     * @param Category $category
+     * @return array
+     */
+    protected function generateProductUrlRewrites(Category $category)
+    {
+        $this->isSkippedProduct = [];
+        $saveRewriteHistory = $category->getData('save_rewrites_history');
+        $storeId = $category->getStoreId();
+        $productUrls = [];
+        if ($category->getAffectedProductIds()) {
+            $this->isSkippedProduct = $category->getAffectedProductIds();
+            $collection = $this->productCollectionFactory->create()
+                ->setStoreId($storeId)
+                ->addIdFilter($category->getAffectedProductIds())
+                ->addAttributeToSelect('name')
                 ->addAttributeToSelect('url_key')
                 ->addAttributeToSelect('url_path');
+            foreach ($collection as $product) {
+                $product->setStoreId($storeId);
+                $product->setData('save_rewrites_history', $saveRewriteHistory);
+                $productUrls = array_merge($productUrls, $this->productUrlRewriteGenerator->generate($product));
+            }
+        } else {
+            $productUrls = array_merge(
+                $productUrls,
+                $this->getCategoryProductsUrlRewrites($category, $storeId, $saveRewriteHistory)
+            );
+        }
+        foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) {
+            $productUrls = array_merge(
+                $productUrls,
+                $this->getCategoryProductsUrlRewrites($childCategory, $storeId, $saveRewriteHistory)
+            );
+        }
+        return $productUrls;
+    }
 
-            foreach ($products as $product) {
-                $product->setData('save_rewrites_history', $category->getData('save_rewrites_history'));
-
-                $this->urlSave->save($this->productUrlGenerator->generateWithChangedCategories(
-                    $product,
-                    [$category->getId() => $category]
-                ));
+    /**
+     * @param Category $category
+     * @param int $storeId
+     * @param bool $saveRewriteHistory
+     * @return UrlRewrite[]
+     */
+    protected function getCategoryProductsUrlRewrites(Category $category, $storeId, $saveRewriteHistory)
+    {
+        /** @var \Magento\Catalog\Model\Resource\Product\Collection $productCollection */
+        $productCollection = $category->getProductCollection()
+            ->addAttributeToSelect('name')
+            ->addAttributeToSelect('url_key')
+            ->addAttributeToSelect('url_path');
+        $productUrls = [];
+        foreach ($productCollection as $product) {
+            if (in_array($product->getId(), $this->isSkippedProduct)) {
+                continue;
             }
+            $this->isSkippedProduct[] = $product->getId();
+            $product->setStoreId($storeId);
+            $product->setData('save_rewrites_history', $saveRewriteHistory);
+            $productUrls = array_merge($productUrls, $this->productUrlRewriteGenerator->generate($product));
+        }
+        return $productUrls;
+    }
+
+    /**
+     * @param Category $category
+     * @return void
+     */
+    protected function deleteCategoryRewritesForChildren(Category $category)
+    {
+        $categoryIds = $this->childrenCategoriesProvider->getChildrenIds($category, true);
+        $categoryIds[] = $category->getId();
+        foreach ($categoryIds as $categoryId) {
+            $this->urlPersist->deleteByData(
+                [
+                    UrlRewrite::ENTITY_ID => $categoryId,
+                    UrlRewrite::ENTITY_TYPE => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+                ]
+            );
+            $this->urlPersist->deleteByData(
+                [
+                    UrlRewrite::METADATA => serialize(['category_id' => $categoryId]),
+                    UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+                ]
+            );
         }
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php
new file mode 100644
index 00000000000..ab1e6bf9c47
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Category;
+
+use Magento\Framework\Event\Observer as EventObserver;
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+
+class Move
+{
+    /** @var CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /**
+     * @param CategoryUrlPathGenerator $categoryUrlPathGenerator
+     */
+    public function __construct(CategoryUrlPathGenerator $categoryUrlPathGenerator)
+    {
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Resource\Category $subject
+     * @param callable $proceed
+     * @param Category $category
+     * @param Category $newParent
+     * @param null|int $afterCategoryId
+     * @return callable
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundChangeParent(
+        \Magento\Catalog\Model\Resource\Category $subject,
+        \Closure $proceed,
+        $category,
+        $newParent,
+        $afterCategoryId
+    ) {
+        $result = $proceed($category, $newParent, $afterCategoryId);
+        $category->setUrlKey($this->categoryUrlPathGenerator->generateUrlKey($category))
+            ->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category));
+        return $result;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php
new file mode 100644
index 00000000000..8c33fd728b7
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php
@@ -0,0 +1,107 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Category;
+
+use Magento\Framework\Event\Observer as EventObserver;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Catalog\Model\CategoryFactory;
+use Magento\Store\Model\Store;
+use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider;
+
+class Remove
+{
+    /** @var UrlPersistInterface */
+    protected $urlPersist;
+
+    /** @var  CategoryFactory */
+    protected $categoryFactory;
+
+    /** @var ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
+
+    /** @var ChildrenCategoriesProvider */
+    protected $childrenCategoriesProvider;
+
+    /**
+     * @param UrlPersistInterface $urlPersist
+     * @param CategoryFactory $categoryFactory
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     * @param ChildrenCategoriesProvider $childrenCategoriesProvider
+     */
+    public function __construct(
+        UrlPersistInterface $urlPersist,
+        CategoryFactory $categoryFactory,
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator,
+        ChildrenCategoriesProvider $childrenCategoriesProvider
+    ) {
+        $this->urlPersist = $urlPersist;
+        $this->categoryFactory = $categoryFactory;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+        $this->childrenCategoriesProvider = $childrenCategoriesProvider;
+    }
+
+    /**
+     * Remove product urls from storage
+     *
+     * @param Category $category
+     * @param callable $proceed
+     * @return mixed
+     */
+    public function aroundDelete(Category $category, \Closure $proceed)
+    {
+        $categoryIds = $this->childrenCategoriesProvider->getChildrenIds($category, true);
+        $categoryIds[] = $category->getId();
+        $result = $proceed();
+        foreach ($categoryIds as $categoryId) {
+            $this->deleteRewritesForCategory($categoryId);
+        }
+        return $result;
+    }
+
+    /**
+     * Remove url rewrites by categoryId
+     *
+     * @param int $categoryId
+     * @return void
+     */
+    protected function deleteRewritesForCategory($categoryId)
+    {
+        $this->urlPersist->deleteByData(
+            [
+                UrlRewrite::ENTITY_ID => $categoryId,
+                UrlRewrite::ENTITY_TYPE => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            ]
+        );
+        $this->urlPersist->deleteByData(
+            [
+                UrlRewrite::METADATA => serialize(['category_id' => $categoryId]),
+                UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+            ]
+        );
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php
new file mode 100644
index 00000000000..7e9b29f446c
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category\Plugin;
+
+use Magento\CatalogUrlRewrite\Model\Category\ProductFactory;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\UrlRewrite\Model\StorageInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+
+class Storage
+{
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
+    /** @var ProductFactory */
+    protected $productFactory;
+
+    /**
+     * @param UrlFinderInterface $urlFinder
+     * @param ProductFactory $productFactory
+     */
+    public function __construct(
+        UrlFinderInterface $urlFinder,
+        ProductFactory $productFactory
+    ) {
+        $this->urlFinder = $urlFinder;
+        $this->productFactory = $productFactory;
+    }
+
+    /**
+     * @param \Magento\UrlRewrite\Model\StorageInterface $object
+     * @param callable $proceed
+     * @param array $urls
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundReplace(StorageInterface $object, \Closure $proceed, array $urls)
+    {
+        $proceed($urls);
+        $toSave = [];
+        foreach ($this->filterUrls($urls) as $record) {
+            $metadata = $record->getMetadata();
+            $toSave[] = [
+                'url_rewrite_id' => $record->getUrlRewriteId(),
+                'category_id' => $metadata['category_id'],
+                'product_id' => $record->getEntityId()
+            ];
+        }
+        if ($toSave) {
+            $this->productFactory->create()->getResource()->saveMultiple($toSave);
+        }
+    }
+
+    /**
+     * @param \Magento\UrlRewrite\Model\StorageInterface $object
+     * @param array $data
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeDeleteByData(StorageInterface $object, array $data)
+    {
+        $toRemove = [];
+        $records = $this->urlFinder->findAllByData($data);
+        foreach ($records as $record) {
+            $toRemove[] = $record->getUrlRewriteId();
+        }
+        if ($toRemove) {
+            $this->productFactory->create()->getResource()->removeMultiple($toRemove);
+        }
+    }
+
+    /**
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    protected function filterUrls(array $urls)
+    {
+        $filteredUrls = [];
+        /** @var UrlRewrite $url */
+        foreach ($urls as $url) {
+            if ($this->isCorrectUrl($url)) {
+                $filteredUrls[] = $url;
+            }
+        }
+        $data = [];
+        foreach ($filteredUrls as $url) {
+            foreach ([UrlRewrite::REQUEST_PATH, UrlRewrite::STORE_ID] as $key) {
+                $fieldValue = $url->getByKey($key);
+                if (!isset($data[$key]) || !in_array($fieldValue, $data[$key])) {
+                    $data[$key][] = $fieldValue;
+                }
+            }
+        }
+        return $data ? $this->urlFinder->findAllByData($data) : [];
+    }
+
+    /**
+     * @param UrlRewrite $url
+     * @return bool
+     */
+    protected function isCorrectUrl(UrlRewrite $url)
+    {
+        $metadata = $url->getMetadata();
+        return $url->getEntityType() == ProductUrlRewriteGenerator::ENTITY_TYPE
+        && !empty($metadata['category_id'])
+        && $url->getIsAutogenerated();
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php
new file mode 100644
index 00000000000..b92a128527b
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php
@@ -0,0 +1,165 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Store;
+
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\Catalog\Model\CategoryFactory;
+use Magento\Catalog\Model\ProductFactory;
+use Magento\Framework\StoreManagerInterface;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Store\Model\Store;
+use Magento\Framework\Model\AbstractModel;
+
+class Group
+{
+    /** @var UrlPersistInterface */
+    protected $urlPersist;
+
+    /** @var CategoryFactory */
+    protected $categoryFactory;
+
+    /** @var ProductFactory */
+    protected $productFactory;
+
+    /** @var CategoryUrlRewriteGenerator */
+    protected $categoryUrlRewriteGenerator;
+
+    /** @var ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
+
+    /** @var StoreManagerInterface  */
+    protected $storeManager;
+
+    /**
+     * @param UrlPersistInterface $urlPersist
+     * @param CategoryFactory $categoryFactory
+     * @param ProductFactory $productFactory
+     * @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        UrlPersistInterface $urlPersist,
+        CategoryFactory $categoryFactory,
+        ProductFactory $productFactory,
+        CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator,
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator,
+        StoreManagerInterface $storeManager
+    ) {
+        $this->urlPersist = $urlPersist;
+        $this->categoryFactory = $categoryFactory;
+        $this->productFactory = $productFactory;
+        $this->categoryUrlRewriteGenerator = $categoryUrlRewriteGenerator;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @param \Magento\Store\Model\Resource\Group $object
+     * @param callable $proceed
+     * @param AbstractModel $group
+     * @return \Magento\Store\Model\Resource\Group
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(
+        \Magento\Store\Model\Resource\Group $object,
+        \Closure $proceed,
+        AbstractModel $group
+    ) {
+        $originGroup = $group;
+        $result = $proceed($originGroup);
+        if (!$group->isObjectNew()
+            && ($group->dataHasChangedFor('website_id')
+                || $group->dataHasChangedFor('root_category_id'))
+        ) {
+            $this->storeManager->reinitStores();
+            foreach ($group->getStoreIds() as $storeId) {
+                $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $storeId]);
+            }
+
+            $this->urlPersist->replace(
+                $this->generateCategoryUrls($group->getRootCategoryId(), $group->getStoreIds())
+            );
+
+            $this->urlPersist->replace(
+                $this->generateProductUrls($group->getWebsiteId(), $group->getOrigData('website_id'))
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Generate url rewrites for products assigned to website
+     *
+     * @param int $websiteId
+     * @param int $originWebsiteId
+     * @return array
+     */
+    protected function generateProductUrls($websiteId, $originWebsiteId)
+    {
+        $urls = [];
+        $websiteIds = $websiteId != $originWebsiteId
+            ? [$websiteId, $originWebsiteId]
+            : [$websiteId];
+        $collection = $this->productFactory->create()
+            ->getCollection()
+            ->addCategoryIds()
+            ->addAttributeToSelect(array('name', 'url_path', 'url_key'))
+            ->addWebsiteFilter($websiteIds);
+        foreach ($collection as $product) {
+            /** @var \Magento\Catalog\Model\Product $product */
+            $product->setStoreId(Store::DEFAULT_STORE_ID);
+            $urls = array_merge(
+                $urls,
+                $this->productUrlRewriteGenerator->generate($product)
+            );
+        }
+
+        return $urls;
+    }
+
+    /**
+     * @param int $rootCategoryId
+     * @param array $storeIds
+     * @return array
+     */
+    protected function generateCategoryUrls($rootCategoryId, $storeIds)
+    {
+        $urls = [];
+        $categories = $this->categoryFactory->create()->getCategories($rootCategoryId, 1, false, true);
+        foreach ($categories as $category) {
+            /** @var \Magento\Catalog\Model\Category $category */
+            $category->setStoreId(Store::DEFAULT_STORE_ID);
+            $category->setStoreIds($storeIds);
+            $urls = array_merge(
+                $urls,
+                $this->categoryUrlRewriteGenerator->generate($category)
+            );
+        }
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php
new file mode 100644
index 00000000000..13bfef17f80
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php
@@ -0,0 +1,171 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Store;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\CategoryFactory;
+use Magento\Catalog\Model\ProductFactory;
+use Magento\Framework\Event\Observer as EventObserver;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Framework\Model\AbstractModel;
+
+class View
+{
+    /** @var UrlPersistInterface */
+    protected $urlPersist;
+
+    /** @var CategoryFactory */
+    protected $categoryFactory;
+
+    /** @var ProductFactory */
+    protected $productFactory;
+
+    /** @var CategoryUrlRewriteGenerator */
+    protected $categoryUrlRewriteGenerator;
+
+    /** @var ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
+
+    /**
+     * @param UrlPersistInterface $urlPersist
+     * @param CategoryFactory $categoryFactory
+     * @param ProductFactory $productFactory
+     * @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     */
+    public function __construct(
+        UrlPersistInterface $urlPersist,
+        CategoryFactory $categoryFactory,
+        ProductFactory $productFactory,
+        CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator,
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator
+    ) {
+        $this->categoryUrlRewriteGenerator = $categoryUrlRewriteGenerator;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+        $this->urlPersist = $urlPersist;
+        $this->categoryFactory = $categoryFactory;
+        $this->productFactory = $productFactory;
+    }
+
+    /**
+     * @param \Magento\Store\Model\Resource\Store $object
+     * @param callable $proceed
+     * @param AbstractModel $store
+     * @return \Magento\Store\Model\Resource\Store
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(
+        \Magento\Store\Model\Resource\Store $object,
+        \Closure $proceed,
+        AbstractModel $store
+    ) {
+        $originStore = $store;
+        $result = $proceed($originStore);
+        if ($store->isObjectNew() || $store->dataHasChangedFor('group_id')) {
+            if (!$store->isObjectNew()) {
+                $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]);
+            }
+
+            $this->urlPersist->replace(
+                $this->generateCategoryUrls($store->getRootCategoryId(), $store->getId())
+            );
+
+            $this->urlPersist->replace(
+                $this->generateProductUrls($store->getWebsiteId(), $store->getOrigData('website_id'), $store->getId())
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Generate url rewrites for products assigned to website
+     *
+     * @param int $websiteId
+     * @param int $originWebsiteId
+     * @param int $storeId
+     * @return array
+     */
+    protected function generateProductUrls($websiteId, $originWebsiteId, $storeId)
+    {
+        $urls = [];
+        $websiteIds = $websiteId != $originWebsiteId && !is_null($originWebsiteId)
+            ? [$websiteId, $originWebsiteId]
+            : [$websiteId];
+        $collection = $this->productFactory->create()
+            ->getCollection()
+            ->addCategoryIds()
+            ->addAttributeToSelect(array('name', 'url_path', 'url_key'))
+            ->addWebsiteFilter($websiteIds);
+        foreach ($collection as $product) {
+            $product->setStoreId($storeId);
+            /** @var \Magento\Catalog\Model\Product $product */
+            $urls = array_merge(
+                $urls,
+                $this->productUrlRewriteGenerator->generate($product)
+            );
+        }
+        return $urls;
+    }
+
+    /**
+     * @param int $rootCategoryId
+     * @param int $storeId
+     * @return array
+     */
+    protected function generateCategoryUrls($rootCategoryId, $storeId)
+    {
+        $urls = [];
+        $categories = $this->categoryFactory->create()->getCategories($rootCategoryId, 1, false, true);
+        foreach ($categories as $category) {
+            /** @var \Magento\Catalog\Model\Category $category */
+            $category->setStoreId($storeId);
+            $urls = array_merge(
+                $urls,
+                $this->categoryUrlRewriteGenerator->generate($category)
+            );
+        }
+        return $urls;
+    }
+
+    /**
+     * @param \Magento\Store\Model\Resource\Store $object
+     * @param callable $proceed
+     * @param AbstractModel $store
+     * @return mixed
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundDelete(
+        \Magento\Store\Model\Resource\Store $object,
+        \Closure $proceed,
+        AbstractModel $store
+    ) {
+        $result = $proceed($store);
+        $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]);
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Cms/Model/Resource/Page/Urlrewrite.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Product.php
similarity index 77%
rename from app/code/Magento/Cms/Model/Resource/Page/Urlrewrite.php
rename to app/code/Magento/CatalogUrlRewrite/Model/Category/Product.php
index f1dc364879d..cd8dfb34698 100644
--- a/app/code/Magento/Cms/Model/Resource/Page/Urlrewrite.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Product.php
@@ -17,24 +17,23 @@
  * 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.
- *
+ *   
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Model\Resource\Page;
+namespace Magento\CatalogUrlRewrite\Model\Category;
 
-/**
- * Cms page url rewrite resource model
- */
-class Urlrewrite extends \Magento\Framework\Model\Resource\Db\AbstractDb
+use Magento\Framework\Model\AbstractModel;
+
+class Product extends AbstractModel
 {
     /**
-     * Init cms page urlrewrite model
+     * Model construct that should be used for object initialization
      *
      * @return void
      */
     protected function _construct()
     {
-        $this->_init('cms_url_rewrite', 'cms_rewrite_id');
+        $this->_init('Magento\CatalogUrlRewrite\Model\Resource\Category\Product');
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php
new file mode 100644
index 00000000000..1ad254fde1b
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php
@@ -0,0 +1,156 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Category;
+
+class CategoryUrlPathGenerator
+{
+    /**
+     * Minimal category level that can be considered for generate path
+     */
+    const MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING = 3;
+
+    /**
+     * XML path for category url suffix
+     */
+    const XML_PATH_CATEGORY_URL_SUFFIX = 'catalog/seo/category_url_suffix';
+
+    /**
+     * Cache for category rewrite suffix
+     *
+     * @var array
+     */
+    protected $categoryUrlSuffix = [];
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface */
+    protected $scopeConfig;
+
+    /** @var \Magento\Framework\StoreManagerInterface */
+    protected $storeManager;
+
+    /** @var \Magento\Catalog\Model\CategoryFactory */
+    protected $categoryFactory;
+
+    public function __construct(
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Catalog\Model\CategoryFactory $categoryFactory
+    ) {
+        $this->storeManager = $storeManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->categoryFactory = $categoryFactory;
+    }
+
+    /**
+     * Build category URL path
+     *
+     * @param \Magento\Catalog\Model\Category|\Magento\Framework\Object $category
+     * @return string
+     */
+    public function getUrlPath($category)
+    {
+        if ($category->getParentId() == Category::TREE_ROOT_ID) {
+            return '';
+        }
+        $path = $category->getUrlPath();
+        if ($path !== null && !$category->dataHasChangedFor('url_key') && !$category->dataHasChangedFor('path_ids')) {
+            return $path;
+        }
+        $path = $category->getUrlKey();
+        if ($this->isNeedToGenerateUrlPathForParent($category)) {
+            $parentPath = $this->getUrlPath($this->categoryFactory->create()->load($category->getParentId()));
+            $path = $parentPath === '' ? $path : $parentPath . '/' . $path;
+        }
+        return $path;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Category $category
+     * @return bool
+     */
+    protected function isNeedToGenerateUrlPathForParent($category)
+    {
+        return $category->getParentId() && $category->getLevel() >= self::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING;
+    }
+
+    /**
+     * Get category url path
+     *
+     * @param \Magento\Catalog\Model\Category $category
+     * @param int $storeId
+     * @return string
+     */
+    public function getUrlPathWithSuffix($category, $storeId = null)
+    {
+        if ($storeId === null) {
+            $storeId = $category->getStoreId();
+        }
+        return $this->getUrlPath($category) . $this->getCategoryUrlSuffix($storeId);
+    }
+
+    /**
+     * Retrieve category rewrite suffix for store
+     *
+     * @param int $storeId
+     * @return string
+     */
+    protected function getCategoryUrlSuffix($storeId = null)
+    {
+        if ($storeId === null) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+        if (!isset($this->categoryUrlSuffix[$storeId])) {
+            $this->categoryUrlSuffix[$storeId] = $this->scopeConfig->getValue(
+                self::XML_PATH_CATEGORY_URL_SUFFIX,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $storeId
+            );
+        }
+        return $this->categoryUrlSuffix[$storeId];
+    }
+
+    /**
+     * Get canonical category url
+     *
+     * @param \Magento\Catalog\Model\Category $category
+     * @return string
+     */
+    public function getCanonicalUrlPath($category)
+    {
+        return 'catalog/category/view/id/' . $category->getId();
+    }
+
+    /**
+     * Generate category url key
+     *
+     * @param \Magento\Catalog\Model\Category $category
+     * @return string
+     */
+    public function generateUrlKey($category)
+    {
+        $urlKey = $category->getUrlKey();
+        return $category->formatUrlKey($urlKey === '' || $urlKey === null ? $category->getName() : $urlKey);
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php
new file mode 100644
index 00000000000..ba3474c4e57
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php
@@ -0,0 +1,132 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
+use Magento\Store\Model\Store;
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator;
+use Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator;
+
+class CategoryUrlRewriteGenerator
+{
+    /** Entity type code */
+    const ENTITY_TYPE = 'category';
+
+    /** @var StoreViewService */
+    protected $storeViewService;
+
+    /** @var \Magento\Catalog\Model\Category */
+    protected $category;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator */
+    protected $childrenUrlRewriteGenerator;
+
+    /**
+     * @param \Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator
+     * @param \Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator
+     * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator $childrenUrlRewriteGenerator
+     * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService
+     */
+    public function __construct(
+        CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator,
+        CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator,
+        ChildrenUrlRewriteGenerator $childrenUrlRewriteGenerator,
+        StoreViewService $storeViewService
+    ) {
+        $this->storeViewService = $storeViewService;
+        $this->canonicalUrlRewriteGenerator = $canonicalUrlRewriteGenerator;
+        $this->childrenUrlRewriteGenerator = $childrenUrlRewriteGenerator;
+        $this->currentUrlRewritesRegenerator = $currentUrlRewritesRegenerator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function generate($category)
+    {
+        $this->category = $category;
+
+        $storeId = $this->category->getStoreId();
+        $urls = $this->isGlobalScope($storeId)
+            ? $this->generateForGlobalScope()
+            : $this->generateForSpecificStoreView($storeId);
+
+        $this->category = null;
+        return $urls;
+    }
+
+    /**
+     * Generate list of urls for global scope
+     *
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    protected function generateForGlobalScope()
+    {
+        $urls = [];
+        $categoryId = $this->category->getId();
+        foreach ($this->category->getStoreIds() as $id) {
+            if (!$this->isGlobalScope($id)
+                && !$this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore($id, $categoryId, Category::ENTITY)
+            ) {
+                $urls = array_merge($urls, $this->generateForSpecificStoreView($id));
+            }
+        }
+        return $urls;
+    }
+
+    /**
+     * Check is global scope
+     *
+     * @param int|null $storeId
+     * @return bool
+     */
+    protected function isGlobalScope($storeId)
+    {
+        return null === $storeId || $storeId == Store::DEFAULT_STORE_ID;
+    }
+
+    /**
+     * Generate list of urls per store
+     *
+     * @param string $storeId
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    protected function generateForSpecificStoreView($storeId)
+    {
+        $urls = array_merge(
+            $this->canonicalUrlRewriteGenerator->generate($storeId, $this->category),
+            $this->childrenUrlRewriteGenerator->generate($storeId, $this->category),
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
+        );
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite/TypeProvider.php b/app/code/Magento/CatalogUrlRewrite/Model/ObjectRegistry.php
similarity index 57%
rename from app/code/Magento/UrlRewrite/Model/UrlRewrite/TypeProvider.php
rename to app/code/Magento/CatalogUrlRewrite/Model/ObjectRegistry.php
index 1d6f90505d7..7b8ca03bf89 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlRewrite/TypeProvider.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ObjectRegistry.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * URL Rewrite Type Provider
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,44 +21,42 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRewrite\Model\UrlRewrite;
-
-use Magento\Framework\Option\ArrayInterface;
+namespace Magento\CatalogUrlRewrite\Model;
 
-class TypeProvider implements ArrayInterface
+class ObjectRegistry
 {
-    const SYSTEM = 1;
-
-    const CUSTOM = 0;
-
     /**
-     * @var array|null
+     * Key is id of entity, value is entity
+     *
+     * @var \Magento\Framework\Object[]
      */
-    protected $_options = null;
+    protected $entitiesMap;
 
     /**
-     * Get all options
-     *
-     * @return array
+     * @param \Magento\Framework\Object[] $entities
      */
-    public function getAllOptions()
+    public function __construct($entities)
     {
-        if (is_null($this->_options)) {
-            $this->_options = array(
-                self::SYSTEM => __('System'),
-                self::CUSTOM => __('Custom'),
-            );
+        $this->entitiesMap = [];
+        foreach ($entities as $entity) {
+            $this->entitiesMap[$entity->getId()] = $entity;
         }
-        return $this->_options;
     }
 
     /**
-     * Return option array
-     *
-     * @return array
+     * @param int $entityId
+     * @return \Magento\Framework\Object|null
+     */
+    public function get($entityId)
+    {
+        return isset($this->entitiesMap[$entityId]) ? $this->entitiesMap[$entityId] : null;
+    }
+
+    /**
+     * @return \Magento\Framework\Object[]
      */
-    public function toOptionArray()
+    public function getList()
     {
-        return $this->getAllOptions();
+        return $this->entitiesMap;
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGenerator.php
new file mode 100644
index 00000000000..84f9677fa5e
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+
+class CanonicalUrlRewriteGenerator
+{
+    /** @var ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @param ProductUrlPathGenerator $productUrlPathGenerator
+     * @param UrlRewriteBuilder $urlRewriteBuilder
+     */
+    public function __construct(ProductUrlPathGenerator $productUrlPathGenerator, UrlRewriteBuilder $urlRewriteBuilder)
+    {
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
+    }
+
+    /**
+     * Generate list based on store view
+     *
+     * @param int $storeId
+     * @param Product $product
+     * @return UrlRewrite[]
+     */
+    public function generate($storeId, Product $product)
+    {
+        return [
+            $this->urlRewriteBuilder
+                ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($product->getId())
+                ->setRequestPath($this->productUrlPathGenerator->getUrlPathWithSuffix($product, $storeId))
+                ->setTargetPath($this->productUrlPathGenerator->getCanonicalUrlPath($product))
+                ->setStoreId($storeId)
+                ->create()
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGenerator.php
new file mode 100644
index 00000000000..7709ac4711f
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGenerator.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\ObjectRegistry;
+use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+
+class CategoriesUrlRewriteGenerator
+{
+    /** @var ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @param ProductUrlPathGenerator $productUrlPathGenerator
+     * @param UrlRewriteBuilder $urlRewriteBuilder
+     */
+    public function __construct(ProductUrlPathGenerator $productUrlPathGenerator, UrlRewriteBuilder $urlRewriteBuilder)
+    {
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
+    }
+
+    /**
+     * Generate list based on categories
+     *
+     * @param int $storeId
+     * @param Product $product
+     * @param ObjectRegistry $productCategories
+     * @return UrlRewrite[]
+     */
+    public function generate($storeId, Product $product, ObjectRegistry $productCategories)
+    {
+        $urls = [];
+        foreach ($productCategories->getList() as $category) {
+            $urls[] = $this->urlRewriteBuilder
+                ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($product->getId())
+                ->setRequestPath($this->productUrlPathGenerator->getUrlPathWithSuffix($product, $storeId, $category))
+                ->setTargetPath($this->productUrlPathGenerator->getCanonicalUrlPath($product, $category))
+                ->setStoreId($storeId)
+                ->setMetadata(['category_id' => $category->getId()])
+                ->create();
+        }
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegenerator.php
new file mode 100644
index 00000000000..0082d14a5a7
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegenerator.php
@@ -0,0 +1,179 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+use Magento\CatalogUrlRewrite\Model\ObjectRegistry;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+use Magento\Framework\StoreManagerInterface;
+
+class CurrentUrlRewritesRegenerator
+{
+    /** @var Product */
+    protected $product;
+
+    /** @var ObjectRegistry */
+    protected $productCategories;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
+    /** @var ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @param UrlFinderInterface $urlFinder
+     * @param ProductUrlPathGenerator $productUrlPathGenerator
+     * @param UrlRewriteBuilder $urlRewriteBuilder
+     */
+    public function __construct(
+        UrlFinderInterface $urlFinder,
+        ProductUrlPathGenerator $productUrlPathGenerator,
+        UrlRewriteBuilder $urlRewriteBuilder
+    ) {
+        $this->urlFinder = $urlFinder;
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
+    }
+
+    /**
+     * Generate list based on current rewrites
+     *
+     * @param int $storeId
+     * @param Product $product
+     * @param ObjectRegistry $productCategories
+     * @return UrlRewrite[]
+     */
+    public function generate($storeId, Product $product, ObjectRegistry $productCategories)
+    {
+        $this->product = $product;
+        $this->productCategories = $productCategories;
+
+        $currentUrlRewrites = $this->urlFinder->findAllByData(
+            [
+                UrlRewrite::STORE_ID => $storeId,
+                UrlRewrite::ENTITY_ID => $this->product->getId(),
+                UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+            ]
+        );
+
+        $urlRewrites = [];
+        foreach ($currentUrlRewrites as $currentUrlRewrite) {
+            $category = $this->retrieveCategoryFromMetadata($currentUrlRewrite);
+            if ($category === false) {
+                continue;
+            }
+            $url = $currentUrlRewrite->getIsAutogenerated()
+                ? $this->generateForAutogenerated($currentUrlRewrite, $storeId, $category)
+                : $this->generateForCustom($currentUrlRewrite, $storeId, $category);
+            $urlRewrites = array_merge($urlRewrites, $url);
+        }
+
+        $this->product = null;
+        $this->productCategories = null;
+        return $urlRewrites;
+    }
+
+    /**
+     * @param UrlRewrite $url
+     * @param int $storeId
+     * @param Category|null $category
+     * @return array
+     */
+    protected function generateForAutogenerated($url, $storeId, $category)
+    {
+        if (!$this->product->getData('save_rewrites_history')) {
+            return [];
+        }
+        $targetPath = $this->productUrlPathGenerator->getUrlPathWithSuffix($this->product, $storeId, $category);
+        if ($url->getRequestPath() === $targetPath) {
+            return [];
+        }
+        return [
+            $this->urlRewriteBuilder
+                ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($this->product->getId())
+                ->setRequestPath($url->getRequestPath())
+                ->setTargetPath($targetPath)
+                ->setRedirectType(OptionProvider::PERMANENT)
+                ->setStoreId($storeId)
+                ->setDescription($url->getDescription())
+                ->setIsAutogenerated(0)
+                ->setMetadata($url->getMetadata())
+                ->create()
+        ];
+    }
+
+    /**
+     * @param UrlRewrite $url
+     * @param int $storeId
+     * @param Category|null $category
+     * @return array
+     */
+    protected function generateForCustom($url, $storeId, $category)
+    {
+        $targetPath = $url->getRedirectType()
+            ? $this->productUrlPathGenerator->getUrlPathWithSuffix($this->product, $storeId, $category)
+            : $url->getTargetPath();
+        if ($url->getRequestPath() === $targetPath) {
+            return [];
+        }
+        return [
+            $this->urlRewriteBuilder
+                ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE)
+                ->setEntityId($this->product->getId())
+                ->setRequestPath($url->getRequestPath())
+                ->setTargetPath($targetPath)
+                ->setRedirectType($url->getRedirectType())
+                ->setStoreId($storeId)
+                ->setDescription($url->getDescription())
+                ->setIsAutogenerated(0)
+                ->setMetadata($url->getMetadata())
+                ->create()
+        ];
+    }
+
+    /**
+     * @param UrlRewrite $url
+     * @return Category|null|bool
+     */
+    protected function retrieveCategoryFromMetadata($url)
+    {
+        $metadata = $url->getMetadata();
+        if (isset($metadata['category_id'])) {
+            $category = $this->productCategories->get($metadata['category_id']);
+            return $category === null ? false : $category;
+        }
+        return null;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php
index 9dfbb358ce5..11e44bf6160 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/Observer.php
@@ -23,41 +23,33 @@
  */
 namespace Magento\CatalogUrlRewrite\Model\Product;
 
-use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper;
-use Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface;
 use Magento\Framework\Event\Observer as EventObserver;
-use Magento\UrlRedirect\Service\V1\UrlSaveInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
 
 class Observer
 {
     /**
-     * @var ProductUrlGeneratorInterface
+     * @var ProductUrlRewriteGenerator
      */
-    protected $productUrlGenerator;
+    protected $productUrlRewriteGenerator;
 
     /**
-     * @var UrlSaveInterface
+     * @var UrlPersistInterface
      */
-    protected $urlSave;
+    protected $urlPersist;
 
     /**
-     * @var CatalogUrlRewriteHelper
-     */
-    protected $catalogUrlRewriteHelper;
-
-    /**
-     * @param ProductUrlGeneratorInterface $productUrlGenerator
-     * @param UrlSaveInterface $urlSave
-     * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     * @param UrlPersistInterface $urlPersist
      */
     public function __construct(
-        ProductUrlGeneratorInterface $productUrlGenerator,
-        UrlSaveInterface $urlSave,
-        CatalogUrlRewriteHelper $catalogUrlRewriteHelper
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator,
+        UrlPersistInterface $urlPersist
     ) {
-        $this->productUrlGenerator = $productUrlGenerator;
-        $this->urlSave = $urlSave;
-        $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+        $this->urlPersist = $urlPersist;
     }
 
     /**
@@ -71,12 +63,36 @@ class Observer
         /** @var \Magento\Catalog\Model\Product $product */
         $product = $observer->getEvent()->getProduct();
 
-        if (!$product->getUrlPath() || $product->getOrigData('url_key') != $product->getData('url_key')) {
-            $product->setUrlPath($this->catalogUrlRewriteHelper->generateProductUrlKeyPath($product));
+        $isChangedWebsites = $product->getIsChangedWebsites();
+        if ($product->dataHasChangedFor('url_key') || $product->getIsChangedCategories() || $isChangedWebsites) {
+            if ($isChangedWebsites) {
+                $this->urlPersist->deleteByData([
+                    UrlRewrite::ENTITY_ID => $product->getId(),
+                    UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+                ]);
+            }
+            $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
         }
+    }
+
+    /**
+     * Remove product urls from storage
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return void
+     */
+    public function processUrlRewriteRemoving(EventObserver $observer)
+    {
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = $observer->getEvent()->getProduct();
 
-        if (!$product->getData('url_key') || $product->getOrigData('url_key') != $product->getData('url_key')) {
-            $this->urlSave->save($this->productUrlGenerator->generate($product));
+        if ($product->getId()) {
+            $this->urlPersist->deleteByData(
+                [
+                    UrlRewrite::ENTITY_ID => $product->getId(),
+                    UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+                ]
+            );
         }
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/Plugin/Import.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/Plugin/Import.php
new file mode 100644
index 00000000000..655ea14dac7
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/Plugin/Import.php
@@ -0,0 +1,105 @@
+<?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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product\Plugin;
+
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+use Magento\Catalog\Model\ProductFactory;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\ImportExport\Model\Import as ImportExport;
+use Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
+
+class Import
+{
+    /** @var ProductFactory  */
+    protected $productFactory;
+
+    /** @var UrlPersistInterface */
+    protected $urlPersist;
+
+    /** @var ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
+
+    /**
+     * @param ProductFactory $productFactory
+     * @param UrlPersistInterface $urlPersist
+     * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
+     */
+    public function __construct(
+        ProductFactory $productFactory,
+        UrlPersistInterface $urlPersist,
+        ProductUrlRewriteGenerator $productUrlRewriteGenerator
+    ) {
+        $this->productFactory = $productFactory;
+        $this->urlPersist = $urlPersist;
+        $this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
+    }
+
+    /**
+     * @param ImportProduct $import
+     * @param bool $result
+     * @return bool
+     */
+    public function afterImportData(ImportProduct $import, $result)
+    {
+        if ($import->getAffectedEntityIds()) {
+            foreach ($import->getAffectedEntityIds() as $productId) {
+                $product = $this->productFactory->create()->load($productId);
+                $productUrls = $this->productUrlRewriteGenerator->generate($product);
+                if ($productUrls) {
+                    $this->urlPersist->replace($productUrls);
+                }
+            }
+        } elseif (ImportExport::BEHAVIOR_DELETE == $import->getBehavior()) {
+            $this->clearProductUrls($import);
+        }
+
+        return $result;
+    }
+
+    /**
+     * @param ImportProduct $import
+     * @return void
+     */
+    protected function clearProductUrls(ImportProduct $import)
+    {
+        $oldSku = $import->getOldSku();
+        while ($bunch = $import->getNextBunch()) {
+            $idToDelete = [];
+            foreach ($bunch as $rowNum => $rowData) {
+                if ($import->validateRow($rowData, $rowNum)
+                    && ImportProduct::SCOPE_DEFAULT == $import->getRowScope($rowData)
+                ) {
+                    $idToDelete[] = $oldSku[$rowData[ImportProduct::COL_SKU]]['entity_id'];
+                }
+            }
+            foreach ($idToDelete as $productId) {
+                $this->urlPersist->deleteByData([
+                    UrlRewrite::ENTITY_ID => $productId,
+                    UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+                ]);
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php
new file mode 100644
index 00000000000..be5e811e248
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+class ProductUrlPathGenerator
+{
+    const XML_PATH_PRODUCT_URL_SUFFIX = 'catalog/seo/product_url_suffix';
+
+    /**
+     * Cache for product rewrite suffix
+     *
+     * @var array
+     */
+    protected $productUrlSuffix = [];
+
+    /** @var \Magento\Framework\StoreManagerInterface */
+    protected $storeManager;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface */
+    protected $scopeConfig;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /**
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param CategoryUrlPathGenerator $categoryUrlPathGenerator
+     */
+    public function __construct(
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
+    ) {
+        $this->storeManager = $storeManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+    }
+
+    /**
+     * Retrieve Product Url path (with category if exists)
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param \Magento\Catalog\Model\Category $category
+     *
+     * @return string
+     */
+    public function getUrlPath($product, $category = null)
+    {
+        $path = $product->getData('url_path');
+        if ($path === null) {
+            $path = $this->generateUrlKey($product);
+        }
+        return $category === null ? $path
+            : $this->categoryUrlPathGenerator->getUrlPath($category) . '/' . $path;
+    }
+
+    /**
+     * Retrieve Product Url path with suffix
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param int $storeId
+     * @param \Magento\Catalog\Model\Category $category
+     * @return string
+     */
+    public function getUrlPathWithSuffix($product, $storeId, $category = null)
+    {
+        return $this->getUrlPath($product, $category) . $this->getProductUrlSuffix($storeId);
+    }
+
+    /**
+     * Get canonical product url path
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param \Magento\Catalog\Model\Category|null $category
+     * @return string
+     */
+    public function getCanonicalUrlPath($product, $category = null)
+    {
+        $path =  'catalog/product/view/id/' . $product->getId();
+        return $category ? $path . '/category/' . $category->getId() : $path;
+    }
+
+    /**
+     * Generate product url key based on url_key entered by merchant or product name
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return string
+     */
+    public function generateUrlKey($product)
+    {
+        $urlKey = $product->getUrlKey();
+        return $product->formatUrlKey($urlKey === '' || $urlKey === null ? $product->getName() : $urlKey);
+    }
+
+    /**
+     * Retrieve product rewrite suffix for store
+     *
+     * @param int $storeId
+     * @return string
+     */
+    protected function getProductUrlSuffix($storeId = null)
+    {
+        if (is_null($storeId)) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+
+        if (!isset($this->productUrlSuffix[$storeId])) {
+            $this->productUrlSuffix[$storeId] = $this->scopeConfig->getValue(
+                self::XML_PATH_PRODUCT_URL_SUFFIX,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $storeId
+            );
+        }
+        return $this->productUrlSuffix[$storeId];
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
new file mode 100644
index 00000000000..140749d6a1e
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
+use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator;
+use Magento\Store\Model\Store;
+
+class ProductUrlRewriteGenerator
+{
+    /**
+     * Entity type code
+     */
+    const ENTITY_TYPE = 'product';
+
+    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService */
+    protected $storeViewService;
+
+    /** @var \Magento\Catalog\Model\Product */
+    protected $product;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator */
+    protected $categoriesUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory */
+    protected $objectRegistryFactory;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry */
+    protected $productCategories;
+
+    /** @var \Magento\Framework\StoreManagerInterface */
+    protected $storeManager;
+
+    /**
+     * @param \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator
+     * @param \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator
+     * @param \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator $categoriesUrlRewriteGenerator
+     * @param \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory $objectRegistryFactory
+     * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator,
+        CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator,
+        CategoriesUrlRewriteGenerator $categoriesUrlRewriteGenerator,
+        ObjectRegistryFactory $objectRegistryFactory,
+        StoreViewService $storeViewService,
+        \Magento\Framework\StoreManagerInterface $storeManager
+    ) {
+        $this->canonicalUrlRewriteGenerator = $canonicalUrlRewriteGenerator;
+        $this->currentUrlRewritesRegenerator = $currentUrlRewritesRegenerator;
+        $this->categoriesUrlRewriteGenerator = $categoriesUrlRewriteGenerator;
+        $this->objectRegistryFactory = $objectRegistryFactory;
+        $this->storeViewService = $storeViewService;
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * Generate product url rewrites
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generate(Product $product)
+    {
+        $this->product = $product;
+        $storeId = $this->product->getStoreId();
+
+        $productCategories = $product->getCategoryCollection()
+            ->addAttributeToSelect('url_key')
+            ->addAttributeToSelect('url_path');
+
+        $urls = $this->isGlobalScope($storeId)
+            ? $this->generateForGlobalScope($productCategories)
+            : $this->generateForSpecificStoreView($storeId, $productCategories);
+
+        $this->product = null;
+        return $urls;
+    }
+
+    /**
+     * Check is global scope
+     *
+     * @param int|null $storeId
+     * @return bool
+     */
+    protected function isGlobalScope($storeId)
+    {
+        return null === $storeId || $storeId == Store::DEFAULT_STORE_ID;
+    }
+
+    /**
+     * Generate list of urls for global scope
+     *
+     * @param \Magento\Framework\Data\Collection $productCategories
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    protected function generateForGlobalScope($productCategories)
+    {
+        $urls = [];
+        $productId = $this->product->getId();
+        foreach ($this->product->getStoreIds() as $id) {
+            if (!$this->isGlobalScope($id)
+                && !$this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore($id, $productId, Product::ENTITY)
+            ) {
+                $urls = array_merge($urls, $this->generateForSpecificStoreView($id, $productCategories));
+            }
+        }
+        return $urls;
+    }
+
+    /**
+     * Generate list of urls for specific store view
+     *
+     * @param int $storeId
+     * @param \Magento\Framework\Data\Collection $productCategories
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    protected function generateForSpecificStoreView($storeId, $productCategories)
+    {
+        $categories = [];
+        foreach ($productCategories as $category) {
+            if ($this->isCategoryProperForGenerating($category, $storeId)) {
+                $categories[] = $category;
+            }
+        }
+        $this->productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
+        $urls = array_merge(
+            $this->canonicalUrlRewriteGenerator->generate($storeId, $this->product),
+            $this->categoriesUrlRewriteGenerator->generate($storeId, $this->product, $this->productCategories),
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->productCategories)
+        );
+        $this->productCategories = null;
+        return $urls;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Category $category
+     * @param int $storeId
+     * @return bool
+     */
+    protected function isCategoryProperForGenerating($category, $storeId)
+    {
+        if ($category->getParentId() != \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
+            list(, $rootCategoryId) = $category->getParentIds();
+            return $rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId();
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/Product.php b/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/Product.php
new file mode 100644
index 00000000000..cd908d3bb6a
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/Product.php
@@ -0,0 +1,84 @@
+<?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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Resource\Category;
+
+use Magento\Framework\Model\Resource\Db\AbstractDb;
+
+class Product extends AbstractDb
+{
+    /**
+     * Product/Category relation table name
+     */
+    const TABLE_NAME = 'catalog_url_rewrite_product_category';
+
+    /**
+     * Chunk for mass insert
+     */
+    const CHUNK_SIZE = 100;
+
+    /**
+     * Primary key auto increment flag
+     *
+     * @var bool
+     */
+    protected $_isPkAutoIncrement = false;
+
+    /**
+     * Resource initialization
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init(self::TABLE_NAME, 'url_rewrite_id');
+    }
+
+    /**
+     * @param array $insertData
+     * @return int
+     */
+    public function saveMultiple(array $insertData)
+    {
+        $write = $this->_getWriteAdapter();
+        if (sizeof($insertData) <= self::CHUNK_SIZE) {
+            return $write->insertMultiple($this->getTable(self::TABLE_NAME), $insertData);
+        }
+        $data = array_chunk($insertData, self::CHUNK_SIZE);
+        $totalCount = 0;
+        foreach ($data as $insertData) {
+            $totalCount += $write->insertMultiple($this->getTable(self::TABLE_NAME), $insertData);
+        }
+        return $totalCount;
+    }
+
+    /**
+     * @param array $removeData
+     * @return int
+     */
+    public function removeMultiple(array $removeData)
+    {
+        $write = $this->_getWriteAdapter();
+        return $write->delete($this->getTable(self::TABLE_NAME), array('url_rewrite_id in (?)' => $removeData));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/ProductCollection.php b/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/ProductCollection.php
new file mode 100644
index 00000000000..cdef9b27ecb
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Resource/Category/ProductCollection.php
@@ -0,0 +1,31 @@
+<?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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Resource\Category;
+
+use Magento\Framework\Model\Resource\Db\Collection\AbstractCollection;
+
+class ProductCollection extends AbstractCollection
+{
+
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php
new file mode 100644
index 00000000000..3de17760a84
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Storage;
+
+use Magento\CatalogUrlRewrite\Model\Resource\Category\Product;
+use Magento\UrlRewrite\Model\Storage\DbStorage as BaseDbStorage;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+
+class DbStorage extends BaseDbStorage
+{
+    /**
+     * @param array $data
+     * @return \Magento\Framework\DB\Select
+     */
+    protected function prepareSelect($data)
+    {
+        $select = $this->connection->select();
+        $select->from(array('url_rewrite' => $this->resource->getTableName('url_rewrite')))
+            ->joinLeft(
+                array('relation' => $this->resource->getTableName(Product::TABLE_NAME)),
+                'url_rewrite.url_rewrite_id = relation.url_rewrite_id'
+            )
+            ->where('url_rewrite.entity_id = ?', $data['entity_id'])
+            ->where('url_rewrite.entity_type = ?', $data['entity_type'])
+            ->where('url_rewrite.store_id = ?', $data['store_id']);
+        if (empty($data[UrlRewrite::METADATA]['category_id'])) {
+            $select->where('relation.category_id IS NULL');
+        } else {
+            $select->where('relation.category_id = ?', $data[UrlRewrite::METADATA]['category_id']);
+        }
+        return $select;
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategorySaveRewritesHistorySetter.php
similarity index 58%
rename from app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php
rename to app/code/Magento/CatalogUrlRewrite/Observer/CategorySaveRewritesHistorySetter.php
index b03a433d44c..f3a8c6e4cd7 100644
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategorySaveRewritesHistorySetter.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,22 +21,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Controller\Adminhtml\Process;
+namespace Magento\CatalogUrlRewrite\Observer;
+
+use Magento\Catalog\Model\Category;
+use Magento\Framework\Event\Observer;
 
-class ListAction extends \Magento\Index\Controller\Adminhtml\Process
+class CategorySaveRewritesHistorySetter
 {
     /**
-     * Display processes grid action
-     *
+     * @param Observer $observer
      * @return void
      */
-    public function execute()
+    public function invoke(Observer $observer)
     {
-        $this->_title->add(__('Index Management'));
+        /** @var Category $category */
+        $category = $observer->getEvent()->getCategory();
+        $data = $observer->getEvent()->getRequest()->getPost();
 
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Index::system_index');
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Index\Block\Adminhtml\Process'));
-        $this->_view->renderLayout();
+        /**
+         * Create Permanent Redirect for old URL key
+         */
+        if ($category->getId() && isset($data['general']['url_key_create_redirect'])) {
+            $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
+        }
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogenerator.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogenerator.php
new file mode 100644
index 00000000000..52201a2023c
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Observer;
+
+use Magento\Catalog\Model\Category;
+use Magento\Framework\Event\Observer;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
+
+class CategoryUrlPathAutogenerator
+{
+    /** @var CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /**
+     * @param CategoryUrlPathGenerator $categoryUrlPathGenerator
+     */
+    public function __construct(CategoryUrlPathGenerator $categoryUrlPathGenerator)
+    {
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+    }
+
+    /**
+     * @param Observer $observer
+     * @return void
+     */
+    public function invoke(Observer $observer)
+    {
+        /** @var Category $category */
+        $category = $observer->getEvent()->getCategory();
+        $category->setUrlKey($this->categoryUrlPathGenerator->generateUrlKey($category))
+            ->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductUrlKeyAutogenerator.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductUrlKeyAutogenerator.php
new file mode 100644
index 00000000000..21d625ed74c
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductUrlKeyAutogenerator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Observer;
+
+use Magento\Catalog\Model\Product;
+use Magento\Framework\Event\Observer;
+use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
+
+class ProductUrlKeyAutogenerator
+{
+    /** @var ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /**
+     * @param ProductUrlPathGenerator $productUrlPathGenerator
+     */
+    public function __construct(ProductUrlPathGenerator $productUrlPathGenerator)
+    {
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+    }
+
+    /**
+     * @param Observer $observer
+     * @return void
+     */
+    public function invoke(Observer $observer)
+    {
+        /** @var Product $product */
+        $product = $observer->getEvent()->getProduct();
+        $product->setUrlKey($this->productUrlPathGenerator->generateUrlKey($product));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
new file mode 100644
index 00000000000..27072a8d4ed
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php
@@ -0,0 +1,57 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Plugin\Catalog\Block\Adminhtml\Category\Tab;
+
+class Attributes
+{
+    /**
+     * @param \Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes $subject
+     * @param \Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes $result
+     *
+     * @return \Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes
+     */
+    public function afterSetForm(
+        \Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes $subject,
+        \Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes $result
+    ) {
+        $form = $subject->getForm();
+        $fieldset = $form->getElements()[0];
+        $field = $form->getElement('url_key');
+        if ($field) {
+            if ($subject->getCategory()->getLevel() == 1) {
+                $fieldset->removeField('url_key');
+                $fieldset->addField(
+                    'url_key',
+                    'hidden',
+                    array('name' => 'url_key', 'value' => $subject->getCategory()->getUrlKey())
+                );
+            } else {
+                $field->setRenderer(
+                    $subject->getLayout()->createBlock('Magento\CatalogUrlRewrite\Block\UrlKeyRenderer')
+                );
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Price.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
similarity index 53%
rename from app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Price.php
rename to app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
index ba23be189a1..006d09c09cc 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Price.php
+++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Product/Edit/Tab/Attributes.php
@@ -21,26 +21,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\CatalogUrlRewrite\Plugin\Catalog\Block\Adminhtml\Product\Edit\Tab;
 
-/**
- * Product form MSRP field helper
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp;
-
-class Price extends \Magento\Framework\Data\Form\Element\Select
+class Attributes
 {
     /**
-     * Retrieve Element HTML fragment
-     *
-     * @return string
+     * @param \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes $subject
+     * @param \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes $result
+     * @return \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes
      */
-    public function getElementHtml()
-    {
-        if (is_null($this->getValue())) {
-            $this->setValue(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price::TYPE_USE_CONFIG);
+    public function afterSetForm(
+        \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes $subject,
+        \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes $result
+    ) {
+        $form = $subject->getForm();
+        $field = $form->getElement('url_key');
+        if ($field) {
+            $field->setRenderer(
+                $subject->getLayout()->createBlock('Magento\CatalogUrlRewrite\Block\UrlKeyRenderer')
+            );
         }
-        return parent::getElementHtml();
+        return $result;
     }
 }
diff --git a/app/code/Magento/UrlRewrite/App/FrontController/Plugin/UrlRewrite.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
similarity index 55%
rename from app/code/Magento/UrlRewrite/App/FrontController/Plugin/UrlRewrite.php
rename to app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
index be99bf62d82..d8bacc6458b 100644
--- a/app/code/Magento/UrlRewrite/App/FrontController/Plugin/UrlRewrite.php
+++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Url Rewrite front controller plugin. Performs url rewrites
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,40 +21,39 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRewrite\App\FrontController\Plugin;
+namespace Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization;
 
-class UrlRewrite
+class Helper
 {
-    /**
-     * @var \Magento\UrlRewrite\App\Request\RewriteService
-     */
-    protected $_rewriteService;
+    /** @var \Magento\Framework\App\RequestInterface */
+    protected $request;
 
     /**
-     * @param \Magento\UrlRewrite\App\Request\RewriteService $rewriteService
+     * @param \Magento\Framework\App\RequestInterface $request
      */
     public function __construct(
-        \Magento\UrlRewrite\App\Request\RewriteService $rewriteService
+        \Magento\Framework\App\RequestInterface $request
     ) {
-        $this->_rewriteService = $rewriteService;
+        $this->request = $request;
     }
 
     /**
-     * Perform url rewrites
-     *
-     * @param \Magento\Framework\App\FrontController $subject
-     * @param callable $proceed
-     * @param \Magento\Framework\App\RequestInterface $request
-     *
-     * @return \Magento\Framework\App\ResponseInterface
+     * @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject
+     * @param \Magento\Catalog\Model\Product $result
+     * @return \Magento\Catalog\Model\Product
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function aroundDispatch(
-        \Magento\Framework\App\FrontController $subject,
-        \Closure $proceed,
-        \Magento\Framework\App\RequestInterface $request
+    public function afterInitialize(
+        \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject,
+        \Magento\Catalog\Model\Product $result
     ) {
-        $this->_rewriteService->applyRewrites($request);
-        return $proceed($request);
+        $productData = $this->request->getPost('product');
+        /**
+         * Create Permanent Redirect for old URL key
+         */
+        if ($result->getId() && isset($productData['url_key_create_redirect'])) {
+            $result->setData('save_rewrites_history', (bool)$productData['url_key_create_redirect']);
+        }
+        return $result;
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php
deleted file mode 100644
index 73abbe199dd..00000000000
--- a/app/code/Magento/CatalogUrlRewrite/Service/V1/AbstractUrlGenerator.php
+++ /dev/null
@@ -1,40 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\CatalogUrlRewrite\Service\V1;
-
-use Magento\Catalog\Model\ProductFactory;
-use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper;
-use Magento\Framework\StoreManagerInterface;
-use Magento\UrlRedirect\Model\OptionProvider;
-use Magento\UrlRedirect\Service\V1\Data\Converter;
-use Magento\UrlRedirect\Service\V1\Data\FilterFactory;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewrite;
-use Magento\UrlRedirect\Service\V1\UrlMatcherInterface;
-
-/**
- * Product Generator
- */
-abstract class AbstractUrlGenerator
-{
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php
deleted file mode 100644
index 31d86734e46..00000000000
--- a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGenerator.php
+++ /dev/null
@@ -1,213 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\CatalogUrlRewrite\Service\V1;
-
-use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper;
-use Magento\Framework\StoreManagerInterface;
-use Magento\UrlRedirect\Model\OptionProvider;
-use Magento\UrlRedirect\Service\V1\Data\FilterFactory;
-use Magento\UrlRedirect\Service\V1\UrlMatcherInterface;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewrite;
-
-/**
- * Product Generator
- */
-class CategoryUrlGenerator implements CategoryUrlGeneratorInterface
-{
-    /**
-     * Entity type
-     */
-    const ENTITY_TYPE_CATEGORY = 'category';
-
-    /**
-     * @var FilterFactory
-     */
-    protected $filterFactory;
-
-    /**
-     * Store manager
-     *
-     * @var \Magento\Framework\StoreManagerInterface
-     */
-    protected $storeManager;
-
-    /**
-     * @var UrlMatcherInterface
-     */
-    protected $urlMatcher;
-
-    /**
-     * @var CatalogUrlRewriteHelper
-     */
-    protected $catalogUrlRewriteHelper;
-
-    /**
-     * @var \Magento\Catalog\Model\Category
-     */
-    protected $category;
-
-    /**
-     * @var null|\Magento\Catalog\Model\Resource\Category\Collection
-     */
-    protected $categories;
-
-    /**
-     * @param FilterFactory $filterFactory
-     * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param UrlMatcherInterface $urlMatcher
-     * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper
-     */
-    public function __construct(
-        FilterFactory $filterFactory,
-        StoreManagerInterface $storeManager,
-        UrlMatcherInterface $urlMatcher,
-        CatalogUrlRewriteHelper $catalogUrlRewriteHelper
-    ) {
-        $this->filterFactory = $filterFactory;
-        $this->storeManager = $storeManager;
-        $this->urlMatcher = $urlMatcher;
-        $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function generate($category)
-    {
-        $this->category = $category;
-        $storeId = $this->category->getStoreId();
-
-        $urls = $this->catalogUrlRewriteHelper->isDefaultStore($storeId)
-            ? $this->generateForDefaultStore() : $this->generateForStore($storeId);
-
-        $this->category = null;
-        return $urls;
-    }
-
-    /**
-     * Generate list of urls for default store
-     *
-     * @return UrlRewrite[]
-     */
-    protected function generateForDefaultStore()
-    {
-        $urls = [];
-        foreach ($this->storeManager->getStores() as $store) {
-            if ($this->catalogUrlRewriteHelper->isNeedCreateUrlRewrite(
-                $store->getStoreId(),
-                $this->category->getId()
-            )) {
-                $urls = array_merge($urls, $this->generateForStore($store->getStoreId()));
-            }
-        }
-        return $urls;
-    }
-
-    /**
-     * Generate list of urls per store
-     *
-     * @param int $storeId
-     * @return UrlRewrite[]
-     */
-    protected function generateForStore($storeId)
-    {
-        $urls[] = $this->createUrlRewrite(
-            $storeId,
-            $this->catalogUrlRewriteHelper->getCategoryUrlKeyPath($this->category),
-            $this->catalogUrlRewriteHelper->getCategoryCanonicalUrlPath($this->category)
-        );
-
-        return array_merge($urls, $this->generateRewritesBasedOnCurrentRewrites($storeId));
-    }
-
-    /**
-     * Generate permanent rewrites based on current rewrites
-     *
-     * @param int $storeId
-     * @return array
-     */
-    protected function generateRewritesBasedOnCurrentRewrites($storeId)
-    {
-        $urls = [];
-        foreach ($this->urlMatcher->findAllByFilter($this->createCurrentUrlRewritesFilter($storeId)) as $url) {
-            $targetPath = null;
-            if ($url->getRedirectType()) {
-                $targetPath = str_replace(
-                    $this->category->getOrigData('url_key'),
-                    $this->category->getData('url_key'),
-                    $url->getTargetPath()
-                );
-                $redirectType = $url->getRedirectType();
-            } elseif ($this->category->getData('save_rewrites_history')) {
-                $targetPath = str_replace(
-                    $this->category->getOrigData('url_key'),
-                    $this->category->getData('url_key'),
-                    $url->getRequestPath()
-                );
-                $redirectType = OptionProvider::PERMANENT;
-            }
-
-            if ($targetPath && $url->getRequestPath() != $targetPath) {
-                $urls[] = $this->createUrlRewrite($storeId, $url->getRequestPath(), $targetPath, $redirectType);
-            }
-        }
-        return $urls;
-    }
-
-    /**
-     * @param int $storeId
-     * @return \Magento\UrlRedirect\Service\V1\Data\Filter
-     */
-    protected function createCurrentUrlRewritesFilter($storeId)
-    {
-        /** @var \Magento\UrlRedirect\Service\V1\Data\Filter $filter */
-        $filter = $this->filterFactory->create();
-
-        $filter->setStoreId($storeId);
-        $filter->setEntityId($this->category->getId());
-        $filter->setEntityType(self::ENTITY_TYPE_CATEGORY);
-        return $filter;
-    }
-
-    /**
-     * Create url rewrite object
-     *
-     * @param int $storeId
-     * @param string $requestPath
-     * @param string $targetPath
-     * @param string|null $redirectType Null or one of OptionProvider const
-     * @return UrlRewrite
-     */
-    protected function createUrlRewrite($storeId, $requestPath, $targetPath, $redirectType = null)
-    {
-        return $this->catalogUrlRewriteHelper->createUrlRewrite(
-            self::ENTITY_TYPE_CATEGORY,
-            $this->category->getId(),
-            $storeId,
-            $requestPath,
-            $targetPath,
-            $redirectType
-        );
-    }
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php
deleted file mode 100644
index a41fd154e90..00000000000
--- a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGenerator.php
+++ /dev/null
@@ -1,254 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\CatalogUrlRewrite\Service\V1;
-
-use Magento\CatalogUrlRewrite\Helper\Data as CatalogUrlRewriteHelper;
-use Magento\Framework\StoreManagerInterface;
-use Magento\UrlRedirect\Model\OptionProvider;
-use Magento\UrlRedirect\Service\V1\Data\FilterFactory;
-use Magento\UrlRedirect\Service\V1\UrlMatcherInterface;
-
-/**
- * Product Generator
- */
-class ProductUrlGenerator implements ProductUrlGeneratorInterface
-{
-    /**
-     * Entity type
-     */
-    const ENTITY_TYPE_PRODUCT = 'product';
-
-    /**
-     * @var FilterFactory
-     */
-    protected $filterFactory;
-
-    /**
-     * Store manager
-     *
-     * @var StoreManagerInterface
-     */
-    protected $storeManager;
-
-    /**
-     * @var UrlMatcherInterface
-     */
-    protected $urlMatcher;
-
-    /**
-     * @var CatalogUrlRewriteHelper
-     */
-    protected $catalogUrlRewriteHelper;
-
-    /**
-     * @var \Magento\Catalog\Model\Product
-     */
-    protected $product;
-
-    /**
-     * @var null|\Magento\Catalog\Model\Resource\Category\Collection
-     */
-    protected $categories;
-
-    /**
-     * @var \Magento\Catalog\Model\Category[]
-     */
-    protected $changedCategories;
-
-    /**
-     * @param FilterFactory $filterFactory
-     * @param StoreManagerInterface $storeManager
-     * @param UrlMatcherInterface $urlMatcher
-     * @param CatalogUrlRewriteHelper $catalogUrlRewriteHelper
-     */
-    public function __construct(
-        FilterFactory $filterFactory,
-        StoreManagerInterface $storeManager,
-        UrlMatcherInterface $urlMatcher,
-        CatalogUrlRewriteHelper $catalogUrlRewriteHelper
-    ) {
-        $this->filterFactory = $filterFactory;
-        $this->storeManager = $storeManager;
-        $this->urlMatcher = $urlMatcher;
-        $this->catalogUrlRewriteHelper = $catalogUrlRewriteHelper;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function generate($product)
-    {
-        $this->product = $product;
-        $storeId = $this->product->getStoreId();
-
-        $urls = $this->catalogUrlRewriteHelper->isDefaultStore($storeId)
-            ? $this->generateForDefaultStore() : $this->generateForStore($storeId);
-
-        $this->product = null;
-        $this->categories = null;
-        return $urls;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function generateWithChangedCategories($product, $changedCategories)
-    {
-        $this->changedCategories = $changedCategories;
-
-        return $this->generate($product);
-    }
-
-    /**
-     * Generate list of urls for default store
-     *
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
-     */
-    protected function generateForDefaultStore()
-    {
-        $urls = [];
-        foreach ($this->storeManager->getStores() as $store) {
-            if ($this->catalogUrlRewriteHelper->isNeedCreateUrlRewrite($store->getStoreId(), $this->product->getId())) {
-                $urls = array_merge($urls, $this->generateForStore($store->getStoreId()));
-            }
-        }
-        return $urls;
-    }
-
-    /**
-     * Generate list of urls per store
-     *
-     * @param int $storeId
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
-     */
-    protected function generateForStore($storeId)
-    {
-        $urls[] = $this->createUrlRewrite(
-            $storeId,
-            $this->catalogUrlRewriteHelper->getProductUrlKeyPath($this->product, $storeId),
-            $this->catalogUrlRewriteHelper->getProductCanonicalUrlPath($this->product)
-        );
-
-        foreach ($this->getCategories() as $category) {
-            if (isset($this->changedCategories[$category->getId()])) {
-                $category = $this->changedCategories[$category->getId()];
-            }
-
-            if ($this->catalogUrlRewriteHelper->isRootCategory($category)) {
-                continue;
-            }
-            $urls[] = $this->createUrlRewrite(
-                $storeId,
-                $this->catalogUrlRewriteHelper->getProductUrlKeyPathWithCategory($this->product, $category, $storeId),
-                $this->catalogUrlRewriteHelper->getProductCanonicalUrlPathWithCategory($this->product, $category)
-            );
-        }
-        return array_merge($urls, $this->generateRewritesBasedOnCurrentRewrites($storeId));
-    }
-
-    /**
-     * Generate permanent rewrites based on current rewrites
-     *
-     * @param int $storeId
-     * @return array
-     */
-    protected function generateRewritesBasedOnCurrentRewrites($storeId)
-    {
-        $urls = [];
-        foreach ($this->urlMatcher->findAllByFilter($this->createCurrentUrlRewritesFilter($storeId)) as $url) {
-            $targetPath = null;
-            if ($url->getRedirectType()) {
-                $targetPath = str_replace(
-                    $this->product->getOrigData('url_key'),
-                    $this->product->getData('url_key'),
-                    $url->getTargetPath()
-                );
-                $redirectType = $url->getRedirectType();
-            } elseif ($this->product->getData('save_rewrites_history')) {
-                $targetPath = str_replace(
-                    $this->product->getOrigData('url_key'),
-                    $this->product->getData('url_key'),
-                    $url->getRequestPath()
-                );
-                $redirectType = OptionProvider::PERMANENT;
-            }
-
-            if ($targetPath && $url->getRequestPath() != $targetPath) {
-                $urls[] = $this->createUrlRewrite($storeId, $url->getRequestPath(), $targetPath, $redirectType);
-            }
-        }
-        return $urls;
-    }
-
-    /**
-     * @param int $storeId
-     * @return \Magento\UrlRedirect\Service\V1\Data\Filter
-     */
-    protected function createCurrentUrlRewritesFilter($storeId)
-    {
-        /** @var \Magento\UrlRedirect\Service\V1\Data\Filter $filter */
-        $filter = $this->filterFactory->create();
-
-        $filter->setStoreId($storeId);
-        $filter->setEntityId($this->product->getId());
-        $filter->setEntityType(self::ENTITY_TYPE_PRODUCT);
-        return $filter;
-    }
-
-    /**
-     * Get categories assigned to product
-     *
-     * @return \Magento\Catalog\Model\Resource\Category\Collection
-     */
-    protected function getCategories()
-    {
-        if (!$this->categories) {
-            $this->categories = $this->product->getCategoryCollection();
-            $this->categories->addAttributeToSelect('url_key');
-            $this->categories->addAttributeToSelect('url_path');
-        }
-        return $this->categories;
-    }
-
-    /**
-     * Create url rewrite object
-     *
-     * @param int $storeId
-     * @param string $requestPath
-     * @param string $targetPath
-     * @param string|null $redirectType Null or one of OptionProvider const
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite
-     */
-    protected function createUrlRewrite($storeId, $requestPath, $targetPath, $redirectType = null)
-    {
-        return $this->catalogUrlRewriteHelper->createUrlRewrite(
-            self::ENTITY_TYPE_PRODUCT,
-            $this->product->getId(),
-            $storeId,
-            $requestPath,
-            $targetPath,
-            $redirectType
-        );
-    }
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php
deleted file mode 100644
index 75daa35a4df..00000000000
--- a/app/code/Magento/CatalogUrlRewrite/Service/V1/ProductUrlGeneratorInterface.php
+++ /dev/null
@@ -1,45 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\CatalogUrlRewrite\Service\V1;
-
-/**
- * Product Generator
- */
-interface ProductUrlGeneratorInterface
-{
-    /**
-     * Generate list of urls
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
-     */
-    public function generate($product);
-
-    /**
-     * @param \Magento\Catalog\Model\Product $product
-     * @param \Magento\Catalog\Model\Category[] $changedCategories
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
-     */
-    public function generateWithChangedCategories($product, $changedCategories);
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/StoreViewService.php b/app/code/Magento/CatalogUrlRewrite/Service/V1/StoreViewService.php
new file mode 100644
index 00000000000..f277e681292
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Service/V1/StoreViewService.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Service\V1;
+
+use Magento\Eav\Model\Config;
+use Magento\Framework\App\Resource;
+
+/**
+ * Store view service
+ */
+class StoreViewService
+{
+    /**
+     * @var \Magento\Eav\Model\Config
+     */
+    protected $eavConfig;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface
+     */
+    protected $connection;
+
+    /**
+     * @param Config $eavConfig
+     * @param \Magento\Framework\App\Resource $resource
+     */
+    public function __construct(
+        Config $eavConfig,
+        Resource $resource
+    ) {
+        $this->eavConfig = $eavConfig;
+        $this->connection = $resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
+    }
+
+    /**
+     * Check that entity has overridden url key for specific store
+     *
+     * @param int $storeId
+     * @param int $entityId
+     * @param string $entityType
+     * @throws \InvalidArgumentException
+     * @return bool
+     */
+    public function doesEntityHaveOverriddenUrlKeyForStore($storeId, $entityId, $entityType)
+    {
+        $attribute = $this->eavConfig->getAttribute($entityType, 'url_key');
+        if (!$attribute) {
+            throw new \InvalidArgumentException(sprintf('Cannot retrieve attribute for entity type "%s"', $entityType));
+        }
+        $select = $this->connection->select()
+            ->from($attribute->getBackendTable(), 'store_id')
+            ->where('attribute_id = ?', $attribute->getId())
+            ->where('entity_id = ?', $entityId);
+
+        return in_array($storeId, $this->connection->fetchCol($select));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json
index 5eecd5076d8..0eb731ddbca 100644
--- a/app/code/Magento/CatalogUrlRewrite/composer.json
+++ b/app/code/Magento/CatalogUrlRewrite/composer.json
@@ -3,15 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-url-redirect": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-catalog-import-export": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-import-export": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-url-rewrite": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CatalogUrlRewrite/data/catalogurlrewrite_setup/data-install-1.0.0.0.php b/app/code/Magento/CatalogUrlRewrite/data/catalogurlrewrite_setup/data-install-1.0.0.0.php
new file mode 100644
index 00000000000..3f96decf0e1
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/data/catalogurlrewrite_setup/data-install-1.0.0.0.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var $this \Magento\Catalog\Model\Resource\Setup */
+$this->addAttribute(
+    \Magento\Catalog\Model\Category::ENTITY,
+    'url_key',
+    array(
+        'type' => 'varchar',
+        'label' => 'URL Key',
+        'input' => 'text',
+        'required' => false,
+        'sort_order' => 3,
+        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
+        'group' => 'General Information'
+    )
+);
+
+$this->addAttribute(
+    \Magento\Catalog\Model\Category::ENTITY,
+    'url_path',
+    array(
+        'type' => 'varchar',
+        'required' => false,
+        'sort_order' => 17,
+        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
+        'visible' => false,
+    )
+);
+
+$this->addAttribute(
+    \Magento\Catalog\Model\Product::ENTITY,
+    'url_key',
+    array(
+        'type' => 'varchar',
+        'label' => 'URL Key',
+        'input' => 'text',
+        'required' => false,
+        'sort_order' => 10,
+        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
+        'used_in_product_listing' => true,
+        'group' => 'Search Engine Optimization'
+    )
+);
+
+$this->addAttribute(
+    \Magento\Catalog\Model\Product::ENTITY,
+    'url_path',
+    array(
+        'type' => 'varchar',
+        'required' => false,
+        'sort_order' => 11,
+        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE,
+        'visible' => false,
+    )
+);
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
index 7f2e29067ac..53e8834d9a3 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
@@ -24,6 +24,31 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\CatalogUrlRewrite\Service\V1\ProductUrlGeneratorInterface" type="Magento\CatalogUrlRewrite\Service\V1\ProductUrlGenerator"/>
-    <preference for="Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGeneratorInterface" type="Magento\CatalogUrlRewrite\Service\V1\CategoryUrlGenerator"/>
+    <type name="Magento\Store\Model\Resource\Store">
+        <plugin name="store_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\View"/>
+    </type>
+    <type name="Magento\Store\Model\Resource\Group">
+        <plugin name="group_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\Group"/>
+    </type>
+    <type name="Magento\Catalog\Model\Category">
+        <plugin name="category_delete_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Remove"/>
+    </type>
+    <type name="Magento\CatalogImportExport\Model\Import\Product">
+        <plugin name="import_save_plugin" type="Magento\CatalogUrlRewrite\Model\Product\Plugin\Import"/>
+    </type>
+    <type name="Magento\Catalog\Model\Resource\Category">
+        <plugin name="category_move_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move"/>
+    </type>
+    <type name="Magento\UrlRewrite\Model\StorageInterface">
+        <plugin name="storage_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Storage"/>
+    </type>
+    <type name="Magento\Catalog\Block\Adminhtml\Category\Tab\Attributes">
+        <plugin name="category_form_url_key_plugin" type="Magento\CatalogUrlRewrite\Plugin\Catalog\Block\Adminhtml\Category\Tab\Attributes"/>
+    </type>
+    <type name="Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes">
+        <plugin name="product_form_url_key_plugin" type="Magento\CatalogUrlRewrite\Plugin\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes"/>
+    </type>
+    <type name="Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper">
+        <plugin name="product_save_rewrites_history_plugin" type="Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization\Helper"/>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
index 1b6588ba293..f6395efefd8 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
@@ -24,10 +24,25 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
-    <event name="catalog_product_save_after">
-        <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Product\Observer" method="processUrlRewriteSaving"/>
+    <event name="catalog_category_prepare_save">
+        <observer name="category_save_rewrites_history_setter" instance="Magento\CatalogUrlRewrite\Observer\CategorySaveRewritesHistorySetter" method="invoke"/>
+    </event>
+    <event name="catalog_category_save_before">
+        <observer name="category_url_path_autogeneration" instance="Magento\CatalogUrlRewrite\Observer\CategoryUrlPathAutogenerator" method="invoke"/>
+    </event>
+    <event name="catalog_product_delete_before">
+        <observer name="process_url_rewrite_removing" instance="Magento\CatalogUrlRewrite\Model\Product\Observer" method="processUrlRewriteRemoving"/>
     </event>
     <event name="catalog_category_save_after">
         <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Category\Observer" method="processUrlRewriteSaving"/>
     </event>
+    <event name="catalog_product_save_before">
+        <observer name="product_url_key_autogeneration" instance="Magento\CatalogUrlRewrite\Observer\ProductUrlKeyAutogenerator" method="invoke"/>
+    </event>
+    <event name="catalog_product_save_after">
+        <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Product\Observer" method="processUrlRewriteSaving"/>
+    </event>
+    <event name="catalog_category_move_after">
+        <observer name="process_url_rewrite_moving" instance="Magento\CatalogUrlRewrite\Model\Category\Observer" method="processUrlRewriteMoving"/>
+    </event>
 </config>
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/system.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/system.xml
new file mode 100644
index 00000000000..8b993c27ad8
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/system.xml
@@ -0,0 +1,52 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/system_file.xsd">
+    <system>
+        <section id="catalog">
+            <group id="seo">
+                <label>Search Engine Optimization</label>
+                <field id="category_url_suffix" translate="label comment" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Category URL Suffix</label>
+                    <backend_model>Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite\Suffix</backend_model>
+                    <comment>You need to refresh the cache.</comment>
+                </field>
+                <field id="product_url_suffix" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Product URL Suffix</label>
+                    <backend_model>Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite\Suffix</backend_model>
+                    <comment>You need to refresh the cache.</comment>
+                </field>
+                <field id="product_use_categories" translate="label" type="select" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Use Categories Path for Product URLs</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="save_rewrites_history" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Create Permanent Redirect for URLs if URL Key Changed</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                </field>
+            </group>
+        </section>
+    </system>
+</config>
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/catalog_attributes.xml b/app/code/Magento/CatalogUrlRewrite/etc/catalog_attributes.xml
new file mode 100644
index 00000000000..3c6a01f297b
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/etc/catalog_attributes.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Catalog/etc/catalog_attributes.xsd">
+    <group name="catalog_category">
+        <attribute name="url_key"/>
+    </group>
+    <group name="catalog_product">
+        <attribute name="url_key"/>
+    </group>
+</config>
diff --git a/app/code/Magento/Index/etc/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/di.xml
similarity index 70%
rename from app/code/Magento/Index/etc/di.xml
rename to app/code/Magento/CatalogUrlRewrite/etc/di.xml
index 6a08ca9a1bb..fd53baf5d43 100644
--- a/app/code/Magento/Index/etc/di.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/di.xml
@@ -24,11 +24,20 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\Index\Model\Indexer\ConfigInterface" type="Magento\Index\Model\Indexer\Config" />
+    <type name="Magento\Catalog\Block\Widget\Link">
+        <arguments>
+            <argument name="urlFinder" xsi:type="object">Magento\CatalogUrlRewrite\Model\Storage\DbStorage</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Model\Product\Url">
+        <arguments>
+            <argument name="urlFinder" xsi:type="object">Magento\CatalogUrlRewrite\Model\Storage\DbStorage</argument>
+        </arguments>
+    </type>
     <type name="Magento\Framework\Module\Updater\SetupFactory">
         <arguments>
             <argument name="resourceTypes" xsi:type="array">
-                <item name="index_setup" xsi:type="string">Magento\Index\Model\Resource\Setup</item>
+                <item name="catalogurlrewrite_setup" xsi:type="string">Magento\Catalog\Model\Resource\Setup</item>
             </argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/Catalog/etc/indexers.xml b/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
similarity index 82%
rename from app/code/Magento/Catalog/etc/indexers.xml
rename to app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
index 52135bd75d7..bf11cd002cd 100644
--- a/app/code/Magento/Catalog/etc/indexers.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/eav_attributes.xml
@@ -23,6 +23,10 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Index/etc/indexers.xsd">
-    <indexer name="catalog_url" instance="Magento\Catalog\Model\Indexer\Url" />
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Eav/etc/eav_attributes.xsd">
+    <entity type="catalog_product">
+        <attribute code="url_key">
+            <field code="is_unique" locked="true" />
+        </attribute>
+    </entity>
 </config>
diff --git a/app/code/Magento/UrlRedirect/etc/frontend/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/install/di.xml
similarity index 68%
rename from app/code/Magento/UrlRedirect/etc/frontend/di.xml
rename to app/code/Magento/CatalogUrlRewrite/etc/install/di.xml
index 7b7acb7b3de..51d426c2e2b 100644
--- a/app/code/Magento/UrlRedirect/etc/frontend/di.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/install/di.xml
@@ -24,15 +24,13 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <type name="Magento\Framework\App\RouterList">
-        <arguments>
-            <argument name="routerList" xsi:type="array">
-                <item name="urlredirect" xsi:type="array">
-                    <item name="class" xsi:type="string">Magento\UrlRedirect\Controller\Router</item>
-                    <item name="disable" xsi:type="boolean">false</item>
-                    <item name="sortOrder" xsi:type="string">40</item>
-                </item>
-            </argument>
-        </arguments>
+    <type name="Magento\CatalogImportExport\Model\Import\Product">
+        <plugin name="import_save_plugin" type="Magento\CatalogUrlRewrite\Model\Product\Plugin\Import"/>
+    </type>
+    <type name="Magento\Catalog\Model\Resource\Category">
+        <plugin name="category_move_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move"/>
+    </type>
+    <type name="Magento\UrlRewrite\Model\StorageInterface">
+        <plugin name="storage_plugin" type="Magento\CatalogUrlRewrite\Model\Category\Plugin\Storage"/>
     </type>
 </config>
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/install/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/install/events.xml
new file mode 100644
index 00000000000..39b12d18bcc
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/etc/install/events.xml
@@ -0,0 +1,42 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="catalog_category_prepare_save">
+        <observer name="category_save_rewrites_history_setter" instance="Magento\CatalogUrlRewrite\Observer\CategorySaveRewritesHistorySetter" method="invoke"/>
+    </event>
+    <event name="catalog_category_save_before">
+        <observer name="category_url_path_autogeneration" instance="Magento\CatalogUrlRewrite\Observer\CategoryUrlPathAutogenerator" method="invoke"/>
+    </event>
+    <event name="catalog_category_save_after">
+        <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Category\Observer" method="processUrlRewriteSaving"/>
+    </event>
+    <event name="catalog_product_save_before">
+        <observer name="product_url_key_autogeneration" instance="Magento\CatalogUrlRewrite\Observer\ProductUrlKeyAutogenerator" method="invoke"/>
+    </event>
+    <event name="catalog_product_save_after">
+        <observer name="process_url_rewrite_saving" instance="Magento\CatalogUrlRewrite\Model\Product\Observer" method="processUrlRewriteSaving"/>
+    </event>
+</config>
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/module.xml b/app/code/Magento/CatalogUrlRewrite/etc/module.xml
index 1ff2849f6f2..8048acf4c5b 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/module.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/module.xml
@@ -24,12 +24,18 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_CatalogUrlRewrite" schema_version="1.0.0.0" active="false">
+    <module name="Magento_CatalogUrlRewrite" schema_version="1.0.0.0" active="true">
+        <sequence>
+            <module name="Magento_Catalog"/>
+        </sequence>
         <depends>
+            <module name="Magento_Backend"/>
             <module name="Magento_Catalog"/>
+            <module name="Magento_CatalogImportExport"/>
             <module name="Magento_Eav"/>
+            <module name="Magento_ImportExport"/>
             <module name="Magento_Store"/>
-            <module name="Magento_UrlRedirect"/>
+            <module name="Magento_UrlRewrite"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Cms/sql/cms_setup/upgrade-1.6.0.1-1.6.0.2.php b/app/code/Magento/CatalogUrlRewrite/sql/catalogurlrewrite_setup/install-1.0.0.0.php
similarity index 56%
rename from app/code/Magento/Cms/sql/cms_setup/upgrade-1.6.0.1-1.6.0.2.php
rename to app/code/Magento/CatalogUrlRewrite/sql/catalogurlrewrite_setup/install-1.0.0.0.php
index 1b13eb808b2..8d0157ef980 100644
--- a/app/code/Magento/Cms/sql/cms_setup/upgrade-1.6.0.1-1.6.0.2.php
+++ b/app/code/Magento/CatalogUrlRewrite/sql/catalogurlrewrite_setup/install-1.0.0.0.php
@@ -17,54 +17,64 @@
  * 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.
- *
+ *   
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+/* @var $installer \Magento\Framework\Module\Setup */
 $installer = $this;
-/** @var $installer \Magento\Catalog\Model\Resource\Setup */
+
+$installer->startSetup();
+
+$tableName = \Magento\CatalogUrlRewrite\Model\Resource\Category\Product::TABLE_NAME;
 $table = $installer->getConnection()->newTable(
-    $installer->getTable('cms_url_rewrite')
+    $installer->getTable($tableName)
 )->addColumn(
-    'cms_rewrite_id',
+    'url_rewrite_id',
     \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
     null,
-    array('identity' => true, 'nullable' => false, 'primary' => true),
-    'Cms Url Rewrite ID'
+    array('unsigned' => true, 'nullable' => false),
+    'url_rewrite_id'
 )->addColumn(
-    'url_rewrite_id',
+    'category_id',
     \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
     null,
     array('unsigned' => true, 'nullable' => false),
-    'Core Url Rewrite ID'
+    'category_id'
+)->addColumn(
+    'product_id',
+    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+    null,
+    array('unsigned' => true, 'nullable' => false),
+    'product_id'
 )->addIndex(
-    $installer->getIdxName('cms_url_rewrite', array('url_rewrite_id')),
-    array('url_rewrite_id')
+    $installer->getIdxName($tableName, array('category_id', 'product_id')),
+    array('category_id', 'product_id')
 )->addForeignKey(
-    $installer->getFkName('cms_url_rewrite', 'url_rewrite_id', 'core_url_rewrite', 'url_rewrite_id'),
-    'url_rewrite_id',
-    $installer->getTable('core_url_rewrite'),
-    'url_rewrite_id',
+    $installer->getFkName($tableName, 'product_id', 'catalog_product_entity', 'entity_id'),
+    'product_id',
+    $installer->getTable('catalog_product_entity'),
+    'entity_id',
+    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
+    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+)->addForeignKey(
+    $installer->getFkName($tableName, 'category_id', 'catalog_category_entity', 'entity_id'),
+    'category_id',
+    $installer->getTable('catalog_category_entity'),
+    'entity_id',
     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-)->addColumn(
-    'cms_page_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
-    null,
-    array('nullable' => false),
-    'Cms Page ID'
-)->addIndex(
-    $installer->getIdxName('cms_url_rewrite', array('cms_page_id')),
-    array('cms_page_id')
 )->addForeignKey(
-    $installer->getFkName('cms_url_rewrite', 'cms_page_id', 'cms_page', 'page_id'),
-    'cms_page_id',
-    $installer->getTable('cms_page'),
-    'page_id',
+    $installer->getFkName($tableName, 'url_rewrite_id', 'url_rewrite', 'url_rewrite_id'),
+    'url_rewrite_id',
+    $installer->getTable('url_rewrite'),
+    'url_rewrite_id',
     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
 )->setComment(
-    'Cms Url Rewrite Table'
+    'url_rewrite_relation'
 );
 $installer->getConnection()->createTable($table);
+
+$installer->endSetup();
diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json
index a8e60e9de4a..0ca946052ef 100644
--- a/app/code/Magento/Centinel/composer.json
+++ b/app/code/Magento/Centinel/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Checkout/Block/Cart.php b/app/code/Magento/Checkout/Block/Cart.php
index d9b2583fc9a..c781da4bed6 100644
--- a/app/code/Magento/Checkout/Block/Cart.php
+++ b/app/code/Magento/Checkout/Block/Cart.php
@@ -45,7 +45,6 @@ class Cart extends \Magento\Checkout\Block\Cart\AbstractCart
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Catalog\Model\Resource\Url $catalogUrlBuilder
@@ -55,7 +54,6 @@ class Cart extends \Magento\Checkout\Block\Cart\AbstractCart
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Catalog\Model\Resource\Url $catalogUrlBuilder,
@@ -65,7 +63,7 @@ class Cart extends \Magento\Checkout\Block\Cart\AbstractCart
     ) {
         $this->_cartHelper = $cartHelper;
         $this->_catalogUrlBuilder = $catalogUrlBuilder;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
         $this->_isScopePrivate = true;
         $this->httpContext = $httpContext;
     }
diff --git a/app/code/Magento/Checkout/Block/Cart/AbstractCart.php b/app/code/Magento/Checkout/Block/Cart/AbstractCart.php
index d0764c03d44..dbcb156887f 100644
--- a/app/code/Magento/Checkout/Block/Cart/AbstractCart.php
+++ b/app/code/Magento/Checkout/Block/Cart/AbstractCart.php
@@ -50,13 +50,6 @@ class AbstractCart extends \Magento\Framework\View\Element\Template
      */
     protected $_itemRenders = array();
 
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
-
     /**
      * @var \Magento\Customer\Model\Session
      */
@@ -69,21 +62,18 @@ class AbstractCart extends \Magento\Framework\View\Element\Template
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         array $data = array()
     ) {
         $this->_customerSession = $customerSession;
         $this->_checkoutSession = $checkoutSession;
-        $this->_catalogData = $catalogData;
         parent::__construct($context, $data);
         $this->_isScopePrivate = true;
     }
@@ -176,17 +166,4 @@ class AbstractCart extends \Magento\Framework\View\Element\Template
         }
         return $this->_totals;
     }
-
-    /**
-     * Check if can apply msrp to totals
-     *
-     * @return bool
-     */
-    public function canApplyMsrp()
-    {
-        if (!$this->getQuote()->hasCanApplyMsrp() && $this->_catalogData->isMsrpEnabled()) {
-            $this->getQuote()->collectTotals();
-        }
-        return $this->getQuote()->getCanApplyMsrp();
-    }
 }
diff --git a/app/code/Magento/Checkout/Block/Cart/Coupon.php b/app/code/Magento/Checkout/Block/Cart/Coupon.php
index dbdd89d06ce..8da8677fd71 100644
--- a/app/code/Magento/Checkout/Block/Cart/Coupon.php
+++ b/app/code/Magento/Checkout/Block/Cart/Coupon.php
@@ -27,19 +27,17 @@ class Coupon extends \Magento\Checkout\Block\Cart\AbstractCart
 {
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         array $data = array()
     ) {
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Checkout/Block/Cart/Shipping.php b/app/code/Magento/Checkout/Block/Cart/Shipping.php
index e28bcf056af..3f44aca2592 100644
--- a/app/code/Magento/Checkout/Block/Cart/Shipping.php
+++ b/app/code/Magento/Checkout/Block/Cart/Shipping.php
@@ -63,7 +63,6 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Directory\Block\Data $directoryBlock
@@ -73,7 +72,6 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Directory\Block\Data $directoryBlock,
@@ -84,7 +82,7 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
         $this->priceCurrency = $priceCurrency;
         $this->_directoryBlock = $directoryBlock;
         $this->_carrierFactory = $carrierFactory;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
index d54530e2f67..5371bfb1e6e 100644
--- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php
+++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
@@ -53,7 +53,6 @@ class Sidebar extends AbstractCart implements IdentityInterface
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Catalog\Model\Resource\Url $catalogUrl
@@ -65,7 +64,6 @@ class Sidebar extends AbstractCart implements IdentityInterface
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Catalog\Model\Resource\Url $catalogUrl,
@@ -76,7 +74,7 @@ class Sidebar extends AbstractCart implements IdentityInterface
         $this->_checkoutHelper = $checkoutHelper;
         $this->_catalogUrl = $catalogUrl;
         $this->_checkoutCart = $checkoutCart;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Checkout/Block/Cart/Totals.php b/app/code/Magento/Checkout/Block/Cart/Totals.php
index ed585a6046c..07b6c04b626 100644
--- a/app/code/Magento/Checkout/Block/Cart/Totals.php
+++ b/app/code/Magento/Checkout/Block/Cart/Totals.php
@@ -49,7 +49,6 @@ class Totals extends \Magento\Checkout\Block\Cart\AbstractCart
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -57,14 +56,13 @@ class Totals extends \Magento\Checkout\Block\Cart\AbstractCart
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
         array $data = array()
     ) {
         $this->_salesConfig = $salesConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Checkout/Block/Shipping/Price.php b/app/code/Magento/Checkout/Block/Shipping/Price.php
index aa28b3e97b6..3a2d573174e 100644
--- a/app/code/Magento/Checkout/Block/Shipping/Price.php
+++ b/app/code/Magento/Checkout/Block/Shipping/Price.php
@@ -41,7 +41,6 @@ class Price extends AbstractCart
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param PriceCurrencyInterface $priceCurrency
@@ -49,14 +48,13 @@ class Price extends AbstractCart
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         PriceCurrencyInterface $priceCurrency,
         array $data = array()
     ) {
         $this->priceCurrency = $priceCurrency;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
     }
 
 
diff --git a/app/code/Magento/Checkout/Block/Total/Nominal.php b/app/code/Magento/Checkout/Block/Total/Nominal.php
index 8fa54996209..6eb39530aba 100644
--- a/app/code/Magento/Checkout/Block/Total/Nominal.php
+++ b/app/code/Magento/Checkout/Block/Total/Nominal.php
@@ -44,7 +44,6 @@ class Nominal extends \Magento\Checkout\Block\Total\DefaultTotal
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -53,7 +52,6 @@ class Nominal extends \Magento\Checkout\Block\Total\DefaultTotal
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
@@ -61,7 +59,7 @@ class Nominal extends \Magento\Checkout\Block\Total\DefaultTotal
         array $data = array()
     ) {
         $this->priceCurrency = $priceCurrency;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $salesConfig, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $data);
     }
 
     /**
diff --git a/app/code/Magento/Checkout/Controller/Cart/Index.php b/app/code/Magento/Checkout/Controller/Cart/Index.php
index 4f7b5e439c0..25423c7e0f8 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Index.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Index.php
@@ -90,7 +90,7 @@ class Index extends \Magento\Checkout\Controller\Cart
         $this->_view->loadLayout();
         $layout = $this->_view->getLayout();
         $layout->initMessages();
-        $layout->getBlock('head')->setTitle(__('Shopping Cart'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Shopping Cart'));
         $this->_view->renderLayout();
         \Magento\Framework\Profiler::stop(__METHOD__ . 'cart_display');
     }
diff --git a/app/code/Magento/Checkout/Controller/Onepage.php b/app/code/Magento/Checkout/Controller/Onepage.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Index.php b/app/code/Magento/Checkout/Controller/Onepage/Index.php
index d83225b5114..2d29c3831d4 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/Index.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/Index.php
@@ -56,7 +56,7 @@ class Index extends \Magento\Checkout\Controller\Onepage
         $this->_view->loadLayout();
         $layout = $this->_view->getLayout();
         $layout->initMessages();
-        $layout->getBlock('head')->setTitle(__('Checkout'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Checkout'));
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php
index a3760e04ced..ffdfb5c0d99 100644
--- a/app/code/Magento/Checkout/Model/Cart.php
+++ b/app/code/Magento/Checkout/Model/Cart.php
@@ -466,7 +466,11 @@ class Cart extends \Magento\Framework\Object implements \Magento\Checkout\Model\
      */
     public function updateItems($data)
     {
-        $this->_eventManager->dispatch('checkout_cart_update_items_before', array('cart' => $this, 'info' => $data));
+        $infoDataObject = new \Magento\Framework\Object($data);
+        $this->_eventManager->dispatch(
+            'checkout_cart_update_items_before',
+            ['cart' => $this, 'info' => $infoDataObject]
+        );
 
         $qtyRecalculatedFlag = false;
         foreach ($data as $itemId => $itemInfo) {
@@ -506,7 +510,10 @@ class Cart extends \Magento\Framework\Object implements \Magento\Checkout\Model\
             );
         }
 
-        $this->_eventManager->dispatch('checkout_cart_update_items_after', array('cart' => $this, 'info' => $data));
+        $this->_eventManager->dispatch(
+            'checkout_cart_update_items_after',
+            ['cart' => $this, 'info' => $infoDataObject]
+        );
         return $this;
     }
 
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index 241e2ac7bac..772f86efbdb 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -3,26 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-authorization": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-gift-message": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-page-cache": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-authorization": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-gift-message": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-page-cache": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-msrp": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Checkout/etc/module.xml b/app/code/Magento/Checkout/etc/module.xml
index f2e9d84340a..233bb2da260 100644
--- a/app/code/Magento/Checkout/etc/module.xml
+++ b/app/code/Magento/Checkout/etc/module.xml
@@ -44,6 +44,7 @@
             <module name="Magento_Wishlist"/>
             <module name="Magento_PageCache"/>
             <module name="Magento_Theme"/>
+            <module name="Magento_Msrp" />
             <module name="Magento_Authorization"/>
         </depends>
     </module>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
index b77f099b0b0..25fb62bcbdc 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
@@ -36,7 +36,9 @@
                 <container name="checkout.cart.widget" as="checkout_cart_widget" label="Shopping Cart Items After"/>
                 <block class="Magento\Checkout\Block\Cart\Shipping" name="checkout.cart.shipping" as="shipping" template="cart/shipping.phtml"/>
                 <block class="Magento\Checkout\Block\Cart\Coupon" name="checkout.cart.coupon" as="coupon" template="cart/coupon.phtml"/>
-                <block class="Magento\Checkout\Block\Cart\Totals" name="checkout.cart.totals" as="totals" template="cart/totals.phtml"/>
+                <container name="checkout.cart.totals.container" as="totals" label="Shopping Cart Totals">
+                    <block class="Magento\Checkout\Block\Cart\Totals" name="checkout.cart.totals" template="cart/totals.phtml"/>
+                </container>
                 <block class="Magento\Checkout\Block\Cart" name="checkout.cart.methods.bottom" template="cart/methods.phtml">
                     <container name="checkout.cart.methods" as="methods" label="Payment Methods After Checkout Button">
                         <block class="Magento\Checkout\Block\QuoteShortcutButtons" name="checkout.cart.shortcut.buttons"/>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/default.xml b/app/code/Magento/Checkout/view/frontend/layout/default.xml
index 959321b5f82..a006c4df829 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/default.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/default.xml
@@ -33,6 +33,9 @@
     <referenceContainer name="header-wrapper">
         <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml">
             <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.sidebar.item.renderers" as="renderer.list" />
+            <container name="minicart.subtotal.container" as="subtotal" label="My Cart Subtotal">
+                <block name="minicart.subtotal" class="Magento\Checkout\Block\Cart\Sidebar" template="cart/subtotal.phtml"/>
+            </container>
             <container name="minicart.extra.info" as="minicart_info" label="My Cart Extra info"/>
             <container name="topCart.extra_actions" as="extra_actions" label="My Cart Extra Actions">
                 <block class="Magento\Catalog\Block\ShortcutButtons" name="topCart.shortcut.buttons"/>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml
index c94ff5af7e4..14f01d2cf9d 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml
@@ -25,8 +25,11 @@
 /** @var $this \Magento\Checkout\Block\Cart\Item\Renderer */
 
 $_item = $this->getItem();
-$isVisibleProduct = $_item->getProduct()->isVisibleInSiteVisibility();
-$canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_item->getProduct(), \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM);
+$product = $_item->getProduct();
+$isVisibleProduct = $product->isVisibleInSiteVisibility();
+/** @var \Magento\Msrp\Helper\Data $helper */
+$helper = $this->helper('Magento\Msrp\Helper\Data');
+$canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinimalPriceLessMsrp($product);
 ?>
 <tbody class="cart item">
 <tr class="item info item-info">
@@ -82,25 +85,19 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite
             <span class="pricing msrp">
                 <span class="msrp notice"><?php echo __('See price before order confirmation.'); ?></span>
                 <?php $helpLinkId = 'cart-msrp-help-' . $_item->getId(); ?>
-                <?php $_product = $_item->getProduct(); ?>
-                <a href="#"
-                   class="action help map"
-                   id="<?php echo($helpLinkId);?>"
-                   data-mage-init='{"addToCart":{"popupId": "#<?php echo($helpLinkId);?>",
-                                                 "productName": "<?php echo $_product->getName() ?>",
-                                                 "realPrice": "<?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>",
-                                                 "msrpPrice": "<?php echo $this->helper('Magento\Core\Helper\Data')->currency($_product->getMsrp(),true,true) ?>",
-                                                 "showAddToCart": false}}'><span><?php echo __("What's this?"); ?></span>
+                <?php $coreHelper = $this->helper('Magento\Core\Helper\Data'); ?>
+                <a href="#" class="action help map" id="<?php echo($helpLinkId); ?>" data-mage-init='{"addToCart":{"helpLinkId": "#<?php echo $helpLinkId;?>","productName": "<?php echo $product->getName(); ?>","showAddToCart": false}}'>
+                    <span><?php echo __("What's this?"); ?></span>
                 </a>
             </span>
             <?php $cols++; ?>
         </td>
     <?php else: ?>
 
-        <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>">
-            <?php echo $this->getUnitPriceHtml($_item); ?>
-            <?php $cols++; ?>
-        </td>
+    <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>">
+        <?php echo $this->getUnitPriceHtml($_item); ?>
+        <?php $cols++; ?>
+    </td>
 
     <?php endif; ?>
     <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>">
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/price/sidebar.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/price/sidebar.phtml
index cae1afcee5c..b5f5770ffdf 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/price/sidebar.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/price/sidebar.phtml
@@ -25,9 +25,7 @@
 /** @var $this \Magento\Checkout\Block\Item\Price\Renderer */
 ?>
 <?php $_item = $this->getItem() ?>
-<div class="pricing details">
-    <div class="rate">
-        <span class="label display"><?php echo __('Price'); ?></span>
-        <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>
-    </div>
+<div class="price-container">
+    <span class="price-label"><?php echo __('Price')?></span>
+    <span class="price-wrapper"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?></span>
 </div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
index 319c68dbc82..9bdb695caaf 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
@@ -21,7 +21,6 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
 /** @var $this \Magento\Checkout\Block\Cart\Sidebar */
 ?>
 <?php if ($this->getInList()): ?>
@@ -68,18 +67,7 @@
                 <?php if ($_cartQty || $this->getAllowCartLink()): ?>
                     <?php $isPossibleOnepageCheckout = $_cartQty && $this->isPossibleOnepageCheckout() ?>
                     <?php if ($isPossibleOnepageCheckout): ?>
-                        <div class="subtotal">
-                            <?php if ($this->canApplyMsrp()): ?>
-                            <span class="mark msrp">
-                                <?php echo __('Order total will be displayed before you submit the order'); ?>
-                            </span>
-                            <?php else: ?>
-                                <span class="mark">
-                                    <?php echo __('Cart Subtotal') ?>
-                                </span>
-                                <?php echo $this->getTotalsHtml() ?>
-                            <?php endif ?>
-                        </div>
+                        <?php echo $this->getChildHtml('subtotal'); ?>
                     <?php endif; ?>
                     <?php echo $this->getChildHtml('minicart_info') ?>
                     <div class="actions">
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml
index 80b6c5762b6..028bc8203bd 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/shipping.phtml
@@ -105,7 +105,7 @@ require([
                            <?php else: ?>
                                 <input name="estimate_method" type="radio" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
                                 <label class="label" for="s_method_<?php echo $_rate->getCode() ?>">
-                                    <span><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?></span>
+                                    <?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
                                     <?php echo $this->getShippingPriceHtml($_rate) ?>
                                 </label>
                            <?php endif ?>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
index a06f9acf686..f12f42d4dd7 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/sidebar/default.phtml
@@ -21,26 +21,30 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
+?>
+<?php
 /** @var $this \Magento\Checkout\Block\Cart\Item\Renderer */
+$_item = $this->getItem();
+$product = $_item->getProduct();
+/** @var \Magento\Msrp\Helper\Data $helper */
+$helper = $this->helper('Magento\Msrp\Helper\Data');
+$canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinimalPriceLessMsrp($product);
+$imageBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')
 ?>
-<?php $_item = $this->getItem() ?>
-<?php $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_item->getProduct(), \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM); ?>
-<?php $imageBlock =  $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')?>
 <li class="item product product-item">
-<div class="product">
-    <?php if ($this->hasProductUrl()): ?>
-        <a href="<?php echo $this->getProductUrl()?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo product-item-photo">
-            <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?>
-        </a>
-    <?php else: ?>
-        <span class="product photo product-item-photo">
-            <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?>
-        </span>
-    <?php endif; ?>
+    <div class="product">
+        <?php if ($this->hasProductUrl()): ?>
+            <a href="<?php echo $this->getProductUrl()?>" title="<?php echo $this->escapeHtml($this->getProductName()) ?>" class="product photo product-item-photo">
+                <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?>
+            </a>
+        <?php else: ?>
+            <span class="product photo product-item-photo">
+                <?php echo $imageBlock->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail')->toHtml() ?>
+            </span>
+        <?php endif; ?>
 
-        <div class="product details">
-            <strong class="product name">
+        <div class="product details product-item-details">
+            <strong class="product name product-item-name">
                 <?php if ($this->hasProductUrl()): ?>
                     <a href="<?php echo $this->getProductUrl() ?>"><?php echo $this->escapeHtml($this->getProductName()) ?></a>
                 <?php else: ?>
@@ -70,38 +74,39 @@
                 </div>
             <?php endif; ?>
 
-        <?php // Prices ?>
+            <?php // Prices ?>
+            <div class="product-item-pricing">
+                <?php if ($canApplyMsrp): ?>
 
-            <?php if ($canApplyMsrp): ?>
-
-                <div class="rate map">
-                    <span class="label"><?php echo __('Price'); ?></span>
-                    <span class="value"><?php echo __('See price before order confirmation.'); ?></span>
-                </div>
+                    <div class="details-map">
+                        <span class="label"><?php echo __('Price'); ?></span>
+                        <span class="value"><?php echo __('See price before order confirmation.'); ?></span>
+                    </div>
 
-            <?php else: ?>
-                <?php echo $this->getSidebarItemPriceHtml($_item); ?>
-            <?php endif; //Can apply MSRP ?>
+                <?php else: ?>
+                    <?php echo $this->getSidebarItemPriceHtml($_item); ?>
+                <?php endif; //Can apply MSRP ?>
 
-            <div class="details qty">
-                <span class="label"><?php echo __('Qty'); ?></span>
-                <span class="value qty"><?php echo $this->getQty() ?></span>
+                <div class="details-qty">
+                    <span class="label"><?php echo __('Qty'); ?></span>
+                    <span class="value qty"><?php echo $this->getQty() ?></span>
+                </div>
             </div>
 
-        <div class="product actions">
-            <?php if ($_item->getProduct()->isVisibleInSiteVisibility()):?>
-            <div class="primary">
-                <a href="<?php echo $this->getConfigureUrl() ?>"
-                   title="<?php echo __('Edit item') ?>"
-                   class="action edit"><span><?php echo __('Edit')?></span></a>
-            </div>
-            <?php endif ?>
-            <div class="secondary">
-                <a href="#" data-post='<?php echo $this->helper('Magento\Checkout\Helper\Cart')->getDeletePostJson($_item); ?>' title="<?php echo __('Remove item') ?>" class="action delete">
-                    <span><?php echo __('Remove')?></span>
-                </a>
+            <div class="product actions">
+                <?php if ($product->isVisibleInSiteVisibility()):?>
+                <div class="primary">
+                    <a href="<?php echo $this->getConfigureUrl() ?>"
+                       title="<?php echo __('Edit item') ?>"
+                       class="action edit"><span><?php echo __('Edit')?></span></a>
+                </div>
+                <?php endif ?>
+                <div class="secondary">
+                    <a href="#" data-post='<?php echo $this->helper('Magento\Checkout\Helper\Cart')->getDeletePostJson($_item); ?>' title="<?php echo __('Remove item') ?>" class="action delete">
+                        <span><?php echo __('Remove')?></span>
+                    </a>
+                </div>
             </div>
         </div>
     </div>
-</div>
 </li>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
new file mode 100644
index 00000000000..ead8da3883b
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/subtotal.phtml
@@ -0,0 +1,31 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** @var $this \Magento\Checkout\Block\Cart\Sidebar */
+?>
+<div class="subtotal">
+    <span class="mark">
+        <?php echo __('Cart Subtotal') ?>
+    </span>
+    <?php echo $this->getTotalsHtml() ?>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/totals.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/totals.phtml
index 16b3b3389b5..61fac6d51e2 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/totals.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/totals.phtml
@@ -29,14 +29,10 @@
  */
 ?>
 <div class="cart-totals">
-<?php if ($this->canApplyMsrp()): ?>
-    <div class="msrp totals"><?php echo __('You will see the order total before you submit the order.'); ?></div>
-<?php else: ?>
     <table id="shopping-cart-totals-table" class="data table totals">
         <?php echo $this->renderTotals(); ?>
         <tfoot>
             <?php echo $this->renderTotals('footer'); ?>
         </tfoot>
     </table>
-<?php endif; ?>
 </div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/item/price/row.phtml b/app/code/Magento/Checkout/view/frontend/templates/item/price/row.phtml
index f521c33736b..854b9b033fe 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/item/price/row.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/item/price/row.phtml
@@ -26,8 +26,8 @@
 
 $_item = $this->getItem();
 ?>
-<span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
-    <span class="cart price">
+<span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+    <span class="cart-price">
         <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?>
     </span>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/item/price/unit.phtml b/app/code/Magento/Checkout/view/frontend/templates/item/price/unit.phtml
index 8da9e3d05c6..4f16aec9f00 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/item/price/unit.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/item/price/unit.phtml
@@ -26,8 +26,8 @@
 
 $_item = $this->getItem();
 ?>
-<span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
-    <span class="cart price">
+<span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+    <span class="cart-price">
         <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>
     </span>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/billing.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/billing.phtml
index 5691c5ce71d..93c9ac461ab 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/billing.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/billing.phtml
@@ -125,7 +125,7 @@
         </div>
 
         <div class="field telephone required">
-            <label class="label" for="billing:telephone"><span><?php echo __('Telephone') ?></span></label>
+            <label class="label" for="billing:telephone"><span><?php echo __('Phone Number') ?></span></label>
             <div class="control">
                 <input type="text" name="billing[telephone]" value="<?php echo $this->escapeHtml($this->getAddress()->getTelephone()) ?>" title="<?php echo __('Telephone') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>" id="billing:telephone" />
             </div>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml
index 9c541610ecc..f8ac576a95d 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/info.phtml
@@ -31,19 +31,11 @@
         <caption>Order Review</caption>
         <thead>
             <tr>
-                <th rowspan="<?php echo $rowspan ?>" class="col item"><?php echo __('Product Name') ?></th>
-                <th colspan="<?php echo $colspan ?>" class="col price"><?php echo __('Price') ?></th>
-                <th rowspan="<?php echo $rowspan ?>" class="col qty"><?php echo __('Qty') ?></th>
-                <th colspan="<?php echo $colspan ?>" class="col subtotal"><?php echo __('Subtotal') ?></th>
+                <th class="col item"><?php echo __('Product Name') ?></th>
+                <th class="col price"><?php echo __('Price') ?></th>
+                <th class="col qty"><?php echo __('Qty') ?></th>
+                <th class="col subtotal"><?php echo __('Subtotal') ?></th>
             </tr>
-            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-            <tr>
-                <th class="col price excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                <th class="col price incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-                <th class="col subtotal excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                <th class="col subtotal incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-            </tr>
-            <?php endif; ?>
         </thead>
         <tfoot>
             <?php echo $this->getChildHtml('totals'); ?>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml
index b88c21432ee..ce95274d4ef 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml
@@ -51,25 +51,29 @@ $_item = $this->getItem();
             <?php echo $addtInfoBlock->setItem($_item)->toHtml() ?>
         <?php endif;?>
     </td>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col price excl tax" data-th="<?php echo $this->escapeHtml(__('Price'));?>">
-        <?php echo $this->getUnitPriceExclTaxHtml($_item); ?>
+    <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price'));?>">
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+            <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+                <?php echo $this->getUnitPriceInclTaxHtml($_item); ?>
+            </span>
+        <?php endif; ?>
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+            <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+                <?php echo $this->getUnitPriceExclTaxHtml($_item); ?>
+            </span>
+        <?php endif; ?>
     </td>
-    <?php endif; ?>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col price incl tax">
-        <?php echo $this->getUnitPriceInclTaxHtml($_item); ?>
+    <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty'));?>"><span class="qty"><?php echo $_item->getQty() ?></span></td>
+    <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal'));?>">
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+            <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+                <?php echo $this->getRowTotalInclTaxHtml($_item); ?>
+            </span>
+        <?php endif; ?>
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+            <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+                <?php echo $this->getRowTotalExclTaxHtml($_item); ?>
+            </span>
+        <?php endif; ?>
     </td>
-    <?php endif; ?>
-    <td class="col qty"><span class="qty"><?php echo $_item->getQty() ?></span></td>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col subtotal excl tax">
-        <?php echo $this->getRowTotalExclTaxHtml($_item); ?>
-    </td>
-    <?php endif; ?>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col subtotal incl tax">
-        <?php echo $this->getRowTotalInclTaxHtml($_item); ?>
-    </td>
-    <?php endif; ?>
 </tr>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_excl_tax.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_excl_tax.phtml
index 2624f4597a3..8a70f4f900b 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_excl_tax.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_excl_tax.phtml
@@ -26,6 +26,6 @@
 
 $_item = $this->getItem();
 ?>
-<span class="cart price">
+<span class="cart-price">
     <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getRowTotal()) ?>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_incl_tax.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_incl_tax.phtml
index 97f5021039b..878f9f02eca 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_incl_tax.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/row_incl_tax.phtml
@@ -27,6 +27,6 @@
 $_item = $this->getItem();
 ?>
 <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getSubtotalInclTax($_item); ?>
-<span class="cart price">
+<span class="cart-price">
     <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl) ?>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_excl_tax.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_excl_tax.phtml
index 5f62b4ef2cf..81013e3ba75 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_excl_tax.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_excl_tax.phtml
@@ -26,6 +26,6 @@
 
 $_item = $this->getItem();
 ?>
-<span class="cart price">
+<span class="cart-price">
     <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_incl_tax.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_incl_tax.phtml
index cfdc0239fc8..5f3e4bd6a62 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_incl_tax.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item/price/unit_incl_tax.phtml
@@ -27,6 +27,6 @@
 $_item = $this->getItem();
 ?>
 <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?>
-<span class="cart price">
+<span class="cart-price">
     <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl) ?>
 </span>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/totals.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/totals.phtml
index 507d9f35ec5..54d630a0405 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/totals.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/totals.phtml
@@ -27,7 +27,7 @@
  */
 ?>
 <?php if ($this->getTotals()): ?>
-    <?php $_colspan = $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices() ? 5 : 3; ?>
+    <?php $_colspan = 3; ?>
     <?php echo $this->renderTotals(null, $_colspan); ?>
     <?php echo $this->renderTotals('footer', $_colspan); ?>
     <?php if ($this->needDisplayBaseGrandtotal()):?>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/shipping.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/shipping.phtml
index 3369eb8313a..7b69b6a9070 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/shipping.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/shipping.phtml
@@ -93,7 +93,7 @@
             </div>
         </div>
         <div class="field telephone required">
-            <label class="label" for="shipping:telephone"><span><?php echo __('Telephone') ?></span></label>
+            <label class="label" for="shipping:telephone"><span><?php echo __('Phone Number') ?></span></label>
             <div class="control">
                 <input type="text" name="shipping[telephone]" value="<?php echo $this->escapeHtml($this->getAddress()->getTelephone()) ?>" title="<?php echo __('Telephone') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>" id="shipping:telephone" />
             </div>
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index e535109311a..ba2e152066f 100644
--- a/app/code/Magento/CheckoutAgreements/composer.json
+++ b/app/code/Magento/CheckoutAgreements/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/Form.php b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/Form.php
index 8972c8694de..a7a2894917b 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/Form.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/Form.php
@@ -71,19 +71,6 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         $this->setTitle(__('Block Information'));
     }
 
-    /**
-     * Load Wysiwyg on demand and Prepare layout
-     *
-     * @return void
-     */
-    protected function _prepareLayout()
-    {
-        parent::_prepareLayout();
-        if ($this->_wysiwygConfig->isEnabled()) {
-            $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
-        }
-    }
-
     /**
      * Prepare form
      *
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/Tab/Content.php b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/Tab/Content.php
index 0338181ad4f..a892280ab80 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/Tab/Content.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/Tab/Content.php
@@ -52,19 +52,6 @@ class Content extends \Magento\Backend\Block\Widget\Form\Generic implements
         parent::__construct($context, $registry, $formFactory, $data);
     }
 
-    /**
-     * Load Wysiwyg on demand and Prepare layout
-     *
-     * @return void
-     */
-    protected function _prepareLayout()
-    {
-        parent::_prepareLayout();
-        if ($this->_wysiwygConfig->isEnabled()) {
-            $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
-        }
-    }
-
     /**
      * Prepare form
      *
diff --git a/app/code/Magento/Cms/Block/Page.php b/app/code/Magento/Cms/Block/Page.php
index 8d5c12fb7a6..5cd355504c5 100644
--- a/app/code/Magento/Cms/Block/Page.php
+++ b/app/code/Magento/Cms/Block/Page.php
@@ -141,13 +141,9 @@ class Page extends \Magento\Framework\View\Element\AbstractBlock implements \Mag
         }
 
         $this->pageConfig->addBodyClass('cms-' . $page->getIdentifier());
-
-        $head = $this->getLayout()->getBlock('head');
-        if ($head) {
-            $head->setTitle($page->getTitle());
-            $head->setKeywords($page->getMetaKeywords());
-            $head->setDescription($page->getMetaDescription());
-        }
+        $this->pageConfig->setTitle($page->getTitle());
+        $this->pageConfig->setKeywords($page->getMetaKeywords());
+        $this->pageConfig->setDescription($page->getMetaDescription());
 
         $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
         if ($pageMainTitle) {
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
new file mode 100644
index 00000000000..bb3f1ab668a
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/AbstractMassDelete.php
@@ -0,0 +1,161 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml;
+
+use Magento\Framework\Model\Resource\Db\Collection\AbstractCollection;
+
+/**
+ * Class AbstractMassDelete
+ */
+class AbstractMassDelete extends \Magento\Backend\App\Action
+{
+    /**
+     * Field id
+     */
+    const ID_FIELD = 'entity_id';
+
+    /**
+     * Redirect url
+     */
+    const REDIRECT_URL = '*/*/index';
+
+    /**
+     * Resource collection
+     *
+     * @var string
+     */
+    protected $collection = 'Magento\Framework\Model\Resource\Db\Collection\AbstractCollection';
+
+    /**
+     * Model
+     *
+     * @var string
+     */
+    protected $model = 'Magento\Framework\Model\AbstractModel';
+
+    /**
+     * Execute action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getParam('massaction', '[]');
+        $data = json_decode($data, true);
+
+        try {
+            if (isset($data['all_selected']) && $data['all_selected'] === true) {
+                if (!empty($data['excluded'])) {
+                    $this->excludedDelete($data['excluded']);
+                } else {
+                    $this->deleteAll();
+                }
+            } elseif (!empty($data['selected'])) {
+                $this->selectedDelete($data['selected']);
+            } else {
+                $this->messageManager->addError(__('Please select item(s).'));
+                $this->_redirect(static::REDIRECT_URL);
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        }
+
+        $this->_redirect(static::REDIRECT_URL);
+    }
+
+    /**
+     * Delete all
+     *
+     * @return void
+     * @throws \Exception
+     */
+    protected function deleteAll()
+    {
+        /** @var AbstractCollection $collection */
+        $collection = $this->_objectManager->get($this->collection);
+        $this->setSuccessMessage($this->delete($collection));
+    }
+
+    /**
+     * Delete all but the not selected
+     *
+     * @param array $excluded
+     * @return void
+     * @throws \Exception
+     */
+    protected function excludedDelete(array $excluded)
+    {
+        /** @var AbstractCollection $collection */
+        $collection = $this->_objectManager->get($this->collection);
+        $collection->addFieldToFilter(static::ID_FIELD, ['nin' => $excluded]);
+        $this->setSuccessMessage($this->delete($collection));
+    }
+
+    /**
+     * Delete selected items
+     *
+     * @param array $selected
+     * @return void
+     * @throws \Exception
+     */
+    protected function selectedDelete(array $selected)
+    {
+        /** @var AbstractCollection $collection */
+        $collection = $this->_objectManager->get($this->collection);
+        $collection->addFieldToFilter(static::ID_FIELD, ['in' => $selected]);
+        $this->setSuccessMessage($this->delete($collection));
+    }
+
+    /**
+     * Delete collection items
+     *
+     * @param AbstractCollection $collection
+     * @return int
+     */
+    protected function delete(AbstractCollection $collection)
+    {
+        $count = 0;
+        foreach ($collection->getAllIds() as $id) {
+            /** @var \Magento\Framework\Model\AbstractModel $model */
+            $model = $this->_objectManager->get($this->model);
+            $model->load($id);
+            $model->delete();
+            ++$count;
+        }
+
+        return $count;
+    }
+
+    /**
+     * Set error messages
+     *
+     * @param int $count
+     * @return void
+     */
+    protected function setSuccessMessage($count)
+    {
+        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $count));
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/MassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/MassDelete.php
new file mode 100644
index 00000000000..6c46d4fd636
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/MassDelete.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+use Magento\Cms\Controller\Adminhtml\AbstractMassDelete;
+
+/**
+ * Class MassDelete
+ */
+class MassDelete extends AbstractMassDelete
+{
+    /**
+     * Field id
+     */
+    const ID_FIELD = 'block_id';
+
+    /**
+     * Resource collection
+     *
+     * @var string
+     */
+    protected $collection = 'Magento\Cms\Model\Resource\Block\Collection';
+
+    /**
+     * Block model
+     *
+     * @var string
+     */
+    protected $model = 'Magento\Cms\Model\Block';
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.php
new file mode 100644
index 00000000000..382aea1bb97
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/MassDelete.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+use Magento\Cms\Controller\Adminhtml\AbstractMassDelete;
+
+/**
+ * Class MassDelete
+ */
+class MassDelete extends AbstractMassDelete
+{
+    /**
+     * Field id
+     */
+    const ID_FIELD = 'page_id';
+
+    /**
+     * Resource collection
+     *
+     * @var string
+     */
+    protected $collection = 'Magento\Cms\Model\Resource\Page\Collection';
+
+    /**
+     * Page model
+     *
+     * @var string
+     */
+    protected $model = 'Magento\Cms\Model\Page';
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
index e6cd640cb63..920b46f235c 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
@@ -58,11 +58,9 @@ class Save extends \Magento\Backend\App\Action
      */
     public function execute()
     {
-        // check if data sent
         $data = $this->getRequest()->getPost();
         if ($data) {
             $data = $this->dataProcessor->filter($data);
-            //init model and set data
             $model = $this->_objectManager->create('Magento\Cms\Model\Page');
 
             $id = $this->getRequest()->getParam('page_id');
@@ -77,31 +75,25 @@ class Save extends \Magento\Backend\App\Action
                 array('page' => $model, 'request' => $this->getRequest())
             );
 
-            //validating
             if (!$this->dataProcessor->validate($data)) {
                 $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
                 return;
             }
 
-            // try to save it
             try {
-                // save the data
                 $model->save();
-
-                // display success message
                 $this->messageManager->addSuccess(__('The page has been saved.'));
-                // clear previously saved data from session
                 $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
-                // check if 'Save and Continue'
                 if ($this->getRequest()->getParam('back')) {
                     $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
                     return;
                 }
-                // go to grid
                 $this->_redirect('*/*/');
                 return;
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
+            } catch (\RuntimeException $e) {
+                $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addException($e, __('Something went wrong while saving the page.'));
             }
diff --git a/app/code/Magento/Cms/Model/Page.php b/app/code/Magento/Cms/Model/Page.php
index 93a2c676c66..2e3b9807d0c 100644
--- a/app/code/Magento/Cms/Model/Page.php
+++ b/app/code/Magento/Cms/Model/Page.php
@@ -62,6 +62,7 @@ namespace Magento\Cms\Model;
  * @method \Magento\Cms\Model\Page setCustomThemeFrom(string $value)
  * @method string getCustomThemeTo()
  * @method \Magento\Cms\Model\Page setCustomThemeTo(string $value)
+ * @method int[] getStores()
  */
 class Page extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\Object\IdentityInterface
 {
diff --git a/app/code/Magento/Cms/Model/Resource/Page.php b/app/code/Magento/Cms/Model/Resource/Page.php
index 90796013df2..fc5fa4387ef 100644
--- a/app/code/Magento/Cms/Model/Resource/Page.php
+++ b/app/code/Magento/Cms/Model/Resource/Page.php
@@ -52,11 +52,6 @@ class Page extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     protected $dateTime;
 
-    /**
-     * @var \Magento\Framework\Filter\FilterManager
-     */
-    protected $filter;
-
     /**
      * Construct
      *
@@ -64,20 +59,17 @@ class Page extends \Magento\Framework\Model\Resource\Db\AbstractDb
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
      * @param \Magento\Framework\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param \Magento\Framework\Filter\FilterManager $filter
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
         \Magento\Framework\Stdlib\DateTime\DateTime $date,
         \Magento\Framework\StoreManagerInterface $storeManager,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
-        \Magento\Framework\Filter\FilterManager $filter
+        \Magento\Framework\Stdlib\DateTime $dateTime
     ) {
         parent::__construct($resource);
         $this->_date = $date;
         $this->_storeManager = $storeManager;
         $this->dateTime = $dateTime;
-        $this->filter = $filter;
     }
 
     /**
@@ -125,14 +117,6 @@ class Page extends \Magento\Framework\Model\Resource\Db\AbstractDb
             $object->setData($field, $this->dateTime->formatDate($value));
         }
 
-        if (!$object->getData('identifier')) {
-            $object->setData('identifier', $this->filter->translitUrl($object->getData('title')));
-        }
-
-        if (!$this->getIsUniquePageToStores($object)) {
-            throw new \Magento\Framework\Model\Exception(__('A page URL key for specified store already exists.'));
-        }
-
         if (!$this->isValidPageIdentifier($object)) {
             throw new \Magento\Framework\Model\Exception(__('The page URL key contains capital letters or disallowed symbols.'));
         }
@@ -141,7 +125,6 @@ class Page extends \Magento\Framework\Model\Resource\Db\AbstractDb
             throw new \Magento\Framework\Model\Exception(__('The page URL key cannot be made of only numbers.'));
         }
 
-        // modify create / update dates
         if ($object->isObjectNew() && !$object->hasCreationTime()) {
             $object->setCreationTime($this->_date->gmtDate());
         }
@@ -286,33 +269,6 @@ class Page extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $select;
     }
 
-    /**
-     * Check for unique of identifier of page to selected store(s).
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @return bool
-     */
-    public function getIsUniquePageToStores(\Magento\Framework\Model\AbstractModel $object)
-    {
-        if ($this->_storeManager->hasSingleStore() || !$object->hasStores()) {
-            $stores = array(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
-        } else {
-            $stores = (array)$object->getData('stores');
-        }
-
-        $select = $this->_getLoadByIdentifierSelect($object->getData('identifier'), $stores);
-
-        if ($object->getId()) {
-            $select->where('cps.page_id <> ?', $object->getId());
-        }
-
-        if ($this->_getWriteAdapter()->fetchRow($select)) {
-            return false;
-        }
-
-        return true;
-    }
-
     /**
      *  Check whether page identifier is numeric
      *
diff --git a/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php b/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
new file mode 100644
index 00000000000..0d91cd6a75f
--- /dev/null
+++ b/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
@@ -0,0 +1,88 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Model\Resource\Page\Grid;
+
+use Magento\Cms\Model\Resource\Page\Collection as PageCollection;
+
+/**
+ * CMS page collection
+ *
+ * Class Collection
+ */
+class Collection extends PageCollection
+{
+    /**
+     * Add field filter to collection
+     *
+     * @param string|array $field
+     * @param string|int|array|null $condition
+     * @return \Magento\Cms\Model\Resource\Block\Grid\Collection
+     */
+    public function addFieldToFilter($field, $condition = null)
+    {
+        if ($field === 'store_id') {
+            return $this->addStoreFilter($condition, false);
+        }
+
+        return parent::addFieldToFilter($field, $condition);
+    }
+
+    /**
+     * Perform operations after collection load
+     *
+     * @return $this
+     */
+    protected function _afterLoad()
+    {
+        $items = $this->getColumnValues('page_id');
+        if (count($items)) {
+            $connection = $this->getConnection();
+            $select = $connection->select()->from(['cps' => $this->getTable('cms_page_store')])
+                ->where('cps.page_id IN (?)', $items);
+            $result = $connection->fetchPairs($select);
+            if ($result) {
+                foreach ($this as $item) {
+                    $pageId = $item->getData('page_id');
+                    if (!isset($result[$pageId])) {
+                        continue;
+                    }
+                    if ($result[$pageId] == 0) {
+                        $stores = $this->_storeManager->getStores(false, true);
+                        $storeId = current($stores)->getId();
+                        $storeCode = key($stores);
+                    } else {
+                        $storeId = $result[$item->getData('page_id')];
+                        $storeCode = $this->_storeManager->getStore($storeId)->getCode();
+                    }
+                    $item->setData('_first_store_id', $storeId);
+                    $item->setData('store_code', $storeCode);
+                    $item->setData('store_id', [$result[$pageId]]);
+                }
+            }
+        }
+
+        $this->_previewFlag = false;
+        return parent::_afterLoad();
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/DataProvider/Block/Row/Actions.php b/app/code/Magento/Cms/Ui/DataProvider/Block/Row/Actions.php
new file mode 100644
index 00000000000..59e60157637
--- /dev/null
+++ b/app/code/Magento/Cms/Ui/DataProvider/Block/Row/Actions.php
@@ -0,0 +1,68 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Ui\DataProvider\Block\Row;
+
+use Magento\Framework\UrlInterface;
+use Magento\Ui\DataProvider\RowInterface;
+
+/**
+ * Class Actions
+ */
+class Actions implements RowInterface
+{
+    /**
+     * Url path
+     */
+    const URL_PATH = 'cms/block/edit';
+
+    /**
+     * @var UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @param UrlInterface $urlBuilder
+     */
+    public function __construct(UrlInterface $urlBuilder)
+    {
+        $this->urlBuilder = $urlBuilder;
+    }
+
+    /**
+     * Get data
+     *
+     * @param array $dataRow
+     * @return mixed
+     */
+    public function getData(array $dataRow)
+    {
+        return [
+            'edit' => [
+                'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['block_id' => $dataRow['block_id']]),
+                'title' => __('Edit'),
+
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php b/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.php
new file mode 100644
index 00000000000..65175c4773c
--- /dev/null
+++ b/app/code/Magento/Cms/Ui/DataProvider/Page/Options/IsActive.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Ui\DataProvider\Page\Options;
+
+use Magento\Ui\DataProvider\OptionsInterface;
+
+/**
+ * Class IsActive
+ */
+class IsActive implements OptionsInterface
+{
+    /**
+     * @var \Magento\Cms\Model\Page
+     */
+    protected $cmsPage;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Cms\Model\Page $cmsPage
+     */
+    public function __construct(\Magento\Cms\Model\Page $cmsPage)
+    {
+        $this->cmsPage = $cmsPage;
+    }
+
+    /**
+     * Get options
+     *
+     * @param array $options
+     * @return array
+     */
+    public function getOptions(array $options = [])
+    {
+        $newOptions = $this->cmsPage->getAvailableStatuses();
+        foreach ($newOptions as $key => $value) {
+            $newOptions[$key] = [
+                'label' => $value,
+                'value' => $key
+            ];
+        }
+
+        return array_merge_recursive($newOptions, $options);
+    }
+}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php b/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php
similarity index 53%
rename from app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php
rename to app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php
index daca432b79c..a3cdb5f24bf 100644
--- a/app/code/Magento/UrlRedirect/Service/V1/Data/Converter.php
+++ b/app/code/Magento/Cms/Ui/DataProvider/Page/Options/PageLayout.php
@@ -21,48 +21,47 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Service\V1\Data;
+namespace Magento\Cms\Ui\DataProvider\Page\Options;
 
-use Magento\Framework\Service\SimpleDataObjectConverter;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewriteBuilderFactory;
+use Magento\Ui\DataProvider\OptionsInterface;
+use Magento\Core\Model\PageLayout\Config\Builder;
 
 /**
- * Data object converter
+ * Class PageLayout
  */
-class Converter
+class PageLayout implements OptionsInterface
 {
     /**
-     * @var UrlRewriteBuilderFactory
+     * @var \Magento\Core\Model\PageLayout\Config\Builder
      */
-    protected $builderFactory;
+    protected $pageLayoutBuilder;
 
     /**
-     * @param UrlRewriteBuilderFactory $builderFactory
-     */
-    public function __construct(UrlRewriteBuilderFactory $builderFactory)
-    {
-        $this->builderFactory = $builderFactory;
-    }
-
-    /**
-     * Convert array to Service Data Object
+     * Constructor
      *
-     * @param array $data
-     * @return UrlRewrite
+     * @param Builder $pageLayoutBuilder
      */
-    public function convertArrayToObject(array $data)
+    public function __construct(Builder $pageLayoutBuilder)
     {
-        return $this->builderFactory->create()->populateWithArray($data)->create();
+        $this->pageLayoutBuilder = $pageLayoutBuilder;
     }
 
     /**
-     * Convert Service Data Object to array
+     * Get options
      *
-     * @param UrlRewrite $object
+     * @param array $options
      * @return array
      */
-    public function convertObjectToArray(UrlRewrite $object)
+    public function getOptions(array $options = [])
     {
-        return SimpleDataObjectConverter::toFlatArray($object);
+        $newOptions = $this->pageLayoutBuilder->getPageLayoutsConfig()->getOptions();
+        foreach ($newOptions as $key => $value) {
+            $newOptions[$key] = [
+                'label' => $value,
+                'value' => $key
+            ];
+        }
+
+        return array_merge_recursive($newOptions, $options);
     }
 }
diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php b/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
new file mode 100644
index 00000000000..36b0da9c589
--- /dev/null
+++ b/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
@@ -0,0 +1,87 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Ui\DataProvider\Page\Row;
+
+use Magento\Framework\UrlInterface;
+use Magento\Ui\DataProvider\RowInterface;
+use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder;
+
+/**
+ * Class Actions
+ */
+class Actions implements RowInterface
+{
+    /**
+     * Url path
+     */
+    const URL_PATH = 'cms/page/edit';
+
+    /**
+     * @var UrlBuilder
+     */
+    protected $actionUrlBuilder;
+
+    /**
+     * @var UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * Constructor
+     *
+     * @param UrlBuilder $actionUrlBuilder
+     * @param UrlInterface $urlBuilder
+     */
+    public function __construct(UrlBuilder $actionUrlBuilder, UrlInterface $urlBuilder)
+    {
+        $this->urlBuilder = $urlBuilder;
+        $this->actionUrlBuilder = $actionUrlBuilder;
+    }
+
+    /**
+     * Get data
+     *
+     * @param array $dataRow
+     * @return mixed
+     */
+    public function getData(array $dataRow)
+    {
+        return [
+            'edit' => [
+                'href' => $this->urlBuilder->getUrl(static::URL_PATH, ['page_id' => $dataRow['page_id']]),
+                'title' => __('Edit'),
+                'hidden' => true
+
+            ],
+            'preview' => [
+                'href' => $this->actionUrlBuilder->getUrl(
+                    $dataRow['identifier'],
+                    isset($dataRow['_first_store_id']) ? $dataRow['_first_store_id'] : null,
+                    isset($dataRow['store_code']) ? $dataRow['store_code'] : null
+                ),
+                'title' => __('Preview')
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json
index abc36c49bc8..da8253d95d9 100644
--- a/app/code/Magento/Cms/composer.json
+++ b/app/code/Magento/Cms/composer.json
@@ -3,18 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-email": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-email": "0.1.0-alpha97",
+        "magento/module-ui": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Cms/etc/module.xml b/app/code/Magento/Cms/etc/module.xml
index 24d9c5e083a..fbd5918bacb 100644
--- a/app/code/Magento/Cms/etc/module.xml
+++ b/app/code/Magento/Cms/etc/module.xml
@@ -28,7 +28,6 @@
         <sequence>
             <module name="Magento_Core"/>
             <module name="Magento_Store"/>
-            <module name="Magento_UrlRewrite" />
             <module name="Magento_Theme"/>
         </sequence>
         <depends>
@@ -39,6 +38,7 @@
             <module name="Magento_Backend"/>
             <module name="Magento_Catalog"/>
             <module name="Magento_Email"/>
+            <module name="Magento_Ui"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_edit.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_edit.xml
index 311554cd27d..ffce5673a34 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_edit.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_edit.xml
@@ -25,19 +25,11 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="editor"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-fileuploader-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <link src="jquery/fileUploader/bootstrap.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Cms\Block\Adminhtml\Block\Edit" name="cms_block_edit"/>
     </referenceContainer>
-</page>
\ No newline at end of file
+</page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
index db432ae3883..6439c07fd16 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_index.xml
@@ -25,85 +25,6 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="content">
-        <block class="Magento\Cms\Block\Adminhtml\Block" name="cms_block">
-            <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.cms.block.grid" as="grid">
-                <arguments>
-                    <argument name="id" xsi:type="string">cmsBlockGrid</argument>
-                    <argument name="dataSource" xsi:type="object">Magento\Cms\Model\Resource\Block\Grid\Collection</argument>
-                    <argument name="default_sort" xsi:type="string">block_identifier</argument>
-                    <argument name="default_dir" xsi:type="string">ASC</argument>
-                </arguments>
-                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="adminhtml.cms.block.grid.columnSet" as="grid.columnSet">
-                    <arguments>
-                        <argument name="id" xsi:type="string">cmsBlockGrid</argument>
-                        <argument name="rowUrl" xsi:type="array">
-                            <item name="path" xsi:type="string">*/*/edit</item>
-                            <item name="extraParamsTemplate" xsi:type="array">
-                                <item name="block_id" xsi:type="string">getId</item>
-                            </item>
-                        </argument>
-                    </arguments>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="title">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Title</argument>
-                            <argument name="align" xsi:type="string">left</argument>
-                            <argument name="index" xsi:type="string">title</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="identifier">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Identifier</argument>
-                            <argument name="align" xsi:type="string">left</argument>
-                            <argument name="index" xsi:type="string">identifier</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="store_id">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Store View</argument>
-                            <argument name="index" xsi:type="string">store_id</argument>
-                            <argument name="type" xsi:type="string">store</argument>
-                            <argument name="store_all" xsi:type="string">1</argument>
-                            <argument name="store_view" xsi:type="string">1</argument>
-                            <argument name="sortable" xsi:type="string">0</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="is_active">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Status</argument>
-                            <argument name="index" xsi:type="string">is_active</argument>
-                            <argument name="type" xsi:type="string">options</argument>
-                            <argument name="options" xsi:type="array">
-                                <item name="disable" xsi:type="array">
-                                    <item name="value" xsi:type="string">0</item>
-                                    <item name="label" xsi:type="string" translate="true">Disabled</item>
-                                </item>
-                                <item name="enable" xsi:type="array">
-                                    <item name="value" xsi:type="string">1</item>
-                                    <item name="label" xsi:type="string" translate="true">Enabled</item>
-                                </item>
-                            </argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="creation_time">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Created</argument>
-                            <argument name="type" xsi:type="string">datetime</argument>
-                            <argument name="index" xsi:type="string">creation_time</argument>
-                            <argument name="column_css_class" xsi:type="string">col-date</argument>
-                            <argument name="header_css_class" xsi:type="string">col-date</argument>
-                        </arguments>
-                    </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="update_time">
-                        <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Modified</argument>
-                            <argument name="type" xsi:type="string">datetime</argument>
-                            <argument name="index" xsi:type="string">update_time</argument>
-                            <argument name="column_css_class" xsi:type="string">col-date</argument>
-                            <argument name="header_css_class" xsi:type="string">col-date</argument>
-                        </arguments>
-                    </block>
-                </block>
-            </block>
-        </block>
+        <ui_component name="cms_block_listing" component="listing" />
     </referenceContainer>
 </page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
new file mode 100644
index 00000000000..4c9f1a309ee
--- /dev/null
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_block_listing.xml
@@ -0,0 +1,148 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
+    <referenceBlock name="listing">
+        <arguments>
+            <argument name="name" xsi:type="string">cms_block_listing</argument>
+            <argument name="dataSource" xsi:type="object">Magento\Cms\Model\Resource\Block\Grid\Collection</argument>
+            <argument name="save_parameters_in_session" xsi:type="string">1</argument>
+            <argument name="configuration" xsi:type="array">
+                <item name="page_actions" xsi:type="array">
+                    <item name="add" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Add New Block</item>
+                    </item>
+                </item>
+            </argument>
+            <argument name="meta" xsi:type="array">
+                <item name="defaults" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="filterable" xsi:type="boolean">true</item>
+                    <item name="sortable" xsi:type="boolean">true</item>
+                </item>
+                <item name="index_field" xsi:type="string">block_id</item>
+                <item name="item_action" xsi:type="string">edit</item>
+                <item name="fields" xsi:type="array">
+                    <item name="block_id" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">ID</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_range</item>
+                    </item>
+                    <item name="title" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Title</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_input</item>
+                    </item>
+                    <item name="identifier" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Identifier</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_input</item>
+                    </item>
+                    <item name="store_id" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Store View</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">store</item>
+                        <item name="sortable" xsi:type="boolean">false</item>
+                        <item name="filter_type" xsi:type="string">filter_store</item>
+                        <item name="options_provider" xsi:type="string">Magento\Ui\DataProvider\Options\Store</item>
+                    </item>
+                    <item name="is_active" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Status</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_select</item>
+                        <item name="options" xsi:type="array">
+                            <item name="disable" xsi:type="array">
+                                <item name="value" xsi:type="string">0</item>
+                                <item name="label" xsi:type="string" translate="true">Disabled</item>
+                            </item>
+                            <item name="enable" xsi:type="array">
+                                <item name="value" xsi:type="string">1</item>
+                                <item name="label" xsi:type="string" translate="true">Enabled</item>
+                            </item>
+                        </item>
+                    </item>
+                    <item name="creation_time" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Created</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">date</item>
+                        <item name="filter_type" xsi:type="string">filter_date</item>
+                    </item>
+                    <item name="update_time" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Modified</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">date</item>
+                        <item name="filter_type" xsi:type="string">filter_date</item>
+                    </item>
+                </item>
+            </argument>
+            <argument name="row_data_provider" xsi:type="array">
+                <item name="actions" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Block\Row\Actions</item>
+                </item>
+                <item name="store_id" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Ui\DataProvider\Row\Store</item>
+                </item>
+            </argument>
+        </arguments>
+        <referenceBlock name="listing_before">
+            <block class="Magento\Ui\ListingContainer\Massaction\View" name="massaction_top">
+                <arguments>
+                    <argument name="content_template" xsi:type="string">Magento_Ui::listingcontainer/massaction/default.phtml</argument>
+                    <argument name="config" xsi:type="array">
+                        <item name="actions" xsi:type="array">
+                            <item name="delete" xsi:type="array">
+                                <item name="label" xsi:type="string" translate="true">Delete</item>
+                                <item name="url" xsi:type="string">cms/block/massDelete</item>
+                            </item>
+                        </item>
+                    </argument>
+                </arguments>
+            </block>
+            <referenceBlock name="filter_base">
+                <arguments>
+                    <argument name="config" xsi:type="array">
+                        <item name="types" xsi:type="array">
+                            <item name="filter_store" xsi:type="array">
+                                <item name="content_template" xsi:type="string">Magento_Store/templates/filter/store.html</item>
+                                <item name="control" xsi:type="string">Magento_Store/js/listing/filter/store</item>
+                            </item>
+                        </item>
+                    </argument>
+                </arguments>
+            </referenceBlock>
+            <referenceBlock name="sorting_base">
+                <arguments>
+                    <argument name="config" xsi:type="array">
+                        <item name="field" xsi:type="string">block_id</item>
+                    </argument>
+                </arguments>
+            </referenceBlock>
+        </referenceBlock>
+    </referenceBlock>
+</page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
index c80aed98c48..ecfc23280d6 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml
@@ -24,18 +24,10 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-fileuploader-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <link src="jquery/fileUploader/bootstrap.js"/>
+    </head>
     <update handle="editor"/>
     <referenceContainer name="content">
         <block class="Magento\Cms\Block\Adminhtml\Page\Edit" name="cms_page_edit"/>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
index 0ade3cda655..bfe3daab138 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_index.xml
@@ -25,6 +25,6 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="content">
-        <block class="Magento\Cms\Block\Adminhtml\Page" name="cms_page"/>
+        <ui_component name="cms_page_listing" component="listing" />
     </referenceContainer>
 </page>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
new file mode 100644
index 00000000000..7dedb50ab33
--- /dev/null
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_listing.xml
@@ -0,0 +1,150 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
+    <referenceBlock name="listing">
+        <arguments>
+            <argument name="name" xsi:type="string">cms_page_listing</argument>
+            <argument name="dataSource" xsi:type="object">Magento\Cms\Model\Resource\Page\Grid\Collection</argument>
+            <argument name="save_parameters_in_session" xsi:type="string">1</argument>
+            <argument name="configuration" xsi:type="array">
+                <item name="page_actions" xsi:type="array">
+                    <item name="add" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Add New Page</item>
+                    </item>
+                </item>
+            </argument>
+            <argument name="meta" xsi:type="array">
+                <item name="defaults" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="filterable" xsi:type="boolean">true</item>
+                    <item name="sortable" xsi:type="boolean">true</item>
+                </item>
+                <item name="index_field" xsi:type="string">page_id</item>
+                <item name="item_action" xsi:type="string">edit</item>
+                <item name="fields" xsi:type="array">
+                    <item name="page_id" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">ID</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_range</item>
+                    </item>
+                    <item name="title" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Title</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_input</item>
+                    </item>
+                    <item name="identifier" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">URL Key</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_input</item>
+                    </item>
+                    <item name="page_layout" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Layout</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_select</item>
+                        <item name="options_provider" xsi:type="string">Magento\Cms\Ui\DataProvider\Page\Options\PageLayout</item>
+                    </item>
+                    <item name="store_id" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Store View</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="sortable" xsi:type="boolean">false</item>
+                        <item name="data_type" xsi:type="string">store</item>
+                        <item name="filter_type" xsi:type="string">filter_store</item>
+                        <item name="options_provider" xsi:type="string">Magento\Ui\DataProvider\Options\Store</item>
+                    </item>
+                    <item name="is_active" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Status</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">text</item>
+                        <item name="filter_type" xsi:type="string">filter_select</item>
+                        <item name="options_provider" xsi:type="string">Magento\Cms\Ui\DataProvider\Page\Options\IsActive</item>
+                    </item>
+                    <item name="creation_time" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Created</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">date</item>
+                        <item name="filter_type" xsi:type="string">filter_date</item>
+                    </item>
+                    <item name="update_time" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Modified</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">date</item>
+                        <item name="filter_type" xsi:type="string">filter_date</item>
+                    </item>
+                    <item name="actions" xsi:type="array">
+                        <item name="title" xsi:type="string" translate="true">Action</item>
+                        <item name="align" xsi:type="string">left</item>
+                        <item name="data_type" xsi:type="string">actions</item>
+                        <item name="filterable" xsi:type="boolean">false</item>
+                        <item name="sortable" xsi:type="boolean">false</item>
+                    </item>
+                </item>
+            </argument>
+            <argument name="row_data_provider" xsi:type="array">
+                <item name="actions" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Cms\Ui\DataProvider\Page\Row\Actions</item>
+                </item>
+                <item name="store_id" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\Ui\DataProvider\Row\Store</item>
+                </item>
+            </argument>
+        </arguments>
+    </referenceBlock>
+    <referenceBlock name="massaction_top">
+        <arguments>
+            <argument name="config" xsi:type="array">
+                <item name="actions" xsi:type="array">
+                    <item name="delete" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Delete</item>
+                        <item name="url" xsi:type="string">cms/page/massDelete</item>
+                    </item>
+                </item>
+            </argument>
+        </arguments>
+    </referenceBlock>
+    <referenceBlock name="filter_base">
+        <arguments>
+            <argument name="config" xsi:type="array">
+                <item name="types" xsi:type="array">
+                    <item name="filter_store" xsi:type="array">
+                        <item name="template" xsi:type="string">Magento_Store/templates/filter/store.html</item>
+                        <item name="control" xsi:type="string">Magento_Store/js/listing/filter/store</item>
+                    </item>
+                </item>
+            </argument>
+        </arguments>
+    </referenceBlock>
+    <referenceBlock name="sorting_base">
+        <arguments>
+            <argument name="config" xsi:type="array">
+                <item name="field" xsi:type="string">page_id</item>
+            </argument>
+        </arguments>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml
index 7c8cbbcb290..f2f91a1955d 100644
--- a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml
+++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml
@@ -25,7 +25,6 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <remove name="footer"/>
-    <remove name="head"/>
     <remove name="left"/>
     <referenceContainer name="content">
         <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Content" name="wysiwyg_images.content" template="browser/content.phtml">
diff --git a/app/code/Magento/Cms/Model/Page/Urlrewrite.php b/app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlPathGenerator.php
similarity index 59%
rename from app/code/Magento/Cms/Model/Page/Urlrewrite.php
rename to app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlPathGenerator.php
index fd0af0f3726..c76526f06bc 100644
--- a/app/code/Magento/Cms/Model/Page/Urlrewrite.php
+++ b/app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlPathGenerator.php
@@ -21,59 +21,49 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Model\Page;
+namespace Magento\CmsUrlRewrite\Model;
 
-/**
- * Page Url rewrite model
- *
- * @method \Magento\Cms\Model\Resource\Page\Urlrewrite getResource() getResource()
- * @method int getCmsPageId() getCmsPageId()
- * @method int getUrlRewriteId() getUrlRewriteId()
- * @method \Magento\Cms\Model\Page\Urlrewrite setCmsPageId() setCmsPageId(int)
- * @method \Magento\Cms\Model\Page\Urlrewrite setUrlRewriteId() setUrlRewriteId(int)
- */
-class Urlrewrite extends \Magento\Framework\Model\AbstractModel
+class CmsPageUrlPathGenerator
 {
-    /**
-     * Initialize resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Cms\Model\Resource\Page\Urlrewrite');
+    /** @var \Magento\Framework\Filter\FilterManager */
+    protected $filterManager;
+
+    public function __construct(
+        \Magento\Framework\Filter\FilterManager $filterManager
+    ) {
+        $this->filterManager = $filterManager;
     }
 
     /**
-     * Generate id path
-     *
      * @param \Magento\Cms\Model\Page $cmsPage
+     *
      * @return string
      */
-    public function generateIdPath($cmsPage)
+    public function getUrlPath($cmsPage)
     {
-        return 'cms_page/' . $cmsPage->getId();
+        return $cmsPage->getIdentifier();
     }
 
     /**
-     * Generate target path
+     * Get canonical product url path
      *
      * @param \Magento\Cms\Model\Page $cmsPage
      * @return string
      */
-    public function generateTargetPath($cmsPage)
+    public function getCanonicalUrlPath($cmsPage)
     {
         return 'cms/page/view/page_id/' . $cmsPage->getId();
     }
 
     /**
-     * Get request path
+     * Generate CMS page url key based on url_key entered by merchant or page title
      *
      * @param \Magento\Cms\Model\Page $cmsPage
      * @return string
      */
-    public function generateRequestPath($cmsPage)
+    public function generateUrlKey($cmsPage)
     {
-        return $cmsPage->getIdentifier();
+        $urlKey = $cmsPage->getIdentifier();
+        return $this->filterManager->translitUrl($urlKey === '' || $urlKey === null ? $cmsPage->getTitle() : $urlKey);
     }
 }
diff --git a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php b/app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlRewriteGenerator.php
similarity index 64%
rename from app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php
rename to app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlRewriteGenerator.php
index 076448145b6..f99d039999f 100644
--- a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGenerator.php
+++ b/app/code/Magento/CmsUrlRewrite/Model/CmsPageUrlRewriteGenerator.php
@@ -21,23 +21,23 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CmsUrlRewrite\Service\V1;
+namespace Magento\CmsUrlRewrite\Model;
 
 use Magento\Framework\StoreManagerInterface;
-use Magento\UrlRedirect\Service\V1\Data\Converter;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
 
-class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface
+class CmsPageUrlRewriteGenerator
 {
     /**
      * Entity type code
      */
     const ENTITY_TYPE = 'cms-page';
 
-    /**
-     * @var Converter
-     */
-    protected $converter;
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator */
+    protected $cmsPageUrlPathGenerator;
 
     /**
      * Store manager
@@ -52,19 +52,23 @@ class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface
     protected $cmsPage;
 
     /**
-     * @param Converter $converter
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder $urlRewriteBuilder
+     * @param \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator
      * @param StoreManagerInterface $storeManager
      */
     public function __construct(
-        Converter $converter,
+        UrlRewriteBuilder $urlRewriteBuilder,
+        CmsPageUrlPathGenerator $cmsPageUrlPathGenerator,
         StoreManagerInterface $storeManager
     ) {
-        $this->converter = $converter;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
         $this->storeManager = $storeManager;
+        $this->cmsPageUrlPathGenerator = $cmsPageUrlPathGenerator;
     }
 
     /**
-     * {@inheritdoc}
+     * @param \Magento\Cms\Model\Page $cmsPage
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
      */
     public function generate($cmsPage)
     {
@@ -79,7 +83,7 @@ class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface
     /**
      * Generate list of urls for default store
      *
-     * @return UrlRewrite[]
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
      */
     protected function generateForAllStores()
     {
@@ -94,7 +98,7 @@ class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface
      * Generate list of urls per store
      *
      * @param int[] $storeIds
-     * @return UrlRewrite[]
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
      */
     protected function generateForSpecificStores($storeIds)
     {
@@ -113,18 +117,18 @@ class CmsPageUrlGenerator implements CmsPageUrlGeneratorInterface
      * Create url rewrite object
      *
      * @param int $storeId
-     * @param string|null $redirectType Null or one of OptionProvider const
-     * @return UrlRewrite
+     * @param int $redirectType
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite
      */
-    protected function createUrlRewrite($storeId, $redirectType = null)
+    protected function createUrlRewrite($storeId, $redirectType = 0)
     {
-        return $this->converter->convertArrayToObject([
-            UrlRewrite::ENTITY_TYPE => self::ENTITY_TYPE,
-            UrlRewrite::ENTITY_ID => $this->cmsPage->getId(),
-            UrlRewrite::STORE_ID => $storeId,
-            UrlRewrite::REQUEST_PATH => $this->cmsPage->getIdentifier(),
-            UrlRewrite::TARGET_PATH => 'cms/page/view/page_id/' . $this->cmsPage->getId(),
-            UrlRewrite::REDIRECT_TYPE => $redirectType,
-        ]);
+        return $this->urlRewriteBuilder->setStoreId($storeId)
+            ->setEntityType(self::ENTITY_TYPE)
+            ->setEntityId($this->cmsPage->getId())
+            ->setRequestPath($this->cmsPage->getIdentifier())
+            ->setTargetPath($this->cmsPageUrlPathGenerator->getCanonicalUrlPath($this->cmsPage))
+            ->setIsAutogenerated(1)
+            ->setRedirectType($redirectType)
+            ->create();
     }
 }
diff --git a/app/code/Magento/CmsUrlRewrite/Model/Observer.php b/app/code/Magento/CmsUrlRewrite/Model/Observer.php
index e5278ac34be..ff6ed1efc66 100644
--- a/app/code/Magento/CmsUrlRewrite/Model/Observer.php
+++ b/app/code/Magento/CmsUrlRewrite/Model/Observer.php
@@ -24,30 +24,28 @@
 namespace Magento\CmsUrlRewrite\Model;
 
 use Magento\Framework\Event\Observer as EventObserver;
-use Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGeneratorInterface;
-use Magento\UrlRedirect\Service\V1\UrlSaveInterface;
-use Magento\Framework\Model\Exception;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
 
 class Observer
 {
     /**
-     * @var CmsPageUrlGeneratorInterface
+     * @var CmsPageUrlRewriteGenerator
      */
-    protected $urlGenerator;
+    protected $cmsPageUrlRewriteGenerator;
 
     /**
-     * @var \Magento\UrlRedirect\Service\V1\UrlSaveInterface
+     * @var UrlPersistInterface
      */
-    protected $urlSave;
+    protected $urlPersist;
 
     /**
-     * @param CmsPageUrlGeneratorInterface $urlGenerator
-     * @param UrlSaveInterface $urlSave
+     * @param CmsPageUrlRewriteGenerator $cmsPageUrlRewriteGenerator
+     * @param UrlPersistInterface $urlPersist
      */
-    public function __construct(CmsPageUrlGeneratorInterface $urlGenerator, UrlSaveInterface $urlSave)
+    public function __construct(CmsPageUrlRewriteGenerator $cmsPageUrlRewriteGenerator, UrlPersistInterface $urlPersist)
     {
-        $this->urlGenerator = $urlGenerator;
-        $this->urlSave = $urlSave;
+        $this->cmsPageUrlRewriteGenerator = $cmsPageUrlRewriteGenerator;
+        $this->urlPersist = $urlPersist;
     }
 
     /**
@@ -55,22 +53,14 @@ class Observer
      *
      * @param \Magento\Framework\Event\Observer $observer
      * @return void
-     * @throws Exception|\Exception
      */
     public function processUrlRewriteSaving(EventObserver $observer)
     {
         /** @var $cmsPage \Magento\Cms\Model\Page */
         $cmsPage = $observer->getEvent()->getObject();
-        if ($cmsPage->getOrigData('identifier') !== $cmsPage->getData('identifier')) {
-            $urls = $this->urlGenerator->generate($cmsPage);
-            try {
-                $this->urlSave->save($urls);
-            } catch (\Exception $e) {
-                if ($e->getCode() === 23000) { // Integrity constraint violation: 1062 Duplicate entry
-                    throw new Exception(__('A page URL key for specified store already exists.'));
-                }
-                throw $e;
-            }
+        if ($cmsPage->dataHasChangedFor('identifier')) {
+            $urls = $this->cmsPageUrlRewriteGenerator->generate($cmsPage);
+            $this->urlPersist->replace($urls);
         }
     }
 }
diff --git a/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/Resource/Page.php b/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/Resource/Page.php
new file mode 100644
index 00000000000..713bce5d689
--- /dev/null
+++ b/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/Resource/Page.php
@@ -0,0 +1,59 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CmsUrlRewrite\Plugin\Cms\Model\Resource;
+
+/**
+ * Before save plugin for \Magento\Cms\Model\Resource\Page:
+ * - autogenerates url_key if the merchant didn't fill this field
+ */
+class Page
+{
+    /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator */
+    protected $cmsPageUrlPathGenerator;
+
+    public function __construct(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator)
+    {
+        $this->cmsPageUrlPathGenerator = $cmsPageUrlPathGenerator;
+    }
+
+    /**
+     * Before save handler
+     *
+     * @param \Magento\Cms\Model\Resource\Page $subject
+     * @param \Magento\Framework\Model\AbstractModel $object
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeSave(
+        \Magento\Cms\Model\Resource\Page $subject,
+        \Magento\Framework\Model\AbstractModel $object
+    ) {
+        /** @var $object \Magento\Cms\Model\Page */
+        $urlKey = $object->getData('identifier');
+        if ($urlKey === '' || $urlKey === null) {
+            $object->setData('identifier', $this->cmsPageUrlPathGenerator->generateUrlKey($object));
+        }
+    }
+}
diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json
index cba14ac474c..acf8fb0f3b8 100644
--- a/app/code/Magento/CmsUrlRewrite/composer.json
+++ b/app/code/Magento/CmsUrlRewrite/composer.json
@@ -3,12 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-url-redirect": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-url-rewrite": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml
index 8f4ed44ca65..68d73903051 100644
--- a/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml
+++ b/app/code/Magento/CmsUrlRewrite/etc/adminhtml/di.xml
@@ -24,5 +24,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGeneratorInterface" type="Magento\CmsUrlRewrite\Service\V1\CmsPageUrlGenerator"/>
+    <type name="Magento\Cms\Model\Resource\Page">
+        <plugin name="cms_url_rewrite_plugin" type="Magento\CmsUrlRewrite\Plugin\Cms\Model\Resource\Page"/>
+    </type>
 </config>
diff --git a/app/code/Magento/CmsUrlRewrite/etc/module.xml b/app/code/Magento/CmsUrlRewrite/etc/module.xml
index 7d40a61c106..9c20c38fdfb 100644
--- a/app/code/Magento/CmsUrlRewrite/etc/module.xml
+++ b/app/code/Magento/CmsUrlRewrite/etc/module.xml
@@ -24,9 +24,10 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_CmsUrlRewrite" schema_version="1.0.0.0" active="false">
+    <module name="Magento_CmsUrlRewrite" schema_version="1.0.0.0" active="true">
         <depends>
-            <module name="Magento_UrlRedirect"/>
+            <module name="Magento_Cms"/>
+            <module name="Magento_UrlRewrite"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json
index 7a1f9aad02e..e17863da679 100644
--- a/app/code/Magento/ConfigurableImportExport/composer.json
+++ b/app/code/Magento/ConfigurableImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-catalog-import-export": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-import-export": "0.1.0-alpha96",
-        "magento/module-configurable-product": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-catalog-import-export": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-import-export": "0.1.0-alpha97",
+        "magento/module-configurable-product": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index ca9ca611ed0..6b78393236a 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -696,6 +696,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
 
             foreach ($data as $attributeId => $attributeValue) {
                 if (isset($usedAttributes[$attributeId])) {
+                    /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attribute */
                     $attribute = $usedAttributes[$attributeId]->getProductAttribute();
                     $label = $attribute->getStoreLabel();
                     $value = $attribute;
@@ -1007,19 +1008,6 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
         return $options;
     }
 
-    /**
-     * Check if Minimum Advertise Price is enabled at least in one option
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param int $visibility
-     * @return bool|null
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function isMapEnabledInOptions($product, $visibility = null)
-    {
-        return null;
-    }
-
     /**
      * Prepare and retrieve options values with product data
      *
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
index e7aa08e135a..11702db2928 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
@@ -25,8 +25,12 @@
  */
 namespace Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute;
 
+use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+use Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data as PriceData;
+
 /**
  * @SuppressWarnings(PHPMD.LongVariable)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
@@ -72,6 +76,13 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     protected $_storeManager;
 
+    /**
+     * Price values cache
+     *
+     * @var PriceData
+     */
+    protected $priceData;
+
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
      * @param \Magento\Framework\Logger $logger
@@ -81,7 +92,9 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $catalogProductTypeConfigurable
      * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute $resource
+     * @param PriceData $priceData
      * @param \Zend_Db_Adapter_Abstract $connection
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
@@ -92,11 +105,13 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         \Magento\ConfigurableProduct\Model\Product\Type\Configurable $catalogProductTypeConfigurable,
         \Magento\Catalog\Helper\Data $catalogData,
         \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute $resource,
+        PriceData $priceData,
         $connection = null
     ) {
         $this->_storeManager = $storeManager;
         $this->_productTypeConfigurable = $catalogProductTypeConfigurable;
         $this->_catalogData = $catalogData;
+        $this->priceData = $priceData;
         parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
     }
 
@@ -259,101 +274,139 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      * Load attribute prices information
      *
      * @return $this
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     protected function _loadPrices()
     {
         if ($this->count()) {
-            $pricings = array(0 => array());
 
-            if ($this->_catalogData->isPriceGlobal()) {
-                $websiteId = 0;
-            } else {
-                $websiteId = (int)$this->_storeManager->getStore($this->getStoreId())->getWebsiteId();
-                $pricing[$websiteId] = array();
+            $values = $this->getPriceValues();
+
+            foreach ($values as $data) {
+                $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
             }
+        }
+        return $this;
+    }
 
-            $select = $this->getConnection()->select()->from(
-                array('price' => $this->_priceTable)
-            )->where(
-                'price.product_super_attribute_id IN (?)',
-                array_keys($this->_items)
-            );
+    /**
+     * Retrieve price values
+     *
+     * @return array
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function getPriceValues()
+    {
+        $cachedPriceData = $this->priceData->getProductPrice($this->getProduct()->getId());
+        if (false !== $cachedPriceData) {
+            return $cachedPriceData;
+        }
 
-            if ($websiteId > 0) {
-                $select->where('price.website_id IN(?)', array(0, $websiteId));
-            } else {
-                $select->where('price.website_id = ?', 0);
-            }
+        $pricings = array(0 => array());
 
-            $query = $this->getConnection()->query($select);
+        if ($this->_catalogData->isPriceGlobal()) {
+            $websiteId = 0;
+        } else {
+            $websiteId = (int) $this->_storeManager->getStore($this->getStoreId())->getWebsiteId();
+            $pricing[$websiteId] = array();
+        }
 
-            while ($row = $query->fetch()) {
-                $pricings[(int)$row['website_id']][] = $row;
-            }
+        $select = $this->getConnection()->select()->from(
+            array('price' => $this->_priceTable)
+        )->where(
+            'price.product_super_attribute_id IN (?)',
+            array_keys($this->_items)
+        );
 
-            $values = array();
-            $usedProducts = $this->getProductType()->getUsedProducts($this->getProduct());
-            if ($usedProducts) {
-                foreach ($this->_items as $item) {
-                    $productAttribute = $item->getProductAttribute();
-                    if (!$productAttribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute) {
-                        continue;
-                    }
-                    $itemId = $item->getId();
-                    $options = $productAttribute->getFrontend()->getSelectOptions();
-                    foreach ($options as $option) {
-                        foreach ($usedProducts as $associatedProduct) {
-                            $attributeCodeValue = $associatedProduct->getData($productAttribute->getAttributeCode());
-                            if (!empty($option['value']) && $option['value'] == $attributeCodeValue) {
-                                // If option available in associated product
-                                if (!isset($values[$item->getId() . ':' . $option['value']])) {
-                                    $values[$itemId . ':' . $option['value']] = array(
-                                        'product_super_attribute_id' => $itemId,
-                                        'value_index' => $option['value'],
-                                        'label' => $option['label'],
-                                        'default_label' => $option['label'],
-                                        'store_label' => $option['label'],
-                                        'is_percent' => 0,
-                                        'pricing_value' => null,
-                                        'use_default_value' => true
-                                    );
-                                }
+        if ($websiteId > 0) {
+            $select->where('price.website_id IN(?)', array(0, $websiteId));
+        } else {
+            $select->where('price.website_id = ?', 0);
+        }
+
+        $query = $this->getConnection()->query($select);
+
+        while ($row = $query->fetch()) {
+            $pricings[(int)$row['website_id']][] = $row;
+        }
+
+        $values = array();
+        $usedProducts = $this->getProductType()->getUsedProducts($this->getProduct());
+        if ($usedProducts) {
+            foreach ($this->_items as $item) {
+                $productAttribute = $item->getProductAttribute();
+                if (!$productAttribute instanceof AbstractAttribute) {
+                    continue;
+                }
+                $itemId = $item->getId();
+                $options = $this->getIncludedOptions($usedProducts, $productAttribute);
+                foreach ($options as $option) {
+                    foreach ($usedProducts as $associatedProduct) {
+                        $attributeCodeValue = $associatedProduct->getData($productAttribute->getAttributeCode());
+                        if (!empty($option['value']) && $option['value'] == $attributeCodeValue) {
+                            // If option available in associated product
+                            if (!isset($values[$item->getId() . ':' . $option['value']])) {
+                                $values[$itemId . ':' . $option['value']] = array(
+                                    'product_super_attribute_id' => $itemId,
+                                    'value_index' => $option['value'],
+                                    'label' => $option['label'],
+                                    'default_label' => $option['label'],
+                                    'store_label' => $option['label'],
+                                    'is_percent' => 0,
+                                    'pricing_value' => null,
+                                    'use_default_value' => true
+                                );
                             }
                         }
                     }
                 }
             }
+        }
 
-            foreach ($pricings[0] as $pricing) {
-                // Addding pricing to options
+        foreach ($pricings[0] as $pricing) {
+            // Addding pricing to options
+            $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
+            if (isset($values[$valueKey])) {
+                $values[$valueKey]['pricing_value'] = $pricing['pricing_value'];
+                $values[$valueKey]['is_percent'] = $pricing['is_percent'];
+                $values[$valueKey]['value_id'] = $pricing['value_id'];
+                $values[$valueKey]['use_default_value'] = true;
+            }
+        }
+
+        if ($websiteId && isset($pricings[$websiteId])) {
+            foreach ($pricings[$websiteId] as $pricing) {
                 $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
                 if (isset($values[$valueKey])) {
                     $values[$valueKey]['pricing_value'] = $pricing['pricing_value'];
                     $values[$valueKey]['is_percent'] = $pricing['is_percent'];
                     $values[$valueKey]['value_id'] = $pricing['value_id'];
-                    $values[$valueKey]['use_default_value'] = true;
+                    $values[$valueKey]['use_default_value'] = false;
                 }
             }
+        }
 
-            if ($websiteId && isset($pricings[$websiteId])) {
-                foreach ($pricings[$websiteId] as $pricing) {
-                    $valueKey = $pricing['product_super_attribute_id'] . ':' . $pricing['value_index'];
-                    if (isset($values[$valueKey])) {
-                        $values[$valueKey]['pricing_value'] = $pricing['pricing_value'];
-                        $values[$valueKey]['is_percent'] = $pricing['is_percent'];
-                        $values[$valueKey]['value_id'] = $pricing['value_id'];
-                        $values[$valueKey]['use_default_value'] = false;
-                    }
-                }
-            }
+        $this->priceData->setProductPrice($this->getProduct()->getId(), $values);
 
-            foreach ($values as $data) {
-                $this->getItemById($data['product_super_attribute_id'])->addPrice($data);
-            }
+        return $values;
+    }
+
+    /**
+     * Get options for all product attribute values from used products
+     *
+     * @param \Magento\Catalog\Model\Product[] $usedProducts
+     * @param AbstractAttribute $productAttribute
+     * @return array
+     */
+    protected function getIncludedOptions(array $usedProducts, AbstractAttribute $productAttribute)
+    {
+        $attributeValues = [];
+        foreach ($usedProducts as $associatedProduct) {
+            $attributeValues[] = $associatedProduct->getData($productAttribute->getAttributeCode());
         }
-        return $this;
+        $options = $productAttribute->getSource()->getSpecificOptions(array_unique($attributeValues));
+        return $options;
+
     }
 
     /**
diff --git a/app/code/Magento/UrlRedirect/Model/StorageInterface.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
similarity index 51%
rename from app/code/Magento/UrlRedirect/Model/StorageInterface.php
rename to app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
index c362c56460c..61a7dc3aaf3 100644
--- a/app/code/Magento/UrlRedirect/Model/StorageInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/Data.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Catalog Configurable Product Attribute Collection
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,44 +23,39 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Model;
 
-use Magento\UrlRedirect\Service\V1\Data\Filter;
+namespace Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price;
 
 /**
- * Url Storage Interface
+ * Class Data
+ * Caching price for performance improvements of Configurable product loading
+ * (Avoiding using static properties of Attribute Collection resource)
+ * @todo Configurable Product models/resouces should be refactored with introduction of new entity(es),
+ * such as ConfigurableOption (or OptionPrice, OptionPriceCollection)
  */
-interface StorageInterface
+class Data
 {
     /**
-     * Find all rows by specific filter
-     *
-     * @param Filter $filter
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
+     * @var array
      */
-    public function findAllByFilter(Filter $filter);
+    protected $prices;
 
     /**
-     * Find row by specific filter
-     *
-     * @param Filter $filter
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite
-     */
-    public function findByFilter(Filter $filter);
-
-    /**
-     * Add multiple urls to storage
-     *
-     * @param array $urls
+     * @param int $productId
+     * @param array $priceData
      * @return void
      */
-    public function addMultiple(array $urls);
+    public function setProductPrice($productId, array $priceData)
+    {
+        $this->prices[$productId] = $priceData;
+    }
 
     /**
-     * Delete data from storage by specific filter
-     *
-     * @param Filter $filter
-     * @return void
+     * @param int $productId
+     * @return array|bool
      */
-    public function deleteByFilter(Filter $filter);
+    public function getProductPrice($productId)
+    {
+        return isset($this->prices[$productId]) ? $this->prices[$productId] : false;
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json
index 42dd8794a7f..dd6b68d1aca 100644
--- a/app/code/Magento/ConfigurableProduct/composer.json
+++ b/app/code/Magento/ConfigurableProduct/composer.json
@@ -3,24 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-catalog-rule": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
-        "magento/module-webapi": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-catalog-rule": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/module-webapi": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/ConfigurableProduct/data/configurableproduct_setup/data-install-1.0.0.0.php b/app/code/Magento/ConfigurableProduct/data/configurableproduct_setup/data-install-1.0.0.0.php
index c5a0949e29f..3a082776544 100644
--- a/app/code/Magento/ConfigurableProduct/data/configurableproduct_setup/data-install-1.0.0.0.php
+++ b/app/code/Magento/ConfigurableProduct/data/configurableproduct_setup/data-install-1.0.0.0.php
@@ -28,9 +28,6 @@ $attributes = array(
     'country_of_manufacture',
     'group_price',
     'minimal_price',
-    'msrp',
-    'msrp_enabled',
-    'msrp_display_actual_price_type',
     'price',
     'special_price',
     'special_from_date',
diff --git a/app/code/Magento/ConfigurableProduct/etc/module.xml b/app/code/Magento/ConfigurableProduct/etc/module.xml
index 45f5c2af24f..5fa18b98e71 100644
--- a/app/code/Magento/ConfigurableProduct/etc/module.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/module.xml
@@ -38,7 +38,6 @@
             <module name="Magento_Sales" />
             <module name="Magento_Core" />
             <module name="Magento_Checkout" />
-            <module name="Magento_Theme" />
             <module name="Magento_Backend" />
             <module name="Magento_Eav" />
             <module name="Magento_Customer" />
diff --git a/app/code/Magento/ConfigurableProduct/sql/configurable_setup/install-1.0.0.0.php b/app/code/Magento/ConfigurableProduct/sql/configurableproduct_setup/install-1.0.0.0.php
similarity index 100%
rename from app/code/Magento/ConfigurableProduct/sql/configurable_setup/install-1.0.0.0.php
rename to app/code/Magento/ConfigurableProduct/sql/configurableproduct_setup/install-1.0.0.0.php
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
index cf299a6cb02..e2569e2bf7e 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
@@ -25,13 +25,9 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="catalog_product_superconfig_config"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-grouped-product-css-grouped-product-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_ConfigurableProduct::css/configurable-product.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_ConfigurableProduct::css/configurable-product.css"/>
+    </head>
     <referenceBlock name="product_tabs">
         <block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config" name="admin.product.edit.tab.super.config.grid.container">
             <block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config" template="Magento_ConfigurableProduct::catalog/product/edit/super/generator.phtml" name="product-variations-generator" as="generator">
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_new.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_new.xml
index 15194898393..bbbd73d4218 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_new.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_new.xml
@@ -29,13 +29,9 @@
         <block class="Magento\ConfigurableProduct\Block\Product\Configurable\AttributeSelector" template="product/configurable/affected-attribute-set-selector/js.phtml"/>
         <block class="Magento\Framework\View\Element\Template" template="Magento_ConfigurableProduct::product/configurable/stock/disabler.phtml"/>
     </referenceContainer>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-configurableproduct-product-product-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_ConfigurableProduct::product/product.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_ConfigurableProduct::product/product.css"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Framework\View\Element\Template" name="affected-attribute-set-form" template="Magento_ConfigurableProduct::product/configurable/affected-attribute-set-selector/form.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml b/app/code/Magento/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml
index a8a78e7adde..225f40ddc61 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml
@@ -24,14 +24,12 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="class" value="type-configurable"/>
+    </body>
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="configurableproduct_product_view_head_components" template="Magento_ConfigurableProduct::js/components.phtml"/>
     </referenceBlock>
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="value" xsi:type="string">type-configurable</argument>
-        </action>
-    </referenceBlock>
     <referenceContainer name="product.info.type">
         <block class="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable" name="product.info.configurable" as="product_type_data" template="Magento_Catalog::product/view/type/default.phtml"/>
         <container name="product.info.configurable.extra" after="product.info.configurable" as="product_type_data_extra" label="Product Extra Info">
diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json
index bf22cae32ad..c4b5409c8bc 100644
--- a/app/code/Magento/Contact/composer.json
+++ b/app/code/Magento/Contact/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Contact/view/email/submitted_form.html b/app/code/Magento/Contact/view/email/submitted_form.html
index 847fbf146cf..d1af780b313 100644
--- a/app/code/Magento/Contact/view/email/submitted_form.html
+++ b/app/code/Magento/Contact/view/email/submitted_form.html
@@ -7,6 +7,6 @@
 @-->
 Name: {{var data.name}}
 E-mail: {{var data.email}}
-Telephone: {{var data.telephone}}
+Phone Number: {{var data.telephone}}
 
 Comment: {{var data.comment}}
\ No newline at end of file
diff --git a/app/code/Magento/Contact/view/frontend/layout/contact_index_index.xml b/app/code/Magento/Contact/view/frontend/layout/contact_index_index.xml
index db2198aa747..136bbae3e51 100644
--- a/app/code/Magento/Contact/view/frontend/layout/contact_index_index.xml
+++ b/app/code/Magento/Contact/view/frontend/layout/contact_index_index.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Contact Us</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Contact Us</title>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Framework\View\Element\Template" name="contactForm" template="Magento_Contact::form.phtml">
             <container name="form.additional.info" label="Form Additional Info"/>
diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml
index db3516d2fa9..53e1a0547f4 100644
--- a/app/code/Magento/Contact/view/frontend/templates/form.phtml
+++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml
@@ -29,7 +29,8 @@
       data-hasrequired="<?php echo __('* Required Fields') ?>"
       data-mage-init='{"validation":{}}'>
     <fieldset class="fieldset">
-        <legend class="legend"><span><?php echo __('Contact Information') ?></span></legend><br />
+        <legend class="legend"><span><?php echo __('Write Us') ?></span></legend><br />
+        <div class="field note"><?php echo __('Jot us a note and we’ll get back to you as quickly as possible.') ?></div>
         <div class="field name required">
             <label class="label" for="name"><span><?php echo __('Name') ?></span></label>
             <div class="control">
@@ -37,21 +38,21 @@
             </div>
         </div>
         <div class="field email required">
-            <label class="label" for="email"><span><?php echo __('Email') ?></span></label>
+            <label class="label" for="email"><span><?php echo __('Email Address') ?></span></label>
             <div class="control">
-                <input name="email" id="email" title="<?php echo __('Email') ?>" value="<?php echo $this->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="text" data-validate="{required:true, 'validate-email':true}"/>
+                <input name="email" id="email" title="<?php echo __('Email Address') ?>" value="<?php echo $this->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="text" data-validate="{required:true, 'validate-email':true}"/>
             </div>
         </div>
         <div class="field telephone">
-            <label class="label" for="telephone"><span><?php echo __('Telephone') ?></span></label>
+            <label class="label" for="telephone"><span><?php echo __('Phone Number') ?></span></label>
             <div class="control">
-                <input name="telephone" id="telephone" title="<?php echo __('Telephone') ?>" value="" class="input-text" type="text" />
+                <input name="telephone" id="telephone" title="<?php echo __('Phone Number') ?>" value="" class="input-text" type="text" />
             </div>
         </div>
         <div class="field comment required">
-            <label class="label" for="comment"><span><?php echo __('Comment') ?></span></label>
+            <label class="label" for="comment"><span><?php echo __('What’s on your mind?') ?></span></label>
             <div class="control">
-                <textarea name="comment" id="comment" title="<?php echo __('Comment') ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"></textarea>
+                <textarea name="comment" id="comment" title="<?php echo __('What’s on your mind?') ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"></textarea>
             </div>
         </div>
         <?php echo $this->getChildHtml('form.additional.info'); ?>
diff --git a/app/code/Magento/Core/Helper/Data.php b/app/code/Magento/Core/Helper/Data.php
index bcc1e403662..b149418deac 100644
--- a/app/code/Magento/Core/Helper/Data.php
+++ b/app/code/Magento/Core/Helper/Data.php
@@ -40,11 +40,15 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     const CONTEXT_STORE = 'store';
 
+    /**#@+
+     * Paths for various config settings
+     */
+    const XML_PATH_DEFAULT_LOCALE = 'general/locale/code';
+    const XML_PATH_DEFAULT_TIMEZONE = 'general/locale/timezone';
     const XML_PATH_DEFAULT_COUNTRY = 'general/country/default';
-
     const XML_PATH_DEV_ALLOW_IPS = 'dev/restrict/allow_ips';
-
     const XML_PATH_CONNECTION_TYPE = 'global/resources/default_setup/connection/type';
+    /**#@- */
 
     /**
      * Const for correct dividing decimal values
@@ -211,7 +215,9 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         $types = array();
         foreach ($this->_cacheConfig->getTypes() as $type => $node) {
-            $types[$type] = $node['label'];
+            if (array_key_exists('label', $node)) {
+                $types[$type] = $node['label'];
+            }
         }
         return $types;
     }
diff --git a/app/code/Magento/Core/Helper/File/Storage/Database.php b/app/code/Magento/Core/Helper/File/Storage/Database.php
index 4f9f06d97c0..3f479431463 100644
--- a/app/code/Magento/Core/Helper/File/Storage/Database.php
+++ b/app/code/Magento/Core/Helper/File/Storage/Database.php
@@ -255,8 +255,9 @@ class Database extends \Magento\Framework\App\Helper\AbstractHelper
                 return false;
             }
 
-            return $this->getStorageFileModel()->saveFile($file, true);
+            return $this->getStorageFileModel()->saveFile($file->getData(), true);
         }
+        return false;
     }
 
     /**
diff --git a/app/code/Magento/Core/Helper/Url.php b/app/code/Magento/Core/Helper/Url.php
index eee8a61f032..6a73d836094 100644
--- a/app/code/Magento/Core/Helper/Url.php
+++ b/app/code/Magento/Core/Helper/Url.php
@@ -80,19 +80,6 @@ class Url extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->_storeManager->getStore()->getBaseUrl();
     }
 
-    /**
-     * @param string $string
-     * @return string
-     */
-    protected function _prepareString($string)
-    {
-        $string = preg_replace('#[^0-9a-z]+#i', '-', $string);
-        $string = strtolower($string);
-        $string = trim($string, '-');
-
-        return $string;
-    }
-
     /**
      * Add request parameter into url
      *
@@ -119,7 +106,9 @@ class Url extends \Magento\Framework\App\Helper\AbstractHelper
                 $arrQueryParams[] = $key . '=' . $value;
             }
         }
-        $url .= $startDelimiter . implode('&', $arrQueryParams);
+        if (!empty($arrQueryParams)) {
+            $url .= $startDelimiter . implode('&', $arrQueryParams);
+        }
 
         return $url;
     }
diff --git a/app/code/Magento/Core/Model/PageLayout/Config/Builder.php b/app/code/Magento/Core/Model/PageLayout/Config/Builder.php
index 0d6fafdf6ab..21433466d67 100644
--- a/app/code/Magento/Core/Model/PageLayout/Config/Builder.php
+++ b/app/code/Magento/Core/Model/PageLayout/Config/Builder.php
@@ -67,7 +67,7 @@ class Builder
     {
         return $this->objectManager->create(
             'Magento\Framework\View\PageLayout\Config',
-            array('configFiles' => $this->getConfigFiles())
+            ['configFiles' => $this->getConfigFiles()]
         );
     }
 
diff --git a/app/code/Magento/Core/composer.json b/app/code/Magento/Core/composer.json
index 7406f63fc50..9d33c4c2962 100644
--- a/app/code/Magento/Core/composer.json
+++ b/app/code/Magento/Core/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-page-cache": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-page-cache": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Core/etc/body.xsd b/app/code/Magento/Core/etc/body.xsd
new file mode 100644
index 00000000000..39cf8f69be9
--- /dev/null
+++ b/app/code/Magento/Core/etc/body.xsd
@@ -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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:complexType name="bodyType">
+        <xs:sequence>
+            <xs:element type="bodyAttributeType" name="attribute" maxOccurs="unbounded" minOccurs="0"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="bodyAttributeType">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute type="xs:string" name="name" use="optional"/>
+                <xs:attribute type="xs:string" name="value" use="optional"/>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+</xs:schema>
diff --git a/app/code/Magento/Core/etc/di.xml b/app/code/Magento/Core/etc/di.xml
index 72ba009dcc6..04ae981c354 100644
--- a/app/code/Magento/Core/etc/di.xml
+++ b/app/code/Magento/Core/etc/di.xml
@@ -82,6 +82,7 @@
     <preference for="Magento\Framework\App\DesignInterface" type="Magento\Core\Model\Design" />
     <preference for="Magento\Framework\Pricing\Amount\AmountInterface" type="Magento\Framework\Pricing\Amount\Base" />
     <preference for="Magento\Framework\Stdlib\CookieManager" type="Magento\Framework\Stdlib\Cookie\PhpCookieManager" />
+    <preference for="Magento\Framework\View\Page\FaviconInterface" type="Magento\Theme\Model\Favicon\Favicon" />
     <type name="Magento\Framework\App\DefaultPath\DefaultPath">
         <arguments>
             <argument name="parts" xsi:type="array">
@@ -524,7 +525,7 @@
     </type>
     <type name="Magento\Framework\Stdlib\DateTime\Timezone">
         <arguments>
-            <argument name="defaultTimezonePath" xsi:type="string">general/locale/timezone</argument>
+            <argument name="defaultTimezonePath" xsi:type="const">Magento\Core\Helper\Data::XML_PATH_DEFAULT_TIMEZONE</argument>
             <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
         </arguments>
     </type>
@@ -536,7 +537,7 @@
     <type name="Magento\Framework\Locale\Resolver">
         <plugin name="initLocale" type="Magento\Framework\Translate\Locale\Resolver\Plugin" sortOrder="10"/>
         <arguments>
-            <argument name="defaultLocalePath" xsi:type="string">general/locale/code</argument>
+            <argument name="defaultLocalePath" xsi:type="const">Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE</argument>
             <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/Core/etc/head.xsd b/app/code/Magento/Core/etc/head.xsd
new file mode 100644
index 00000000000..3b4c20e53a2
--- /dev/null
+++ b/app/code/Magento/Core/etc/head.xsd
@@ -0,0 +1,67 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, 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:complexType name="linkType">
+        <xs:attribute name="src" type="xs:string" use="required"/>
+        <xs:attribute name="defer" type="xs:string"/>
+        <xs:attribute name="ie_condition" type="xs:string"/>
+        <xs:attribute name="charset" type="xs:string"/>
+        <xs:attribute name="hreflang" type="xs:string"/>
+        <xs:attribute name="media" type="xs:string"/>
+        <xs:attribute name="rel" type="xs:string"/>
+        <xs:attribute name="rev" type="xs:string"/>
+        <xs:attribute name="sizes" type="xs:string"/>
+        <xs:attribute name="target" type="xs:string"/>
+        <xs:attribute name="type" type="xs:string"/>
+    </xs:complexType>
+
+    <xs:complexType name="metaType">
+        <xs:attribute name="content" type="xs:string" use="required"/>
+        <xs:attribute name="charset" type="xs:string" />
+        <xs:attribute name="http-equiv" type="xs:string"/>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="scheme" type="xs:string"/>
+    </xs:complexType>
+
+    <xs:complexType name="scriptType">
+        <xs:attribute name="src" type="xs:string" use="required"/>
+        <xs:attribute name="defer" type="xs:string"/>
+        <xs:attribute name="ie_condition" type="xs:string"/>
+        <xs:attribute name="async" type="xs:string"/>
+        <xs:attribute name="charset" type="xs:string"/>
+        <xs:attribute name="type" type="xs:string"/>
+    </xs:complexType>
+
+    <xs:complexType name="headType">
+        <xs:sequence minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="title" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="css" type="linkType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="link" type="linkType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="meta" type="metaType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="script" type="scriptType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+</xs:schema>
diff --git a/app/code/Magento/Index/etc/indexers_merged.xsd b/app/code/Magento/Core/etc/html.xsd
similarity index 60%
rename from app/code/Magento/Index/etc/indexers_merged.xsd
rename to app/code/Magento/Core/etc/html.xsd
index d4a190032c5..d0c51668c4e 100644
--- a/app/code/Magento/Index/etc/indexers_merged.xsd
+++ b/app/code/Magento/Core/etc/html.xsd
@@ -23,17 +23,18 @@
  * @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:redefine schemaLocation="indexers.xsd">
-        <xs:complexType name="indexerDeclaration">
-            <xs:complexContent>
-                <xs:restriction base="indexerDeclaration">
-                    <xs:sequence>
-                        <xs:element name="depends" type="dependencyDeclaration" minOccurs="0" maxOccurs="unbounded" />
-                    </xs:sequence>
-                    <xs:attribute name="instance" type="instanceType" use="required" />
-                </xs:restriction>
-            </xs:complexContent>
-        </xs:complexType>
-    </xs:redefine>
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:complexType name="htmlType">
+        <xs:sequence>
+            <xs:element type="htmlAttributeType" name="attribute"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="htmlAttributeType">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute type="xs:string" name="name"/>
+                <xs:attribute type="xs:string" name="value"/>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
 </xs:schema>
diff --git a/app/code/Magento/Core/etc/layouts.xsd b/app/code/Magento/Core/etc/layouts.xsd
index cbaf7c5a2bf..805c6d4b7a1 100644
--- a/app/code/Magento/Core/etc/layouts.xsd
+++ b/app/code/Magento/Core/etc/layouts.xsd
@@ -142,6 +142,18 @@
 
     <xs:element type="containerReferenceType" name="referenceContainer"/>
 
+    <xs:element type="uiComponentType" name="ui_component">
+        <xs:annotation>
+            <xs:documentation>
+                Argument name must be unique in scope of all Blocks, Containers and other UI Components.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:key name="uiElementArgumentName">
+            <xs:selector xpath="./arguments/argument"></xs:selector>
+            <xs:field xpath="@name"></xs:field>
+        </xs:key>
+    </xs:element>
+
     <xs:element name="arguments" type="argumentsType"/>
     <xs:element name="container" type="containerType"/>
     <xs:element name="update" type="updateType"/>
@@ -154,6 +166,12 @@
         </xs:restriction>
     </xs:simpleType>
 
+    <xs:simpleType name="componentNameType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[a-zA-Z][a-zA-Z\d\-_\.]*"/>
+        </xs:restriction>
+    </xs:simpleType>
+
     <xs:simpleType name="elementNameType">
         <xs:restriction base="xs:string">
             <xs:pattern value="[a-zA-Z][a-zA-Z\d\-_\.]*"/>
@@ -203,6 +221,7 @@
             <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceContainer" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
         <xs:attribute type="elementNameType" name="name"/>
         <xs:attribute type="xs:string" name="label"/>
@@ -233,6 +252,7 @@
             <xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="ui_component" minOccurs="0" />
         </xs:sequence>
         <xs:attribute type="elementNameType" name="name" use="optional"/>
         <xs:attribute type="blockClassType" name="class" use="optional"/>
@@ -248,6 +268,28 @@
         <xs:attribute type="xs:int" name="ttl" use="optional"/>
     </xs:complexType>
 
+    <xs:complexType name="uiComponentType" mixed="true">
+        <xs:annotation>
+            <xs:documentation>
+                Part of view that can generate appropriate content.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence minOccurs="0" maxOccurs="unbounded">
+            <xs:element ref="arguments" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute type="componentNameType" name="component" use="optional"/>
+        <xs:attribute type="elementNameType" name="name" use="optional"/>
+        <xs:attribute type="elementAliasType" name="as" use="optional"/>
+        <xs:attribute type="elementPositionType" name="before" use="optional"/>
+        <xs:attribute type="elementPositionType" name="after" use="optional"/>
+        <xs:attribute type="elementOutputType" name="output" use="optional"/>
+        <xs:attribute type="xs:string" name="acl" use="optional"/>
+        <xs:attribute type="xs:string" name="ifconfig" use="optional"/>
+        <xs:attribute type="xs:string" name="group" use="optional" />
+        <xs:attribute type="xs:boolean" name="cacheable" default="true" use="optional"/>
+        <xs:attribute type="xs:int" name="ttl" use="optional"/>
+    </xs:complexType>
+
     <xs:complexType name="actionType">
         <xs:annotation>
             <xs:documentation>
@@ -308,6 +350,7 @@
             <xs:element ref="referenceBlock" minOccurs="0" />
             <xs:element ref="referenceContainer" minOccurs="0"/>
             <xs:element ref="update" minOccurs="0" />
+            <xs:element ref="ui_component" minOccurs="0" />
         </xs:choice>
         <xs:attribute type="elementNameType" name="name" use="required"/>
     </xs:complexType>
@@ -321,6 +364,7 @@
             <xs:element ref="move" minOccurs="0" />
             <xs:element ref="referenceBlock" minOccurs="0" />
             <xs:element ref="update" minOccurs="0" />
+            <xs:element ref="ui_component" minOccurs="0" />
         </xs:choice>
         <xs:attribute type="elementNameType" name="name" use="required"/>
         <xs:attribute type="htmlTagType" name="htmlTag"/>
diff --git a/app/code/Magento/Core/etc/page.xsd b/app/code/Magento/Core/etc/page.xsd
index 1d4a4e6b766..24f8128d422 100644
--- a/app/code/Magento/Core/etc/page.xsd
+++ b/app/code/Magento/Core/etc/page.xsd
@@ -25,20 +25,15 @@
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:include schemaLocation="layouts.xsd"/>
-
-    <xs:element name="page" type="pageType">
-        <xs:unique name="blockKey">
-            <xs:selector xpath=".//block"/>
-            <xs:field xpath="@name"/>
-        </xs:unique>
-        <xs:unique name="containerKey">
-            <xs:selector xpath=".//container"/>
-            <xs:field xpath="@name"/>
-        </xs:unique>
-    </xs:element>
+    <xs:include schemaLocation="head.xsd"/>
+    <xs:include schemaLocation="body.xsd"/>
+    <xs:include schemaLocation="html.xsd"/>
 
     <xs:complexType name="pageType">
         <xs:sequence minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="html" type="htmlType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="body" type="bodyType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="head" type="headType" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceBlock" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="referenceContainer" minOccurs="0" maxOccurs="unbounded"/>
@@ -46,9 +41,21 @@
             <xs:element ref="update" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="remove" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="move" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="ui_component" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
         <xs:attribute  type="xs:string" name="layout" />
         <xs:attribute  type="xs:string" name="label" />
         <xs:attribute  type="xs:string" name="design_abstraction" />
     </xs:complexType>
+
+    <xs:element name="page" type="pageType">
+        <xs:unique name="blockKey">
+            <xs:selector xpath=".//block"/>
+            <xs:field xpath="@name"/>
+        </xs:unique>
+        <xs:unique name="containerKey">
+            <xs:selector xpath=".//container"/>
+            <xs:field xpath="@name"/>
+        </xs:unique>
+    </xs:element>
 </xs:schema>
diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json
index 2c54b3deff5..0ada7c1ab43 100644
--- a/app/code/Magento/Cron/composer.json
+++ b/app/code/Magento/Cron/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php
index 4180dc7adc9..e4427be41cb 100644
--- a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php
+++ b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php
@@ -22,13 +22,11 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\CurrencySymbol\Model\System;
+
 /**
  * Custom currency symbol model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\CurrencySymbol\Model\System;
-
 class Currencysymbol
 {
     /**
@@ -69,7 +67,7 @@ class Currencysymbol
      */
     const XML_PATH_CUSTOM_CURRENCY_SYMBOL = 'currency/options/customsymbol';
 
-    const XML_PATH_ALLOWED_CURRENCIES = 'currency/options/allow';
+    const XML_PATH_ALLOWED_CURRENCIES = \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW;
 
     /*
      * Separator used in config in allowed currencies list
@@ -155,34 +153,6 @@ class Currencysymbol
         $this->_scopeConfig = $scopeConfig;
     }
 
-    /**
-     * Sets store Id
-     *
-     * @param  string|null $storeId
-     * @return $this
-     */
-    public function setStoreId($storeId = null)
-    {
-        $this->_storeId = $storeId;
-        $this->_symbolsData = array();
-
-        return $this;
-    }
-
-    /**
-     * Sets website Id
-     *
-     * @param string|null $websiteId
-     * @return $this
-     */
-    public function setWebsiteId($websiteId = null)
-    {
-        $this->_websiteId = $websiteId;
-        $this->_symbolsData = array();
-
-        return $this;
-    }
-
     /**
      * Returns currency symbol properties array based on config values
      *
@@ -307,6 +277,8 @@ class Currencysymbol
         $this->_storeManager->reinitStores();
 
         $this->clearCache();
+        //Reset symbols cache since new data is added
+        $this->_symbolsData = [];
 
         $this->_eventManager->dispatch(
             'admin_system_config_changed_section_currency',
@@ -337,7 +309,7 @@ class Currencysymbol
      *
      * @return $this
      */
-    public function clearCache()
+    protected function clearCache()
     {
         // clear cache for frontend
         foreach ($this->_cacheTypes as $cacheType) {
diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json
index 3ed42a6ef46..92f7949f60b 100644
--- a/app/code/Magento/CurrencySymbol/composer.json
+++ b/app/code/Magento/CurrencySymbol/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-page-cache": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-page-cache": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Customer/Block/Address/Book.php b/app/code/Magento/Customer/Block/Address/Book.php
index f1999fc1aa3..39388bcfd43 100644
--- a/app/code/Magento/Customer/Block/Address/Book.php
+++ b/app/code/Magento/Customer/Block/Address/Book.php
@@ -82,8 +82,7 @@ class Book extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $this->getLayout()->getBlock('head')->setTitle(__('Address Book'));
-
+        $this->pageConfig->setTitle(__('Address Book'));
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Customer/Block/Address/Edit.php b/app/code/Magento/Customer/Block/Address/Edit.php
index 5f4989d8211..ca9b2e6d75f 100644
--- a/app/code/Magento/Customer/Block/Address/Edit.php
+++ b/app/code/Magento/Customer/Block/Address/Edit.php
@@ -137,9 +137,7 @@ class Edit extends \Magento\Directory\Block\Data
             )->create();
         }
 
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle($this->getTitle());
-        }
+        $this->pageConfig->setTitle($this->getTitle());
 
         if ($postedData = $this->_customerSession->getAddressFormData(true)) {
             if (!empty($postedData['region_id']) || !empty($postedData['region'])) {
diff --git a/app/code/Magento/Customer/Block/Form/Edit.php b/app/code/Magento/Customer/Block/Form/Edit.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Customer/Block/Form/Login.php b/app/code/Magento/Customer/Block/Form/Login.php
index ce2c40b5c41..a0f41ddc52a 100644
--- a/app/code/Magento/Customer/Block/Form/Login.php
+++ b/app/code/Magento/Customer/Block/Form/Login.php
@@ -89,7 +89,7 @@ class Login extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $this->getLayout()->getBlock('head')->setTitle(__('Customer Login'));
+        $this->pageConfig->setTitle(__('Customer Login'));
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Customer/Block/Form/Register.php b/app/code/Magento/Customer/Block/Form/Register.php
index 8c8cf2f64e5..f8e64473190 100644
--- a/app/code/Magento/Customer/Block/Form/Register.php
+++ b/app/code/Magento/Customer/Block/Form/Register.php
@@ -100,10 +100,7 @@ class Register extends \Magento\Directory\Block\Data
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Create New Customer Account'));
-        }
+        $this->pageConfig->setTitle(__('Create New Customer Account'));
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Customer/Controller/Account/Edit.php b/app/code/Magento/Customer/Controller/Account/Edit.php
index a07456177f2..d89d5b2e95b 100644
--- a/app/code/Magento/Customer/Controller/Account/Edit.php
+++ b/app/code/Magento/Customer/Controller/Account/Edit.php
@@ -91,7 +91,7 @@ class Edit extends \Magento\Customer\Controller\Account
         $this->_getSession()->setCustomerData($customerDataObject);
         $this->_getSession()->setChangePassword($this->getRequest()->getParam('changepass') == 1);
 
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Account Information'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Account Information'));
         $this->_view->getLayout()->getBlock('messages')->setEscapeMessageFlag(true);
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php
index 742bcd3d151..23a41d93a64 100644
--- a/app/code/Magento/Customer/Controller/Account/EditPost.php
+++ b/app/code/Magento/Customer/Controller/Account/EditPost.php
@@ -135,7 +135,7 @@ class EditPost extends \Magento\Customer\Controller\Account
 
             try {
                 $this->_customerDetailsBuilder->setCustomer($customer);
-                $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+                $this->_customerAccountService->updateCustomer($customerId, $this->_customerDetailsBuilder->create());
             } catch (AuthenticationException $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (InputException $e) {
diff --git a/app/code/Magento/Customer/Controller/Account/Index.php b/app/code/Magento/Customer/Controller/Account/Index.php
index a4ac0da966d..47c91793117 100644
--- a/app/code/Magento/Customer/Controller/Account/Index.php
+++ b/app/code/Magento/Customer/Controller/Account/Index.php
@@ -35,7 +35,7 @@ class Index extends \Magento\Customer\Controller\Account
     {
         $this->_view->loadLayout();
         $this->_view->getLayout()->initMessages();
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Account'));
+        $this->_view->getPage()->getConfig()->setTitle(__('My Account'));
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php
index db5df3518de..cfe1aea7599 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php
@@ -68,7 +68,11 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Group
                 $this->_customerGroupBuilder->setTaxClassId($taxClass);
                 $customerGroup = $this->_customerGroupBuilder->create();
 
-                $id = $this->_groupService->saveGroup($customerGroup);
+                if (!is_null($id)) {
+                    $this->_groupService->updateGroup($id, $customerGroup);
+                } else {
+                    $id = $this->_groupService->createGroup($customerGroup);
+                }
                 $this->messageManager->addSuccess(__('The customer group has been saved.'));
                 $this->getResponse()->setRedirect($this->getUrl('customer/group'));
                 return;
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php
index c143d64cdd6..ea07275c290 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php
@@ -43,7 +43,7 @@ class MassAssignGroup extends \Magento\Customer\Controller\Adminhtml\Index
                 $customerDetails = $this->_customerDetailsBuilder
                     ->setCustomer($customer)
                     ->create();
-                $this->_customerAccountService->updateCustomer($customerDetails);
+                $this->_customerAccountService->updateCustomer($customerId, $customerDetails);
             },
             $customerIds
         );
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
index e674cb73d4a..1dcd16ed6e4 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
@@ -159,7 +159,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index
                     $customer
                 )->setAddresses($addresses)->create();
                 if ($isExistingCustomer) {
-                    $this->_customerAccountService->updateCustomer($customerDetails);
+                    $this->_customerAccountService->updateCustomer($customerId, $customerDetails);
                 } else {
                     $customer = $this->_customerAccountService->createCustomer($customerDetails);
                     $customerId = $customer->getId();
diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php
old mode 100755
new mode 100644
index e8615a90e93..1dec5ce132e
--- a/app/code/Magento/Customer/Helper/Address.php
+++ b/app/code/Magento/Customer/Helper/Address.php
@@ -25,6 +25,7 @@ namespace Magento\Customer\Helper;
 
 use Magento\Directory\Model\Country\Format;
 use Magento\Customer\Service\V1\Data\Eav\AttributeMetadata;
+use Magento\Framework\Exception\NoSuchEntityException;
 
 /**
  * Customer address helper
@@ -256,22 +257,28 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function getAttributeValidationClass($attributeCode)
     {
-        /** @var $attribute \Magento\Customer\Service\V1\Data\Eav\AttributeMetadata */
-        $attribute = isset($this->_attributes[$attributeCode])
-            ? $this->_attributes[$attributeCode]
-            : $this->_addressMetadataService->getAttributeMetadata($attributeCode);
-        $class = $attribute ? $attribute->getFrontendClass() : '';
-        if (in_array($attributeCode, array('firstname', 'middlename', 'lastname', 'prefix', 'suffix', 'taxvat'))) {
-            if ($class && !$attribute->isVisible()) {
-                // address attribute is not visible thus its validation rules are not applied
-                $class = '';
-            }
+        $class = '';
+
+        try {
+            /** @var $attribute \Magento\Customer\Service\V1\Data\Eav\AttributeMetadata */
+            $attribute = isset($this->_attributes[$attributeCode])
+                ? $this->_attributes[$attributeCode]
+                : $this->_addressMetadataService->getAttributeMetadata($attributeCode);
+            $class = $attribute ? $attribute->getFrontendClass() : '';
+            if (in_array($attributeCode, array('firstname', 'middlename', 'lastname', 'prefix', 'suffix', 'taxvat'))) {
+                if ($class && !$attribute->isVisible()) {
+                    // address attribute is not visible thus its validation rules are not applied
+                    $class = '';
+                }
 
-            /** @var $customerAttribute \Magento\Customer\Service\V1\Data\Eav\AttributeMetadata */
-            $customerAttribute = $this->_customerMetadataService->getAttributeMetadata($attributeCode);
-            $class .= $customerAttribute &&
-                $customerAttribute->isVisible() ? $customerAttribute->getFrontendClass() : '';
-            $class = implode(' ', array_unique(array_filter(explode(' ', $class))));
+                /** @var $customerAttribute \Magento\Customer\Service\V1\Data\Eav\AttributeMetadata */
+                $customerAttribute = $this->_customerMetadataService->getAttributeMetadata($attributeCode);
+                $class .= $customerAttribute &&
+                    $customerAttribute->isVisible() ? $customerAttribute->getFrontendClass() : '';
+                $class = implode(' ', array_unique(array_filter(explode(' ', $class))));
+            }
+        } catch (NoSuchEntityException $e) {
+            // the attribute does not exist so just return an empty string
         }
 
         return $class;
diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
index c9e5159b97e..16b6483c854 100644
--- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php
+++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
@@ -489,7 +489,7 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractModel
         }
 
         if (!\Zend_Validate::is($this->getTelephone(), 'NotEmpty')) {
-            $errors[] = __('Please enter the telephone number.');
+            $errors[] = __('Please enter the phone number.');
         }
 
         $_havingOptionalZip = $this->_directoryData->getCountriesWithOptionalZip();
diff --git a/app/code/Magento/Customer/Model/Group.php b/app/code/Magento/Customer/Model/Group.php
index af37e5a978c..2d2068d49cf 100644
--- a/app/code/Magento/Customer/Model/Group.php
+++ b/app/code/Magento/Customer/Model/Group.php
@@ -73,18 +73,12 @@ class Group extends \Magento\Framework\Model\AbstractModel
      */
     protected $_storesConfig;
 
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
     /**
      * Constructor
      *
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Store\Model\StoresConfig $storesConfig
-     * @param \Magento\Index\Model\Indexer $indexer
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
@@ -93,13 +87,11 @@ class Group extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Store\Model\StoresConfig $storesConfig,
-        \Magento\Index\Model\Indexer $indexer,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
     ) {
         $this->_storesConfig = $storesConfig;
-        $this->_indexer = $indexer;
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
     }
 
@@ -164,18 +156,6 @@ class Group extends \Magento\Framework\Model\AbstractModel
         return false;
     }
 
-    /**
-     * Run reindex process after data save
-     *
-     * @return $this
-     */
-    protected function _afterSave()
-    {
-        parent::_afterSave();
-        $this->_indexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
-        return $this;
-    }
-
     /**
      * Prepare data before save
      *
diff --git a/app/code/Magento/Customer/Model/GroupRegistry.php b/app/code/Magento/Customer/Model/GroupRegistry.php
index 24f4267107d..195496d8d87 100644
--- a/app/code/Magento/Customer/Model/GroupRegistry.php
+++ b/app/code/Magento/Customer/Model/GroupRegistry.php
@@ -65,7 +65,7 @@ class GroupRegistry
         }
         $group = $this->groupFactory->create();
         $group->load($groupId);
-        if (is_null($group->getId())) {
+        if (is_null($group->getId()) || $group->getId() != $groupId) {
             throw NoSuchEntityException::singleField('groupId', $groupId);
         }
         $this->registry[$groupId] = $group;
diff --git a/app/code/Magento/Customer/Model/Resource/Setup.php b/app/code/Magento/Customer/Model/Resource/Setup.php
index a55b15d883c..14b2bb6b7f7 100644
--- a/app/code/Magento/Customer/Model/Resource/Setup.php
+++ b/app/code/Magento/Customer/Model/Resource/Setup.php
@@ -441,7 +441,7 @@ class Setup extends \Magento\Eav\Model\Entity\Setup
                     ),
                     'telephone' => array(
                         'type' => 'varchar',
-                        'label' => 'Telephone',
+                        'label' => 'Phone Number',
                         'input' => 'text',
                         'sort_order' => 120,
                         'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}',
diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Customer/Service/V1/AddressMetadataService.php b/app/code/Magento/Customer/Service/V1/AddressMetadataService.php
index fd526f96749..c1b8b470530 100644
--- a/app/code/Magento/Customer/Service/V1/AddressMetadataService.php
+++ b/app/code/Magento/Customer/Service/V1/AddressMetadataService.php
@@ -85,6 +85,9 @@ class AddressMetadataService implements AddressMetadataServiceInterface
             $attributes[$attribute->getAttributeCode()] = $this->attributeMetadataConverter
                 ->createMetadataAttribute($attribute);
         }
+        if (empty($attributes)) {
+            throw NoSuchEntityException::singleField('formCode', $formCode);
+        }
         return $attributes;
     }
 
@@ -95,7 +98,7 @@ class AddressMetadataService implements AddressMetadataServiceInterface
     {
         /** @var AbstractAttribute $attribute */
         $attribute = $this->attributeMetadataDataProvider->getAttribute(self::ENTITY_TYPE_ADDRESS, $attributeCode);
-        if ($attribute) {
+        if ($attribute && ($attributeCode === 'id' || !is_null($attribute->getId()))) {
             $attributeMetadata = $this->attributeMetadataConverter->createMetadataAttribute($attribute);
             return $attributeMetadata;
         } else {
@@ -142,7 +145,11 @@ class AddressMetadataService implements AddressMetadataServiceInterface
     {
         $customAttributes = [];
         if (!$this->addressDataObjectMethods) {
-            $this->addressDataObjectMethods = array_flip(get_class_methods($dataObjectClassName));
+            $dataObjectMethods = array_flip(get_class_methods($dataObjectClassName));
+            $baseClassDataObjectMethods = array_flip(
+                get_class_methods('Magento\Framework\Service\Data\AbstractExtensibleObject')
+            );
+            $this->addressDataObjectMethods = array_diff_key($dataObjectMethods, $baseClassDataObjectMethods);
         }
         foreach ($this->getAllAttributesMetadata() as $attributeMetadata) {
             $attributeCode = $attributeMetadata->getAttributeCode();
diff --git a/app/code/Magento/Customer/Service/V1/CustomerAccountService.php b/app/code/Magento/Customer/Service/V1/CustomerAccountService.php
index 4000b68b0a5..4b34f881786 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerAccountService.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerAccountService.php
@@ -52,6 +52,7 @@ use Magento\Framework\Service\V1\Data\SearchCriteria;
 use Magento\Framework\Service\V1\Data\SortOrder;
 use Magento\Framework\UrlInterface;
 use Magento\Framework\StoreManagerInterface;
+use Magento\Framework\Stdlib\String as StringHelper;
 
 /**
  * Handle various customer account actions
@@ -147,6 +148,11 @@ class CustomerAccountService implements CustomerAccountServiceInterface
      */
     private $configShare;
 
+    /**
+     * @var StringHelper
+     */
+    private $stringHelper;
+
     /**
      * @param CustomerFactory $customerFactory
      * @param ManagerInterface $eventManager
@@ -166,6 +172,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
      * @param Logger $logger
      * @param Encryptor $encryptor
      * @param ConfigShare $configShare
+     * @param StringHelper $stringHelper
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -187,7 +194,8 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         UrlInterface $url,
         Logger $logger,
         Encryptor $encryptor,
-        ConfigShare $configShare
+        ConfigShare $configShare,
+        StringHelper $stringHelper
     ) {
         $this->customerFactory = $customerFactory;
         $this->eventManager = $eventManager;
@@ -207,12 +215,13 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         $this->logger = $logger;
         $this->encryptor = $encryptor;
         $this->configShare = $configShare;
+        $this->stringHelper = $stringHelper;
     }
 
     /**
      * {@inheritdoc}
      */
-    public function resendConfirmation($email, $websiteId, $redirectUrl = '')
+    public function resendConfirmation($email, $websiteId = null, $redirectUrl = '')
     {
         $customer = $this->customerRegistry->retrieveByEmail($email, $websiteId);
         if (!$customer->getConfirmation()) {
@@ -259,6 +268,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
      */
     public function authenticate($username, $password)
     {
+        $this->checkPasswordStrength($password);
         $customerModel = $this->customerFactory->create();
         $customerModel->setWebsiteId($this->storeManager->getStore()->getWebsiteId());
         try {
@@ -288,6 +298,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
     public function validateResetPasswordLinkToken($customerId, $resetPasswordLinkToken)
     {
         $this->validateResetPasswordToken($customerId, $resetPasswordLinkToken);
+        return true;
     }
 
     /**
@@ -341,6 +352,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         $customerModel = $this->validateResetPasswordToken($customerId, $resetToken);
         $customerModel->setRpToken(null);
         $customerModel->setRpTokenCreatedAt(null);
+        $this->checkPasswordStrength($newPassword);
         $customerModel->setPasswordHash($this->getPasswordHash($newPassword));
         $customerModel->save();
     }
@@ -369,8 +381,11 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         $password = null,
         $redirectUrl = ''
     ) {
-        //Generate password hash
-        $password = $password ? $password : $this->mathRandom->getRandomString(self::DEFAULT_PASSWORD_LENGTH);
+        if ($password) {
+            $this->checkPasswordStrength($password);
+        } else {
+            $password = $this->mathRandom->getRandomString(self::MIN_PASSWORD_LENGTH);
+        }
         $hash = $this->getPasswordHash($password);
         return $this->createCustomerWithPasswordHash($customerDetails, $hash, $redirectUrl);
     }
@@ -460,22 +475,26 @@ class CustomerAccountService implements CustomerAccountServiceInterface
     /**
      * {@inheritdoc}
      */
-    public function updateCustomer(Data\CustomerDetails $customerDetails)
+    public function updateCustomer($customerId, Data\CustomerDetails $customerDetails)
     {
         $customer = $customerDetails->getCustomer();
         // Making this call first will ensure the customer already exists.
-        $this->customerRegistry->retrieve($customer->getId());
+        $this->customerRegistry->retrieve($customerId);
+
+        if ($customerId != $customer->getId()) {
+            throw InputException::invalidFieldValue('id', $customer->getId());
+        }
 
         $this->saveCustomer(
             $customer,
-            $this->converter->getCustomerModel($customer->getId())->getPasswordHash()
+            $this->converter->getCustomerModel($customerId)->getPasswordHash()
         );
 
         $addresses = $customerDetails->getAddresses();
         // If $address is null, no changes must made to the list of addresses
         // be careful $addresses != null would be true of $addresses is an empty array
         if ($addresses !== null) {
-            $existingAddresses = $this->customerAddressService->getAddresses($customer->getId());
+            $existingAddresses = $this->customerAddressService->getAddresses($customerId);
             /** @var Data\Address[] $deletedAddresses */
             $deletedAddresses = array_udiff(
                 $existingAddresses,
@@ -490,7 +509,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
             foreach ($deletedAddresses as $address) {
                 $this->customerAddressService->deleteAddress($address->getId());
             }
-            $this->customerAddressService->saveAddresses($customer->getId(), $addresses);
+            $this->customerAddressService->saveAddresses($customerId, $addresses);
         }
 
         return true;
@@ -617,6 +636,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         }
         $customerModel->setRpToken(null);
         $customerModel->setRpTokenCreatedAt(null);
+        $this->checkPasswordStrength($newPassword);
         $customerModel->setPasswordHash($this->getPasswordHash($newPassword));
         $customerModel->save();
         // FIXME: Are we using the proper template here?
@@ -625,6 +645,27 @@ class CustomerAccountService implements CustomerAccountServiceInterface
         return true;
     }
 
+    /**
+     * Make sure that password complies with minimum security requirements.
+     *
+     * @param string $password
+     * @return void
+     * @throws InputException
+     */
+    protected function checkPasswordStrength($password)
+    {
+        $length = $this->stringHelper->strlen($password);
+        if ($length < self::MIN_PASSWORD_LENGTH) {
+            throw new InputException(
+                'The password must have at least %min_length characters.',
+                ['min_length' => self::MIN_PASSWORD_LENGTH]
+            );
+        }
+        if ($this->stringHelper->strlen(trim($password)) != $length) {
+            throw new InputException('The password can not begin or end with a space.');
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -810,7 +851,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
      */
     private function validateResetPasswordToken($customerId, $resetPasswordLinkToken)
     {
-        if (!is_int($customerId) || empty($customerId) || $customerId < 0) {
+        if (empty($customerId) || $customerId < 0) {
             $params = ['value' => $customerId, 'fieldName' => 'customerId'];
             throw new InputException(InputException::INVALID_FIELD_VALUE, $params);
         }
@@ -868,7 +909,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
     /**
      * {@inheritdoc}
      */
-    public function updateCustomerDetailsByEmail(
+    public function updateCustomerByEmail(
         $customerEmail,
         CustomerDetails $customerDetails,
         $websiteId = null
@@ -886,7 +927,7 @@ class CustomerAccountService implements CustomerAccountServiceInterface
             ->setCustomer($customerData)
             ->create();
 
-        return $this->updateCustomer($customerDetails);
+        return $this->updateCustomer($customerId, $customerDetails);
     }
 
     /**
diff --git a/app/code/Magento/Customer/Service/V1/CustomerAccountServiceInterface.php b/app/code/Magento/Customer/Service/V1/CustomerAccountServiceInterface.php
index 97e891e0db7..54448946c06 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerAccountServiceInterface.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerAccountServiceInterface.php
@@ -52,7 +52,7 @@ interface CustomerAccountServiceInterface
 
     const EMAIL_RESET = 'email_reset';
 
-    const DEFAULT_PASSWORD_LENGTH = 6;
+    const MIN_PASSWORD_LENGTH = 6;
 
     /**
      * Create Customer Account
@@ -93,16 +93,17 @@ interface CustomerAccountServiceInterface
      * CustomerDetails contains an array of Address Data. In the event that no change was made to addresses
      * the array must be null.
      *
+     * @param string $customerId
      * @param \Magento\Customer\Service\V1\Data\CustomerDetails $customerDetails
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerDetails is not found.
      * @return bool True if this customer was updated
      */
-    public function updateCustomer(\Magento\Customer\Service\V1\Data\CustomerDetails $customerDetails);
+    public function updateCustomer($customerId, \Magento\Customer\Service\V1\Data\CustomerDetails $customerDetails);
 
     /**
      * Retrieve Customer
      *
-     * @param int $customerId
+     * @param string $customerId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return \Magento\Customer\Service\V1\Data\Customer
      */
@@ -111,7 +112,7 @@ interface CustomerAccountServiceInterface
     /**
      * Used to activate a customer account using a key that was sent in a confirmation e-mail.
      *
-     * @param int $customerId
+     * @param string $customerId
      * @param string $confirmationKey Sent to customer in an confirmation e-mail.
      * @return \Magento\Customer\Service\V1\Data\Customer
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer doesn't exist
@@ -144,7 +145,7 @@ interface CustomerAccountServiceInterface
     /**
      * Change customer password.
      *
-     * @param int $customerId
+     * @param string $customerId
      * @param string $currentPassword
      * @param string $newPassword
      * @return bool True if password changed
@@ -166,9 +167,9 @@ interface CustomerAccountServiceInterface
     /**
      * Check if password reset token is valid
      *
-     * @param int $customerId
+     * @param string $customerId
      * @param string $resetPasswordLinkToken
-     * @return void
+     * @return bool True if the token is valid
      * @throws \Magento\Framework\Exception\State\InputMismatchException If token is mismatched
      * @throws \Magento\Framework\Exception\State\ExpiredException If token is expired
      * @throws \Magento\Framework\Exception\InputException If token or customer id is invalid
@@ -181,7 +182,7 @@ interface CustomerAccountServiceInterface
      *
      * @param string $email
      * @param string $template Type of email to send.  Must be one of the email constants.
-     * @param int $websiteId Optional id.  If the website id is not provided
+     * @param string $websiteId Optional id.  If the website id is not provided
      *                       it will be retrieved from the store manager
      * @return void
      */
@@ -190,7 +191,7 @@ interface CustomerAccountServiceInterface
     /**
      * Reset customer password.
      *
-     * @param int $customerId
+     * @param string $customerId
      * @param string $resetToken Token sent to customer via e-mail
      * @param string $newPassword
      * @return void
@@ -204,7 +205,7 @@ interface CustomerAccountServiceInterface
     /**
      * Gets the account confirmation status
      *
-     * @param int $customerId
+     * @param string $customerId
      * @return string returns one of the account confirmation statuses
      *
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
@@ -222,7 +223,7 @@ interface CustomerAccountServiceInterface
      * @throws \Magento\Framework\Exception\NoSuchEntityException If no customer found for provided email
      * @throws \Magento\Framework\Exception\State\InvalidTransitionException If confirmation is not needed
      */
-    public function resendConfirmation($email, $websiteId, $redirectUrl = '');
+    public function resendConfirmation($email, $websiteId = null, $redirectUrl = '');
 
     /**
      * Validate customer entity
@@ -240,7 +241,7 @@ interface CustomerAccountServiceInterface
      * Indicates if the Customer for the provided customerId is restricted to being read only
      * for the currently logged in user, or if modifications can be made.
      *
-     * @param int $customerId
+     * @param string $customerId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return bool true if modifications can be made; false if read only.
      */
@@ -250,7 +251,7 @@ interface CustomerAccountServiceInterface
      * Indicates if the Customer for the currently logged in user as specified by the provided
      * customerId can be deleted.
      *
-     * @param int $customerId
+     * @param string $customerId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return bool true if the customer can be deleted
      */
@@ -259,7 +260,7 @@ interface CustomerAccountServiceInterface
     /**
      * Retrieve customer details
      *
-     * @param int $customerId
+     * @param string $customerId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return \Magento\Customer\Service\V1\Data\CustomerDetails
      */
@@ -268,7 +269,7 @@ interface CustomerAccountServiceInterface
     /**
      * Delete Customer
      *
-     * @param int $customerId
+     * @param string $customerId
      * @throws \Magento\Customer\Exception If something goes wrong during delete
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return bool True if the customer was deleted
@@ -287,8 +288,8 @@ interface CustomerAccountServiceInterface
     /**
      * Check store availability for customer given the customerId
      *
-     * @param int $customerWebsiteId
-     * @param int $storeId
+     * @param string $customerWebsiteId
+     * @param string $storeId
      * @return bool
      */
     public function isCustomerInStore($customerWebsiteId, $storeId);
@@ -297,7 +298,7 @@ interface CustomerAccountServiceInterface
      * Retrieve customer
      *
      * @param string $customerEmail
-     * @param int $websiteId If not set, will use the current websiteId
+     * @param string $websiteId If not set, will use the current websiteId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerEmail is not found.
      * @return \Magento\Customer\Service\V1\Data\Customer
      */
@@ -307,7 +308,7 @@ interface CustomerAccountServiceInterface
      * Retrieve customer details
      *
      * @param string $customerEmail
-     * @param int $websiteId If not set, will use the current websiteId
+     * @param string $websiteId If not set, will use the current websiteId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerEmail is not found.
      * @return \Magento\Customer\Service\V1\Data\CustomerDetails
      */
@@ -320,11 +321,11 @@ interface CustomerAccountServiceInterface
      *
      * @param string $customerEmail
      * @param \Magento\Customer\Service\V1\Data\CustomerDetails $customerDetails
-     * @param int $websiteId If not set, will use the current websiteId
+     * @param string $websiteId If not set, will use the current websiteId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerDetails is not found.
      * @return bool True if this customer was updated
      */
-    public function updateCustomerDetailsByEmail(
+    public function updateCustomerByEmail(
         $customerEmail,
         \Magento\Customer\Service\V1\Data\CustomerDetails $customerDetails,
         $websiteId = null
@@ -334,7 +335,7 @@ interface CustomerAccountServiceInterface
      * Delete Customer by email
      *
      * @param string $customerEmail
-     * @param int $websiteId If not set, will use the current websiteId
+     * @param string $websiteId If not set, will use the current websiteId
      * @throws \Magento\Customer\Exception If something goes wrong during delete
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
      * @return bool True if the customer was deleted
diff --git a/app/code/Magento/Customer/Service/V1/CustomerAddressServiceInterface.php b/app/code/Magento/Customer/Service/V1/CustomerAddressServiceInterface.php
index 85e37696ffd..71b4d069ed9 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerAddressServiceInterface.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerAddressServiceInterface.php
@@ -31,7 +31,7 @@ interface CustomerAddressServiceInterface
     /**
      * Retrieve all Customer Addresses
      *
-     * @param int $customerId
+     * @param string $customerId
      * @return \Magento\Customer\Service\V1\Data\Address[]
      * @throws \Magento\Framework\Exception\NoSuchEntityException If the customer Id is invalid
      */
@@ -40,7 +40,7 @@ interface CustomerAddressServiceInterface
     /**
      * Retrieve default billing address
      *
-     * @param int $customerId
+     * @param string $customerId
      * @return \Magento\Customer\Service\V1\Data\Address
      * @throws \Magento\Framework\Exception\NoSuchEntityException If the customer Id is invalid
      */
@@ -49,7 +49,7 @@ interface CustomerAddressServiceInterface
     /**
      * Retrieve default shipping address
      *
-     * @param int $customerId
+     * @param string $customerId
      * @return \Magento\Customer\Service\V1\Data\Address
      * @throws \Magento\Framework\Exception\NoSuchEntityException If the customer Id is invalid
      */
@@ -58,7 +58,7 @@ interface CustomerAddressServiceInterface
     /**
      * Retrieve address by id
      *
-     * @param int $addressId
+     * @param string $addressId
      * @return \Magento\Customer\Service\V1\Data\Address
      * @throws \Magento\Framework\Exception\NoSuchEntityException If no address can be found for the provided id.
      */
@@ -67,7 +67,7 @@ interface CustomerAddressServiceInterface
     /**
      * Removes an address by id.
      *
-     * @param int $addressId
+     * @param string $addressId
      * @return bool True if the address was deleted
      * @throws \Magento\Framework\Exception\NoSuchEntityException If no address can be found for the provided id.
      */
@@ -85,7 +85,7 @@ interface CustomerAddressServiceInterface
      * This doesn't support partial updates to addresses, meaning
      * that a full set of data must be provided with each Address
      *
-     * @param int $customerId
+     * @param string $customerId
      * @param \Magento\Customer\Service\V1\Data\Address[] $addresses
      * @throws \Magento\Framework\Exception\InputException If there are validation errors.
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with customerId is not found.
diff --git a/app/code/Magento/Customer/Service/V1/CustomerGroupService.php b/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
index 60bd524faf7..12abb802090 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
@@ -47,6 +47,9 @@ use Magento\Framework\Service\V1\Data\SortOrder;
  */
 class CustomerGroupService implements CustomerGroupServiceInterface
 {
+
+    const MESSAGE_CUSTOMER_GROUP_ID_IS_NOT_EXPECTED = 'ID is not expected for this request.';
+
     /**
      * @var GroupFactory
      */
@@ -268,28 +271,64 @@ class CustomerGroupService implements CustomerGroupServiceInterface
     /**
      * {@inheritdoc}
      */
-    public function saveGroup(Data\CustomerGroup $group)
+    public function createGroup(Data\CustomerGroup $group)
     {
+        if ($group->getId()) {
+            throw new InputException(self::MESSAGE_CUSTOMER_GROUP_ID_IS_NOT_EXPECTED);
+        }
+
         if (!$group->getCode()) {
             throw InputException::invalidFieldValue('code', $group->getCode());
         }
 
-        $customerGroup = null;
+        /** @var /Magento/Customer/Model/Group $customerGroup */
+        $customerGroup = $this->_groupFactory->create();
+        $customerGroup->setCode($group->getCode());
 
-        if ($group->getId()) {
-            try {
-                $customerGroup = $this->_groupRegistry->retrieve($group->getId());
-            } catch (NoSuchEntityException $e) {
-                throw NoSuchEntityException::singleField('id', $group->getId());
+        /** @var int $taxClassId */
+        $taxClassId = $group->getTaxClassId();
+        if (!$taxClassId) {
+            $taxClassId = self::DEFAULT_TAX_CLASS_ID;
+        }
+        $this->_verifyTaxClassModel($taxClassId, $group);
+
+        $customerGroup->setTaxClassId($taxClassId);
+        try {
+            $customerGroup->save();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            /**
+             * Would like a better way to determine this error condition but
+             *  difficult to do without imposing more database calls
+             */
+            if ($e->getMessage() === __('Customer Group already exists.')) {
+                throw new InvalidTransitionException('Customer Group already exists.');
             }
+            throw $e;
         }
 
-        if (!$customerGroup) {
-            $customerGroup = $this->_groupFactory->create();
+        return $customerGroup->getId();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function updateGroup($groupId, Data\CustomerGroup $group)
+    {
+        if (!$group->getCode()) {
+            throw InputException::invalidFieldValue('code', $group->getCode());
+        }
+
+        /** @var /Magento/Customer/Model/Group $customerGroup */
+        $customerGroup = null;
+        try {
+            $customerGroup = $this->_groupRegistry->retrieve($groupId);
+        } catch (NoSuchEntityException $e) {
+            throw NoSuchEntityException::singleField('id', $groupId);
         }
 
         $customerGroup->setCode($group->getCode());
 
+        /** @var int $taxClassId */
         $taxClassId = $group->getTaxClassId();
         if (!$taxClassId) {
             $taxClassId = self::DEFAULT_TAX_CLASS_ID;
@@ -310,7 +349,7 @@ class CustomerGroupService implements CustomerGroupServiceInterface
             throw $e;
         }
 
-        return $customerGroup->getId();
+        return true;
     }
 
     /**
diff --git a/app/code/Magento/Customer/Service/V1/CustomerGroupServiceInterface.php b/app/code/Magento/Customer/Service/V1/CustomerGroupServiceInterface.php
index c2926abcaf5..a635ff9dd42 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerGroupServiceInterface.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerGroupServiceInterface.php
@@ -59,7 +59,7 @@ interface CustomerGroupServiceInterface
     /**
      * Get a customer group by group ID.
      *
-     * @param int $groupId
+     * @param string $groupId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If $groupId is not found
      * @return \Magento\Customer\Service\V1\Data\CustomerGroup
      */
@@ -68,7 +68,7 @@ interface CustomerGroupServiceInterface
     /**
      * Get default group
      *
-     * @param int $storeId Defaults the current store
+     * @param string $storeId Defaults the current store
      * @throws \Magento\Framework\Exception\NoSuchEntityException If default group for $storeId is not found
      * @return \Magento\Customer\Service\V1\Data\CustomerGroup
      */
@@ -77,29 +77,42 @@ interface CustomerGroupServiceInterface
     /**
      * Check if the group can be deleted
      *
-     * @param int $groupId
+     * @param string $groupId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If group is not found
      * @return bool True, if this group can be deleted
      */
     public function canDelete($groupId);
 
     /**
-     * Save group
+     * Create group
      *
      * @param \Magento\Customer\Service\V1\Data\CustomerGroup $group
      * @throws \Magento\Framework\Exception\InputException If there is a problem with the input
-     * @throws \Magento\Framework\Exception\NoSuchEntityException If a group ID is sent but the group does not exist
      * @throws \Magento\Framework\Exception\State\InvalidTransitionException
      *      If saving customer group with customer group code that is used by an existing customer group
      * @throws \Magento\Framework\Model\Exception If something goes wrong during save
      * @return int customer group ID
      */
-    public function saveGroup(\Magento\Customer\Service\V1\Data\CustomerGroup $group);
+    public function createGroup(\Magento\Customer\Service\V1\Data\CustomerGroup $group);
+
+    /**
+     * Update group
+     *
+     * @param string $groupId
+     * @param \Magento\Customer\Service\V1\Data\CustomerGroup $group
+     * @throws \Magento\Framework\Exception\InputException If there is a problem with the input
+     * @throws \Magento\Framework\Exception\NoSuchEntityException If a group ID is sent but the group does not exist
+     * @throws \Magento\Framework\Exception\State\InvalidTransitionException
+     *      If saving customer group with customer group code that is used by an existing customer group
+     * @throws \Magento\Framework\Model\Exception If something goes wrong during save
+     * @return bool True if this group was updated
+     */
+    public function updateGroup($groupId, \Magento\Customer\Service\V1\Data\CustomerGroup $group);
 
     /**
      * Delete group
      *
-     * @param int $groupId
+     * @param string $groupId
      * @throws \Magento\Framework\Exception\NoSuchEntityException If $groupId is not found
      * @throws \Magento\Framework\Exception\StateException Thrown if cannot delete group
      * @throws \Exception If something goes wrong during delete
diff --git a/app/code/Magento/Customer/Service/V1/CustomerMetadataService.php b/app/code/Magento/Customer/Service/V1/CustomerMetadataService.php
index b37ac097871..fad3a7af130 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerMetadataService.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerMetadataService.php
@@ -86,6 +86,9 @@ class CustomerMetadataService implements CustomerMetadataServiceInterface
             $attributes[$attribute->getAttributeCode()] = $this->attributeMetadataConverter
                 ->createMetadataAttribute($attribute);
         }
+        if (empty($attributes)) {
+            throw NoSuchEntityException::singleField('formCode', $formCode);
+        }
         return $attributes;
     }
 
@@ -96,7 +99,7 @@ class CustomerMetadataService implements CustomerMetadataServiceInterface
     {
         /** @var AbstractAttribute $attribute */
         $attribute = $this->attributeMetadataDataProvider->getAttribute(self::ENTITY_TYPE_CUSTOMER, $attributeCode);
-        if ($attribute) {
+        if ($attribute && ($attributeCode === 'id' || !is_null($attribute->getId()))) {
             $attributeMetadata = $this->attributeMetadataConverter->createMetadataAttribute($attribute);
             return $attributeMetadata;
         } else {
@@ -143,7 +146,11 @@ class CustomerMetadataService implements CustomerMetadataServiceInterface
     {
         $customAttributes = [];
         if (!$this->customerDataObjectMethods) {
-            $this->customerDataObjectMethods = array_flip(get_class_methods($dataObjectClassName));
+            $dataObjectMethods = array_flip(get_class_methods($dataObjectClassName));
+            $baseClassDataObjectMethods = array_flip(
+                get_class_methods('Magento\Framework\Service\Data\AbstractExtensibleObject')
+            );
+            $this->customerDataObjectMethods = array_diff_key($dataObjectMethods, $baseClassDataObjectMethods);
         }
         foreach ($this->getAllAttributesMetadata() as $attributeMetadata) {
             $attributeCode = $attributeMetadata->getAttributeCode();
diff --git a/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataConverter.php b/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataConverter.php
index 507bc29f52c..ccc20e2429d 100644
--- a/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataConverter.php
+++ b/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataConverter.php
@@ -72,9 +72,17 @@ class AttributeMetadataConverter
         $options = [];
         if ($attribute->usesSource()) {
             foreach ($attribute->getSource()->getAllOptions() as $option) {
-                $options[] = $this->_optionBuilder->setLabel($option['label'])
-                    ->setValue($option['value'])
-                    ->create();
+                if (!is_array($option['value'])) {
+                    $this->_optionBuilder->setValue($option['value']);
+                } else {
+                    $optionArray = [];
+                    foreach ($option['value'] as $optionArrayValues) {
+                        $optionArray[] = $this->_optionBuilder->populateWithArray($optionArrayValues)->create();
+                    }
+                    $this->_optionBuilder->setOptions($optionArray);
+                }
+                $this->_optionBuilder->setLabel($option['label']);
+                $options[] = $this->_optionBuilder->create();
             }
         }
         $validationRules = [];
diff --git a/app/code/Magento/Customer/Service/V1/Data/Eav/Option.php b/app/code/Magento/Customer/Service/V1/Data/Eav/Option.php
index 9b13abae9cf..ad03c669030 100644
--- a/app/code/Magento/Customer/Service/V1/Data/Eav/Option.php
+++ b/app/code/Magento/Customer/Service/V1/Data/Eav/Option.php
@@ -37,6 +37,8 @@ class Option extends \Magento\Framework\Service\Data\AbstractExtensibleObject
 
     const VALUE = 'value';
 
+    const OPTIONS = 'options';
+
     /**
      * Get option label
      *
@@ -50,10 +52,20 @@ class Option extends \Magento\Framework\Service\Data\AbstractExtensibleObject
     /**
      * Get option value
      *
-     * @return string
+     * @return string|null
      */
     public function getValue()
     {
         return $this->_get(self::VALUE);
     }
+
+    /**
+     * Get nested options
+     *
+     * @return \Magento\Customer\Service\V1\Data\Eav\Option[]|null
+     */
+    public function getOptions()
+    {
+        return $this->_get(self::OPTIONS);
+    }
 }
diff --git a/app/code/Magento/Customer/Service/V1/Data/Eav/OptionBuilder.php b/app/code/Magento/Customer/Service/V1/Data/Eav/OptionBuilder.php
index facd06ac9e3..79e07a52407 100644
--- a/app/code/Magento/Customer/Service/V1/Data/Eav/OptionBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/Eav/OptionBuilder.php
@@ -49,4 +49,16 @@ class OptionBuilder extends \Magento\Framework\Service\Data\AbstractExtensibleOb
     {
         return $this->_set(Option::VALUE, $value);
     }
+
+
+    /**
+     * Set nested options
+     *
+     * @param \Magento\Customer\Service\V1\Data\Eav\Option[] $options
+     * @return $this
+     */
+    public function setOptions($options)
+    {
+        return $this->_set(Option::OPTIONS, $options);
+    }
 }
diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json
index ff5775d3367..e1d3c73fe7d 100644
--- a/app/code/Magento/Customer/composer.json
+++ b/app/code/Magento/Customer/composer.json
@@ -3,28 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-newsletter": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-index": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-review": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-page-cache": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
-        "magento/module-authorization": "0.1.0-alpha96",
-        "magento/module-integration": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-newsletter": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-review": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-page-cache": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/module-authorization": "0.1.0-alpha97",
+        "magento/module-integration": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Customer/etc/module.xml b/app/code/Magento/Customer/etc/module.xml
index e50495d8ebb..ae300c23a9e 100644
--- a/app/code/Magento/Customer/etc/module.xml
+++ b/app/code/Magento/Customer/etc/module.xml
@@ -40,7 +40,6 @@
             <module name="Magento_Sales"/>
             <module name="Magento_Checkout"/>
             <module name="Magento_Wishlist"/>
-            <module name="Magento_Index"/>
             <module name="Magento_Theme"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Review"/>
diff --git a/app/code/Magento/Customer/etc/webapi.xml b/app/code/Magento/Customer/etc/webapi.xml
index c4efa8e5be8..4308398117b 100644
--- a/app/code/Magento/Customer/etc/webapi.xml
+++ b/app/code/Magento/Customer/etc/webapi.xml
@@ -26,43 +26,61 @@
 <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
     <!-- Customer Group Service-->
-    <route url="/V1/customerGroup/:groupId" method="GET">
+    <route url="/V1/customerGroups/:groupId" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="getGroup"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup" method="GET">
+    <route url="/V1/customerGroups" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="getGroups"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup/default/:storeId" method="GET">
+    <route url="/V1/customerGroups/default/:storeId" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="getDefaultGroup"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup/canDelete/:groupId" method="GET">
+    <route url="/V1/customerGroups/default" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="getDefaultGroup"/>
+        <resources>
+            <resource ref="Magento_Customer::group"/>
+        </resources>
+    </route>
+    <route url="/V1/customerGroups/:groupId/permissions" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="canDelete"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup/search" method="PUT">
+    <route url="/V1/customerGroups/search" method="POST">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="searchGroups"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup" method="PUT">
-        <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="saveGroup"/>
+    <route url="/V1/customerGroups/search" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="searchGroups"/>
+        <resources>
+            <resource ref="Magento_Customer::group"/>
+        </resources>
+    </route>
+    <route url="/V1/customerGroups" method="POST">
+        <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="createGroup"/>
+        <resources>
+            <resource ref="Magento_Customer::group"/>
+        </resources>
+    </route>
+    <route url="/V1/customerGroups/:groupId" method="PUT">
+        <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="updateGroup"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
         </resources>
     </route>
-    <route url="/V1/customerGroup/:groupId" method="DELETE">
+    <route url="/V1/customerGroups/:groupId" method="DELETE">
         <service class="Magento\Customer\Service\V1\CustomerGroupServiceInterface" method="deleteGroup"/>
         <resources>
             <resource ref="Magento_Customer::group"/>
@@ -70,25 +88,25 @@
     </route>
 
     <!-- Customer Metadata Service-->
-    <route url="/V1/customerAttributeMetadata/:attributeCode" method="GET">
+    <route url="/V1/attributeMetadata/customer/attribute/:attributeCode" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerMetadataServiceInterface" method="getAttributeMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAttributeMetadata/form/:formCode" method="GET">
+    <route url="/V1/attributeMetadata/customer/form/:formCode" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerMetadataServiceInterface" method="getAttributes"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAttributeMetadata" method="GET">
+    <route url="/V1/attributeMetadata/customer" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerMetadataServiceInterface" method="getAllAttributesMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAttributeMetadata/custom" method="GET">
+    <route url="/V1/attributeMetadata/customer/custom" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerMetadataServiceInterface" method="getCustomAttributesMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
@@ -96,25 +114,25 @@
     </route>
 
     <!-- Customer Address Metadata Service-->
-    <route url="/V1/addressAttributeMetadata/:attributeCode" method="GET">
+    <route url="/V1/attributeMetadata/customerAddress/attribute/:attributeCode" method="GET">
         <service class="Magento\Customer\Service\V1\AddressMetadataServiceInterface" method="getAttributeMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/addressAttributeMetadata/form/:formCode" method="GET">
+    <route url="/V1/attributeMetadata/customerAddress/form/:formCode" method="GET">
         <service class="Magento\Customer\Service\V1\AddressMetadataServiceInterface" method="getAttributes"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/addressAttributeMetadata" method="GET">
+    <route url="/V1/attributeMetadata/customerAddress" method="GET">
         <service class="Magento\Customer\Service\V1\AddressMetadataServiceInterface" method="getAllAttributesMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/addressAttributeMetadata/custom" method="GET">
+    <route url="/V1/attributeMetadata/customerAddress/custom" method="GET">
         <service class="Magento\Customer\Service\V1\AddressMetadataServiceInterface" method="getCustomAttributesMetadata"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
@@ -122,42 +140,41 @@
     </route>
 
     <!-- Customer Account Service-->
-    <route url="/V1/customerAccounts/details" method="GET">
+    <route url="/V1/customers" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomerDetailsByEmail"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/details" method="PUT">
-        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="updateCustomerDetailsByEmail"/>
+    <route url="/V1/customers" method="PUT">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="updateCustomerByEmail"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <!-- TODO: changePassword is a case of SELF. Need to revisit. For now manage is assigned -->
-    <!-- TODO: createCustomer, authenticate, validateResetPasswordLinkToken, initiatePasswordReset, resetPassword, resendConfirmation apis
-               can be accessed anonymously and need no resources to be assigned. Webapi framework doesn't support support that as yet.
-               Adding Magento_Customer::customer temporarily until handling anonymous users is finalized -->
-    <route url="/V1/customerAccounts" method="POST">
+    <route url="/V1/customers" method="POST">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="createCustomer"/>
         <resources>
             <resource ref="anonymous"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts" method="PUT">
+    <route url="/V1/customers/:customerId" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="updateCustomer"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId" method="GET">
-        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomerDetails"/>
+    <route url="/V1/customers/me" method="PUT">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="updateCustomer"/>
         <resources>
-            <resource ref="Magento_Customer::customer"/>
+            <resource ref="self"/>
         </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
     </route>
-    <route url="/V1/customer/me" method="GET">
-        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomer"/>
+    <route url="/V1/customers/me" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomerDetails"/>
         <resources>
             <resource ref="self"/>
         </resources>
@@ -165,142 +182,192 @@
             <parameter name="customerId" force="true">%customer_id%</parameter>
         </data>
     </route>
-    <route url="/V1/customerAccounts/:customerId/customer" method="GET">
-        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomer"/>
+    <route url="/V1/customers/:customerId" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomerDetails"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId/activateCustomer" method="PUT">
+    <route url="/V1/customers/me/activate" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="activateCustomer"/>
         <resources>
-            <resource ref="Magento_Customer::manage"/>
+            <resource ref="self"/>
+        </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
+    </route>
+    <route url="/V1/customers/search" method="POST">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="searchCustomers"/>
+        <resources>
+            <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/search" method="PUT">
+    <route url="/V1/customers/search" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="searchCustomers"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/authenticate" method="PUT">
+    <route url="/V1/customers/:customerId/activate" method="PUT">
+        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="activateCustomer"/>
+        <resources>
+            <resource ref="Magento_Customer::manage"/>
+        </resources>
+    </route>
+    <route url="/V1/customers/login" method="POST">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="authenticate"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId/changePassword" method="PUT">
+    <route url="/V1/customers/me/password" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="changePassword"/>
         <resources>
-            <resource ref="Magento_Customer::manage"/>
+            <resource ref="self"/>
         </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
     </route>
-    <route url="/V1/customerAccounts/:customerId/validateResetPasswordLinkToken/:resetPasswordLinkToken" method="GET">
+    <route url="/V1/customers/:customerId/password/resetLinkToken/:resetPasswordLinkToken" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="validateResetPasswordLinkToken"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/initiatePasswordReset" method="PUT">
+    <route url="/V1/customers/password" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="initiatePasswordReset"/>
         <resources>
-            <resource ref="Magento_Customer::customer"/>
+            <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId/resetPassword" method="PUT">
+    <route url="/V1/customers/:customerId/password" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="resetPassword"/>
         <resources>
-            <resource ref="Magento_Customer::customer"/>
+            <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId/confirmationStatus" method="GET">
+    <route url="/V1/customers/:customerId/confirm" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getConfirmationStatus"/>
         <resources>
-            <resource ref="Magento_Customer::customer"/>
+            <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/resendConfirmation" method="PUT">
+    <route url="/V1/customers/confirm" method="POST">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="resendConfirmation"/>
         <resources>
-            <resource ref="Magento_Customer::customer"/>
+            <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/validateCustomerData" method="PUT">
+    <route url="/V1/customers/validate" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="validateCustomerData"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId/canModify" method="GET">
+    <route url="/V1/customers/:customerId/permissions/modify" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="canModify"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts" method="GET">
-        <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="getCustomerByEmail"/>
-        <resources>
-            <resource ref="Magento_Customer::customer"/>
-        </resources>
-    </route>
-    <route url="/V1/customerAccounts/:customerId/canDelete" method="GET">
+    <route url="/V1/customers/:customerId/permissions/delete" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="canDelete"/>
         <resources>
             <resource ref="Magento_Customer::customer"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/:customerId" method="DELETE">
+    <route url="/V1/customers/:customerId" method="DELETE">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="deleteCustomer"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts" method="DELETE">
+    <route url="/V1/customers" method="DELETE">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="deleteCustomerByEmail"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customerAccounts/isEmailAvailable" method="PUT">
+    <route url="/V1/customers/isEmailAvailable" method="POST">
         <service class="Magento\Customer\Service\V1\CustomerAccountServiceInterface" method="isEmailAvailable"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/:customerId/address" method="GET">
+
+    <!-- Customer Address Service-->
+    <route url="/V1/customers/me/addresses" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getAddresses"/>
+        <resources>
+            <resource ref="self"/>
+        </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
+    </route>
+    <route url="/V1/customers/:customerId/addresses" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getAddresses"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/address/:addressId" method="GET">
+    <route url="/V1/customers/addresses/:addressId" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getAddress"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/:customerId/address/defaultBilling" method="GET">
+    <route url="/V1/customers/me/billingAddress" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getDefaultBillingAddress"/>
+        <resources>
+            <resource ref="self"/>
+        </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
+    </route>
+    <route url="/V1/customers/:customerId/billingAddress" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getDefaultBillingAddress"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/:customerId/address/defaultShipping" method="GET">
+    <route url="/V1/customers/me/shippingAddress" method="GET">
+        <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getDefaultShippingAddress"/>
+        <resources>
+            <resource ref="self"/>
+        </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
+    </route>
+    <route url="/V1/customers/:customerId/shippingAddress" method="GET">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="getDefaultShippingAddress"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/address/:addressId" method="DELETE">
+    <route url="/V1/addresses/:addressId" method="DELETE">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="deleteAddress"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
-    <route url="/V1/customer/:customerId/address" method="POST">
+    <route url="/V1/customers/:customerId/addresses" method="PUT">
         <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="saveAddresses"/>
         <resources>
             <resource ref="Magento_Customer::manage"/>
         </resources>
     </route>
+    <route url="/V1/customers/me/addresses" method="PUT">
+        <service class="Magento\Customer\Service\V1\CustomerAddressServiceInterface" method="saveAddresses"/>
+        <resources>
+            <resource ref="self"/>
+        </resources>
+        <data>
+            <parameter name="customerId" force="true">%customer_id%</parameter>
+        </data>
+    </route>
 </routes>
diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account.xml
index f0ae85bb1ab..7fe30004898 100644
--- a/app/code/Magento/Customer/view/frontend/layout/customer_account.xml
+++ b/app/code/Magento/Customer/view/frontend/layout/customer_account.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd" label="Customer My Account (All Pages)" design_abstraction="custom">
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="class" xsi:type="string">account</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="account"/>
+    </body>
     <referenceContainer name="sidebar.main">
         <block class="Magento\Framework\View\Element\Html\Links" name="customer_account_navigation" before="-" template="Magento_Customer::account/navigation.phtml">
             <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-account-link">
diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_confirmation.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_confirmation.xml
index 50a1eb3695f..1b6bf3ce5ff 100644
--- a/app/code/Magento/Customer/view/frontend/layout/customer_account_confirmation.xml
+++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_confirmation.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Send confirmation link</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Send confirmation link</title>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Framework\View\Element\Template" name="accountConfirmation" template="Magento_Customer::form/confirmation.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_createpassword.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_createpassword.xml
index 76236133690..5bb398f8e60 100644
--- a/app/code/Magento/Customer/view/frontend/layout/customer_account_createpassword.xml
+++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_createpassword.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Reset a Password</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Reset a Password</title>
+    </head>
     <referenceBlock name="root">
         <action method="setHeaderTitle">
             <argument translate="true" name="title" xsi:type="string">Reset a Password</argument>
diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_forgotpassword.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_forgotpassword.xml
index 75baa8cb41c..ce979c44bc7 100644
--- a/app/code/Magento/Customer/view/frontend/layout/customer_account_forgotpassword.xml
+++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_forgotpassword.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Forgot Your Password</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Forgot Your Password</title>
+    </head>
     <referenceBlock name="root">
         <action method="setHeaderTitle">
             <argument translate="true" name="title" xsi:type="string">Password forgotten</argument>
diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
index 1ae68868aff..ef1923e4fa5 100644
--- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
@@ -43,9 +43,9 @@
             </div>
         </div>
         <div class="field telephone required">
-            <label class="label" for="telephone"><span><?php echo __('Telephone') ?></span></label>
+            <label class="label" for="telephone"><span><?php echo __('Phone Number') ?></span></label>
             <div class="control">
-                <input type="text" name="telephone" value="<?php echo $this->escapeHtml($this->getAddress()->getTelephone()) ?>" title="<?php echo __('Telephone') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>" id="telephone">
+                <input type="text" name="telephone" value="<?php echo $this->escapeHtml($this->getAddress()->getTelephone()) ?>" title="<?php echo __('Phone Number') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>" id="telephone">
             </div>
         </div>
         <div class="field fax">
diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
index 45f5babe56f..e7ef71d0d75 100644
--- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
@@ -79,9 +79,9 @@
                 </div>
             </div>
             <div class="field telephone">
-                <label for="telephone" class="label"><span><?php echo __('Telephone') ?></span></label>
+                <label for="telephone" class="label"><span><?php echo __('Phone Number') ?></span></label>
                 <div class="control">
-                    <input type="text" name="telephone" id="telephone" value="<?php echo $this->escapeHtml($this->getFormData()->getTelephone()) ?>" title="<?php echo __('Telephone') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>">
+                    <input type="text" name="telephone" id="telephone" value="<?php echo $this->escapeHtml($this->getFormData()->getTelephone()) ?>" title="<?php echo __('Phone Number') ?>" class="input-text <?php echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>">
                 </div>
             </div>
 
diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json
index 548dc135217..b422fcd758f 100644
--- a/app/code/Magento/CustomerImportExport/composer.json
+++ b/app/code/Magento/CustomerImportExport/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-import-export": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-import-export": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php b/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
index 2de881bb8c2..2451af6d44d 100644
--- a/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
+++ b/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
@@ -29,11 +29,6 @@ namespace Magento\DesignEditor\Controller\Varien\Router;
  */
 class Standard extends \Magento\Core\App\Router\Base
 {
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
-
     /**
      * Routers that must not been matched
      *
@@ -48,11 +43,6 @@ class Standard extends \Magento\Core\App\Router\Base
      */
     protected $_routerList;
 
-    /**
-     * @var \Magento\UrlRewrite\App\Request\RewriteService
-     */
-    protected $_urlRewriteService;
-
     /**
      * @var \Magento\DesignEditor\Helper\Data
      */
@@ -81,7 +71,6 @@ class Standard extends \Magento\Core\App\Router\Base
      * @param string $routerId
      * @param \Magento\Framework\Code\NameBuilder $nameBuilder
      * @param \Magento\Framework\App\RouterListInterface $routerList
-     * @param \Magento\UrlRewrite\App\Request\RewriteService $urlRewriteService
      * @param \Magento\DesignEditor\Helper\Data $designEditorHelper
      * @param \Magento\DesignEditor\Model\State $designEditorState
      * @param \Magento\Backend\Model\Auth\Session $session
@@ -101,7 +90,6 @@ class Standard extends \Magento\Core\App\Router\Base
         $routerId,
         \Magento\Framework\Code\NameBuilder $nameBuilder,
         \Magento\Framework\App\RouterListInterface $routerList,
-        \Magento\UrlRewrite\App\Request\RewriteService $urlRewriteService,
         \Magento\DesignEditor\Helper\Data $designEditorHelper,
         \Magento\DesignEditor\Model\State $designEditorState,
         \Magento\Backend\Model\Auth\Session $session
@@ -119,7 +107,6 @@ class Standard extends \Magento\Core\App\Router\Base
             $routerId,
             $nameBuilder
         );
-        $this->_urlRewriteService = $urlRewriteService;
         $this->_routerList = $routerList;
         $this->_designEditorHelper = $designEditorHelper;
         $this->_state = $designEditorState;
@@ -146,9 +133,10 @@ class Standard extends \Magento\Core\App\Router\Base
 
         // prepare request to imitate
         $this->_prepareVdeRequest($request);
-
-        // apply rewrites
-        $this->_urlRewriteService->applyRewrites($request);
+        /**
+         * Deprecated line of code was here which should be adopted if needed:
+         * $this->_urlRewriteService->applyRewrites($request);
+         */
 
         // match routers
         $controller = null;
diff --git a/app/code/Magento/DesignEditor/Model/Observer.php b/app/code/Magento/DesignEditor/Model/Observer.php
index c2dfb3aa885..a2d8a4ca74c 100644
--- a/app/code/Magento/DesignEditor/Model/Observer.php
+++ b/app/code/Magento/DesignEditor/Model/Observer.php
@@ -33,21 +33,31 @@ class Observer
     /**
      * @var \Magento\Framework\ObjectManager
      */
-    protected $_objectManager;
+    protected $objectManager;
 
     /**
      * @var \Magento\DesignEditor\Helper\Data
      */
-    protected $_helper;
+    protected $helper;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
 
     /**
      * @param \Magento\Framework\ObjectManager $objectManager
      * @param \Magento\DesignEditor\Helper\Data $helper
+     * @param \Magento\Framework\Registry $registry
      */
-    public function __construct(\Magento\Framework\ObjectManager $objectManager, \Magento\DesignEditor\Helper\Data $helper)
-    {
-        $this->_objectManager = $objectManager;
-        $this->_helper = $helper;
+    public function __construct(
+        \Magento\Framework\ObjectManager $objectManager,
+        \Magento\DesignEditor\Helper\Data $helper,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->objectManager = $objectManager;
+        $this->helper = $helper;
+        $this->registry = $registry;
     }
 
     /**
@@ -59,16 +69,14 @@ class Observer
      */
     public function clearJs(EventObserver $event)
     {
-        /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = $event->getEvent()->getLayout();
-        $blockHead = $layout->getBlock('head');
-        if (!$blockHead || !$blockHead->getData('vde_design_mode')) {
+        /** @var $pageAssets \Magento\Framework\View\Asset\GroupedCollection */
+        $pageAssets = $this->objectManager->get('Magento\Framework\View\Asset\GroupedCollection');
+
+        /** @todo Temporary solution for vde mode should be verified with PO and refactored */
+        if (!$this->registry->registry('vde_design_mode')) {
             return;
         }
 
-        /** @var $pageAssets \Magento\Framework\View\Asset\GroupedCollection */
-        $pageAssets = $this->_objectManager->get('Magento\Framework\View\Asset\GroupedCollection');
-
         $vdeAssets = array();
         foreach ($pageAssets->getGroups() as $group) {
             if ($group->getProperty('flag_name') == 'vde_design_mode') {
@@ -100,14 +108,14 @@ class Observer
         $theme = $event->getData('theme');
         if ($configuration->getControlConfig() instanceof \Magento\DesignEditor\Model\Config\Control\QuickStyles) {
             /** @var $renderer \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\Renderer */
-            $renderer = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\QuickStyles\Renderer');
+            $renderer = $this->objectManager->create('Magento\DesignEditor\Model\Editor\Tools\QuickStyles\Renderer');
             $content = $renderer->render($configuration->getAllControlsData());
             /** @var $cssService \Magento\DesignEditor\Model\Theme\Customization\File\QuickStyleCss */
-            $cssService = $this->_objectManager->create(
+            $cssService = $this->objectManager->create(
                 'Magento\DesignEditor\Model\Theme\Customization\File\QuickStyleCss'
             );
             /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
-            $singleFile = $this->_objectManager->create(
+            $singleFile = $this->objectManager->create(
                 'Magento\Theme\Model\Theme\SingleFile',
                 array('fileService' => $cssService)
             );
@@ -126,7 +134,7 @@ class Observer
         /** @var $theme \Magento\Core\Model\Theme|null */
         $theme = $event->getTheme() ?: $event->getDataObject()->getTheme();
         /** @var $change \Magento\DesignEditor\Model\Theme\Change */
-        $change = $this->_objectManager->create('Magento\DesignEditor\Model\Theme\Change');
+        $change = $this->objectManager->create('Magento\DesignEditor\Model\Theme\Change');
         if ($theme && $theme->getId()) {
             $change->loadByThemeId($theme->getId());
             $change->setThemeId($theme->getId())->setChangeTime(null);
diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json
index cefb80f5533..76d6d3100b3 100644
--- a/app/code/Magento/DesignEditor/composer.json
+++ b/app/code/Magento/DesignEditor/composer.json
@@ -3,17 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-url-rewrite": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/DesignEditor/etc/module.xml b/app/code/Magento/DesignEditor/etc/module.xml
index 19dc07ee289..1067c9cc097 100644
--- a/app/code/Magento/DesignEditor/etc/module.xml
+++ b/app/code/Magento/DesignEditor/etc/module.xml
@@ -34,7 +34,6 @@
             <module name="Magento_Backend"/>
             <module name="Magento_Core"/>
             <module name="Magento_Eav"/>
-            <module name="Magento_UrlRewrite"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_files_index.xml b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_files_index.xml
index b1771312b54..844d664cb24 100644
--- a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_files_index.xml
+++ b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_files_index.xml
@@ -25,7 +25,6 @@
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <remove name="footer"/>
-    <remove name="head"/>
     <referenceContainer name="left">
         <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Files\Content" name="editor_files.js" template="Magento_DesignEditor::editor/tools/files/js.phtml"/>
         <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Files\Tree" name="editor_files.tree" template="Magento_DesignEditor::editor/tools/files/tree.phtml"/>
diff --git a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_firstentrance.xml b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_firstentrance.xml
index 44888b49ada..ae4d67c3789 100644
--- a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_firstentrance.xml
+++ b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_firstentrance.xml
@@ -24,18 +24,10 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-designeditor-js-bootstrap-edit-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::js/bootstrap/edit.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-designeditor-css-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::css/styles.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_DesignEditor::js/bootstrap/edit.js"/>
+        <css src="Magento_DesignEditor::css/styles.css"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Backend\Block\Template" name="available.theme.list.container" as="theme_container" template="Magento_DesignEditor::theme/selector/first_entrance.phtml">
             <block class="Magento\DesignEditor\Block\Adminhtml\Theme\Selector\SelectorList\Available" name="available.theme.list" template="Magento_DesignEditor::theme/list/available.phtml">
diff --git a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_index.xml b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_index.xml
index 3270aad61c7..a1b98032ba7 100644
--- a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_index.xml
+++ b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_index.xml
@@ -24,18 +24,10 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-designeditor-js-bootstrap-edit-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::js/bootstrap/edit.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-designeditor-css-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::css/styles.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_DesignEditor::js/bootstrap/edit.js"/>
+        <css src="Magento_DesignEditor::css/styles.css"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\DesignEditor\Block\Adminhtml\Theme\Selector\Tabs" name="theme.selector.tabs">
             <action method="addTab">
diff --git a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_launch.xml b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_launch.xml
index 76a45cf6a6e..7bff8f9b72a 100644
--- a/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_launch.xml
+++ b/app/code/Magento/DesignEditor/view/adminhtml/layout/adminhtml_system_design_editor_launch.xml
@@ -24,66 +24,52 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="backend.page">
-        <action method="setTemplate">
-            <argument name="file" xsi:type="string">Magento_DesignEditor::editor.phtml</argument>
-        </action>
-    </referenceBlock>
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-designeditor-css-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::css/styles.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-designeditor-js-bootstrap-launch-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_DesignEditor::js/bootstrap/launch.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
-    <referenceContainer name="content">
-        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Container" name="design_editor" template="Magento_DesignEditor::editor/container.phtml">
-            <block class="Magento\Backend\Block\Template" name="design_editor_toolbar" template="Magento_DesignEditor::editor/toolbar.phtml">
-                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons" name="design_editor_toolbar_buttons" template="Magento_DesignEditor::editor/toolbar/buttons.phtml">
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Edit" name="design_editor_toolbar_buttons_edit" template="Magento_DesignEditor::editor/toolbar/buttons/edit.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Save" name="design_editor_toolbar_buttons_save"/>
-                </block>
-            </block>
-            <block class="Magento\DesignEditor\Block\Adminhtml\Theme\Selector\StoreView" name="theme.selector.storeview" template="Magento_DesignEditor::theme/selector/storeview.phtml"/>
-            <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools" name="design_editor_tools" template="Magento_DesignEditor::editor/tools.phtml">
-                <block class="Magento\Backend\Block\Template" name="design_editor_tools_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/super-handle.phtml"/>
-                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles" name="design_editor_tools_quick-styles" template="Magento_DesignEditor::editor/tools/tabs.phtml">
-                    <block class="Magento\Backend\Block\Template" name="design_editor_tools_quick-styles_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/handle.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Tabs\Body" name="design_editor_tools_quick-styles_tab_body" as="tab_body" template="Magento_DesignEditor::editor/tools/tabs/body.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Header" name="design_editor_tools_quick-styles_header" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Backgrounds" name="design_editor_tools_quick-styles_backgrounds" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Buttons" name="design_editor_tools_quick-styles_buttons" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Tips" name="design_editor_tools_quick-styles_tips" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Fonts" name="design_editor_tools_quick-styles_fonts" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+    <body>
+        <attribute name="id" value="html-body"/>
+    </body>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <css src="Magento_DesignEditor::css/styles.css"/>
+        <link src="Magento_DesignEditor::js/bootstrap/launch.js"/>
+    </head>
+    <remove name="backend.page"/>
+    <referenceContainer name="root">
+        <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_DesignEditor::editor.phtml">
+            <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Container" name="design_editor" template="Magento_DesignEditor::editor/container.phtml">
+                <block class="Magento\Backend\Block\Template" name="design_editor_toolbar" template="Magento_DesignEditor::editor/toolbar.phtml">
+                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons" name="design_editor_toolbar_buttons" template="Magento_DesignEditor::editor/toolbar/buttons.phtml">
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Edit" name="design_editor_toolbar_buttons_edit" template="Magento_DesignEditor::editor/toolbar/buttons/edit.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Save" name="design_editor_toolbar_buttons_save"/>
+                    </block>
                 </block>
-                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Block" name="design_editor_tools_block" template="Magento_DesignEditor::editor/tools/block.phtml"/>
-                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Settings" name="design_editor_tools_settings" template="Magento_DesignEditor::editor/tools/settings.phtml"/>
-                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code" name="design_editor_tools_code" template="Magento_DesignEditor::editor/tools/tabs.phtml">
-                    <block class="Magento\Backend\Block\Template" name="design_editor_tools_code_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/handle.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Tabs\Body" name="design_editor_tools_code_tab_body" as="tab_body" template="Magento_DesignEditor::editor/tools/tabs/body.phtml"/>
-                    <!-- Tab with CSS list -->
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Css" name="design_editor_tools_code_css" template="Magento_DesignEditor::editor/tools/code/css.phtml"/>
-                    <!-- Tab with JavaScript list -->
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Js" name="design_editor_tools_code_js" template="Magento_DesignEditor::editor/tools/code/js.phtml"/>
-                    <!-- Tab with Custom CSS -->
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Custom" name="design_editor_tools_code_custom" template="Magento_DesignEditor::editor/tools/code/custom.phtml"/>
-                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\ImageSizing" name="design_editor_tools_code_image_sizing" template="Magento_DesignEditor::editor/tools/code/image-sizing.phtml"/>
+                <block class="Magento\DesignEditor\Block\Adminhtml\Theme\Selector\StoreView" name="theme.selector.storeview" template="Magento_DesignEditor::theme/selector/storeview.phtml"/>
+                <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools" name="design_editor_tools" template="Magento_DesignEditor::editor/tools.phtml">
+                    <block class="Magento\Backend\Block\Template" name="design_editor_tools_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/super-handle.phtml"/>
+                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles" name="design_editor_tools_quick-styles" template="Magento_DesignEditor::editor/tools/tabs.phtml">
+                        <block class="Magento\Backend\Block\Template" name="design_editor_tools_quick-styles_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/handle.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Tabs\Body" name="design_editor_tools_quick-styles_tab_body" as="tab_body" template="Magento_DesignEditor::editor/tools/tabs/body.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Header" name="design_editor_tools_quick-styles_header" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Backgrounds" name="design_editor_tools_quick-styles_backgrounds" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Buttons" name="design_editor_tools_quick-styles_buttons" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Tips" name="design_editor_tools_quick-styles_tips" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\QuickStyles\Fonts" name="design_editor_tools_quick-styles_fonts" template="Magento_DesignEditor::editor/tools/quick-styles/form.phtml"/>
+                    </block>
+                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Block" name="design_editor_tools_block" template="Magento_DesignEditor::editor/tools/block.phtml"/>
+                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Settings" name="design_editor_tools_settings" template="Magento_DesignEditor::editor/tools/settings.phtml"/>
+                    <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code" name="design_editor_tools_code" template="Magento_DesignEditor::editor/tools/tabs.phtml">
+                        <block class="Magento\Backend\Block\Template" name="design_editor_tools_code_tab_handle" as="tab_handle" template="Magento_DesignEditor::editor/tools/tabs/handle.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Tabs\Body" name="design_editor_tools_code_tab_body" as="tab_body" template="Magento_DesignEditor::editor/tools/tabs/body.phtml"/>
+                        <!-- Tab with CSS list -->
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Css" name="design_editor_tools_code_css" template="Magento_DesignEditor::editor/tools/code/css.phtml"/>
+                        <!-- Tab with JavaScript list -->
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Js" name="design_editor_tools_code_js" template="Magento_DesignEditor::editor/tools/code/js.phtml"/>
+                        <!-- Tab with Custom CSS -->
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Custom" name="design_editor_tools_code_custom" template="Magento_DesignEditor::editor/tools/code/custom.phtml"/>
+                        <block class="Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\ImageSizing" name="design_editor_tools_code_image_sizing" template="Magento_DesignEditor::editor/tools/code/image-sizing.phtml"/>
+                    </block>
                 </block>
             </block>
+            <block class="Magento\Backend\Block\Template" name="theme.dialog" template="Magento_DesignEditor::dialog.phtml"/>
         </block>
-        <block class="Magento\Backend\Block\Template" name="theme.dialog" template="Magento_DesignEditor::dialog.phtml"/>
     </referenceContainer>
 </page>
diff --git a/app/code/Magento/DesignEditor/view/adminhtml/templates/editor.phtml b/app/code/Magento/DesignEditor/view/adminhtml/templates/editor.phtml
index 2a9a2c52cab..a540501b85a 100644
--- a/app/code/Magento/DesignEditor/view/adminhtml/templates/editor.phtml
+++ b/app/code/Magento/DesignEditor/view/adminhtml/templates/editor.phtml
@@ -22,20 +22,12 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
-<head>
-    <?php echo $this->getChildHtml('head') ?>
-</head>
-<body id="html-body"<?php echo $this->getBodyClass() ? ' class="' . $this->getBodyClass() . '"' : ''; ?>>
-    <?php echo $this->getChildHtml('content') ?>
-    <div id="loading-mask" style="display:none">
-        <p class="loader" id="loading_mask_loader">
-            <img src="<?php echo $this->getViewFileUrl('images/ajax-loader-tr.gif') ?>"
-                 alt="<?php echo __('Loading...') ?>"/>
-            <br/>
-            <?php echo __('Please wait...') ?>
-        </p>
-    </div>
-</body>
-</html>
+<?php echo $this->getChildHtml('content') ?>
+<div id="loading-mask" style="display:none">
+    <p class="loader" id="loading_mask_loader">
+        <img src="<?php echo $this->getViewFileUrl('images/ajax-loader-tr.gif') ?>"
+             alt="<?php echo __('Loading...') ?>"/>
+        <br/>
+        <?php echo __('Please wait...') ?>
+    </p>
+</div>
diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json
index 663cd5d8450..764da496332 100644
--- a/app/code/Magento/Dhl/composer.json
+++ b/app/code/Magento/Dhl/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Directory/Model/Config/Source/Country/Full.php b/app/code/Magento/Directory/Model/Config/Source/Country/Full.php
index fdb06a32f70..4ed1d718fc3 100644
--- a/app/code/Magento/Directory/Model/Config/Source/Country/Full.php
+++ b/app/code/Magento/Directory/Model/Config/Source/Country/Full.php
@@ -23,6 +23,9 @@
  */
 namespace Magento\Directory\Model\Config\Source\Country;
 
+/**
+ * @codeCoverageIgnore
+ */
 class Full extends \Magento\Directory\Model\Config\Source\Country implements \Magento\Framework\Option\ArrayInterface
 {
     /**
diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json
index e52b58243fb..a58450d3f7f 100644
--- a/app/code/Magento/Directory/composer.json
+++ b/app/code/Magento/Directory/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php b/app/code/Magento/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
index 2c0816e33cd..0ff961d8987 100644
--- a/app/code/Magento/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
+++ b/app/code/Magento/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
@@ -160,11 +160,8 @@ class Downloadable extends \Magento\Backend\Block\Widget implements \Magento\Bac
      */
     protected function _toHtml()
     {
-        $accordion = $this->getLayout()->createBlock(
-            'Magento\Backend\Block\Widget\Accordion'
-        )->setId(
-            $this->accordionBlockId
-        );
+        $accordion = $this->getLayout()->createBlock('Magento\Backend\Block\Widget\Accordion')
+            ->setId($this->accordionBlockId);
         $accordion->addItem(
             'samples',
             array(
diff --git a/app/code/Magento/Downloadable/Controller/Customer/Products.php b/app/code/Magento/Downloadable/Controller/Customer/Products.php
index b2db83e6667..f3862e933e8 100644
--- a/app/code/Magento/Downloadable/Controller/Customer/Products.php
+++ b/app/code/Magento/Downloadable/Controller/Customer/Products.php
@@ -71,10 +71,7 @@ class Products extends \Magento\Framework\App\Action\Action
         if ($block = $this->_view->getLayout()->getBlock('downloadable_customer_products_list')) {
             $block->setRefererUrl($this->_redirect->getRefererUrl());
         }
-        $headBlock = $this->_view->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('My Downloadable Products'));
-        }
+        $this->_view->getPage()->getConfig()->setTitle(__('My Downloadable Products'));
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json
index d4f93e34f4d..427bfb86449 100644
--- a/app/code/Magento/Downloadable/composer.json
+++ b/app/code/Magento/Downloadable/composer.json
@@ -3,25 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-gift-message": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-gift-message": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-msrp": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php b/app/code/Magento/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php
deleted file mode 100644
index 139c4ffc8f6..00000000000
--- a/app/code/Magento/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php
+++ /dev/null
@@ -1,53 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/** @var $installer \Magento\Catalog\Model\Resource\Setup */
-$installer = $this;
-
-$msrpEnabled = $installer->getAttribute('catalog_product', 'msrp_enabled', 'apply_to');
-if ($msrpEnabled && strstr($msrpEnabled, \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) == false) {
-    $installer->updateAttribute(
-        'catalog_product',
-        'msrp_enabled',
-        array('apply_to' => $msrpEnabled . ',' . \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE)
-    );
-}
-
-$msrpDisplay = $installer->getAttribute('catalog_product', 'msrp_display_actual_price_type', 'apply_to');
-if ($msrpDisplay && strstr($msrpEnabled, \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) == false) {
-    $installer->updateAttribute(
-        'catalog_product',
-        'msrp_display_actual_price_type',
-        array('apply_to' => $msrpDisplay . ',' . \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE)
-    );
-}
-
-$msrp = $installer->getAttribute('catalog_product', 'msrp', 'apply_to');
-if ($msrp && strstr($msrpEnabled, \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) == false) {
-    $installer->updateAttribute(
-        'catalog_product',
-        'msrp',
-        array('apply_to' => $msrp . ',' . \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE)
-    );
-}
diff --git a/app/code/Magento/Downloadable/etc/module.xml b/app/code/Magento/Downloadable/etc/module.xml
index 9a0a14069bc..95c8bd61ba4 100644
--- a/app/code/Magento/Downloadable/etc/module.xml
+++ b/app/code/Magento/Downloadable/etc/module.xml
@@ -43,6 +43,7 @@
             <module name="Magento_Wishlist"/>
             <module name="Magento_GiftMessage"/>
             <module name="Magento_CatalogInventory"/>
+            <module name="Magento_Msrp" />
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Downloadable/view/frontend/layout/catalog_product_view_type_downloadable.xml b/app/code/Magento/Downloadable/view/frontend/layout/catalog_product_view_type_downloadable.xml
index aa7e7b9bf2f..fbb9bfe93cf 100644
--- a/app/code/Magento/Downloadable/view/frontend/layout/catalog_product_view_type_downloadable.xml
+++ b/app/code/Magento/Downloadable/view/frontend/layout/catalog_product_view_type_downloadable.xml
@@ -24,6 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="class" value="page-product-downloadable"/>
+    </body>
     <referenceContainer name="product.info.type">
         <block class="Magento\Downloadable\Block\Catalog\Product\View\Type" name="product.info.downloadable" as="product_type_data" template="catalog/product/type.phtml">
             <block class="Magento\CatalogInventory\Block\Stockqty\DefaultStockqty" name="product.info.downloadable.extra" as="product_type_data_extra" template="stockqty/default.phtml"/>
@@ -36,7 +39,6 @@
                 <arguments>
                     <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                     <argument name="price_type_code" xsi:type="string">link_price</argument>
-                    <argument name="display_msrp_help_message" xsi:type="string">1</argument>
                 </arguments>
             </block>
         </block>
diff --git a/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/links.phtml b/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/links.phtml
index f64a777e6e2..f2991c53f49 100644
--- a/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/links.phtml
+++ b/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/links.phtml
@@ -31,7 +31,8 @@
         <label class="label"><span><?php echo $this->getLinksTitle() ?></span></label>
         <div class="control" id="downloadable-links-list"
              data-mage-init='{"downloadable":{
-                 "linkElement":"input:checkbox",
+                 "linkElement":"input:checkbox[value]",
+                 "allElements":"#links_all",
                  "config":<?php echo $this->getJsonConfig() ?>}
              }'
              data-container-for="downloadable-links">
@@ -58,6 +59,13 @@
                     </label>
                 </div>
             <?php endforeach; ?>
+            <div class="field choice downloads-all">
+                <input type="checkbox"
+                       data-notchecked="<?php echo __('Select all')?>"
+                       data-checked="<?php echo __('Unselect all')?>"
+                       id="links_all" />
+                <label class="label" for="links_all"><span><?php echo __('Select all')?></span></label>
+            </div>
         </div>
         <?php if ($_isRequired): ?>
             <span id="links-advice-container"></span>
diff --git a/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/samples.phtml b/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/samples.phtml
index 83ab77b6107..054fcf1821b 100644
--- a/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/samples.phtml
+++ b/app/code/Magento/Downloadable/view/frontend/templates/catalog/product/samples.phtml
@@ -30,13 +30,13 @@
 ?>
 
 <?php if ($this->hasSamples()): ?>
-    <dl class="downloadable samples">
-        <dt class="samples title"><?php echo $this->getSamplesTitle() ?></dt>
+    <dl class="items samples">
+        <dt class="item-title samples-item-title"><?php echo $this->getSamplesTitle() ?></dt>
         <?php $_samples = $this->getSamples() ?>
         <?php foreach ($_samples as $_sample): ?>
-            <dd class="sample item">
+            <dd class="item samples-item">
                 <a href="<?php echo $this->getSampleUrl($_sample) ?>" <?php echo $this->getIsOpenInNewWindow()?'onclick="this.target=\'_blank\'"':''; ?>
-                   class="sample link">
+                   class="item-link samples-item-link">
                     <?php echo $this->escapeHtml($_sample->getTitle()) ?>
                 </a>
             </dd>
diff --git a/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml b/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml
index 8f5d0924188..73b59b516be 100644
--- a/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml
+++ b/app/code/Magento/Downloadable/view/frontend/templates/checkout/cart/item/default.phtml
@@ -24,8 +24,11 @@
 ?>
 <?php
 $_item = $this->getItem();
-$isVisibleProduct = $_item->getProduct()->isVisibleInSiteVisibility();
-$canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_item->getProduct(), \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM);
+$product = $_item->getProduct();
+$isVisibleProduct = $product->isVisibleInSiteVisibility();
+/** @var \Magento\Msrp\Helper\Data $helper */
+$helper = $this->helper('Magento\Msrp\Helper\Data');
+$canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinimalPriceLessMsrp($product);
 ?>
 <?php echo $this->getChildHtml('item_extra') ?>
 <tbody class="cart item">
@@ -36,7 +39,7 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite
                    title="<?php echo $this->escapeHtml($this->getProductName()) ?>"
                    class="product photo product-item-photo">
             <?php endif; ?>
-            <?php echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')->init($_item->getProduct(), 'cart_page_product_thumbnail')->toHtml(); ?>
+            <?php echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Image')->init($product, 'cart_page_product_thumbnail')->toHtml(); ?>
             <?php if ($this->hasProductUrl()):?></a><?php endif;?>
             <div class="product details product-item-details">
                 <strong class="product name product-item-name">
@@ -79,17 +82,15 @@ $canApplyMsrp = $this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($_ite
         </td>
     <?php if ($canApplyMsrp): ?>
         <td class="col msrp">
-            <span class="cart price">
+            <span class="cart-price">
                 <span class="msrp notice"><?php echo __('See price before order confirmation.'); ?></span>
                 <?php $helpLinkId = 'cart-msrp-help-' . $_item->getId(); ?>
                 <a id="<?php echo $helpLinkId ?>" href="#" class="action help map"><?php echo __("What's this?"); ?></a>
                 <script type="text/javascript">
-require(['prototype'], function(){
-
-    Catalog.Map.addHelpLink($('<?php echo $helpLinkId ?>'), "<?php echo __("What's this?") ?>");
-                
-});
-</script>
+                    require(['prototype'], function () {
+                        Catalog.Map.addHelpLink($('<?php echo $helpLinkId ?>'), "<?php echo __("What's this?") ?>");
+                    });
+                </script>
             </span>
             <?php $cols++; ?>
         </td>
diff --git a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml
index 509f1f54c69..fc18f0c56c0 100644
--- a/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml
+++ b/app/code/Magento/Downloadable/view/frontend/templates/sales/order/invoice/items/renderer/downloadable.phtml
@@ -78,7 +78,7 @@
         <?php echo $this->getItemPriceHtml(); ?>
     </td>
     <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>">
-        <span class="qty summary" data-th="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"><?php echo $_item->getQty()*1 ?></span>
+        <span class="qty summary" data-label="<?php echo $this->escapeHtml(__('Qty Invoiced')); ?>"><?php echo $_item->getQty()*1 ?></span>
     </td>
     <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal')); ?>">
         <?php echo $this->getItemRowTotalHtml(); ?>
diff --git a/app/code/Magento/Downloadable/view/frontend/web/downloadable.js b/app/code/Magento/Downloadable/view/frontend/web/downloadable.js
index 86931ae8cac..9431e745cae 100644
--- a/app/code/Magento/Downloadable/view/frontend/web/downloadable.js
+++ b/app/code/Magento/Downloadable/view/frontend/web/downloadable.js
@@ -28,9 +28,25 @@ define([
 
     $.widget('mage.downloadable', {
         _create: function() {
+            var self = this;
+
             this.element.find(this.options.linkElement).on('change', $.proxy(function() {
                 this._reloadPrice();
             }, this));
+
+            this.element.find(this.options.allElements).on('change', function() {
+                if (this.checked) {
+                    $('label[for="' + this.id + '"] > span').text($(this).attr('data-checked'));
+                    self.element.find(self.options.linkElement + ':not(:checked)').each(function(){
+                        $(this).trigger('click');
+                    });
+                } else {
+                    $('[for="' + this.id + '"] > span').text($(this).attr('data-notchecked'));
+                    self.element.find(self.options.linkElement + ':checked').each(function(){
+                        $(this).trigger('click');
+                    });
+                }
+            });
         },
 
         /**
@@ -48,6 +64,7 @@ define([
                 inclTaxPrice += this.options.config.links[$(element).val()].inclTaxPrice;
                 exclTaxPrice += this.options.config.links[$(element).val()].exclTaxPrice;
             }, this));
+
             this.element.trigger('changePrice', {
                 'config': 'config',
                 'price': {
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
index 77fab5ff5c2..97efc56711e 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
@@ -38,7 +38,7 @@ abstract class AbstractData
      *
      * @var \Magento\Eav\Model\Attribute
      */
-    protected $_attribite;
+    protected $_attribute;
 
     /**
      * Entity instance
@@ -121,7 +121,7 @@ abstract class AbstractData
      */
     public function setAttribute(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute)
     {
-        $this->_attribite = $attribute;
+        $this->_attribute = $attribute;
         return $this;
     }
 
@@ -133,10 +133,10 @@ abstract class AbstractData
      */
     public function getAttribute()
     {
-        if (!$this->_attribite) {
+        if (!$this->_attribute) {
             throw new CoreException(__('Attribute object is undefined'));
         }
-        return $this->_attribite;
+        return $this->_attribute;
     }
 
     /**
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php
index b159e60b695..7cf458c4fcc 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php
@@ -99,6 +99,28 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
         return $options;
     }
 
+    /**
+     * Retrieve Option values array by ids
+     *
+     * @param string|array $ids
+     * @param bool $withEmpty Add empty option to array
+     * @return array
+     */
+    public function getSpecificOptions($ids, $withEmpty = true)
+    {
+        $options = $this->_attrOptionCollectionFactory->create()
+            ->setPositionOrder('asc')
+            ->setAttributeFilter($this->getAttribute()->getId())
+            ->addFieldToFilter('main_table.option_id', array('in' => $ids))
+            ->setStoreFilter($this->getAttribute()->getStoreId())
+            ->load()
+            ->toOptionArray();
+        if ($withEmpty) {
+            array_unshift($options, array('label' => '', 'value' => ''));
+        }
+        return $options;
+    }
+
     /**
      * Get a text for option value
      *
@@ -113,7 +135,7 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
             $value = explode(',', $value);
         }
 
-        $options = $this->getAllOptions(false);
+        $options = $this->getSpecificOptions($value, false);
 
         if ($isMultiple) {
             $values = array();
diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json
index a3e663f3090..4762b42b045 100644
--- a/app/code/Magento/Eav/composer.json
+++ b/app/code/Magento/Eav/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Edit/Form.php b/app/code/Magento/Email/Block/Adminhtml/Template/Edit/Form.php
index ec40d0fbe78..b3dc3efb207 100644
--- a/app/code/Magento/Email/Block/Adminhtml/Template/Edit/Form.php
+++ b/app/code/Magento/Email/Block/Adminhtml/Template/Edit/Form.php
@@ -68,23 +68,9 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      */
     protected function _prepareLayout()
     {
-        if ($head = $this->getLayout()->getBlock('head')) {
-            $head->addChild(
-                'prototype-window-js',
-                'Magento\Theme\Block\Html\Head\Script',
-                array('file' => 'prototype/window.js')
-            );
-            $head->addChild(
-                'prototype-windows-themes-default-css',
-                'Magento\Theme\Block\Html\Head\Css',
-                array('file' => 'prototype/windows/themes/default.css')
-            );
-            $head->addChild(
-                'magento-core-prototype-magento-css',
-                'Magento\Theme\Block\Html\Head\Css',
-                array('file' => 'Magento_Core::prototype/magento.css')
-            );
-        }
+        $this->pageConfig->addPageAsset('prototype/window.js');
+        $this->pageConfig->addPageAsset('prototype/windows/themes/default.css');
+        $this->pageConfig->addPageAsset('Magento_Core::prototype/magento.css');
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json
index 7a66e13c43e..8b02103b840 100644
--- a/app/code/Magento/Email/composer.json
+++ b/app/code/Magento/Email/composer.json
@@ -3,16 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Email/etc/module.xml b/app/code/Magento/Email/etc/module.xml
index bbc8e18e27a..76ddc96cf16 100644
--- a/app/code/Magento/Email/etc/module.xml
+++ b/app/code/Magento/Email/etc/module.xml
@@ -35,7 +35,6 @@
             <module name="Magento_Core"/>
             <module name="Magento_Cms"/>
             <module name="Magento_Backend"/>
-            <module name="Magento_Theme"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_edit.xml b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_edit.xml
index 2b1cae0e2e3..fd109d19166 100644
--- a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_edit.xml
+++ b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_edit.xml
@@ -24,11 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-     <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-email-js-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Email::js/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_Email::js/bootstrap.js"/>
+    </head>
 </page>
diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json
index f8070283374..c23658cc4a4 100644
--- a/app/code/Magento/Fedex/composer.json
+++ b/app/code/Magento/Fedex/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json
index 7cfb649cea5..38540a41549 100644
--- a/app/code/Magento/GiftMessage/composer.json
+++ b/app/code/Magento/GiftMessage/composer.json
@@ -3,21 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-multishipping": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-multishipping": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GiftMessage/etc/module.xml b/app/code/Magento/GiftMessage/etc/module.xml
index e61d225a16b..cd07313e986 100644
--- a/app/code/Magento/GiftMessage/etc/module.xml
+++ b/app/code/Magento/GiftMessage/etc/module.xml
@@ -39,7 +39,6 @@
             <module name="Magento_Core"/>
             <module name="Magento_Customer"/>
             <module name="Magento_Eav"/>
-            <module name="Magento_Theme"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/GiftMessage/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/GiftMessage/view/adminhtml/layout/sales_order_view.xml
index 51214d4ea01..7101a6292d6 100644
--- a/app/code/Magento/GiftMessage/view/adminhtml/layout/sales_order_view.xml
+++ b/app/code/Magento/GiftMessage/view/adminhtml/layout/sales_order_view.xml
@@ -24,13 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
     <referenceBlock name="order_item_extra_info">
         <block class="Magento\GiftMessage\Block\Adminhtml\Sales\Order\View\Giftoptions" name="gift_options_link" template="sales/order/view/giftoptions.phtml">
             <block class="Magento\GiftMessage\Block\Adminhtml\Sales\Order\View\Items" name="gift_options_item_data" template="sales/order/view/items.phtml"/>
diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json
index e37ee726ebb..5d8a4ec9ad4 100644
--- a/app/code/Magento/GoogleAdwords/composer.json
+++ b/app/code/Magento/GoogleAdwords/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json
index ab0d0972e6b..1520dd03b09 100644
--- a/app/code/Magento/GoogleAnalytics/composer.json
+++ b/app/code/Magento/GoogleAnalytics/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json
index 5fcca9ffc28..b3bc0b4e288 100644
--- a/app/code/Magento/GoogleOptimizer/composer.json
+++ b/app/code/Magento/GoogleOptimizer/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-google-analytics": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-google-analytics": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_category_view.xml b/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_category_view.xml
index 160d76cfb16..5f6e4a85626 100644
--- a/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_category_view.xml
+++ b/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_category_view.xml
@@ -24,7 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\GoogleOptimizer\Block\Code\Category" before="-" name="googleoptimizer.experiment.script"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_product_view.xml
index 536bfac6065..c8e69375781 100644
--- a/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_product_view.xml
+++ b/app/code/Magento/GoogleOptimizer/view/frontend/layout/catalog_product_view.xml
@@ -24,7 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\GoogleOptimizer\Block\Code\Product" before="-" name="googleoptimizer.experiment.script"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/GoogleOptimizer/view/frontend/layout/cms_page_view.xml b/app/code/Magento/GoogleOptimizer/view/frontend/layout/cms_page_view.xml
index 48b2d671f56..c8f53e719a5 100644
--- a/app/code/Magento/GoogleOptimizer/view/frontend/layout/cms_page_view.xml
+++ b/app/code/Magento/GoogleOptimizer/view/frontend/layout/cms_page_view.xml
@@ -24,7 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\GoogleOptimizer\Block\Code\Page" before="-" name="googleoptimizer.experiment.script"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Condition.php b/app/code/Magento/GoogleShopping/Model/Attribute/Condition.php
index 1ed8a8345d5..c8ea3743744 100644
--- a/app/code/Magento/GoogleShopping/Model/Attribute/Condition.php
+++ b/app/code/Magento/GoogleShopping/Model/Attribute/Condition.php
@@ -54,6 +54,7 @@ class Condition extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
         $availableConditions = array(self::CONDITION_NEW, self::CONDITION_USED, self::CONDITION_REFURBISHED);
 
         $mapValue = $this->getProductAttributeValue($product);
+        $mapValue = !is_null($mapValue) ? mb_convert_case($mapValue, MB_CASE_LOWER) : $mapValue;
         if (!is_null($mapValue) && in_array($mapValue, $availableConditions)) {
             $condition = $mapValue;
         } else {
diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json
index f457471c4f1..40ab8c4fc33 100644
--- a/app/code/Magento/GoogleShopping/composer.json
+++ b/app/code/Magento/GoogleShopping/composer.json
@@ -3,20 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GoogleShopping/etc/adminhtml/events.xml b/app/code/Magento/GoogleShopping/etc/adminhtml/events.xml
index f10715e501e..b4fe8d5f9e9 100644
--- a/app/code/Magento/GoogleShopping/etc/adminhtml/events.xml
+++ b/app/code/Magento/GoogleShopping/etc/adminhtml/events.xml
@@ -24,7 +24,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
-    <event name="catalog_product_save_after">
+    <event name="catalog_product_save_commit_after">
         <observer name="googleshopping_observer" instance="Magento\GoogleShopping\Model\Observer" method="saveProductItem" />
     </event>
     <event name="catalog_product_delete_before">
diff --git a/app/code/Magento/GoogleShopping/etc/module.xml b/app/code/Magento/GoogleShopping/etc/module.xml
index 89c6286283d..a1d4df7bdee 100644
--- a/app/code/Magento/GoogleShopping/etc/module.xml
+++ b/app/code/Magento/GoogleShopping/etc/module.xml
@@ -37,7 +37,6 @@
             <module name="Magento_Directory"/>
             <module name="Magento_Eav"/>
             <module name="Magento_Tax"/>
-            <module name="Magento_Theme"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/GoogleShopping/view/adminhtml/layout/adminhtml_googleshopping_items_index.xml b/app/code/Magento/GoogleShopping/view/adminhtml/layout/adminhtml_googleshopping_items_index.xml
index 07ac63527a8..5ff3bd78037 100644
--- a/app/code/Magento/GoogleShopping/view/adminhtml/layout/adminhtml_googleshopping_items_index.xml
+++ b/app/code/Magento/GoogleShopping/view/adminhtml/layout/adminhtml_googleshopping_items_index.xml
@@ -24,16 +24,12 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-googleshopping-js-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_GoogleShopping::js/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_GoogleShopping::js/bootstrap.js"/>
+    </head>
     <referenceContainer name="page.main.actions">
-        <block class="Magento\Backend\Block\Store\Switcher" 
-               name="store_switcher" 
+        <block class="Magento\Backend\Block\Store\Switcher"
+               name="store_switcher"
                template="Magento_Backend::store/switcher.phtml" />
     </referenceContainer>
 </page>
diff --git a/app/code/Magento/GoogleShopping/view/frontend/layout/cms_index_index.xml b/app/code/Magento/GoogleShopping/view/frontend/layout/cms_index_index.xml
index fff3f77e0de..48ddf5978c5 100644
--- a/app/code/Magento/GoogleShopping/view/frontend/layout/cms_index_index.xml
+++ b/app/code/Magento/GoogleShopping/view/frontend/layout/cms_index_index.xml
@@ -24,7 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\GoogleShopping\Block\SiteVerification"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json
index 9387c28ecdd..ff4046298de 100644
--- a/app/code/Magento/GroupedImportExport/composer.json
+++ b/app/code/Magento/GroupedImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-import-export": "0.1.0-alpha96",
-        "magento/module-catalog-import-export": "0.1.0-alpha96",
-        "magento/module-grouped-product": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-import-export": "0.1.0-alpha97",
+        "magento/module-catalog-import-export": "0.1.0-alpha97",
+        "magento/module-grouped-product": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
index 9308008bb7a..b4e77702c70 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -93,6 +93,9 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
      */
     protected $_appState;
 
+    /** @var \Magento\Msrp\Helper\Data  */
+    protected $msrpData;
+
     /**
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Catalog\Model\Product\Option $catalogProductOption
@@ -108,6 +111,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
      * @param \Magento\Framework\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus
      * @param \Magento\Framework\App\State $appState
+     * @param \Magento\Msrp\Helper\Data $msrpData
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -127,12 +131,14 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
         \Magento\Framework\StoreManagerInterface $storeManager,
         \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus,
         \Magento\Framework\App\State $appState,
+        \Magento\Msrp\Helper\Data $msrpData,
         array $data = array()
     ) {
         $this->productLinks = $catalogProductLink;
         $this->_storeManager = $storeManager;
         $this->_catalogProductStatus = $catalogProductStatus;
         $this->_appState = $appState;
+        $this->msrpData = $msrpData;
         parent::__construct(
             $productFactory,
             $catalogProductOption,
@@ -481,4 +487,19 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
         }
         return parent::beforeSave($product);
     }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @return int
+     */
+    public function getChildrenMsrp(\Magento\Catalog\Model\Product $product)
+    {
+        $prices = [];
+        foreach ($this->getAssociatedProducts($product) as $item) {
+            if ($item->getMsrp() !== null) {
+                $prices[] = $item->getMsrp();
+            }
+        }
+        return min($prices);
+    }
 }
diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json
index b0fba94c66a..f1fcf590315 100644
--- a/app/code/Magento/GroupedProduct/composer.json
+++ b/app/code/Magento/GroupedProduct/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-msrp": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/GroupedProduct/etc/module.xml b/app/code/Magento/GroupedProduct/etc/module.xml
index c6b6ca0063e..9d06488e731 100644
--- a/app/code/Magento/GroupedProduct/etc/module.xml
+++ b/app/code/Magento/GroupedProduct/etc/module.xml
@@ -40,7 +40,7 @@
             <module name="Magento_Backend" />
             <module name="Magento_Eav" />
             <module name="Magento_Customer" />
-            <module name="Magento_Theme" />
+            <module name="Magento_Msrp" />
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/layout/catalog_product_grouped.xml b/app/code/Magento/GroupedProduct/view/adminhtml/layout/catalog_product_grouped.xml
index ca72e17fd65..e40ba57b44a 100644
--- a/app/code/Magento/GroupedProduct/view/adminhtml/layout/catalog_product_grouped.xml
+++ b/app/code/Magento/GroupedProduct/view/adminhtml/layout/catalog_product_grouped.xml
@@ -25,13 +25,9 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="groupedproduct_popup_grid"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-grouped-product-css-grouped-product-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_GroupedProduct::css/grouped-product.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_GroupedProduct::css/grouped-product.css"/>
+    </head>
     <referenceBlock name="product_tabs">
         <block class="Magento\GroupedProduct\Block\Product\Grouped\AssociatedProducts" name="catalog.product.edit.grouped.container" template="product/grouped/container.phtml">
             <block class="Magento\Framework\View\Element\Template" name="catalog.product.edit.tab.super.container" template="Magento_GroupedProduct::product/grouped/grouped.phtml">
diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js
index ffeaa58a5d4..06975db91c8 100644
--- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js
+++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js
@@ -25,7 +25,8 @@ define([
     "jquery",
     "jquery/ui",
     "mage/translate",
-    "jquery/template"
+    "jquery/template",
+    "mage/adminhtml/grid"
 ], function($){
     'use strict';
     $.widget('mage.groupedProduct', {
diff --git a/app/code/Magento/GroupedProduct/view/base/templates/product/price/final_price.phtml b/app/code/Magento/GroupedProduct/view/base/templates/product/price/final_price.phtml
index 46724dca1d3..10a042dcc6a 100644
--- a/app/code/Magento/GroupedProduct/view/base/templates/product/price/final_price.phtml
+++ b/app/code/Magento/GroupedProduct/view/base/templates/product/price/final_price.phtml
@@ -38,7 +38,7 @@ if ($minProduct) {
             $minProduct->getPriceInfo()->getPrice('final_price')->getAmount(),
             $minProduct,
             $minProduct->getPriceInfo()->getPrice('final_price'),
-            []
+            ['include_container' => true]
         );
 }
 ?>
diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json
index 35e9b69c05d..561eddbb92c 100644
--- a/app/code/Magento/ImportExport/composer.json
+++ b/app/code/Magento/ImportExport/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-indexer": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-indexer": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Index/App/Indexer.php b/app/code/Magento/Index/App/Indexer.php
deleted file mode 100644
index 530a44aceb2..00000000000
--- a/app/code/Magento/Index/App/Indexer.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * Indexer application
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\App;
-
-use Magento\Framework\App\Console\Response;
-use Magento\Framework\App;
-use Magento\Framework\AppInterface;
-
-class Indexer implements AppInterface
-{
-    /**
-     * Report directory
-     *
-     * @var string
-     */
-    protected $_reportDir;
-
-    /**
-     * @var \Magento\Framework\App\Filesystem
-     */
-    protected $_filesystem;
-
-    /**
-     * @var \Magento\Index\Model\IndexerFactory
-     */
-    protected $_indexerFactory;
-
-    /**
-     * @var \Magento\Framework\App\Console\Response
-     */
-    protected $_response;
-
-    /**
-     * @param string $reportDir
-     * @param \Magento\Framework\App\Filesystem $filesystem
-     * @param \Magento\Index\Model\IndexerFactory $indexerFactory
-     * @param Response $response
-     */
-    public function __construct(
-        $reportDir,
-        \Magento\Framework\App\Filesystem $filesystem,
-        \Magento\Index\Model\IndexerFactory $indexerFactory,
-        Response $response
-    ) {
-        $this->_reportDir = $reportDir;
-        $this->_filesystem = $filesystem;
-        $this->_indexerFactory = $indexerFactory;
-        $this->_response = $response;
-    }
-
-    /**
-     * Run application
-     *
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function launch()
-    {
-        /* Clean reports */
-        $directory = $this->_filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::ROOT_DIR);
-        $path = $directory->getRelativePath($this->_reportDir);
-        if ($directory->isExist($path)) {
-            $directory->delete($path);
-        }
-
-        /* Run all indexer processes */
-        /** @var $indexer \Magento\Index\Model\Indexer */
-        $indexer = $this->_indexerFactory->create();
-        /** @var $process \Magento\Index\Model\Process */
-        foreach ($indexer->getProcessesCollection() as $process) {
-            if ($process->getIndexer()->isVisible()) {
-                $process->reindexEverything();
-            }
-        }
-        $this->_response->setCode(0);
-        return $this->_response;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function catchException(App\Bootstrap $bootstrap, \Exception $exception)
-    {
-        return false;
-    }
-}
diff --git a/app/code/Magento/Index/App/Shell.php b/app/code/Magento/Index/App/Shell.php
deleted file mode 100644
index 0898d252943..00000000000
--- a/app/code/Magento/Index/App/Shell.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/**
- * Index shell application
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\App;
-
-use Magento\Framework\App\Console\Response;
-use Magento\Framework\App\Bootstrap;
-use Magento\Framework\AppInterface;
-
-class Shell implements AppInterface
-{
-    /**
-     * Filename of the entry point script
-     *
-     * @var string
-     */
-    protected $_entryFileName;
-
-    /**
-     * @var \Magento\Index\Model\ShellFactory
-     */
-    protected $_shellFactory;
-
-    /**
-     * @var \Magento\Framework\App\Console\Response
-     */
-    protected $_response;
-
-    /**
-     * @param string $entryFileName
-     * @param \Magento\Index\Model\ShellFactory $shellFactory
-     * @param Response $response
-     */
-    public function __construct($entryFileName, \Magento\Index\Model\ShellFactory $shellFactory, Response $response)
-    {
-        $this->_entryFileName = $entryFileName;
-        $this->_shellFactory = $shellFactory;
-        $this->_response = $response;
-    }
-
-    /**
-     * Run application
-     *
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function launch()
-    {
-        /** @var $shell \Magento\Index\Model\Shell */
-        $shell = $this->_shellFactory->create(array('entryPoint' => $this->_entryFileName));
-        $shell->run();
-        if ($shell->hasErrors()) {
-            $this->_response->setCode(-1);
-        } else {
-            $this->_response->setCode(0);
-        }
-        return $this->_response;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function catchException(Bootstrap $bootstrap, \Exception $exception)
-    {
-        return false;
-    }
-}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process.php b/app/code/Magento/Index/Block/Adminhtml/Process.php
deleted file mode 100644
index 0b69d2f6563..00000000000
--- a/app/code/Magento/Index/Block/Adminhtml/Process.php
+++ /dev/null
@@ -1,39 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Block\Adminhtml;
-
-class Process extends \Magento\Backend\Block\Widget\Grid\Container
-{
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_blockGroup = 'Magento_Index';
-        $this->_controller = 'adminhtml_process';
-        $this->_headerText = __('Index Management');
-        parent::_construct();
-        $this->buttonList->remove('add');
-    }
-}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php b/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
deleted file mode 100644
index 959dc8a818a..00000000000
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
+++ /dev/null
@@ -1,106 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Block\Adminhtml\Process;
-
-class Edit extends \Magento\Backend\Block\Widget\Form\Container
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\Framework\Registry $registry,
-        array $data = array()
-    ) {
-        $this->_coreRegistry = $registry;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_objectId = 'process_id';
-        $this->_controller = 'adminhtml_process';
-        $this->_blockGroup = 'Magento_Index';
-
-        parent::_construct();
-
-        $this->buttonList->update('save', 'label', __('Save Process'));
-        if ($this->_coreRegistry->registry('current_index_process')) {
-            $this->buttonList->add(
-                'reindex',
-                array('label' => __('Reindex Data'), 'onclick' => "setLocation('{$this->getRunUrl()}')")
-            );
-        }
-        $this->buttonList->remove('reset');
-        $this->buttonList->remove('delete');
-    }
-
-    /**
-     * Get back button url
-     *
-     * @return string
-     */
-    public function getBackUrl()
-    {
-        return $this->getUrl('adminhtml/process/list');
-    }
-
-    /**
-     * Get process reindex action url
-     *
-     * @return string
-     */
-    public function getRunUrl()
-    {
-        return $this->getUrl(
-            'adminhtml/process/reindexProcess',
-            array('process' => $this->_coreRegistry->registry('current_index_process')->getId())
-        );
-    }
-
-    /**
-     * Retrieve text for header element depending on loaded page
-     *
-     * @return string
-     */
-    public function getHeaderText()
-    {
-        $process = $this->_coreRegistry->registry('current_index_process');
-        if ($process && $process->getId()) {
-            return __("'%1' Index Process Information", $process->getIndexer()->getName());
-        }
-    }
-}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tab/Main.php b/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tab/Main.php
deleted file mode 100644
index 2826f39441d..00000000000
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tab/Main.php
+++ /dev/null
@@ -1,131 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Block\Adminhtml\Process\Edit\Tab;
-
-use Magento\Backend\Block\Widget\Form;
-
-class Main extends \Magento\Backend\Block\Widget\Form\Generic implements \Magento\Backend\Block\Widget\Tab\TabInterface
-{
-    /**
-     * Prepare form
-     *
-     * @return Form
-     */
-    protected function _prepareForm()
-    {
-        $model = $this->_coreRegistry->registry('current_index_process');
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create();
-        $form->setHtmlIdPrefix('index_process_');
-        $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('General'), 'class' => 'fieldset-wide'));
-
-        $fieldset->addField('process_id', 'hidden', array('name' => 'process', 'value' => $model->getId()));
-
-        $fieldset->addField(
-            'name',
-            'note',
-            array(
-                'label' => __('Index Name'),
-                'title' => __('Index Name'),
-                'text' => '<strong>' . $model->getIndexer()->getName() . '</strong>'
-            )
-        );
-
-        $fieldset->addField(
-            'description',
-            'note',
-            array(
-                'label' => __('Index Description'),
-                'title' => __('Index Description'),
-                'text' => $model->getIndexer()->getDescription()
-            )
-        );
-
-        $fieldset->addField(
-            'mode',
-            'select',
-            array(
-                'label' => __('Index Mode'),
-                'title' => __('Index Mode'),
-                'name' => 'mode',
-                'value' => $model->getMode(),
-                'values' => $model->getModesOptions()
-            )
-        );
-
-        $this->setForm($form);
-        return parent::_prepareForm();
-    }
-
-    /**
-     * Prepare label for tab
-     *
-     * @return string
-     */
-    public function getTabLabel()
-    {
-        return __('Process Information');
-    }
-
-    /**
-     * Prepare title for tab
-     *
-     * @return string
-     */
-    public function getTabTitle()
-    {
-        return __('Process Information');
-    }
-
-    /**
-     * Returns status flag about this tab can be shown or not
-     *
-     * @return true
-     */
-    public function canShowTab()
-    {
-        return true;
-    }
-
-    /**
-     * Returns status flag about this tab hidden or not
-     *
-     * @return false
-     */
-    public function isHidden()
-    {
-        return false;
-    }
-
-    /**
-     * Check permission for passed action
-     *
-     * @param string $action
-     * @return true
-     */
-    protected function _isAllowedAction($action)
-    {
-        return true;
-    }
-}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Grid.php b/app/code/Magento/Index/Block/Adminhtml/Process/Grid.php
deleted file mode 100644
index 74e9efba01e..00000000000
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Grid.php
+++ /dev/null
@@ -1,326 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Block\Adminhtml\Process;
-
-class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
-{
-    /**
-     * Process model
-     *
-     * @var \Magento\Index\Model\Process
-     */
-    protected $_indexProcess;
-
-    /**
-     * Mass-action block
-     *
-     * @var string
-     */
-    protected $_massactionBlockName = 'Magento\Index\Block\Adminhtml\Process\Grid\Massaction';
-
-    /**
-     * Event repository
-     *
-     * @var \Magento\Index\Model\EventRepository
-     */
-    protected $_eventRepository;
-
-    /**
-     * @var \Magento\Index\Model\Resource\Process\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Backend\Helper\Data $backendHelper
-     * @param \Magento\Index\Model\Resource\Process\CollectionFactory $factory
-     * @param \Magento\Index\Model\Process $indexProcess
-     * @param \Magento\Index\Model\EventRepository $eventRepository
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Backend\Helper\Data $backendHelper,
-        \Magento\Index\Model\Resource\Process\CollectionFactory $factory,
-        \Magento\Index\Model\Process $indexProcess,
-        \Magento\Index\Model\EventRepository $eventRepository,
-        array $data = array()
-    ) {
-        parent::__construct($context, $backendHelper, $data);
-        $this->_eventRepository = $eventRepository;
-        $this->_indexProcess = $indexProcess;
-        $this->_collectionFactory = $factory;
-    }
-
-    /**
-     * Class constructor
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setId('indexer_processes_grid');
-        $this->setFilterVisibility(false);
-        $this->setPagerVisibility(false);
-    }
-
-    /**
-     * Prepare grid collection
-     *
-     * @return $this
-     */
-    protected function _prepareCollection()
-    {
-        $this->setCollection($this->_collectionFactory->create());
-        parent::_prepareCollection();
-
-        return $this;
-    }
-
-    /**
-     * Add name and description to collection elements
-     *
-     * @return $this
-     */
-    protected function _afterLoadCollection()
-    {
-        /** @var $item \Magento\Index\Model\Process */
-        foreach ($this->_collection as $key => $item) {
-            if (!$item->getIndexer()->isVisible()) {
-                $this->_collection->removeItemByKey($key);
-                continue;
-            }
-            $item->setName($item->getIndexer()->getName());
-            $item->setDescription($item->getIndexer()->getDescription());
-            $item->setUpdateRequired($this->_eventRepository->hasUnprocessed($item) ? 1 : 0);
-            if ($item->isLocked()) {
-                $item->setStatus(\Magento\Index\Model\Process::STATUS_RUNNING);
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Prepare grid columns
-     *
-     * @return $this
-     */
-    protected function _prepareColumns()
-    {
-        $this->addColumn(
-            'indexer_code',
-            array('header' => __('Index'), 'index' => 'name', 'sortable' => false)
-        );
-
-        $this->addColumn(
-            'description',
-            array('header' => __('Description'), 'index' => 'description', 'sortable' => false)
-        );
-
-        $this->addColumn(
-            'mode',
-            array(
-                'header' => __('Mode'),
-                'index' => 'mode',
-                'type' => 'options',
-                'options' => $this->_indexProcess->getModesOptions()
-            )
-        );
-
-        $this->addColumn(
-            'status',
-            array(
-                'header' => __('Status'),
-                'index' => 'status',
-                'type' => 'options',
-                'options' => $this->_indexProcess->getStatusesOptions(),
-                'frame_callback' => array($this, 'decorateStatus')
-            )
-        );
-
-        $this->addColumn(
-            'update_required',
-            array(
-                'header' => __('Update Required'),
-                'sortable' => false,
-                'index' => 'update_required',
-                'type' => 'options',
-                'options' => $this->_indexProcess->getUpdateRequiredOptions(),
-                'frame_callback' => array($this, 'decorateUpdateRequired')
-            )
-        );
-
-        $this->addColumn(
-            'ended_at',
-            array(
-                'header' => __('Updated'),
-                'type' => 'datetime',
-                'index' => 'ended_at',
-                'frame_callback' => array($this, 'decorateDate')
-            )
-        );
-
-        $this->addColumn(
-            'action',
-            array(
-                'header' => __('Action'),
-                'type' => 'action',
-                'getter' => 'getId',
-                'actions' => array(
-                    array(
-                        'caption' => __('Reindex Data'),
-                        'url' => array('base' => '*/*/reindexProcess'),
-                        'field' => 'process'
-                    )
-                ),
-                'filter' => false,
-                'sortable' => false,
-                'is_system' => true
-            )
-        );
-
-        parent::_prepareColumns();
-
-        return $this;
-    }
-
-    /**
-     * Decorate status column values
-     *
-     * @param string $value
-     * @param \Magento\Index\Model\Process $row
-     * @param \Magento\Backend\Block\Widget\Grid\Column $column
-     * @param bool $isExport
-     *
-     * @return string
-     */
-    public function decorateStatus($value, $row, $column, $isExport)
-    {
-        $class = '';
-        switch ($row->getStatus()) {
-            case \Magento\Index\Model\Process::STATUS_PENDING:
-                $class = 'grid-severity-notice';
-                break;
-            case \Magento\Index\Model\Process::STATUS_RUNNING:
-                $class = 'grid-severity-major';
-                break;
-            case \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX:
-                $class = 'grid-severity-critical';
-                break;
-        }
-        return '<span class="' . $class . '"><span>' . $value . '</span></span>';
-    }
-
-    /**
-     * Decorate "Update Required" column values
-     *
-     * @param string $value
-     * @param \Magento\Index\Model\Process $row
-     * @param \Magento\Backend\Block\Widget\Grid\Column $column
-     * @param bool $isExport
-     *
-     * @return string
-     */
-    public function decorateUpdateRequired($value, $row, $column, $isExport)
-    {
-        $class = '';
-        switch ($row->getUpdateRequired()) {
-            case 0:
-                $class = 'grid-severity-notice';
-                break;
-            case 1:
-                $class = 'grid-severity-critical';
-                break;
-        }
-        return '<span class="' . $class . '"><span>' . $value . '</span></span>';
-    }
-
-    /**
-     * Decorate last run date coumn
-     *
-     * @param string $value
-     * @param \Magento\Index\Model\Process $row
-     * @param \Magento\Backend\Block\Widget\Grid\Column $column
-     * @param bool $isExport
-     *
-     * @return string
-     */
-    public function decorateDate($value, $row, $column, $isExport)
-    {
-        if (!$value) {
-            return __('Never');
-        }
-        return $value;
-    }
-
-    /**
-     * Get row edit url
-     *
-     * @param \Magento\Index\Model\Process $row
-     *
-     * @return string
-     */
-    public function getRowUrl($row)
-    {
-        return $this->getUrl('adminhtml/*/edit', array('process' => $row->getId()));
-    }
-
-    /**
-     * Add mass-actions to grid
-     *
-     * @return $this
-     */
-    protected function _prepareMassaction()
-    {
-        $this->setMassactionIdField('process_id');
-        $this->getMassactionBlock()->setFormFieldName('process');
-
-        $modeOptions = $this->_indexProcess->getModesOptions();
-
-        $this->getMassactionBlock()->addItem(
-            'change_mode',
-            array(
-                'label' => __('Change Index Mode'),
-                'url' => $this->getUrl('adminhtml/*/massChangeMode'),
-                'additional' => array(
-                    'mode' => array(
-                        'name' => 'index_mode',
-                        'type' => 'select',
-                        'class' => 'required-entry',
-                        'label' => __('Index mode'),
-                        'values' => $modeOptions
-                    )
-                )
-            )
-        );
-
-        $this->getMassactionBlock()->addItem(
-            'reindex',
-            array('label' => __('Reindex Data'), 'url' => $this->getUrl('adminhtml/*/massReindex'), 'selected' => true)
-        );
-
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process.php b/app/code/Magento/Index/Controller/Adminhtml/Process.php
deleted file mode 100644
index 28b247780f7..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process.php
+++ /dev/null
@@ -1,92 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml;
-
-use Magento\Backend\App\Action;
-
-class Process extends \Magento\Backend\App\Action
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @var \Magento\Index\Model\ProcessFactory
-     */
-    protected $_processFactory;
-
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Index\Model\ProcessFactory $processFactory
-     * @param \Magento\Index\Model\Indexer $indexer
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\Registry $coreRegistry,
-        \Magento\Index\Model\ProcessFactory $processFactory,
-        \Magento\Index\Model\Indexer $indexer
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        $this->_processFactory = $processFactory;
-        $this->_indexer = $indexer;
-        parent::__construct($context);
-    }
-
-    /**
-     * Initialize process object by request
-     *
-     * @return \Magento\Index\Model\Process|false
-     */
-    protected function _initProcess()
-    {
-        $processId = $this->getRequest()->getParam('process');
-        if ($processId) {
-            /** @var $process \Magento\Index\Model\Process */
-            $process = $this->_processFactory->create()->load($processId);
-            if ($process->getId() && $process->getIndexer()->isVisible()) {
-                return $process;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check ACL permissins
-     *
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Index::index');
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php b/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php
deleted file mode 100644
index 3cd62ad5722..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php
+++ /dev/null
@@ -1,52 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml\Process;
-
-class Edit extends \Magento\Index\Controller\Adminhtml\Process
-{
-    /**
-     * Process detail and edit action
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            $this->_title->add($process->getIndexCode());
-            $this->_title->add(__('System'));
-            $this->_title->add(__('Index Management'));
-            $this->_title->add(__($process->getIndexer()->getName()));
-
-            $this->_coreRegistry->register('current_index_process', $process);
-            $this->_view->loadLayout();
-            $this->_view->renderLayout();
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-            $this->_redirect('adminhtml/*/list');
-        }
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php b/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php
deleted file mode 100644
index c5b05b84b50..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php
+++ /dev/null
@@ -1,61 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml\Process;
-
-class MassChangeMode extends \Magento\Index\Controller\Adminhtml\Process
-{
-    /**
-     * Mass change index mode of selected processes index
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $processIds = $this->getRequest()->getParam('process');
-        if (empty($processIds) || !is_array($processIds)) {
-            $this->messageManager->addError(__('Please select Index(es)'));
-        } else {
-            try {
-                $counter = 0;
-                $mode = $this->getRequest()->getParam('index_mode');
-                foreach ($processIds as $processId) {
-                    /* @var $process \Magento\Index\Model\Process */
-                    $process = $this->_processFactory->create()->load($processId);
-                    if ($process->getId() && $process->getIndexer()->isVisible()) {
-                        $process->setMode($mode)->save();
-                        $counter++;
-                    }
-                }
-                $this->messageManager->addSuccess(__('Total of %1 index(es) have changed index mode.', $counter));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
-            }
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php b/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php
deleted file mode 100644
index 175642f82fa..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php
+++ /dev/null
@@ -1,60 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml\Process;
-
-class MassReindex extends \Magento\Index\Controller\Adminhtml\Process
-{
-    /**
-     * Mass rebuild selected processes index
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $processIds = $this->getRequest()->getParam('process');
-        if (empty($processIds) || !is_array($processIds)) {
-            $this->messageManager->addError(__('Please select Indexes'));
-        } else {
-            try {
-                $counter = 0;
-                foreach ($processIds as $processId) {
-                    /* @var $process \Magento\Index\Model\Process */
-                    $process = $this->_indexer->getProcessById($processId);
-                    if ($process && $process->getIndexer()->isVisible()) {
-                        $process->reindexEverything();
-                        $counter++;
-                    }
-                }
-                $this->messageManager->addSuccess(__('Total of %1 index(es) have reindexed data.', $counter));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
-            }
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php
deleted file mode 100644
index 9cd0b6df8f7..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php
+++ /dev/null
@@ -1,56 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml\Process;
-
-class ReindexProcess extends \Magento\Index\Controller\Adminhtml\Process
-{
-    /**
-     * Reindex all data what process is responsible
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            try {
-                \Magento\Framework\Profiler::start('__INDEX_PROCESS_REINDEX_ALL__');
-
-                $process->reindexEverything();
-                \Magento\Framework\Profiler::stop('__INDEX_PROCESS_REINDEX_ALL__');
-                $this->messageManager->addSuccess(__('%1 index was rebuilt.', $process->getIndexer()->getName()));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('There was a problem with reindexing process.'));
-            }
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php b/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php
deleted file mode 100644
index af69f23f74f..00000000000
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php
+++ /dev/null
@@ -1,57 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Controller\Adminhtml\Process;
-
-class Save extends \Magento\Index\Controller\Adminhtml\Process
-{
-    /**
-     * Save process data
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            $mode = $this->getRequest()->getPost('mode');
-            if ($mode) {
-                $process->setMode($mode);
-            }
-            try {
-                $process->save();
-                $this->messageManager->addSuccess(__('The index has been saved.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('There was a problem with saving process.'));
-            }
-            $this->_redirect('adminhtml/*/list');
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-            $this->_redirect('adminhtml/*/list');
-        }
-    }
-}
diff --git a/app/code/Magento/Index/Model/Event.php b/app/code/Magento/Index/Model/Event.php
deleted file mode 100644
index eb4bfc0eb56..00000000000
--- a/app/code/Magento/Index/Model/Event.php
+++ /dev/null
@@ -1,384 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-use Magento\Index\Model\Indexer;
-
-/**
- * @method \Magento\Index\Model\Resource\Event _getResource()
- * @method \Magento\Index\Model\Resource\Event getResource()
- * @method \Magento\Index\Model\Event setType(string $value)
- * @method \Magento\Index\Model\Event setEntity(string $value)
- * @method int getEntityPk()
- * @method \Magento\Index\Model\Event setEntityPk(int $value)
- * @method string getCreatedAt()
- * @method \Magento\Index\Model\Event setCreatedAt(string $value)
- * @method \Magento\Index\Model\Event setOldData(string $value)
- * @method \Magento\Index\Model\Event setNewData(string $value)
- * @method \Magento\Framework\Object getDataObject()
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Event extends \Magento\Framework\Model\AbstractModel
-{
-    /**
-     * Predefined event types
-     */
-    const TYPE_SAVE = 'save';
-
-    const TYPE_DELETE = 'delete';
-
-    const TYPE_MASS_ACTION = 'mass_action';
-
-    const TYPE_REINDEX = 'reindex';
-
-    /**
-     * Array of related processes ids
-     * @var array
-     */
-    protected $_processIds = null;
-
-    /**
-     * New and old data namespace. Used for separate processes data
-     *
-     * @var string
-     */
-    protected $_dataNamespace = null;
-
-    /**
-     * Process object which currently working with event
-     *
-     * @var null|Process $process
-     */
-    protected $_process = null;
-
-    /**
-     * @var Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime
-     */
-    protected $dateTime;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param Indexer $indexer
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        Indexer $indexer,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        $this->_indexer = $indexer;
-        $this->dateTime = $dateTime;
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-    }
-
-    /**
-     * Initialize resource
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Index\Model\Resource\Event');
-    }
-
-    /**
-     * Specify process object
-     *
-     * @param null|\Magento\Index\Model\Process $process
-     * @return $this
-     */
-    public function setProcess($process)
-    {
-        $this->_process = $process;
-        return $this;
-    }
-
-    /**
-     * Get related process object
-     *
-     * @return Process|null
-     */
-    public function getProcess()
-    {
-        return $this->_process;
-    }
-
-    /**
-     * Specify namespace for old and new data
-     *
-     * @param string $namespace
-     * @return $this
-     */
-    public function setDataNamespace($namespace)
-    {
-        $this->_dataNamespace = $namespace;
-        return $this;
-    }
-
-    /**
-     * Reset old and new data arrays
-     *
-     * @return $this
-     */
-    public function resetData()
-    {
-        if ($this->_dataNamespace) {
-            $data = $this->getNewData(false);
-            $data[$this->_dataNamespace] = null;
-            $this->setNewData($data);
-        } else {
-            $this->setNewData(array());
-        }
-        return $this;
-    }
-
-    /**
-     * Add process id to event object
-     *
-     * @param string|int $processId
-     * @param string $status
-     * @return  $this
-     */
-    public function addProcessId($processId, $status = \Magento\Index\Model\Process::EVENT_STATUS_NEW)
-    {
-        $this->_processIds[$processId] = $status;
-        return $this;
-    }
-
-    /**
-     * Get event process ids
-     *
-     * @return array
-     */
-    public function getProcessIds()
-    {
-        return $this->_processIds;
-    }
-
-    /**
-     * Merge new data
-     *
-     * @param array $previous
-     * @param mixed $current
-     * @return array
-     */
-    protected function _mergeNewDataRecursive($previous, $current)
-    {
-        if (!is_array($current)) {
-            if (!is_null($current)) {
-                $previous[] = $current;
-            }
-            return $previous;
-        }
-
-        foreach ($previous as $key => $value) {
-            if (array_key_exists($key, $current) && !is_null($current[$key]) && is_array($previous[$key])) {
-                if (!is_string($key) || is_array($current[$key])) {
-                    $current[$key] = $this->_mergeNewDataRecursive($previous[$key], $current[$key]);
-                }
-            } elseif (!array_key_exists($key, $current) || is_null($current[$key])) {
-                $current[$key] = $previous[$key];
-            } elseif (!is_array($previous[$key]) && !is_string($key)) {
-                $current[] = $previous[$key];
-            }
-        }
-
-        return $current;
-    }
-
-    /**
-     * Merge previous event data to object.
-     * Used for events duplicated protection
-     *
-     * @param array $data
-     * @return $this
-     */
-    public function mergePreviousData($data)
-    {
-        if (!empty($data['event_id'])) {
-            $this->setId($data['event_id']);
-            $this->setCreatedAt($data['created_at']);
-        }
-
-        if (!empty($data['new_data'])) {
-            $previousNewData = unserialize($data['new_data']);
-            $currentNewData = $this->getNewData(false);
-            $currentNewData = $this->_mergeNewDataRecursive($previousNewData, $currentNewData);
-            $this->setNewData(serialize($currentNewData));
-        }
-        return $this;
-    }
-
-    /**
-     * Clean new data, unset data for done processes
-     *
-     * @return $this
-     */
-    public function cleanNewData()
-    {
-        $processIds = $this->getProcessIds();
-        if (!is_array($processIds) || empty($processIds)) {
-            return $this;
-        }
-
-        $newData = $this->getNewData(false);
-        foreach ($processIds as $processId => $processStatus) {
-            if ($processStatus == \Magento\Index\Model\Process::EVENT_STATUS_DONE) {
-                $process = $this->_indexer->getProcessById($processId);
-                if ($process) {
-                    $namespace = get_class($process->getIndexer());
-                    if (array_key_exists($namespace, $newData)) {
-                        unset($newData[$namespace]);
-                    }
-                }
-            }
-        }
-        $this->setNewData(serialize($newData));
-
-        return $this;
-    }
-
-    /**
-     * Get event old data array
-     *
-     * @param bool $useNamespace
-     * @return array
-     *
-     * @deprecated since 1.6.2.0
-     */
-    public function getOldData($useNamespace = true)
-    {
-        return array();
-    }
-
-    /**
-     * Get event new data array
-     *
-     * @param bool $useNamespace
-     * @return array
-     */
-    public function getNewData($useNamespace = true)
-    {
-        $data = $this->_getData('new_data');
-        if (is_string($data)) {
-            $data = unserialize($data);
-        } elseif (empty($data) || !is_array($data)) {
-            $data = array();
-        }
-        if ($useNamespace && $this->_dataNamespace) {
-            return isset($data[$this->_dataNamespace]) ? $data[$this->_dataNamespace] : array();
-        }
-        return $data;
-    }
-
-    /**
-     * Add new values to old data array (overwrite if value with same key exist)
-     *
-     * @param array|string $key
-     * @param null|mixed $value
-     * @return $this
-     *
-     * @deprecated since 1.6.2.0
-     */
-    public function addOldData($key, $value = null)
-    {
-        return $this;
-    }
-
-    /**
-     * Add new values to new data array (overwrite if value with same key exist)
-     *
-     * @param array|string $key
-     * @param null|mixed $value
-     * @return $this
-     */
-    public function addNewData($key, $value = null)
-    {
-        $newData = $this->getNewData(false);
-        if (!is_array($key)) {
-            $key = array($key => $value);
-        }
-        if ($this->_dataNamespace) {
-            if (!isset($newData[$this->_dataNamespace])) {
-                $newData[$this->_dataNamespace] = array();
-            }
-            $newData[$this->_dataNamespace] = array_merge($newData[$this->_dataNamespace], $key);
-        } else {
-            $newData = array_merge($newData, $key);
-        }
-        $this->setNewData($newData);
-        return $this;
-    }
-
-    /**
-     * Get event entity code.
-     * Entity code declare what kind of data object related with event (product, category etc.)
-     *
-     * @return string
-     */
-    public function getEntity()
-    {
-        return $this->_getData('entity');
-    }
-
-    /**
-     * Get event action type.
-     * Data related on self::TYPE_* constants
-     *
-     * @return string
-     */
-    public function getType()
-    {
-        return $this->_getData('type');
-    }
-
-    /**
-     * Serelaize old and new data arrays before saving
-     *
-     * @return $this
-     */
-    protected function _beforeSave()
-    {
-        $newData = $this->getNewData(false);
-        $this->setNewData(serialize($newData));
-        if (!$this->hasCreatedAt()) {
-            $this->setCreatedAt($this->dateTime->formatDate(time(), true));
-        }
-        return parent::_beforeSave();
-    }
-}
diff --git a/app/code/Magento/Index/Model/EventRepository.php b/app/code/Magento/Index/Model/EventRepository.php
deleted file mode 100644
index 3a62a9d096f..00000000000
--- a/app/code/Magento/Index/Model/EventRepository.php
+++ /dev/null
@@ -1,68 +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.
- * 
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-use Magento\Index\Model\Resource\Event\Collection;
-
-class EventRepository
-{
-    /**
-     * Event collection factory
-     *
-     * @var \Magento\Index\Model\Resource\Event\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @param \Magento\Index\Model\Resource\Event\CollectionFactory $collectionFactory
-     */
-    public function __construct(\Magento\Index\Model\Resource\Event\CollectionFactory $collectionFactory)
-    {
-        $this->_collectionFactory = $collectionFactory;
-    }
-
-    /**
-     * Check whether unprocessed events exist for provided process
-     *
-     * @param int|array|Process $process
-     * @return bool
-     */
-    public function hasUnprocessed($process)
-    {
-        return (bool)$this->getUnprocessed($process)->getSize();
-    }
-
-    /**
-     * Retrieve list of unprocessed events
-     *
-     * @param int|array|Process $process
-     * @return Collection
-     */
-    public function getUnprocessed($process)
-    {
-        $collection = $this->_collectionFactory->create();
-        $collection->addProcessFilter($process, \Magento\Index\Model\Process::EVENT_STATUS_NEW);
-        return $collection;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Indexer.php b/app/code/Magento/Index/Model/Indexer.php
deleted file mode 100644
index d8ec300c330..00000000000
--- a/app/code/Magento/Index/Model/Indexer.php
+++ /dev/null
@@ -1,339 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-use Magento\Framework\Event\ManagerInterface;
-use Magento\Index\Model\Resource\Process as ResourceProcess;
-use Magento\Index\Model\Resource\Process\Collection;
-
-/**
- * Indexer strategy
- */
-class Indexer
-{
-    /**
-     * Collection of available processes
-     *
-     * @var \Magento\Index\Model\Resource\Process\Collection
-     */
-    protected $_processesCollection;
-
-    /**
-     * @var ResourceProcess
-     */
-    protected $_resourceProcess;
-
-    /**
-     * Core event manager proxy
-     *
-     * @var ManagerInterface
-     */
-    protected $_eventManager = null;
-
-    /**
-     * @var \Magento\Index\Model\EventFactory
-     */
-    protected $_indexEventFactory;
-
-    /**
-     * @var \Magento\Index\Model\Resource\Process\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @param \Magento\Index\Model\Resource\Process\CollectionFactory $collectionFactory
-     * @param ResourceProcess $resourceProcess
-     * @param ManagerInterface $eventManager
-     * @param \Magento\Index\Model\EventFactory $indexEventFactory
-     */
-    public function __construct(
-        \Magento\Index\Model\Resource\Process\CollectionFactory $collectionFactory,
-        ResourceProcess $resourceProcess,
-        ManagerInterface $eventManager,
-        \Magento\Index\Model\EventFactory $indexEventFactory
-    ) {
-        $this->_collectionFactory = $collectionFactory;
-        $this->_resourceProcess = $resourceProcess;
-        $this->_eventManager = $eventManager;
-        $this->_indexEventFactory = $indexEventFactory;
-        $this->_processesCollection = $this->_createCollection();
-    }
-
-    /**
-     * @return \Magento\Index\Model\Resource\Process\Collection
-     */
-    private function _createCollection()
-    {
-        return $this->_collectionFactory->create();
-    }
-
-    /**
-     * Get collection of all available processes
-     *
-     * @return \Magento\Index\Model\Resource\Process\Collection
-     */
-    public function getProcessesCollection()
-    {
-        return $this->_processesCollection;
-    }
-
-    /**
-     * Get index process by specific id
-     *
-     * @param int $processId
-     * @return false|Process
-     */
-    public function getProcessById($processId)
-    {
-        foreach ($this->_processesCollection as $process) {
-            if ($process->getId() == $processId) {
-                return $process;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Get index process by specific code
-     *
-     * @param string $code
-     * @return false|Process
-     */
-    public function getProcessByCode($code)
-    {
-        foreach ($this->_processesCollection as $process) {
-            if ($process->getIndexerCode() == $code) {
-                return $process;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Indexing all pending events.
-     * Events set can be limited by event entity and type
-     *
-     * @param   null|string $entity
-     * @param   null|string $type
-     * @return  $this
-     * @throws \Exception
-     */
-    public function indexEvents($entity = null, $type = null)
-    {
-        $this->_eventManager->dispatch('start_index_events' . $this->_getEventTypeName($entity, $type));
-        $this->_resourceProcess->beginTransaction();
-        try {
-            $this->_runAll('indexEvents', array($entity, $type));
-            $this->_resourceProcess->commit();
-        } catch (\Exception $e) {
-            $this->_resourceProcess->rollBack();
-            throw $e;
-        }
-        $this->_eventManager->dispatch('end_index_events' . $this->_getEventTypeName($entity, $type));
-        return $this;
-    }
-
-    /**
-     * Index one event by all processes
-     *
-     * @param   Event $event
-     * @return  $this
-     */
-    public function indexEvent(Event $event)
-    {
-        $this->_runAll('safeProcessEvent', array($event));
-        return $this;
-    }
-
-    /**
-     * Register event in each indexing process process
-     *
-     * @param Event $event
-     * @return $this
-     */
-    public function registerEvent(Event $event)
-    {
-        $this->_runAll('register', array($event));
-        return $this;
-    }
-
-    /**
-     * Create new event log and register event in all processes
-     *
-     * @param   \Magento\Framework\Object $entity
-     * @param   string $entityType
-     * @param   string $eventType
-     * @param   bool $doSave
-     * @return  Event
-     */
-    public function logEvent(\Magento\Framework\Object $entity, $entityType, $eventType, $doSave = true)
-    {
-        $event = $this->_indexEventFactory->create()->setEntity(
-            $entityType
-        )->setType(
-            $eventType
-        )->setDataObject(
-            $entity
-        )->setEntityPk(
-            $entity->getId()
-        );
-
-        $this->registerEvent($event);
-        if ($doSave) {
-            $event->save();
-        }
-        return $event;
-    }
-
-    /**
-     * Create new event log and register event in all processes.
-     * Initiate events indexing procedure.
-     *
-     * @param   \Magento\Framework\Object $entity
-     * @param   string $entityType
-     * @param   string $eventType
-     * @return  $this
-     * @throws \Exception
-     */
-    public function processEntityAction(\Magento\Framework\Object $entity, $entityType, $eventType)
-    {
-        $event = $this->logEvent($entity, $entityType, $eventType, false);
-        /**
-         * Index and save event just in case if some process matched it
-         */
-        if ($event->getProcessIds()) {
-            $this->_eventManager->dispatch('start_process_event' . $this->_getEventTypeName($entityType, $eventType));
-            $this->_resourceProcess->beginTransaction();
-            try {
-                $this->indexEvent($event);
-                $this->_resourceProcess->commit();
-            } catch (\Exception $e) {
-                $this->_resourceProcess->rollBack();
-                throw $e;
-            }
-            $event->save();
-            $this->_eventManager->dispatch('end_process_event' . $this->_getEventTypeName($entityType, $eventType));
-        }
-        return $this;
-    }
-
-    /**
-     * Reindex all processes
-     *
-     * @return void
-     */
-    public function reindexAll()
-    {
-        $this->_reindexCollection($this->_createCollection());
-    }
-
-    /**
-     * Reindex only processes that are invalidated
-     *
-     * @return void
-     */
-    public function reindexRequired()
-    {
-        $collection = $this->_createCollection();
-        $collection->addFieldToFilter('status', \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX);
-        $this->_reindexCollection($collection);
-    }
-
-    /**
-     * Sub-routine for iterating collection and reindexing all processes of specified collection
-     *
-     * @param Collection $collection
-     * @return void
-     */
-    private function _reindexCollection(Collection $collection)
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        foreach ($collection as $process) {
-            $process->reindexEverything();
-        }
-    }
-
-    /**
-     * Run all processes method with parameters
-     * Run by depends priority
-     * Not recursive call is not implement
-     *
-     * @param string $method
-     * @param array $args
-     * @return void
-     */
-    protected function _runAll($method, $args)
-    {
-        $checkLocks = $method != 'register';
-        $processed = array();
-        foreach ($this->_processesCollection as $process) {
-            $code = $process->getIndexerCode();
-            if (in_array($code, $processed)) {
-                continue;
-            }
-            $hasLocks = false;
-
-            if ($process->getDepends()) {
-                foreach ($process->getDepends() as $processCode) {
-                    $dependProcess = $this->getProcessByCode($processCode);
-                    if ($dependProcess && !in_array($processCode, $processed)) {
-                        if ($checkLocks && $dependProcess->isLocked()) {
-                            $hasLocks = true;
-                        } else {
-                            call_user_func_array(array($dependProcess, $method), $args);
-                            if ($checkLocks && $dependProcess->getMode() == \Magento\Index\Model\Process::MODE_MANUAL
-                            ) {
-                                $hasLocks = true;
-                            } else {
-                                $processed[] = $processCode;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (!$hasLocks) {
-                call_user_func_array(array($process, $method), $args);
-                $processed[] = $code;
-            }
-        }
-    }
-
-    /**
-     * Get event type name
-     *
-     * @param null|string $entityType
-     * @param null|string $eventType
-     * @return string
-     */
-    protected function _getEventTypeName($entityType = null, $eventType = null)
-    {
-        $eventName = $entityType . '_' . $eventType;
-        $eventName = trim($eventName, '_');
-        if (!empty($eventName)) {
-            $eventName = '_' . $eventName;
-        }
-        return $eventName;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php b/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
deleted file mode 100644
index e3156dca525..00000000000
--- a/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
+++ /dev/null
@@ -1,181 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Abstract index process class
- * Predefine list of methods required by indexer
- */
-namespace Magento\Index\Model\Indexer;
-
-use Magento\Index\Model\Event;
-use Magento\Index\Model\IndexerInterface;
-
-abstract class AbstractIndexer extends \Magento\Framework\Model\AbstractModel implements IndexerInterface
-{
-    /**
-     * @var array
-     */
-    protected $_matchedEntities = array();
-
-    /**
-     * Whether the indexer should be displayed on process/list page
-     *
-     * @var bool
-     */
-    protected $_isVisible = true;
-
-    /**
-     * Get Indexer name
-     *
-     * @return string
-     */
-    abstract public function getName();
-
-    /**
-     * Get Indexer description
-     *
-     * @return string
-     */
-    public function getDescription()
-    {
-        return '';
-    }
-
-    /**
-     * Register indexer required data inside event object
-     *
-     * @param   Event $event
-     * @return  void
-     */
-    abstract protected function _registerEvent(Event $event);
-
-    /**
-     * Process event based on event state data
-     *
-     * @param   Event $event
-     * @return  $this
-     */
-    abstract protected function _processEvent(Event $event);
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param Event $event
-     * @return IndexerInterface
-     */
-    public function register(Event $event)
-    {
-        if ($this->matchEvent($event)) {
-            $this->_registerEvent($event);
-        }
-        return $this;
-    }
-
-    /**
-     * Process event
-     *
-     * @param   Event $event
-     * @return  $this
-     */
-    public function processEvent(Event $event)
-    {
-        if ($this->matchEvent($event)) {
-            $this->_processEvent($event);
-        }
-        return $this;
-    }
-
-    /**
-     * Check if event can be matched by process
-     *
-     * @param Event $event
-     * @return bool
-     */
-    public function matchEvent(Event $event)
-    {
-        $entity = $event->getEntity();
-        $type = $event->getType();
-        return $this->matchEntityAndType($entity, $type);
-    }
-
-    /**
-     * Check if indexer matched specific entity and action type
-     *
-     * @param   string $entity
-     * @param   string $type
-     * @return  bool
-     */
-    public function matchEntityAndType($entity, $type)
-    {
-        if (isset($this->_matchedEntities[$entity])) {
-            if (in_array($type, $this->_matchedEntities[$entity])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Rebuild all index data
-     *
-     * @return  void
-     */
-    public function reindexAll()
-    {
-        $this->_getResource()->reindexAll();
-    }
-
-    /**
-     * Try dynamicly detect and call event handler from resource model.
-     * Handler name will be generated from event entity and type code
-     *
-     * @param   Event $event
-     * @return  $this
-     */
-    public function callEventHandler(Event $event)
-    {
-        if ($event->getEntity()) {
-            $method = $event->getEntity() . '_' . $event->getType();
-        } else {
-            $method = $event->getType();
-        }
-        $method = str_replace(' ', '', ucwords(str_replace('_', ' ', $method)));
-
-        $resourceModel = $this->_getResource();
-        if (method_exists($resourceModel, $method)) {
-            $resourceModel->{$method}($event);
-        }
-        return $this;
-    }
-
-    /**
-     * Whether the indexer should be displayed on process/list page
-     *
-     * @return bool
-     */
-    public function isVisible()
-    {
-        return $this->_isVisible;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Indexer/Config.php b/app/code/Magento/Index/Model/Indexer/Config.php
deleted file mode 100644
index 3cde009d3ae..00000000000
--- a/app/code/Magento/Index/Model/Indexer/Config.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/**
- * Indexer configuration model
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer;
-
-class Config extends \Magento\Framework\Config\Data\Scoped implements \Magento\Index\Model\Indexer\ConfigInterface
-{
-    /**
-     * Scope priority loading scheme
-     *
-     * @var string[]
-     */
-    protected $_scopePriorityScheme = array('global');
-
-    /**
-     * @param \Magento\Index\Model\Indexer\Config\Reader $reader
-     * @param \Magento\Framework\Config\ScopeInterface $configScope
-     * @param \Magento\Framework\Config\CacheInterface $cache
-     * @param string $cacheId
-     */
-    public function __construct(
-        \Magento\Index\Model\Indexer\Config\Reader $reader,
-        \Magento\Framework\Config\ScopeInterface $configScope,
-        \Magento\Framework\Config\CacheInterface $cache,
-        $cacheId = 'indexerConfigCache'
-    ) {
-        parent::__construct($reader, $configScope, $cache, $cacheId);
-    }
-
-    /**
-     * Get indexer data by name
-     *
-     * @param string $name
-     * @return array
-     */
-    public function getIndexer($name)
-    {
-        return $this->get($name, array());
-    }
-
-    /**
-     * Get indexers configuration
-     *
-     * @return array
-     */
-    public function getAll()
-    {
-        return $this->get();
-    }
-}
diff --git a/app/code/Magento/Index/Model/Indexer/Config/Converter.php b/app/code/Magento/Index/Model/Indexer/Config/Converter.php
deleted file mode 100644
index 3f25fee98d0..00000000000
--- a/app/code/Magento/Index/Model/Indexer/Config/Converter.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * Indexers configuration converter
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer\Config;
-
-class Converter implements \Magento\Framework\Config\ConverterInterface
-{
-    /**
-     * Convert config
-     *
-     * @param mixed $source
-     * @return array
-     */
-    public function convert($source)
-    {
-        $output = array();
-
-        /** @var \DOMNodeList $indexers */
-        $indexers = $source->getElementsByTagName('indexer');
-
-        /** @var DOMNode $indexer */
-        foreach ($indexers as $indexer) {
-            $indexerConfig = array();
-            foreach ($indexer->attributes as $attribute) {
-                $indexerConfig[$attribute->nodeName] = $attribute->nodeValue;
-            }
-
-            $dependencies = array();
-            /** @var DOMNode $dependency */
-            foreach ($indexer->getElementsByTagName('depends') as $dependency) {
-                $dependencies[] = $dependency->attributes->getNamedItem('name')->nodeValue;
-            }
-            $indexerConfig['depends'] = $dependencies;
-            $output[$indexer->attributes->getNamedItem('name')->nodeValue] = $indexerConfig;
-        }
-
-        return $output;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Indexer/Config/SchemaLocator.php b/app/code/Magento/Index/Model/Indexer/Config/SchemaLocator.php
deleted file mode 100644
index e50a5d31620..00000000000
--- a/app/code/Magento/Index/Model/Indexer/Config/SchemaLocator.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/**
- * Indexer configuration schema locator
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer\Config;
-
-class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
-{
-    /**
-     * Path to corresponding XSD file with validation rules for merged config
-     *
-     * @var string
-     */
-    protected $_schema = null;
-
-    /**
-     * Path to corresponding XSD file with validation rules for separate config files
-     *
-     * @var string
-     */
-    protected $_perFileSchema = null;
-
-    /**
-     * @param \Magento\Framework\Module\Dir\Reader $moduleReader
-     */
-    public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
-    {
-        $this->_schema = $moduleReader->getModuleDir('etc', 'Magento_Index') . '/indexers_merged.xsd';
-        $this->_perFileSchema = $moduleReader->getModuleDir('etc', 'Magento_Index') . '/indexers.xsd';
-    }
-
-    /**
-     * Get path to merged config schema
-     *
-     * @return string|null
-     */
-    public function getSchema()
-    {
-        return $this->_schema;
-    }
-
-    /**
-     * Get path to pre file validation schema
-     *
-     * @return string|null
-     */
-    public function getPerFileSchema()
-    {
-        return $this->_perFileSchema;
-    }
-}
diff --git a/app/code/Magento/Index/Model/IndexerInterface.php b/app/code/Magento/Index/Model/IndexerInterface.php
deleted file mode 100644
index 4587409710c..00000000000
--- a/app/code/Magento/Index/Model/IndexerInterface.php
+++ /dev/null
@@ -1,100 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-/**
- * Indexer interface
- */
-interface IndexerInterface
-{
-    /**
-     * Get indexer name
-     *
-     * @return mixed
-     */
-    public function getName();
-
-    /**
-     * Get Indexer description
-     *
-     * @return string
-     */
-    public function getDescription();
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function register(\Magento\Index\Model\Event $event);
-
-    /**
-     * Process event
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function processEvent(\Magento\Index\Model\Event $event);
-
-    /**
-     * Check if event can be matched by process
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return bool
-     */
-    public function matchEvent(\Magento\Index\Model\Event $event);
-
-    /**
-     * Check if indexer matched specific entity and action type
-     *
-     * @param   string $entity
-     * @param   string $type
-     * @return  bool
-     */
-    public function matchEntityAndType($entity, $type);
-
-    /**
-     * Rebuild all index data
-     *
-     * @return void
-     */
-    public function reindexAll();
-
-    /**
-     * Try dynamicly detect and call event hanler from resource model.
-     * Handler name will be generated from event entity and type code
-     *
-     * @param   \Magento\Index\Model\Event $event
-     * @return  \Magento\Index\Model\Indexer\AbstractIndexer
-     */
-    public function callEventHandler(\Magento\Index\Model\Event $event);
-
-    /**
-     * Whether the indexer should be displayed on process/list page
-     *
-     * @return bool
-     */
-    public function isVisible();
-}
diff --git a/app/code/Magento/Index/Model/Lock/Storage.php b/app/code/Magento/Index/Model/Lock/Storage.php
deleted file mode 100644
index 8916c347de9..00000000000
--- a/app/code/Magento/Index/Model/Lock/Storage.php
+++ /dev/null
@@ -1,83 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Lock file storage for index processes
- */
-namespace Magento\Index\Model\Lock;
-
-use Magento\Index\Model\Process\File;
-use Magento\Index\Model\Process\FileFactory;
-use Magento\Framework\App\Filesystem;
-use Magento\Framework\Filesystem\Directory\WriteInterface;
-
-class Storage
-{
-    /**
-     * @var FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * File handlers by process IDs
-     *
-     * @var array
-     */
-    protected $_fileHandlers = array();
-
-    /**
-     * Directory instance
-     *
-     * @var WriteInterface
-     */
-    protected $_varDirectory;
-
-    /**
-     * @param FileFactory $fileFactory
-     * @param Filesystem $filesystem
-     */
-    public function __construct(FileFactory $fileFactory, Filesystem $filesystem)
-    {
-        $this->_fileFactory = $fileFactory;
-        $this->_varDirectory = $filesystem->getDirectoryWrite(Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Get file handler by process ID
-     *
-     * @param string $processId
-     * @return File
-     */
-    public function getFile($processId)
-    {
-        if (!isset($this->_fileHandlers[$processId])) {
-            $this->_varDirectory->create('locks');
-            $fileName = 'locks/index_process_' . $processId . '.lock';
-            $stream = $this->_varDirectory->openFile($fileName, 'w+');
-            $stream->write(date('r'));
-            $this->_fileHandlers[$processId] = $this->_fileFactory->create(array('streamHandler' => $stream));
-        }
-        return $this->_fileHandlers[$processId];
-    }
-}
diff --git a/app/code/Magento/Index/Model/Observer.php b/app/code/Magento/Index/Model/Observer.php
deleted file mode 100644
index 31597e4bbe2..00000000000
--- a/app/code/Magento/Index/Model/Observer.php
+++ /dev/null
@@ -1,154 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-use Magento\Framework\Event\Observer as EventObserver;
-
-class Observer
-{
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @param \Magento\Index\Model\Indexer $indexer
-     */
-    public function __construct(\Magento\Index\Model\Indexer $indexer)
-    {
-        $this->_indexer = $indexer;
-    }
-
-    /**
-     * Store after commit observer. Process store related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processStoreSave(EventObserver $observer)
-    {
-        $store = $observer->getEvent()->getStore();
-        $this->_indexer->processEntityAction(
-            $store,
-            \Magento\Store\Model\Store::ENTITY,
-            \Magento\Index\Model\Event::TYPE_SAVE
-        );
-    }
-
-    /**
-     * Store group after commit observer. Process store group related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processStoreGroupSave(EventObserver $observer)
-    {
-        $storeGroup = $observer->getEvent()->getStoreGroup();
-        $this->_indexer->processEntityAction(
-            $storeGroup,
-            \Magento\Store\Model\Store::ENTITY,
-            \Magento\Index\Model\Event::TYPE_SAVE
-        );
-    }
-
-    /**
-     * Website save after commit observer. Process website related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processWebsiteSave(EventObserver $observer)
-    {
-        $website = $observer->getEvent()->getWebsite();
-        $this->_indexer->processEntityAction(
-            $website,
-            \Magento\Store\Model\Website::ENTITY,
-            \Magento\Index\Model\Event::TYPE_SAVE
-        );
-    }
-
-    /**
-     * Store after commit observer. Process store related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processStoreDelete(EventObserver $observer)
-    {
-        $store = $observer->getEvent()->getStore();
-        $this->_indexer->processEntityAction(
-            $store,
-            \Magento\Store\Model\Store::ENTITY,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        );
-    }
-
-    /**
-     * Store group after commit observer. Process store group related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processStoreGroupDelete(EventObserver $observer)
-    {
-        $storeGroup = $observer->getEvent()->getStoreGroup();
-        $this->_indexer->processEntityAction(
-            $storeGroup,
-            \Magento\Store\Model\Store::ENTITY,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        );
-    }
-
-    /**
-     * Website save after commit observer. Process website related indexes
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processWebsiteDelete(EventObserver $observer)
-    {
-        $website = $observer->getEvent()->getWebsite();
-        $this->_indexer->processEntityAction(
-            $website,
-            \Magento\Store\Model\Website::ENTITY,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        );
-    }
-
-    /**
-     * Config data after commit observer.
-     *
-     * @param EventObserver $observer
-     * @return void
-     */
-    public function processConfigDataSave(EventObserver $observer)
-    {
-        $configData = $observer->getEvent()->getConfigData();
-        $this->_indexer->processEntityAction(
-            $configData,
-            \Magento\Framework\App\Config\ValueInterface::ENTITY,
-            \Magento\Index\Model\Event::TYPE_SAVE
-        );
-    }
-}
diff --git a/app/code/Magento/Index/Model/Process.php b/app/code/Magento/Index/Model/Process.php
deleted file mode 100644
index 72aecfe8341..00000000000
--- a/app/code/Magento/Index/Model/Process.php
+++ /dev/null
@@ -1,634 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-use Magento\Index\Model\Resource\Event\Collection;
-
-/**
- * @method \Magento\Index\Model\Resource\Process _getResource()
- * @method \Magento\Index\Model\Resource\Process getResource()
- * @method string getIndexerCode()
- * @method \Magento\Index\Model\Process setIndexerCode(string $value)
- * @method string getStatus()
- * @method \Magento\Index\Model\Process setStatus(string $value)
- * @method string getStartedAt()
- * @method \Magento\Index\Model\Process setStartedAt(string $value)
- * @method string getEndedAt()
- * @method \Magento\Index\Model\Process setEndedAt(string $value)
- * @method string getMode()
- * @method \Magento\Index\Model\Process setMode(string $value)
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Process extends \Magento\Framework\Model\AbstractModel
-{
-    /**
-     * Process statuses
-     */
-    const STATUS_RUNNING = 'working';
-
-    const STATUS_PENDING = 'pending';
-
-    const STATUS_REQUIRE_REINDEX = 'require_reindex';
-
-    /**
-     * Process event statuses
-     */
-    const EVENT_STATUS_NEW = 'new';
-
-    const EVENT_STATUS_DONE = 'done';
-
-    const EVENT_STATUS_ERROR = 'error';
-
-    const EVENT_STATUS_WORKING = 'working';
-
-    /**
-     * Process modes
-     * Process mode allow disable automatic process events processing
-     */
-    const MODE_MANUAL = 'manual';
-
-    const MODE_REAL_TIME = 'real_time';
-
-    /**
-     * Indexer stategy object
-     *
-     * @var \Magento\Index\Model\Indexer\AbstractIndexer
-     */
-    protected $_currentIndexer;
-
-    /**
-     * Lock file entity storage
-     *
-     * @var \Magento\Index\Model\Lock\Storage
-     */
-    protected $_lockStorage;
-
-    /**
-     * Instance of current process file
-     *
-     * @var \Magento\Index\Model\Process\File
-     */
-    protected $_processFile;
-
-    /**
-     * Event repostiory
-     *
-     * @var \Magento\Index\Model\EventRepository
-     */
-    protected $_eventRepository;
-
-    /**
-     * @var \Magento\Index\Model\IndexerFactory
-     */
-    protected $_indexerFactory;
-
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @var \Magento\Index\Model\Resource\Event
-     */
-    protected $_resourceEvent;
-
-    /**
-     * @var \Magento\Index\Model\Indexer\ConfigInterface
-     */
-    protected $_indexerConfig;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Index\Model\Resource\Event $resourceEvent
-     * @param \Magento\Index\Model\Indexer\Factory $indexerFactory
-     * @param \Magento\Index\Model\Indexer $indexer
-     * @param \Magento\Index\Model\Indexer\ConfigInterface $indexerConfig
-     * @param \Magento\Index\Model\Lock\Storage $lockStorage
-     * @param \Magento\Index\Model\EventRepository $eventRepository
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Index\Model\Resource\Event $resourceEvent,
-        \Magento\Index\Model\Indexer\Factory $indexerFactory,
-        \Magento\Index\Model\Indexer $indexer,
-        \Magento\Index\Model\Indexer\ConfigInterface $indexerConfig,
-        \Magento\Index\Model\Lock\Storage $lockStorage,
-        \Magento\Index\Model\EventRepository $eventRepository,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-        $this->_indexerConfig = $indexerConfig;
-        $this->_indexerFactory = $indexerFactory;
-        $this->_indexer = $indexer;
-        $this->_resourceEvent = $resourceEvent;
-        $this->_lockStorage = $lockStorage;
-        $this->_eventRepository = $eventRepository;
-    }
-
-    /**
-     * Initialize resource
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Index\Model\Resource\Process');
-    }
-
-    /**
-     * Set indexer class name as data namespace for event object
-     *
-     * @param   Event $event
-     * @return  $this
-     */
-    protected function _setEventNamespace(Event $event)
-    {
-        $namespace = get_class($this->getIndexer());
-        $event->setDataNamespace($namespace);
-        $event->setProcess($this);
-        return $this;
-    }
-
-    /**
-     * Remove indexer namespace from event
-     *
-     * @param Event $event
-     * @return $this
-     */
-    protected function _resetEventNamespace($event)
-    {
-        $event->setDataNamespace(null);
-        $event->setProcess(null);
-        return $this;
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param Event $event
-     * @return $this
-     */
-    public function register(Event $event)
-    {
-        if ($this->matchEvent($event)) {
-            $this->_setEventNamespace($event);
-            $this->getIndexer()->register($event);
-            $event->addProcessId($this->getId());
-            $this->_resetEventNamespace($event);
-            if ($this->getMode() == self::MODE_MANUAL) {
-                $this->_getResource()->updateStatus($this, self::STATUS_REQUIRE_REINDEX);
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Check if event can be matched by process
-     *
-     * @param Event $event
-     * @return bool
-     */
-    public function matchEvent(Event $event)
-    {
-        return $this->getIndexer()->matchEvent($event);
-    }
-
-    /**
-     * Check if specific entity and action type is matched
-     *
-     * @param   string $entity
-     * @param   string $type
-     * @return  bool
-     */
-    public function matchEntityAndType($entity, $type)
-    {
-        if ($entity !== null && $type !== null) {
-            return $this->getIndexer()->matchEntityAndType($entity, $type);
-        }
-        return true;
-    }
-
-    /**
-     * Reindex all data what this process responsible is
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     * @throws \Exception
-     */
-    public function reindexAll()
-    {
-        if ($this->isLocked()) {
-            throw new \Magento\Framework\Model\Exception(
-                __(
-                    '%1 Index process is not working now. Please try running this process later.',
-                    $this->getIndexer()->getName()
-                )
-            );
-        }
-
-        $processStatus = $this->getStatus();
-
-        $this->_getResource()->startProcess($this);
-        $this->lock();
-        try {
-            $eventsCollection = $this->_eventRepository->getUnprocessed($this);
-            if ($processStatus == self::STATUS_PENDING && $eventsCollection->getSize() > 0 ||
-                $this->getForcePartialReindex()
-            ) {
-                $this->_getResource()->beginTransaction();
-                try {
-                    $this->_processEventsCollection($eventsCollection, false);
-                    $this->_getResource()->commit();
-                } catch (\Exception $e) {
-                    $this->_getResource()->rollBack();
-                    throw $e;
-                }
-            } else {
-                //Update existing events since we'll do reindexAll
-                $this->_resourceEvent->updateProcessEvents($this);
-                $this->getIndexer()->reindexAll();
-            }
-            $this->unlock();
-
-            if ($this->getMode() == self::MODE_MANUAL && $this->_eventRepository->hasUnprocessed($this)) {
-                $this->_getResource()->updateStatus($this, self::STATUS_REQUIRE_REINDEX);
-            } else {
-                $this->_getResource()->endProcess($this);
-            }
-        } catch (\Exception $e) {
-            $this->unlock();
-            $this->_getResource()->failProcess($this);
-            throw $e;
-        }
-        $this->_eventManager->dispatch('after_reindex_process_' . $this->getIndexerCode());
-    }
-
-    /**
-     * Reindex all data what this process responsible is
-     * Check and using depends processes
-     *
-     * @return $this|void
-     */
-    public function reindexEverything()
-    {
-        if ($this->getData('runed_reindexall')) {
-            return $this;
-        }
-
-        $this->setForcePartialReindex(
-            $this->getStatus() == self::STATUS_PENDING && $this->_eventRepository->hasUnprocessed($this)
-        );
-
-        if ($this->getDepends()) {
-            foreach ($this->getDepends() as $code) {
-                $process = $this->_indexer->getProcessByCode($code);
-                if ($process) {
-                    $process->reindexEverything();
-                }
-            }
-        }
-
-        $this->setData('runed_reindexall', true);
-        return $this->reindexAll();
-    }
-
-    /**
-     * Process event with assigned indexer object
-     *
-     * @param Event $event
-     * @return $this
-     */
-    public function processEvent(Event $event)
-    {
-        if (!$this->matchEvent($event)) {
-            return $this;
-        }
-        if ($this->getMode() == self::MODE_MANUAL) {
-            $this->changeStatus(self::STATUS_REQUIRE_REINDEX);
-            return $this;
-        }
-
-        // Commented  due to deadlock
-        // @todo: Verify: It is required for partial update
-        //$this->_getResource()->updateProcessStartDate($this);
-
-        $this->_setEventNamespace($event);
-        $isError = false;
-
-        try {
-            $this->getIndexer()->processEvent($event);
-        } catch (\Exception $e) {
-            $isError = true;
-        }
-        $event->resetData();
-        $this->_resetEventNamespace($event);
-        //$this->_getResource()->updateProcessEndDate($this);
-        $event->addProcessId($this->getId(), $isError ? self::EVENT_STATUS_ERROR : self::EVENT_STATUS_DONE);
-
-        return $this;
-    }
-
-    /**
-     * Get Indexer strategy object
-     *
-     * @throws \Magento\Framework\Model\Exception
-     * @return \Magento\Index\Model\IndexerInterface
-     */
-    public function getIndexer()
-    {
-        if ($this->_currentIndexer === null) {
-            $name = $this->_getData('indexer_code');
-            if (!$name) {
-                throw new \Magento\Framework\Model\Exception(__('Indexer name is not defined.'));
-            }
-            $indexerConfiguration = $this->_indexerConfig->getIndexer($name);
-            if (!$indexerConfiguration || empty($indexerConfiguration['instance'])) {
-                throw new \Magento\Framework\Model\Exception(__('Indexer model is not defined.'));
-            }
-            $indexerModel = $this->_indexerFactory->create($indexerConfiguration['instance']);
-            if ($indexerModel instanceof \Magento\Index\Model\Indexer\AbstractIndexer) {
-                $this->_currentIndexer = $indexerModel;
-            } else {
-                throw new \Magento\Framework\Model\Exception(
-                    __('Indexer model should extend \Magento\Index\Model\Indexer\Abstract.')
-                );
-            }
-        }
-        return $this->_currentIndexer;
-    }
-
-    /**
-     * Index pending events addressed to the process
-     *
-     * @param   null|string $entity
-     * @param   null|string $type
-     * @return  $this
-     * @throws \Exception
-     */
-    public function indexEvents($entity = null, $type = null)
-    {
-        /**
-         * Check if process indexer can match entity code and action type
-         */
-        if ($entity !== null && $type !== null) {
-            if (!$this->getIndexer()->matchEntityAndType($entity, $type)) {
-                return $this;
-            }
-        }
-
-        if ($this->getMode() == self::MODE_MANUAL) {
-            return $this;
-        }
-
-        if ($this->isLocked()) {
-            return $this;
-        }
-
-        $this->lock();
-        try {
-            /**
-             * Prepare events collection
-             */
-            $eventsCollection = $this->_eventRepository->getUnprocessed($this);
-            if ($entity !== null) {
-                $eventsCollection->addEntityFilter($entity);
-            }
-            if ($type !== null) {
-                $eventsCollection->addTypeFilter($type);
-            }
-
-            $this->_processEventsCollection($eventsCollection);
-            $this->unlock();
-        } catch (\Exception $e) {
-            $this->unlock();
-            throw $e;
-        }
-        return $this;
-    }
-
-    /**
-     * Process all events of the collection
-     *
-     * @param Collection $eventsCollection
-     * @param bool $skipUnmatched
-     * @return $this
-     */
-    protected function _processEventsCollection(Collection $eventsCollection, $skipUnmatched = true)
-    {
-        // We can't reload the collection because of transaction
-        /** @var $event \Magento\Index\Model\Event */
-        while (true == ($event = $eventsCollection->fetchItem())) {
-            try {
-                $this->processEvent($event);
-                if (!$skipUnmatched) {
-                    $eventProcessIds = $event->getProcessIds();
-                    if (!isset($eventProcessIds[$this->getId()])) {
-                        $event->addProcessId($this->getId(), null);
-                    }
-                }
-            } catch (\Exception $e) {
-                $event->addProcessId($this->getId(), self::EVENT_STATUS_ERROR);
-            }
-            $event->save();
-        }
-        return $this;
-    }
-
-    /**
-     * Update status process/event association
-     *
-     * @param   Event $event
-     * @param   string $status
-     * @return  $this
-     */
-    public function updateEventStatus(Event $event, $status)
-    {
-        $this->_getResource()->updateEventStatus($this->getId(), $event->getId(), $status);
-        return $this;
-    }
-
-    /**
-     * Get process file instance
-     *
-     * @return \Magento\Index\Model\Process\File
-     */
-    protected function _getProcessFile()
-    {
-        if (!$this->_processFile) {
-            $this->_processFile = $this->_lockStorage->getFile($this->getId());
-        }
-        return $this->_processFile;
-    }
-
-    /**
-     * Lock process without blocking.
-     * This method allow protect multiple process running and fast lock validation.
-     *
-     * @return $this
-     */
-    public function lock()
-    {
-        $this->_getProcessFile()->processLock();
-        return $this;
-    }
-
-    /**
-     * Lock and block process.
-     * If new instance of the process will try validate locking state
-     * script will wait until process will be unlocked
-     *
-     * @return $this
-     */
-    public function lockAndBlock()
-    {
-        $this->_getProcessFile()->processLock(false);
-        return $this;
-    }
-
-    /**
-     * Unlock process
-     *
-     * @return $this
-     */
-    public function unlock()
-    {
-        $this->_getProcessFile()->processUnlock();
-        return $this;
-    }
-
-    /**
-     * Check if process is locked by another user
-     *
-     * @param bool $needUnlock
-     * @return bool
-     */
-    public function isLocked($needUnlock = true)
-    {
-        return $this->_getProcessFile()->isProcessLocked($needUnlock);
-    }
-
-    /**
-     * Change process status
-     *
-     * @param string $status
-     * @return $this
-     */
-    public function changeStatus($status)
-    {
-        $this->_eventManager->dispatch('index_process_change_status', array('process' => $this, 'status' => $status));
-        $this->_getResource()->updateStatus($this, $status);
-        return $this;
-    }
-
-    /**
-     * Get list of process mode options
-     *
-     * @return array
-     */
-    public function getModesOptions()
-    {
-        return array(self::MODE_REAL_TIME => __('Update on Save'), self::MODE_MANUAL => __('Manual Update'));
-    }
-
-    /**
-     * Get list of process status options
-     *
-     * @return array
-     */
-    public function getStatusesOptions()
-    {
-        return array(
-            self::STATUS_PENDING => __('Ready'),
-            self::STATUS_RUNNING => __('Processing'),
-            self::STATUS_REQUIRE_REINDEX => __('Reindex Required')
-        );
-    }
-
-    /**
-     * Get list of "Update Required" options
-     *
-     * @return array
-     */
-    public function getUpdateRequiredOptions()
-    {
-        return array(0 => __('No'), 1 => __('Yes'));
-    }
-
-    /**
-     * Retrieve depend indexer codes
-     *
-     * @return array
-     */
-    public function getDepends()
-    {
-        $depends = $this->getData('depends');
-        if (is_null($depends)) {
-            $depends = array();
-            $indexerConfiguration = $this->_indexerConfig->getIndexer($this->getIndexerCode());
-            if ($indexerConfiguration) {
-                if (isset($indexerConfiguration['depends']) && is_array($indexerConfiguration['depends'])) {
-                    $depends = $indexerConfiguration['depends'];
-                }
-            }
-
-            $this->setData('depends', $depends);
-        }
-
-        return $depends;
-    }
-
-    /**
-     * Process event with locks checking
-     *
-     * @param Event $event
-     * @return $this
-     * @throws \Exception
-     */
-    public function safeProcessEvent(Event $event)
-    {
-        if (!$this->matchEvent($event)) {
-            return $this;
-        }
-        if ($this->isLocked()) {
-            return $this;
-        }
-        $this->lock();
-        try {
-            $this->processEvent($event);
-            $this->unlock();
-        } catch (\Exception $e) {
-            $this->unlock();
-            throw $e;
-        }
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Process/File.php b/app/code/Magento/Index/Model/Process/File.php
deleted file mode 100644
index d6174506fb5..00000000000
--- a/app/code/Magento/Index/Model/Process/File.php
+++ /dev/null
@@ -1,134 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Process;
-
-use Magento\Framework\Filesystem\FilesystemException;
-use Magento\Framework\Filesystem\File\WriteInterface;
-
-/**
- * Process file entity
- */
-class File
-{
-    /**
-     * Stream handle instance
-     *
-     * @var WriteInterface
-     */
-    protected $_streamHandler;
-
-    /**
-     * Is stream locked
-     *
-     * @var bool
-     */
-    protected $_streamLocked;
-
-    /**
-     * Process lock flag:
-     * - true  - if process is already locked by another user
-     * - false - if process is locked by us
-     * - null  - unknown lock status
-     *
-     * @var bool
-     */
-    protected $_processLocked = null;
-
-    /**
-     * @param WriteInterface $streamHandler
-     */
-    public function __construct(WriteInterface $streamHandler)
-    {
-        $this->_streamHandler = $streamHandler;
-    }
-
-    /**
-     * Lock process file
-     *
-     * @param bool $nonBlocking
-     * @return void
-     */
-    public function processLock($nonBlocking = true)
-    {
-        $lockMode = LOCK_EX;
-        if ($nonBlocking) {
-            $lockMode = $lockMode | LOCK_NB;
-        }
-        try {
-            $this->_streamHandler->lock($lockMode);
-            $this->_streamLocked = true;
-        } catch (FilesystemException $e) {
-            $this->_streamLocked = false;
-        }
-        // true if process is locked by other user
-        $this->_processLocked = !$this->_streamLocked;
-    }
-
-    /**
-     * Unlock process file
-     *
-     * @return bool
-     */
-    public function processUnlock()
-    {
-        $this->_processLocked = null;
-        try {
-            $this->_streamHandler->unlock();
-            $this->_streamLocked = false;
-        } catch (FilesystemException $e) {
-            $this->_streamLocked = true;
-        }
-        return !$this->_streamLocked;
-    }
-
-    /**
-     * Check if process is locked by another user
-     *
-     * @param bool $needUnlock
-     * @return bool|null
-     */
-    public function isProcessLocked($needUnlock = true)
-    {
-        if (!$this->_streamHandler) {
-            return null;
-        }
-
-        if ($this->_processLocked !== null) {
-            return $this->_processLocked;
-        } else {
-            try {
-                $this->_streamHandler->lock(LOCK_EX | LOCK_NB);
-                if ($needUnlock) {
-                    $this->_streamHandler->unlock();
-                    $this->_streamLocked = false;
-                } else {
-                    $this->_streamLocked = true;
-                }
-                return false;
-            } catch (FilesystemException $e) {
-                return true;
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Index/Model/Resource/Event.php b/app/code/Magento/Index/Model/Resource/Event.php
deleted file mode 100644
index fcfad015068..00000000000
--- a/app/code/Magento/Index/Model/Resource/Event.php
+++ /dev/null
@@ -1,135 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Resource;
-
-use Magento\Framework\Model\AbstractModel;
-use Magento\Index\Model\Process as ProcessModel;
-
-/**
- * Index Event Resource Model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Event extends \Magento\Framework\Model\Resource\Db\AbstractDb
-{
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('index_event', 'event_id');
-    }
-
-    /**
-     * Check if semilar event exist before start saving data
-     *
-     * @param AbstractModel $object
-     * @return $this
-     */
-    protected function _beforeSave(AbstractModel $object)
-    {
-        /**
-         * Check if event already exist and merge previous data
-         */
-        if (!$object->getId()) {
-            $select = $this->_getReadAdapter()->select()->from(
-                $this->getMainTable()
-            )->where(
-                'type=?',
-                $object->getType()
-            )->where(
-                'entity=?',
-                $object->getEntity()
-            );
-            if ($object->hasEntityPk()) {
-                $select->where('entity_pk=?', $object->getEntityPk());
-            }
-            $data = $this->_getWriteAdapter()->fetchRow($select);
-            if ($data) {
-                $object->mergePreviousData($data);
-            }
-        }
-        $object->cleanNewData();
-        return parent::_beforeSave($object);
-    }
-
-    /**
-     * Save assigned processes
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @return $this
-     */
-    protected function _afterSave(AbstractModel $object)
-    {
-        $processIds = $object->getProcessIds();
-        if (is_array($processIds)) {
-            $processTable = $this->getTable('index_process_event');
-            if (empty($processIds)) {
-                $this->_getWriteAdapter()->delete($processTable);
-            } else {
-                foreach ($processIds as $processId => $processStatus) {
-                    if (is_null($processStatus) || $processStatus == ProcessModel::EVENT_STATUS_DONE) {
-                        $this->_getWriteAdapter()->delete(
-                            $processTable,
-                            array('process_id = ?' => $processId, 'event_id = ?' => $object->getId())
-                        );
-                        continue;
-                    }
-                    $data = array(
-                        'process_id' => $processId,
-                        'event_id' => $object->getId(),
-                        'status' => $processStatus
-                    );
-                    $this->_getWriteAdapter()->insertOnDuplicate($processTable, $data, array('status'));
-                }
-            }
-        }
-        return parent::_afterSave($object);
-    }
-
-    /**
-     * Update status for events of process
-     *
-     * @param int|array|ProcessModel $process
-     * @param string $status
-     * @return $this
-     */
-    public function updateProcessEvents($process, $status = ProcessModel::EVENT_STATUS_DONE)
-    {
-        $whereCondition = '';
-        if ($process instanceof ProcessModel) {
-            $whereCondition = array('process_id = ?' => $process->getId());
-        } elseif (is_array($process) && !empty($process)) {
-            $whereCondition = array('process_id IN (?)' => $process);
-        } elseif (!is_array($whereCondition)) {
-            $whereCondition = array('process_id = ?' => $process);
-        }
-        $this->_getWriteAdapter()->update(
-            $this->getTable('index_process_event'),
-            array('status' => $status),
-            $whereCondition
-        );
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Resource/Event/Collection.php b/app/code/Magento/Index/Model/Resource/Event/Collection.php
deleted file mode 100644
index ea517a913a8..00000000000
--- a/app/code/Magento/Index/Model/Resource/Event/Collection.php
+++ /dev/null
@@ -1,136 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Resource\Event;
-
-use Magento\Index\Model\Process;
-
-/**
- * Index Event Collection
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
-{
-    /**
-     * Initialize resource
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Index\Model\Event', 'Magento\Index\Model\Resource\Event');
-    }
-
-    /**
-     * Add filter by entity
-     *
-     * @param string|array $entity
-     * @return $this
-     */
-    public function addEntityFilter($entity)
-    {
-        if (is_array($entity) && !empty($entity)) {
-            $this->addFieldToFilter('entity', array('in' => $entity));
-        } else {
-            $this->addFieldToFilter('entity', $entity);
-        }
-        return $this;
-    }
-
-    /**
-     * Add filter by type
-     *
-     * @param string|array $type
-     * @return $this
-     */
-    public function addTypeFilter($type)
-    {
-        if (is_array($type) && !empty($type)) {
-            $this->addFieldToFilter('type', array('in' => $type));
-        } else {
-            $this->addFieldToFilter('type', $type);
-        }
-        return $this;
-    }
-
-    /**
-     * Add filter by process and status to events collection
-     *
-     * @param int|array|Process $process
-     * @param string $status
-     * @return $this
-     */
-    public function addProcessFilter($process, $status = null)
-    {
-        $this->_joinProcessEventTable();
-        if ($process instanceof Process) {
-            $this->addFieldToFilter('process_event.process_id', $process->getId());
-        } elseif (is_array($process) && !empty($process)) {
-            $this->addFieldToFilter('process_event.process_id', array('in' => $process));
-        } else {
-            $this->addFieldToFilter('process_event.process_id', $process);
-        }
-
-        if ($status !== null) {
-            if (is_array($status) && !empty($status)) {
-                $this->addFieldToFilter('process_event.status', array('in' => $status));
-            } else {
-                $this->addFieldToFilter('process_event.status', $status);
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Join index_process_event table to event table
-     *
-     * @return $this
-     */
-    protected function _joinProcessEventTable()
-    {
-        if (!$this->getFlag('process_event_table_joined')) {
-            $this->getSelect()->join(
-                array('process_event' => $this->getTable('index_process_event')),
-                'process_event.event_id=main_table.event_id',
-                array('process_event_status' => 'status')
-            );
-            $this->setFlag('process_event_table_joined', true);
-        }
-        return $this;
-    }
-
-    /**
-     * Reset collection state
-     *
-     * @return $this
-     */
-    public function reset()
-    {
-        $this->_totalRecords = null;
-        $this->_data = null;
-        $this->_isCollectionLoaded = false;
-        $this->_items = array();
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Resource/Process.php b/app/code/Magento/Index/Model/Resource/Process.php
deleted file mode 100644
index 15bfe4098cc..00000000000
--- a/app/code/Magento/Index/Model/Resource/Process.php
+++ /dev/null
@@ -1,180 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Resource;
-
-use Magento\Index\Model\Process as ModelProcess;
-
-/**
- * Index Process Resource Model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Process extends \Magento\Framework\Model\Resource\Db\AbstractDb
-{
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime
-     */
-    protected $dateTime;
-
-    /**
-     * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     */
-    public function __construct(\Magento\Framework\App\Resource $resource, \Magento\Framework\Stdlib\DateTime $dateTime)
-    {
-        $this->dateTime = $dateTime;
-        parent::__construct($resource);
-    }
-
-    /**
-     * Initialize  table and table pk
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('index_process', 'process_id');
-    }
-
-    /**
-     * Update process/event association row status
-     *
-     * @param int $processId
-     * @param int $eventId
-     * @param string $status
-     * @return $this
-     */
-    public function updateEventStatus($processId, $eventId, $status)
-    {
-        $adapter = $this->_getWriteAdapter();
-        $condition = array('process_id = ?' => $processId, 'event_id = ?' => $eventId);
-        $adapter->update($this->getTable('index_process_event'), array('status' => $status), $condition);
-        return $this;
-    }
-
-    /**
-     * Register process end
-     *
-     * @param ModelProcess $process
-     * @return $this
-     */
-    public function endProcess(ModelProcess $process)
-    {
-        $data = array('status' => ModelProcess::STATUS_PENDING, 'ended_at' => $this->dateTime->formatDate(time()));
-        $this->_updateProcessData($process->getId(), $data);
-        return $this;
-    }
-
-    /**
-     * Register process start
-     *
-     * @param ModelProcess $process
-     * @return $this
-     */
-    public function startProcess(ModelProcess $process)
-    {
-        $data = array('status' => ModelProcess::STATUS_RUNNING, 'started_at' => $this->dateTime->formatDate(time()));
-        $this->_updateProcessData($process->getId(), $data);
-        return $this;
-    }
-
-    /**
-     * Register process fail
-     *
-     * @param ModelProcess $process
-     * @return $this
-     */
-    public function failProcess(ModelProcess $process)
-    {
-        $data = array(
-            'status' => ModelProcess::STATUS_REQUIRE_REINDEX,
-            'ended_at' => $this->dateTime->formatDate(time())
-        );
-        $this->_updateProcessData($process->getId(), $data);
-        return $this;
-    }
-
-    /**
-     * Update process status field
-     *
-     *
-     * @param ModelProcess $process
-     * @param string $status
-     * @return $this
-     */
-    public function updateStatus($process, $status)
-    {
-        $data = array('status' => $status);
-        $this->_updateProcessData($process->getId(), $data);
-        return $this;
-    }
-
-    /**
-     * Updates process data
-     * @param int $processId
-     * @param array $data
-     * @return $this
-     */
-    protected function _updateProcessData($processId, $data)
-    {
-        $bind = array('process_id=?' => $processId);
-        $this->_getWriteAdapter()->update($this->getMainTable(), $data, $bind);
-
-        return $this;
-    }
-
-    /**
-     * Update process start date
-     *
-     * @param ModelProcess $process
-     * @return $this
-     */
-    public function updateProcessStartDate(ModelProcess $process)
-    {
-        $this->_updateProcessData($process->getId(), array('started_at' => $this->dateTime->formatDate(time())));
-        return $this;
-    }
-
-    /**
-     * Update process end date
-     *
-     * @param ModelProcess $process
-     * @return $this
-     */
-    public function updateProcessEndDate(ModelProcess $process)
-    {
-        $this->_updateProcessData($process->getId(), array('ended_at' => $this->dateTime->formatDate(time())));
-        return $this;
-    }
-
-    /**
-     * Whether transaction is already started
-     *
-     * @return bool
-     */
-    public function isInTransaction()
-    {
-        return $this->_getWriteAdapter()->getTransactionLevel() > 0;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Resource/Process/Collection.php b/app/code/Magento/Index/Model/Resource/Process/Collection.php
deleted file mode 100644
index c537c7a01df..00000000000
--- a/app/code/Magento/Index/Model/Resource/Process/Collection.php
+++ /dev/null
@@ -1,72 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Resource\Process;
-
-/**
- * Index Process Collection
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
-{
-    /**
-     * Initialize resource
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Index\Model\Process', 'Magento\Index\Model\Resource\Process');
-    }
-
-    /**
-     * Add count of unprocessed events to process collection
-     *
-     * @return $this
-     */
-    public function addEventsStats()
-    {
-        $countsSelect = $this->getConnection()->select()->from(
-            $this->getTable('index_process_event'),
-            array('process_id', 'events' => 'COUNT(*)')
-        )->where(
-            'status=?',
-            \Magento\Index\Model\Process::EVENT_STATUS_NEW
-        )->group(
-            'process_id'
-        );
-        $this->getSelect()->joinLeft(
-            array('e' => $countsSelect),
-            'e.process_id=main_table.process_id',
-            array(
-                'events' => $this->getConnection()->getCheckSql(
-                    $this->getConnection()->prepareSqlCondition('e.events', array('null' => null)),
-                    0,
-                    'e.events'
-                )
-            )
-        );
-        return $this;
-    }
-}
diff --git a/app/code/Magento/Index/Model/Resource/Setup.php b/app/code/Magento/Index/Model/Resource/Setup.php
deleted file mode 100644
index f752418b17e..00000000000
--- a/app/code/Magento/Index/Model/Resource/Setup.php
+++ /dev/null
@@ -1,106 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Index Setup Model
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Index\Model\Resource;
-
-class Setup extends \Magento\Framework\Module\Setup
-{
-    /**
-     * @var \Magento\Index\Model\Indexer\ConfigInterface
-     */
-    protected $_indexerConfig;
-
-    /**
-     * @param \Magento\Framework\Module\Setup\Context $context
-     * @param string $resourceName
-     * @param \Magento\Index\Model\Indexer\ConfigInterface $indexerConfig
-     * @param string $moduleName
-     * @param string $connectionName
-     */
-    public function __construct(
-        \Magento\Framework\Module\Setup\Context $context,
-        $resourceName,
-        \Magento\Index\Model\Indexer\ConfigInterface $indexerConfig,
-        $moduleName = 'Magento_Index',
-        $connectionName = \Magento\Framework\Module\Updater\SetupInterface::DEFAULT_SETUP_CONNECTION
-    ) {
-        $this->_indexerConfig = $indexerConfig;
-        parent::__construct($context, $resourceName, $moduleName, $connectionName);
-    }
-
-    /**
-     * Apply Index module DB updates and sync indexes declaration
-     *
-     * @return void
-     */
-    public function applyUpdates()
-    {
-        parent::applyUpdates();
-        $this->_syncIndexes();
-    }
-
-    /**
-     * Sync indexes declarations in config and in DB
-     *
-     * @return $this
-     */
-    protected function _syncIndexes()
-    {
-        $connection = $this->getConnection();
-        if (!$connection) {
-            return $this;
-        }
-        $indexCodes = array();
-        foreach (array_keys($this->_indexerConfig->getAll()) as $name) {
-            $indexCodes[] = $name;
-        }
-        $table = $this->getTable('index_process');
-        $select = $connection->select()->from($table, 'indexer_code');
-        $existingIndexes = $connection->fetchCol($select);
-        $delete = array_diff($existingIndexes, $indexCodes);
-        $insert = array_diff($indexCodes, $existingIndexes);
-
-        if (!empty($delete)) {
-            $connection->delete($table, $connection->quoteInto('indexer_code IN (?)', $delete));
-        }
-        if (!empty($insert)) {
-            $insertData = array();
-            foreach ($insert as $code) {
-                $insertData[] = array(
-                    'indexer_code' => $code,
-                    'status' => \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX
-                );
-            }
-            if (method_exists($connection, 'insertArray') && is_callable([$connection, 'insertArray'])) {
-                $connection->insertArray($table, array('indexer_code', 'status'), $insertData);
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Index/Model/Shell.php b/app/code/Magento/Index/Model/Shell.php
deleted file mode 100644
index 2146bcdf04a..00000000000
--- a/app/code/Magento/Index/Model/Shell.php
+++ /dev/null
@@ -1,268 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-/**
- * Shell model, used to work with indexers via command line
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Shell extends \Magento\Framework\App\AbstractShell
-{
-    /**
-     * Error status - whether errors have happened
-     *
-     * @var bool
-     */
-    protected $_hasErrors = false;
-
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @param \Magento\Framework\App\Filesystem $filesystem
-     * @param string $entryPoint
-     * @param Indexer $indexer
-     */
-    public function __construct(\Magento\Framework\App\Filesystem $filesystem, $entryPoint, Indexer $indexer)
-    {
-        $this->_indexer = $indexer;
-        parent::__construct($filesystem, $entryPoint);
-    }
-
-    /**
-     * Runs this model, assumed to be run by command-line
-     *
-     * @return $this
-     */
-    public function run()
-    {
-        if ($this->_showHelp()) {
-            return $this;
-        }
-
-        if ($this->getArg('info')) {
-            $this->_runShowInfo();
-        } else if ($this->getArg('status') || $this->getArg('mode')) {
-            $this->_runShowStatusOrMode();
-        } else if ($this->getArg('mode-realtime') || $this->getArg('mode-manual')) {
-            $this->_runSetMode();
-        } else if ($this->getArg('reindex') || $this->getArg('reindexall')) {
-            $this->_runReindex();
-        } else {
-            echo $this->getUsageHelp();
-        }
-        return $this;
-    }
-
-    /**
-     * Shows information about indexes
-     *
-     * @return $this
-     */
-    protected function _runShowInfo()
-    {
-        $processes = $this->_parseIndexerString('all');
-        foreach ($processes as $process) {
-            /* @var $process \Magento\Index\Model\Process */
-            echo sprintf('%-30s', $process->getIndexerCode());
-            echo $process->getIndexer()->getName() . "\n";
-        }
-        return $this;
-    }
-
-    /**
-     * Shows information about statuses or modes
-     *
-     * @return $this
-     */
-    protected function _runShowStatusOrMode()
-    {
-        if ($this->getArg('status')) {
-            $processes = $this->_parseIndexerString($this->getArg('status'));
-        } else {
-            $processes = $this->_parseIndexerString($this->getArg('mode'));
-        }
-        foreach ($processes as $process) {
-            /* @var $process \Magento\Index\Model\Process */
-            $status = 'unknown';
-            if ($this->getArg('status')) {
-                switch ($process->getStatus()) {
-                    case \Magento\Index\Model\Process::STATUS_PENDING:
-                        $status = 'Pending';
-                        break;
-                    case \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX:
-                        $status = 'Require Reindex';
-                        break;
-
-                    case \Magento\Index\Model\Process::STATUS_RUNNING:
-                        $status = 'Running';
-                        break;
-
-                    default:
-                        $status = 'Ready';
-                        break;
-                }
-            } else {
-                switch ($process->getMode()) {
-                    case \Magento\Index\Model\Process::MODE_REAL_TIME:
-                        $status = 'Update on Save';
-                        break;
-                    case \Magento\Index\Model\Process::MODE_MANUAL:
-                        $status = 'Manual Update';
-                        break;
-                }
-            }
-            echo sprintf('%-30s ', $process->getIndexer()->getName() . ':') . $status . "\n";
-        }
-        return $this;
-    }
-
-    /**
-     * Sets new mode for indexes
-     *
-     * @return $this
-     */
-    protected function _runSetMode()
-    {
-        if ($this->getArg('mode-realtime')) {
-            $mode = \Magento\Index\Model\Process::MODE_REAL_TIME;
-            $processes = $this->_parseIndexerString($this->getArg('mode-realtime'));
-        } else {
-            $mode = \Magento\Index\Model\Process::MODE_MANUAL;
-            $processes = $this->_parseIndexerString($this->getArg('mode-manual'));
-        }
-        foreach ($processes as $process) {
-            /* @var $process \Magento\Index\Model\Process */
-            try {
-                $process->setMode($mode)->save();
-                echo $process->getIndexer()->getName() . " index was successfully changed index mode\n";
-            } catch (\Magento\Framework\Model\Exception $e) {
-                echo $e->getMessage() . "\n";
-                $this->_hasErrors = true;
-            } catch (\Exception $e) {
-                echo $process->getIndexer()->getName() . " index process unknown error:\n";
-                echo $e . "\n";
-                $this->_hasErrors = true;
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Reindexes indexer(s)
-     *
-     * @return void
-     */
-    protected function _runReindex()
-    {
-        if ($this->getArg('reindex')) {
-            $processes = $this->_parseIndexerString($this->getArg('reindex'));
-        } else {
-            $processes = $this->_parseIndexerString('all');
-        }
-
-        foreach ($processes as $process) {
-            /* @var $process \Magento\Index\Model\Process */
-            try {
-                $startTime = microtime(true);
-                $process->reindexEverything();
-                $resultTime = microtime(true) - $startTime;
-                echo $process->getIndexer()->getName()
-                    . " index was rebuilt successfully in " . gmdate('H:i:s', $resultTime) . "\n";
-            } catch (\Magento\Framework\Model\Exception $e) {
-                echo $e->getMessage() . "\n";
-                $this->_hasErrors = true;
-            } catch (\Exception $e) {
-                echo $process->getIndexer()->getName() . " index process unknown error:\n";
-                echo $e . "\n";
-                $this->_hasErrors = true;
-            }
-        }
-    }
-
-    /**
-     * Parses string with indexers and return array of indexer instances
-     *
-     * @param string $string
-     * @return array
-     */
-    protected function _parseIndexerString($string)
-    {
-        $processes = array();
-        if ($string == 'all') {
-            $collection = $this->_indexer->getProcessesCollection();
-            foreach ($collection as $process) {
-                $processes[] = $process;
-            }
-        } else if (!empty($string)) {
-            $codes = explode(',', $string);
-            foreach ($codes as $code) {
-                $process = $this->_indexer->getProcessByCode(trim($code));
-                if (!$process) {
-                    echo 'Warning: Unknown indexer with code ' . trim($code) . "\n";
-                    $this->_hasErrors = true;
-                } else {
-                    $processes[] = $process;
-                }
-            }
-        }
-        return $processes;
-    }
-
-    /**
-     * Return whether there errors have happened
-     *
-     * @return bool
-     */
-    public function hasErrors()
-    {
-        return $this->_hasErrors;
-    }
-
-    /**
-     * Retrieves usage help message
-     *
-     * @return string
-     */
-    public function getUsageHelp()
-    {
-        return <<<USAGE
-Usage:  php -f {$this->_entryPoint} -- [options]
-
-  --status <indexer>            Show Indexer(s) Status
-  --mode <indexer>              Show Indexer(s) Index Mode
-  --mode-realtime <indexer>     Set index mode type "Update on Save"
-  --mode-manual <indexer>       Set index mode type "Manual Update"
-  --reindex <indexer>           Reindex Data
-  info                          Show allowed indexers
-  reindexall                    Reindex Data by all indexers
-  help                          This help
-
-  <indexer>     Comma separated indexer codes or value "all" for all indexers
-USAGE;
-    }
-}
diff --git a/app/code/Magento/Index/Model/System/Message/IndexOutdated.php b/app/code/Magento/Index/Model/System/Message/IndexOutdated.php
deleted file mode 100644
index a25fc378e56..00000000000
--- a/app/code/Magento/Index/Model/System/Message/IndexOutdated.php
+++ /dev/null
@@ -1,128 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\System\Message;
-
-class IndexOutdated implements \Magento\Framework\Notification\MessageInterface
-{
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @var \Magento\Framework\UrlInterface
-     */
-    protected $_urlBuilder;
-
-    /**
-     * @var \Magento\Framework\AuthorizationInterface
-     */
-    protected $_authorization;
-
-    /**
-     * @var array|null
-     */
-    protected $_indexes = null;
-
-    /**
-     * @param \Magento\Index\Model\Indexer $indexer
-     * @param \Magento\Framework\UrlInterface $urlBuilder
-     * @param \Magento\Framework\AuthorizationInterface $authorization
-     */
-    public function __construct(
-        \Magento\Index\Model\Indexer $indexer,
-        \Magento\Framework\UrlInterface $urlBuilder,
-        \Magento\Framework\AuthorizationInterface $authorization
-    ) {
-        $this->_indexer = $indexer;
-        $this->_urlBuilder = $urlBuilder;
-        $this->_authorization = $authorization;
-    }
-
-    /**
-     * @return array
-     */
-    protected function _getProcessesForReindex()
-    {
-        if ($this->_indexes === null) {
-            $this->_indexes = array();
-            $processes = $this->_indexer->getProcessesCollection()->addEventsStats();
-            /** @var $process \Magento\Index\Model\Process */
-            foreach ($processes as $process) {
-                if (($process->getStatus() == \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX ||
-                    $process->getEvents() > 0) && $process->getIndexer()->isVisible()
-                ) {
-                    $this->_indexes[] = $process->getIndexer()->getName();
-                }
-            }
-        }
-        return $this->_indexes;
-    }
-
-    /**
-     * Retrieve unique message identity
-     *
-     * @return string
-     */
-    public function getIdentity()
-    {
-        $data = $this->_getProcessesForReindex() ?: array();
-        return md5('OUTDATED_INDEXES' . implode(':', $data));
-    }
-
-    /**
-     * Check whether
-     *
-     * @return bool
-     */
-    public function isDisplayed()
-    {
-        return $this->_authorization->isAllowed('Magento_Index::index') && $this->_getProcessesForReindex();
-    }
-
-    /**
-     * Retrieve message text
-     *
-     * @return string
-     */
-    public function getText()
-    {
-        $data = $this->_getProcessesForReindex() ?: array();
-        $indexList = implode(', ', $data);
-        $url = $this->_urlBuilder->getUrl('adminhtml/process/list');
-        $text = __('One or more of the Indexes are not up to date: %1', $indexList) . '. ';
-        $text .= __('Please go to <a href="%1">Index Management</a> and rebuild required indexes.', $url);
-        return $text;
-    }
-
-    /**
-     * Retrieve message severity
-     *
-     * @return int
-     */
-    public function getSeverity()
-    {
-        return self::SEVERITY_CRITICAL;
-    }
-}
diff --git a/app/code/Magento/Index/etc/events.xml b/app/code/Magento/Index/etc/events.xml
deleted file mode 100644
index d95ba2a15ca..00000000000
--- a/app/code/Magento/Index/etc/events.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
-    <event name="store_save_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processStoreSave" />
-    </event>
-    <event name="store_group_save_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processStoreGroupSave" />
-    </event>
-    <event name="website_save_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processWebsiteSave" />
-    </event>
-    <event name="store_delete_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processStoreDelete" />
-    </event>
-    <event name="store_group_delete_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processStoreGroupDelete" />
-    </event>
-    <event name="website_delete_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processWebsiteDelete" />
-    </event>
-    <event name="config_data_save_commit_after">
-        <observer name="index" instance="Magento\Index\Model\Observer" method="processConfigDataSave" />
-    </event>
-</config>
diff --git a/app/code/Magento/Index/etc/indexers.xsd b/app/code/Magento/Index/etc/indexers.xsd
deleted file mode 100644
index e6759758130..00000000000
--- a/app/code/Magento/Index/etc/indexers.xsd
+++ /dev/null
@@ -1,97 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, 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="indexer" type="indexerDeclaration" minOccurs="1" maxOccurs="unbounded">
-                    <xs:unique name="uniqueDependsName">
-                        <xs:annotation>
-                            <xs:documentation>
-                                Dependent indexer name must be unique
-                            </xs:documentation>
-                        </xs:annotation>
-                        <xs:selector xpath="depends" />
-                        <xs:field xpath="@name" />
-                    </xs:unique>
-                </xs:element>
-            </xs:sequence>
-        </xs:complexType>
-        <xs:unique name="uniqueIndexerName">
-            <xs:annotation>
-                <xs:documentation>
-                    Indexer name must be unique
-                </xs:documentation>
-            </xs:annotation>
-            <xs:selector xpath="indexer" />
-            <xs:field xpath="@name" />
-        </xs:unique>
-    </xs:element>
-
-    <xs:complexType name="indexerDeclaration">
-        <xs:annotation>
-            <xs:documentation>
-                Indexer declaration
-            </xs:documentation>
-        </xs:annotation>
-        <xs:sequence>
-            <xs:element name="depends" type="dependencyDeclaration" minOccurs="0" maxOccurs="unbounded" />
-        </xs:sequence>
-        <xs:attribute name="name" type="identifierType" use="required" />
-        <xs:attribute name="instance" type="instanceType" use="optional" />
-    </xs:complexType>
-
-    <xs:complexType name="dependencyDeclaration">
-        <xs:annotation>
-            <xs:documentation>
-                Dependency declaration
-            </xs:documentation>
-        </xs:annotation>
-        <xs:attribute name="name" type="identifierType" use="required" />
-    </xs:complexType>
-
-    <xs:simpleType name="identifierType">
-        <xs:annotation>
-            <xs:documentation>
-                Identifier can contain only [a-z_].
-            </xs:documentation>
-        </xs:annotation>
-        <xs:restriction base="xs:string">
-            <xs:pattern value="[a-z_]+" />
-        </xs:restriction>
-    </xs:simpleType>
-
-    <xs:simpleType name="instanceType">
-        <xs:annotation>
-            <xs:documentation>
-                Instance name can contain only [a-zA-Z_\\\\].
-            </xs:documentation>
-        </xs:annotation>
-        <xs:restriction base="xs:string">
-            <xs:pattern value="[a-zA-Z_\\\\]+" />
-        </xs:restriction>
-    </xs:simpleType>
-</xs:schema>
diff --git a/app/code/Magento/Index/i18n/de_DE.csv b/app/code/Magento/Index/i18n/de_DE.csv
deleted file mode 100644
index 9ca3f4b392a..00000000000
--- a/app/code/Magento/Index/i18n/de_DE.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,Nein
-Action,Aktion
-General,Allgemein
-Yes,Ja
-Status,Status
-Description,Beschreibung
-System,System
-Never,Nie
-Updated,Updated
-"Index Management","Index Management"
-"Save Process","Save Process"
-"Reindex Data","Daten neu indexieren"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Index Name"
-"Index Description","Index Beschreibung"
-"Index Mode","Index Modus"
-"Process Information","Informationen verarbeiten"
-Index,Index
-Mode,Modus
-"Update Required","Update erforderlich"
-"Change Index Mode","Index-Modus ändern"
-"Index mode",Indexmodus
-"Cannot initialize the indexer process.","Indexer-Verarbeitung konnte nicht initialisiert werden."
-"The index has been saved.","Der Index wurde gespeichert."
-"There was a problem with saving process.","Beim Speichern ist ein Problem aufgetreten."
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","Bei der Verarbeitung der Reindexierung ist ein Problem aufgetreten."
-"Please select Indexes","Bitte Indexe auswählen"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Bitte Index(e) auswählen"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Indexer-Vorlage nicht definiert."
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","Aktualisierung gespeichert."
-"Manual Update","Manuelle Aktualisierung"
-Ready,Fertig
-Processing,"Verarbeitung läuft"
-"Reindex Required","Neuindexierung erforderlich"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/en_US.csv b/app/code/Magento/Index/i18n/en_US.csv
deleted file mode 100644
index 438556cd67b..00000000000
--- a/app/code/Magento/Index/i18n/en_US.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,No
-Action,Action
-General,General
-Yes,Yes
-Status,Status
-Description,Description
-System,System
-Never,Never
-Updated,Updated
-"Index Management","Index Management"
-"Save Process","Save Process"
-"Reindex Data","Reindex Data"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Index Name"
-"Index Description","Index Description"
-"Index Mode","Index Mode"
-"Process Information","Process Information"
-Index,Index
-Mode,Mode
-"Update Required","Update Required"
-"Change Index Mode","Change Index Mode"
-"Index mode","Index mode"
-"Cannot initialize the indexer process.","Cannot initialize the indexer process."
-"The index has been saved.","The index has been saved."
-"There was a problem with saving process.","There was a problem with saving process."
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","There was a problem with reindexing process."
-"Please select Indexes","Please select Indexes"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Please select Index(es)"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Indexer model is not defined."
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","Update on Save"
-"Manual Update","Manual Update"
-Ready,Ready
-Processing,Processing
-"Reindex Required","Reindex Required"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/es_ES.csv b/app/code/Magento/Index/i18n/es_ES.csv
deleted file mode 100644
index abe1e543764..00000000000
--- a/app/code/Magento/Index/i18n/es_ES.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,No
-Action,Acción
-General,General
-Yes,Sí
-Status,Estado
-Description,Descripción
-System,Sistema
-Never,Nunca
-Updated,Updated
-"Index Management","Gestión de Índices"
-"Save Process","Save Process"
-"Reindex Data","Volver a indexear los datos"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Nombre de indice"
-"Index Description","Descripción del indice"
-"Index Mode","Modalidad de indice"
-"Process Information","Información de proceso"
-Index,Indice
-Mode,Modalidad
-"Update Required","Es necesaria la actualización."
-"Change Index Mode","Cambiar la modalidad de indexación"
-"Index mode","Modo de índice"
-"Cannot initialize the indexer process.","No se puede iniciar el proceso de indexación"
-"The index has been saved.","El indice se ha guardado"
-"There was a problem with saving process.","Hubo un problema mientras se guardaba"
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","Hubo un problema con el proceso de indexear de nuevo"
-"Please select Indexes","Por favor seleccione indices"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Por favor seleccione indice(s)"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Modelo de indexeado no definido"
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","actualización guardada"
-"Manual Update","Actualización manual"
-Ready,Listo
-Processing,Procesando
-"Reindex Required","Volver a indexear requerido"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/fr_FR.csv b/app/code/Magento/Index/i18n/fr_FR.csv
deleted file mode 100644
index efc407dcf9c..00000000000
--- a/app/code/Magento/Index/i18n/fr_FR.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,Non
-Action,Action
-General,Général
-Yes,Oui
-Status,État
-Description,Description
-System,Système
-Never,Jamais
-Updated,Updated
-"Index Management","Gestion index"
-"Save Process","Save Process"
-"Reindex Data","Ré-indexer données"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Nom index"
-"Index Description","Description index"
-"Index Mode","Mode index"
-"Process Information","Traiter infos"
-Index,Index
-Mode,Mode
-"Update Required","Mise à jour nécessaire"
-"Change Index Mode","Change mode index"
-"Index mode","Mode index"
-"Cannot initialize the indexer process.","Ne peut initialiser le traitement de l'indexage"
-"The index has been saved.","L'index a été sauvegardé."
-"There was a problem with saving process.","Il y a eu un problème avec le traitement de sauvegarde."
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","Il y a eu un problème avec le traitement de ré-indexage."
-"Please select Indexes","Veuillez sélectionner des index"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Veuillez sélectionner un ou plusieurs index"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Modèle indexage non défini."
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","Mise à jour lors de la sauvegarde"
-"Manual Update","Mise à jour manuelle"
-Ready,Prêt
-Processing,Traitement
-"Reindex Required","Ré-indexage requis"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/nl_NL.csv b/app/code/Magento/Index/i18n/nl_NL.csv
deleted file mode 100644
index fa4cbe6a31f..00000000000
--- a/app/code/Magento/Index/i18n/nl_NL.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,Nee
-Action,Actie
-General,Algemeen
-Yes,Ja
-Status,Status
-Description,Beschrijving
-System,Systeem
-Never,Nooit
-Updated,Updated
-"Index Management","Index Management"
-"Save Process","Save Process"
-"Reindex Data","Data herindexeren"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Index Naam"
-"Index Description","Index Omschrijving"
-"Index Mode","Index Modus"
-"Process Information",Procesinformatie
-Index,Index
-Mode,Modus
-"Update Required","Update is Nodig"
-"Change Index Mode","Change Index Modus"
-"Index mode","Index modus"
-"Cannot initialize the indexer process.","Kan het indexeerproces niet initialiseren."
-"The index has been saved.","De index is opgeslagen."
-"There was a problem with saving process.","Er is een probleem bij het opslaan."
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","Er was een probleem met het herindexeren."
-"Please select Indexes","Selecteer indexen"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Selecteer index(en)"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Indexeermodel is niet gedefinieerd."
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","Update bij opslaan."
-"Manual Update","Handmatige Update"
-Ready,Gereed
-Processing,"Aan het verwerken"
-"Reindex Required","Herindexering noodzakelijk"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/pt_BR.csv b/app/code/Magento/Index/i18n/pt_BR.csv
deleted file mode 100644
index a332b075a9b..00000000000
--- a/app/code/Magento/Index/i18n/pt_BR.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,Não
-Action,Ação
-General,Geral
-Yes,Sim
-Status,Status
-Description,Descrição
-System,Sistema
-Never,Nunca
-Updated,Updated
-"Index Management","Gerenciamento de Índice"
-"Save Process","Save Process"
-"Reindex Data","Reindexar Dados"
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name","Nome do Índice"
-"Index Description","Descrição de Índice"
-"Index Mode","Modo de Índice"
-"Process Information","Processar informação"
-Index,Índice
-Mode,Modo
-"Update Required","Atualização necessária"
-"Change Index Mode","Alterar Modo de Indexação"
-"Index mode","Modo de Índice"
-"Cannot initialize the indexer process.","Não é possível inicializar processo indexador."
-"The index has been saved.","O índice foi salvo"
-"There was a problem with saving process.","Houve um problema no processo de salvar."
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.","Houve um problema com o processo de reindexação."
-"Please select Indexes","Por favor, selecione índices"
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)","Por favor, selecione índice(es)"
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.","Modelo indexador não está definido."
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save","Atualização em Salvar"
-"Manual Update","Atualização Manual"
-Ready,Pronto
-Processing,Processando
-"Reindex Required","Obrigatório Reindexar"
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/i18n/zh_CN.csv b/app/code/Magento/Index/i18n/zh_CN.csv
deleted file mode 100644
index c35413f791a..00000000000
--- a/app/code/Magento/Index/i18n/zh_CN.csv
+++ /dev/null
@@ -1,42 +0,0 @@
-No,否
-Action,操作
-General,常规
-Yes,是
-Status,状态
-Description,描述
-System,系统
-Never,永不
-Updated,Updated
-"Index Management",索引管理
-"Save Process","Save Process"
-"Reindex Data",重新索引数据
-"'%1' Index Process Information","'%1' Index Process Information"
-"Index Name",索引名称
-"Index Description",索引描述
-"Index Mode",索引模式
-"Process Information",处理信息
-Index,索引
-Mode,模式
-"Update Required",需要更新
-"Change Index Mode",更改索引模式
-"Index mode",索引模式
-"Cannot initialize the indexer process.",无法初始化索引器进程。
-"The index has been saved.",索引已保存。
-"There was a problem with saving process.",保存进程遇到问题。
-"%1 index was rebuilt.","%1 index was rebuilt."
-"There was a problem with reindexing process.",重新索引进程遇到问题。
-"Please select Indexes",请选择索引
-"Total of %1 index(es) have reindexed data.","Total of %1 index(es) have reindexed data."
-"Please select Index(es)",请选择索引
-"Total of %1 index(es) have changed index mode.","Total of %1 index(es) have changed index mode."
-"%1 Index process is not working now. Please try running this process later.","%1 Index process is not working now. Please try running this process later."
-"Indexer name is not defined.","Indexer name is not defined."
-"Indexer model is not defined.",索引器模型未定义。
-"Indexer model should extend \Magento\Index\Model\Indexer\Abstract.","Indexer model should extend \Magento\Index\Model\Indexer\Abstract."
-"Update on Save",保存时更新
-"Manual Update",手动更新
-Ready,就绪
-Processing,正在处理
-"Reindex Required",需要重新索引
-"One or more of the Indexes are not up to date: %1","One or more of the Indexes are not up to date: %1"
-"Please go to <a href=""%1"">Index Management</a> and rebuild required indexes.","Please go to <a href=""%1"">Index Management</a> and rebuild required indexes."
diff --git a/app/code/Magento/Index/sql/index_setup/install-1.6.0.0.php b/app/code/Magento/Index/sql/index_setup/install-1.6.0.0.php
deleted file mode 100644
index 5ae4fa33f7f..00000000000
--- a/app/code/Magento/Index/sql/index_setup/install-1.6.0.0.php
+++ /dev/null
@@ -1,189 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-$installer = $this;
-/* @var $installer \Magento\Index\Model\Resource\Setup */
-
-$installer->startSetup();
-
-/**
- * Create table 'index_event'
- */
-$table = $installer->getConnection()->newTable(
-    $installer->getTable('index_event')
-)->addColumn(
-    'event_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT,
-    null,
-    array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
-    'Event Id'
-)->addColumn(
-    'type',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    64,
-    array('nullable' => false),
-    'Type'
-)->addColumn(
-    'entity',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    64,
-    array('nullable' => false),
-    'Entity'
-)->addColumn(
-    'entity_pk',
-    \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT,
-    null,
-    array(),
-    'Entity Primary Key'
-)->addColumn(
-    'created_at',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
-    null,
-    array('nullable' => false),
-    'Creation Time'
-)->addColumn(
-    'old_data',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    '2M',
-    array(),
-    'Old Data'
-)->addColumn(
-    'new_data',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    '2M',
-    array(),
-    'New Data'
-)->addIndex(
-    $installer->getIdxName(
-        'index_event',
-        array('type', 'entity', 'entity_pk'),
-        \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
-    ),
-    array('type', 'entity', 'entity_pk'),
-    array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE)
-)->setComment(
-    'Index Event'
-);
-$installer->getConnection()->createTable($table);
-
-/**
- * Create table 'index_process'
- */
-$table = $installer->getConnection()->newTable(
-    $installer->getTable('index_process')
-)->addColumn(
-    'process_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-    null,
-    array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
-    'Process Id'
-)->addColumn(
-    'indexer_code',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    32,
-    array('nullable' => false),
-    'Indexer Code'
-)->addColumn(
-    'status',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    15,
-    array('nullable' => false, 'default' => 'pending'),
-    'Status'
-)->addColumn(
-    'started_at',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
-    null,
-    array(),
-    'Started At'
-)->addColumn(
-    'ended_at',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
-    null,
-    array(),
-    'Ended At'
-)->addColumn(
-    'mode',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    9,
-    array('nullable' => false, 'default' => 'real_time'),
-    'Mode'
-)->addIndex(
-    $installer->getIdxName(
-        'index_process',
-        array('indexer_code'),
-        \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
-    ),
-    array('indexer_code'),
-    array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE)
-)->setComment(
-    'Index Process'
-);
-$installer->getConnection()->createTable($table);
-
-/**
- * Create table 'index_process_event'
- */
-$table = $installer->getConnection()->newTable(
-    $installer->getTable('index_process_event')
-)->addColumn(
-    'process_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-    null,
-    array('unsigned' => true, 'nullable' => false, 'primary' => true),
-    'Process Id'
-)->addColumn(
-    'event_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT,
-    null,
-    array('unsigned' => true, 'nullable' => false, 'primary' => true),
-    'Event Id'
-)->addColumn(
-    'status',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    7,
-    array('nullable' => false, 'default' => 'new'),
-    'Status'
-)->addIndex(
-    $installer->getIdxName('index_process_event', array('event_id')),
-    array('event_id')
-)->addForeignKey(
-    $installer->getFkName('index_process_event', 'event_id', 'index_event', 'event_id'),
-    'event_id',
-    $installer->getTable('index_event'),
-    'event_id',
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-)->addForeignKey(
-    $installer->getFkName('index_process_event', 'process_id', 'index_process', 'process_id'),
-    'process_id',
-    $installer->getTable('index_process'),
-    'process_id',
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-)->setComment(
-    'Index Process Event'
-);
-$installer->getConnection()->createTable($table);
-
-$installer->endSetup();
diff --git a/app/code/Magento/Index/view/adminhtml/layout/adminhtml_process_edit.xml b/app/code/Magento/Index/view/adminhtml/layout/adminhtml_process_edit.xml
deleted file mode 100644
index fa11da04be7..00000000000
--- a/app/code/Magento/Index/view/adminhtml/layout/adminhtml_process_edit.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceContainer name="content">
-        <block class="Magento\Index\Block\Adminhtml\Process\Edit" name="process_edit"/>
-    </referenceContainer>
-    <referenceContainer name="left">
-        <block class="Magento\Index\Block\Adminhtml\Process\Edit\Tabs" name="index_edit_tabs">
-            <action method="addTab">
-                <argument name="name" xsi:type="string">main_section</argument>
-                <argument name="block" xsi:type="string">Magento\Index\Block\Adminhtml\Process\Edit\Tab\Main</argument>
-            </action>
-        </block>
-    </referenceContainer>
-</page>
diff --git a/app/code/Magento/Indexer/App/Indexer.php b/app/code/Magento/Indexer/App/Indexer.php
index 44fb9a96e73..f84527f37f3 100644
--- a/app/code/Magento/Indexer/App/Indexer.php
+++ b/app/code/Magento/Indexer/App/Indexer.php
@@ -39,11 +39,6 @@ class Indexer implements \Magento\Framework\AppInterface
      */
     protected $filesystem;
 
-    /**
-     * @var \Magento\Index\Model\IndexerFactory
-     */
-    protected $_indexerFactory;
-
     /**
      * @param string $reportDir
      * @param \Magento\Framework\Filesystem $filesystem
diff --git a/app/code/Magento/Indexer/Block/Backend/Container.php b/app/code/Magento/Indexer/Block/Backend/Container.php
index 11c7cdcaaa6..44fb741949c 100644
--- a/app/code/Magento/Indexer/Block/Backend/Container.php
+++ b/app/code/Magento/Indexer/Block/Backend/Container.php
@@ -34,7 +34,7 @@ class Container extends \Magento\Backend\Block\Widget\Grid\Container
     {
         $this->_controller = 'indexer';
         $this->_blockGroup = 'Magento_Indexer';
-        $this->_headerText = __('New Indexer Management');
+        $this->_headerText = __('Indexer Management');
         parent::_construct();
         $this->buttonList->remove('add');
     }
diff --git a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php
index 51dfdc1ca44..cd84c30398c 100644
--- a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php
+++ b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php
@@ -33,7 +33,7 @@ class ListAction extends \Magento\Indexer\Controller\Adminhtml\Indexer
      */
     public function execute()
     {
-        $this->_title->add(__('New Index Management'));
+        $this->_title->add(__('Index Management'));
 
         $this->_view->loadLayout();
         $this->_setActiveMenu('Magento_Indexer::system_index');
diff --git a/app/code/Magento/Index/Model/Resource/AbstractResource.php b/app/code/Magento/Indexer/Model/Resource/AbstractResource.php
similarity index 99%
rename from app/code/Magento/Index/Model/Resource/AbstractResource.php
rename to app/code/Magento/Indexer/Model/Resource/AbstractResource.php
index a08a066cb84..f57c3ad9411 100644
--- a/app/code/Magento/Index/Model/Resource/AbstractResource.php
+++ b/app/code/Magento/Indexer/Model/Resource/AbstractResource.php
@@ -27,7 +27,7 @@
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Index\Model\Resource;
+namespace Magento\Indexer\Model\Resource;
 
 use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\DB\Select;
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index fa1728a98e0..895ea508063 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-page-cache": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-page-cache": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Indexer/etc/acl.xml b/app/code/Magento/Indexer/etc/acl.xml
index ecc2b372817..4fa49ccb2c1 100644
--- a/app/code/Magento/Indexer/etc/acl.xml
+++ b/app/code/Magento/Indexer/etc/acl.xml
@@ -29,7 +29,7 @@
             <resource id="Magento_Adminhtml::admin">
                 <resource id="Magento_Adminhtml::system">
                     <resource id="Magento_Adminhtml::tools">
-                        <resource id="Magento_Indexer::index" title="New Index Management" sortOrder="30" />
+                        <resource id="Magento_Indexer::index" title="Index Management" sortOrder="30" />
                         <resource id="Magento_Indexer::changeMode" title="Change indexer mode" sortOrder="40" />
                     </resource>
                 </resource>
diff --git a/app/code/Magento/Indexer/etc/adminhtml/menu.xml b/app/code/Magento/Indexer/etc/adminhtml/menu.xml
index a3aa754ab08..649daccc2d5 100644
--- a/app/code/Magento/Indexer/etc/adminhtml/menu.xml
+++ b/app/code/Magento/Indexer/etc/adminhtml/menu.xml
@@ -25,6 +25,6 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/menu.xsd">
     <menu>
-        <add id="Magento_Indexer::system_index" title="New Index Management" module="Magento_Indexer" sortOrder="30" parent="Magento_Backend::system_tools" action="indexer/indexer/list" resource="Magento_Indexer::index"/>
+        <add id="Magento_Indexer::system_index" title="Index Management" module="Magento_Indexer" sortOrder="30" parent="Magento_Backend::system_tools" action="indexer/indexer/list" resource="Magento_Indexer::index"/>
     </menu>
 </config>
diff --git a/app/code/Magento/Indexer/i18n/de_DE.csv b/app/code/Magento/Indexer/i18n/de_DE.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/de_DE.csv
+++ b/app/code/Magento/Indexer/i18n/de_DE.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/en_US.csv b/app/code/Magento/Indexer/i18n/en_US.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/en_US.csv
+++ b/app/code/Magento/Indexer/i18n/en_US.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/es_ES.csv b/app/code/Magento/Indexer/i18n/es_ES.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/es_ES.csv
+++ b/app/code/Magento/Indexer/i18n/es_ES.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/fr_FR.csv b/app/code/Magento/Indexer/i18n/fr_FR.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/fr_FR.csv
+++ b/app/code/Magento/Indexer/i18n/fr_FR.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/nl_NL.csv b/app/code/Magento/Indexer/i18n/nl_NL.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/nl_NL.csv
+++ b/app/code/Magento/Indexer/i18n/nl_NL.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/pt_BR.csv b/app/code/Magento/Indexer/i18n/pt_BR.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/pt_BR.csv
+++ b/app/code/Magento/Indexer/i18n/pt_BR.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Indexer/i18n/zh_CN.csv b/app/code/Magento/Indexer/i18n/zh_CN.csv
index ebe2a2f240e..aab33db9d18 100644
--- a/app/code/Magento/Indexer/i18n/zh_CN.csv
+++ b/app/code/Magento/Indexer/i18n/zh_CN.csv
@@ -6,10 +6,10 @@ Mode,Mode
 "Update on Save","Update on Save"
 Ready,Ready
 Processing,Processing
-"New Indexer Management","New Indexer Management"
+"Indexer Management","Indexer Management"
 "Update by Schedule","Update by Schedule"
 "Reindex required","Reindex required"
-"New Index Management","New Index Management"
+"Index Management","Index Management"
 "Please select indexers.","Please select indexers."
 "A total of %1 indexer(s) have been turned Update on Save mode on.","A total of %1 indexer(s) have been turned Update on Save mode on."
 "We couldn't change indexer(s)' mode because of an error.","We couldn't change indexer(s)' mode because of an error."
diff --git a/app/code/Magento/Install/composer.json b/app/code/Magento/Install/composer.json
index 94f9c15eff7..54dfe0c181d 100644
--- a/app/code/Magento/Install/composer.json
+++ b/app/code/Magento/Install/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-user": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-user": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Install/view/adminhtml/layout/default.xml b/app/code/Magento/Install/view/adminhtml/layout/default.xml
index b3ba328b0a5..3bacc754557 100644
--- a/app/code/Magento/Install/view/adminhtml/layout/default.xml
+++ b/app/code/Magento/Install/view/adminhtml/layout/default.xml
@@ -24,11 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-install-survey-notification-js" after="jquery">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Install::survey_notification.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_Install::survey_notification.js"/>
+    </head>
 </page>
diff --git a/app/code/Magento/Install/view/install/templates/page.phtml b/app/code/Magento/Install/view/install/templates/page.phtml
index 20c623ff9ae..83c6dfce4f7 100644
--- a/app/code/Magento/Install/view/install/templates/page.phtml
+++ b/app/code/Magento/Install/view/install/templates/page.phtml
@@ -22,11 +22,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php
-/**
- * @var $this \Magento\Theme\Block\Html\Head
- */
-?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json
index effb8a631bc..9c0e59d43d4 100644
--- a/app/code/Magento/Integration/composer.json
+++ b/app/code/Magento/Integration/composer.json
@@ -3,18 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-user": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
-        "magento/module-authorization": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-user": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/module-authorization": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Integration/etc/module.xml b/app/code/Magento/Integration/etc/module.xml
index eb76e22b29d..0e4006a7e16 100644
--- a/app/code/Magento/Integration/etc/module.xml
+++ b/app/code/Magento/Integration/etc/module.xml
@@ -36,7 +36,6 @@
             <module name="Magento_Core"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Customer"/>
-            <module name="Magento_Theme"/>
             <module name="Magento_User"/>
         </depends>
     </module>
diff --git a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_index.xml b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_index.xml
index 9084a59de97..aa065fb1b8a 100644
--- a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_index.xml
+++ b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_index.xml
@@ -26,13 +26,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-integration-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Integration::integration.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_Integration::integration.css"/>
+    </head>
     <update handle="adminhtml_integration_grid_block"/>
     <referenceBlock name="content">
         <block class="Magento\Backend\Block\Template" name="integration.popup.container" template="Magento_Integration::integration/popup_container.phtml" before="-"/>
diff --git a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_new.xml b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_new.xml
index d64bd1140cd..1a7a5a6f04a 100644
--- a/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_new.xml
+++ b/app/code/Magento/Integration/view/adminhtml/layout/adminhtml_integration_new.xml
@@ -23,14 +23,10 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-integration-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Integration::integration.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <head>
+        <css src="Magento_Integration::integration.css"/>
+    </head>
     <update handle="adminhtml_integration_edit"/>
     <referenceBlock name="content">
         <block class="Magento\Backend\Block\Template" name="integration.popup.container" template="Magento_Integration::integration/popup_container.phtml" before="-"/>
diff --git a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml
index 0c57fe56d62..2f1fd42eb00 100644
--- a/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml
+++ b/app/code/Magento/Integration/view/adminhtml/templates/integration/popup_container.phtml
@@ -45,7 +45,7 @@ require([
      * Confirm dialog for delete integration action
      */
     $(function () {
-        $('#integrationGrid_table').on('click', 'button#delete', function (e) {
+        $('div#integrationGrid').on('click', 'button#delete', function (e) {
             $('#integration-delete-container').dialog({
                 modal: true,
                 autoOpen: true,
@@ -53,7 +53,7 @@ require([
                 minHeight: 200,
                 minWidth: 300,
                 dialogClass: "no-close",
-                position: {at: 'top'},
+                position: {at: 'center'},
                 buttons: {
                     Cancel: function () {
                         $(this).dialog("close");
diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json
index eb767363bad..8086986cb7b 100644
--- a/app/code/Magento/LayeredNavigation/composer.json
+++ b/app/code/Magento/LayeredNavigation/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/page_one_column.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/1column.xml
similarity index 100%
rename from app/code/Magento/LayeredNavigation/view/frontend/layout/page_one_column.xml
rename to app/code/Magento/LayeredNavigation/view/frontend/layout/1column.xml
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/page_two_columns_left.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/2columns-left.xml
similarity index 100%
rename from app/code/Magento/LayeredNavigation/view/frontend/layout/page_two_columns_left.xml
rename to app/code/Magento/LayeredNavigation/view/frontend/layout/2columns-left.xml
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/page_two_columns_right.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/2columns-right.xml
similarity index 100%
rename from app/code/Magento/LayeredNavigation/view/frontend/layout/page_two_columns_right.xml
rename to app/code/Magento/LayeredNavigation/view/frontend/layout/2columns-right.xml
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/page_three_columns.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/3columns.xml
similarity index 100%
rename from app/code/Magento/LayeredNavigation/view/frontend/layout/page_three_columns.xml
rename to app/code/Magento/LayeredNavigation/view/frontend/layout/3columns.xml
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/catalog_category_view_type_layered.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/catalog_category_view_type_layered.xml
index 1a9c3455d71..026096a37ad 100644
--- a/app/code/Magento/LayeredNavigation/view/frontend/layout/catalog_category_view_type_layered.xml
+++ b/app/code/Magento/LayeredNavigation/view/frontend/layout/catalog_category_view_type_layered.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="root">
-        <action method="addBodyClass">
-            <argument name="class" xsi:type="string">page-with-filter</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="page-with-filter"/>
+    </body>
     <referenceContainer name="sidebar.main">
         <block class="Magento\LayeredNavigation\Block\Navigation\Category" name="catalog.leftnav" before="-" template="layer/view.phtml">
             <block class="Magento\LayeredNavigation\Block\Navigation\State\Category" name="catalog.navigation.state" as="state" />
diff --git a/app/code/Magento/LayeredNavigation/view/frontend/layout/catalogsearch_advanced_result.xml b/app/code/Magento/LayeredNavigation/view/frontend/layout/catalogsearch_advanced_result.xml
index e9923f2e9f1..e1c51db81d0 100644
--- a/app/code/Magento/LayeredNavigation/view/frontend/layout/catalogsearch_advanced_result.xml
+++ b/app/code/Magento/LayeredNavigation/view/frontend/layout/catalogsearch_advanced_result.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="left">
         <block class="Magento\LayeredNavigation\Block\Navigation\AdvancedSearch" name="advanced.search.leftnav" before="-" template="layer/view.phtml">
             <block class="Magento\LayeredNavigation\Block\Navigation\State\AdvancedSearch" name="advanced.search.navigation.state" as="state" />
diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json
index 83aa5c46e14..69e46c04b5f 100644
--- a/app/code/Magento/Log/composer.json
+++ b/app/code/Magento/Log/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Log/view/adminhtml/layout/customer_online_index.xml b/app/code/Magento/Log/view/adminhtml/layout/visitor_online_index.xml
similarity index 100%
rename from app/code/Magento/Log/view/adminhtml/layout/customer_online_index.xml
rename to app/code/Magento/Log/view/adminhtml/layout/visitor_online_index.xml
diff --git a/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type.php b/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type.php
new file mode 100644
index 00000000000..6a3ce7eda43
--- /dev/null
+++ b/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Block\Adminhtml\Product\Helper\Form;
+
+/**
+ * Product form MSRP field helper
+ */
+class Type extends \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Price
+{
+    /** @var \Magento\Msrp\Model\Config*/
+    protected $config;
+
+    /**
+     * @param \Magento\Framework\Data\Form\Element\Factory $factoryElement
+     * @param \Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection
+     * @param \Magento\Framework\Escaper $escaper
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency
+     * @param \Magento\Tax\Helper\Data $taxData
+     * @param \Magento\Msrp\Model\Config $config
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\Data\Form\Element\Factory $factoryElement,
+        \Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection,
+        \Magento\Framework\Escaper $escaper,
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\Locale\CurrencyInterface $localeCurrency,
+        \Magento\Tax\Helper\Data $taxData,
+        \Magento\Msrp\Model\Config $config,
+        array $data = array()
+    ) {
+        parent::__construct(
+            $factoryElement,
+            $factoryCollection,
+            $escaper,
+            $storeManager,
+            $localeCurrency,
+            $taxData,
+            $data
+        );
+        $this->config = $config;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function toHtml()
+    {
+        if ($this->config->isEnabled()) {
+            return parent::toHtml();
+        }
+        return '';
+    }
+}
diff --git a/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type/Price.php b/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type/Price.php
new file mode 100644
index 00000000000..8ad31a3d047
--- /dev/null
+++ b/app/code/Magento/Msrp/Block/Adminhtml/Product/Helper/Form/Type/Price.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Block\Adminhtml\Product\Helper\Form\Type;
+
+use Magento\Framework\Data\Form\Element\CollectionFactory;
+use Magento\Framework\Data\Form\Element\Factory;
+use Magento\Framework\Escaper;
+
+/**
+ * Product form MSRP field helper
+ */
+class Price extends \Magento\Framework\Data\Form\Element\Select
+{
+    /** @var \Magento\Msrp\Model\Config */
+    protected $config;
+
+    /**
+     * @param Factory $factoryElement
+     * @param CollectionFactory $factoryCollection
+     * @param Escaper $escaper
+     * @param \Magento\Msrp\Model\Config $config
+     * @param array $data
+     */
+    public function __construct(
+        Factory $factoryElement,
+        CollectionFactory $factoryCollection,
+        Escaper $escaper,
+        \Magento\Msrp\Model\Config $config,
+        $data = array()
+    ) {
+        parent::__construct($factoryElement, $factoryCollection, $escaper, $data);
+        $this->config = $config;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function toHtml()
+    {
+        if (!$this->config->isEnabled()) {
+            return '';
+        }
+        return parent::toHtml();
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Category/Widget/Link.php b/app/code/Magento/Msrp/Block/Popup.php
similarity index 60%
rename from app/code/Magento/Catalog/Block/Category/Widget/Link.php
rename to app/code/Magento/Msrp/Block/Popup.php
index 204e730b26c..4bfccea2e02 100644
--- a/app/code/Magento/Catalog/Block/Category/Widget/Link.php
+++ b/app/code/Magento/Msrp/Block/Popup.php
@@ -21,29 +21,50 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Msrp\Block;
 
-/**
- * Widget to display link to the category
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Catalog\Block\Category\Widget;
-
-class Link extends \Magento\Catalog\Block\Widget\Link
+class Popup extends \Magento\Framework\View\Element\Template
 {
+    /**
+     * @var \Magento\Msrp\Model\Config
+     */
+    protected $config;
+
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite
-     * @param \Magento\Catalog\Model\Resource\Category $resourceCategory
+     * @param \Magento\Msrp\Model\Config $config
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\UrlRewrite\Model\Resource\UrlRewrite $urlRewrite,
-        \Magento\Catalog\Model\Resource\Category $resourceCategory,
+        \Magento\Msrp\Model\Config $config,
         array $data = array()
     ) {
-        parent::__construct($context, $urlRewrite, $data);
-        $this->_entityResource = $resourceCategory;
+        $this->config = $config;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return $this->config->isEnabled();
+    }
+
+    /**
+     * @return string
+     */
+    public function getExplanationMessage()
+    {
+        return $this->config->getExplanationMessage();
+    }
+
+    /**
+     * @return string
+     */
+    public function getExplanationMessageWhatsThis()
+    {
+        return $this->config->getExplanationMessageWhatsThis();
     }
 }
diff --git a/app/code/Magento/Rss/Block/AbstractBlock.php b/app/code/Magento/Msrp/Block/Total.php
similarity index 54%
rename from app/code/Magento/Rss/Block/AbstractBlock.php
rename to app/code/Magento/Msrp/Block/Total.php
index 6b1128bde84..265552f7b00 100644
--- a/app/code/Magento/Rss/Block/AbstractBlock.php
+++ b/app/code/Magento/Msrp/Block/Total.php
@@ -21,55 +21,46 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Block;
+namespace Magento\Msrp\Block;
 
-class AbstractBlock extends \Magento\Framework\View\Element\Template
+/**
+ * @method string getOriginalBlockName()
+ */
+class Total extends \Magento\Framework\View\Element\Template
 {
-    /**
-     * @var \Magento\Framework\App\Http\Context
-     */
-    protected $httpContext;
+    /** @var \Magento\Msrp\Model\Config */
+    protected $config;
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
+     * @param \Magento\Msrp\Model\Config $config
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
+        \Magento\Msrp\Model\Config $config,
         array $data = array()
     ) {
-        $this->httpContext = $httpContext;
         parent::__construct($context, $data);
-        $this->_isScopePrivate = true;
+        $this->config = $config;
     }
 
     /**
-     * Get store id
-     *
-     * @return int
+     * @return string
      */
-    protected function _getStoreId()
+    protected function _toHtml()
     {
-        $storeId = (int)$this->getRequest()->getParam('store_id');
-        if ($storeId == null) {
-            $storeId = $this->_storeManager->getStore()->getId();
+        /** @var \Magento\Checkout\Block\Cart\AbstractCart $originalBlock */
+        $originalBlock = $this->getLayout()->getBlock($this->getOriginalBlockName());
+        $quote = $originalBlock->getQuote();
+        if (!$quote->hasCanApplyMsrp() && $this->config->isEnabled()) {
+            $quote->collectTotals();
         }
-        return $storeId;
-    }
-
-    /**
-     * Get customer group id
-     *
-     * @return int
-     */
-    protected function _getCustomerGroupId()
-    {
-        $customerGroupId =   (int) $this->getRequest()->getParam('cid');
-        if ($customerGroupId == null) {
-            $customerGroupId = $this->httpContext->getValue(\Magento\Customer\Helper\Data::CONTEXT_GROUP);
+        if ($quote->getCanApplyMsrp()) {
+            $originalBlock->setTemplate('');
+            return parent::_toHtml();
+        } else {
+            return '';
         }
-        return $customerGroupId;
     }
 }
diff --git a/app/code/Magento/Msrp/Helper/Data.php b/app/code/Magento/Msrp/Helper/Data.php
new file mode 100644
index 00000000000..98531d5ca97
--- /dev/null
+++ b/app/code/Magento/Msrp/Helper/Data.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Helper;
+
+use Magento\Framework\App\Helper\AbstractHelper;
+use Magento\Framework\App\Helper\Context;
+use Magento\Msrp\Model\Product\Attribute\Source\Type;
+use Magento\Framework\StoreManagerInterface;
+use Magento\Catalog\Model\ProductFactory;
+use Magento\Catalog\Model\Product;
+
+/**
+ * Msrp data helper
+ */
+class Data extends AbstractHelper
+{
+    /**
+     * @var ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Msrp\Model\Product\Options
+     */
+    protected $productOptions;
+
+    /**
+     * @var \Magento\Msrp\Model\Config
+     */
+    protected $config;
+
+    /**
+     * @param Context $context
+     * @param ProductFactory $productFactory
+     * @param StoreManagerInterface $storeManager
+     * @param \Magento\Msrp\Model\Product\Options $productOptions
+     * @param \Magento\Msrp\Model\Msrp $msrp
+     * @param \Magento\Msrp\Model\Config $config
+     */
+    public function __construct(
+        Context $context,
+        ProductFactory $productFactory,
+        StoreManagerInterface $storeManager,
+        \Magento\Msrp\Model\Product\Options $productOptions,
+        \Magento\Msrp\Model\Msrp $msrp,
+        \Magento\Msrp\Model\Config $config
+    ) {
+        parent::__construct($context);
+        $this->productFactory = $productFactory;
+        $this->storeManager = $storeManager;
+        $this->productOptions = $productOptions;
+        $this->msrp = $msrp;
+        $this->config = $config;
+    }
+
+    /**
+     * Check if can apply Minimum Advertise price to product
+     * in specific visibility
+     *
+     * @param int|Product $product
+     * @param int|null $visibility Check displaying price in concrete place (by default generally)
+     * @return bool
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function canApplyMsrp($product, $visibility = null)
+    {
+        if (!$this->config->isEnabled()) {
+            return false;
+        }
+        if (is_numeric($product)) {
+            $product = $this->productFactory->create()
+                ->setStoreId($this->storeManager->getStore()->getId())
+                ->load($product);
+        }
+        $result = $this->msrp->canApplyToProduct($product);
+        if ($result && $visibility !== null) {
+            $productPriceVisibility = $product->getMsrpDisplayActualPriceType();
+            if ($productPriceVisibility == Type\Price::TYPE_USE_CONFIG) {
+                $productPriceVisibility = $this->config->getDisplayActualPriceType();
+            }
+            $result = $productPriceVisibility == $visibility;
+        }
+
+        if ($product->getTypeInstance()->isComposite($product) && (!$result || $visibility !== null)) {
+            $isEnabledInOptions = $this->productOptions->isEnabled($product, $visibility);
+            if ($isEnabledInOptions !== null) {
+                $result = $isEnabledInOptions;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get Msrp message for price
+     *
+     * @param Product $product
+     * @return string
+     */
+    public function getMsrpPriceMessage($product)
+    {
+        $message = "";
+        if ($this->canApplyMsrp($product, Type::TYPE_IN_CART)) {
+            $message = __('To see product price, add this item to your cart. You can always remove it later.');
+        } elseif ($this->canApplyMsrp($product, Type::TYPE_BEFORE_ORDER_CONFIRM)) {
+            $message = __('See price before order confirmation.');
+        }
+        return $message;
+    }
+
+    /**
+     * Check is product need gesture to show price
+     *
+     * @param int|Product $product
+     * @return bool
+     */
+    public function isShowPriceOnGesture($product)
+    {
+        return $this->canApplyMsrp($product, Type::TYPE_ON_GESTURE);
+    }
+
+    /**
+     * @param int|Product $product
+     * @return bool
+     */
+    public function isShowBeforeOrderConfirm($product)
+    {
+        return $this->canApplyMsrp($product, Type::TYPE_BEFORE_ORDER_CONFIRM);
+    }
+
+    /**
+     * @param int|Product $product
+     * @return bool|float
+     */
+    public function isMinimalPriceLessMsrp($product)
+    {
+        if (is_numeric($product)) {
+            $product = $this->productFactory->create()
+                ->setStoreId($this->storeManager->getStore()->getId())
+                ->load($product);
+        }
+        $msrp = $product->getMsrp();
+        $price = $product->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE);
+        if ($msrp === null) {
+            if ($product->getTypeId() !== \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE) {
+                return false;
+            } else {
+                $msrp = $product->getTypeInstance()->getChildrenMsrp($product);
+            }
+        }
+        return $msrp > $price->getValue();
+    }
+}
diff --git a/app/code/Magento/Msrp/Model/Config.php b/app/code/Magento/Msrp/Model/Config.php
new file mode 100644
index 00000000000..d55447e2a02
--- /dev/null
+++ b/app/code/Magento/Msrp/Model/Config.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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Model;
+
+use Magento\Store\Model\ScopeInterface;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\StoreManagerInterface;
+use Magento\Framework\Escaper;
+
+class Config
+{
+    /**#@+
+     * Minimum advertise price constants
+     */
+    const XML_PATH_MSRP_ENABLED = 'sales/msrp/enabled';
+    const XML_PATH_MSRP_DISPLAY_ACTUAL_PRICE_TYPE = 'sales/msrp/display_price_type';
+    const XML_PATH_MSRP_EXPLANATION_MESSAGE = 'sales/msrp/explanation_message';
+    const XML_PATH_MSRP_EXPLANATION_MESSAGE_WHATS_THIS = 'sales/msrp/explanation_message_whats_this';
+    /**#@-*/
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var Escaper
+     */
+    protected $escaper;
+
+    /**
+     * @var int
+     */
+    protected $storeId;
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     * @param StoreManagerInterface $storeManager
+     * @param Escaper $escaper
+     */
+    public function __construct(
+        ScopeConfigInterface $scopeConfig,
+        StoreManagerInterface $storeManager,
+        Escaper $escaper
+    ) {
+        $this->scopeConfig = $scopeConfig;
+        $this->storeManager = $storeManager;
+        $this->escaper = $escaper;
+    }
+
+    /**
+     * Set a specified store ID value
+     *
+     * @param int $store
+     * @return $this
+     */
+    public function setStoreId($store)
+    {
+        $this->storeId = $store;
+        return $this;
+    }
+
+    /**
+     * Check if Minimum Advertised Price is enabled
+     *
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return (bool)$this->scopeConfig->getValue(
+            self::XML_PATH_MSRP_ENABLED,
+            ScopeInterface::SCOPE_STORE,
+            $this->storeId
+        );
+    }
+
+    /**
+     * Return Msrp display actual type
+     *
+     * @return null|string
+     */
+    public function getDisplayActualPriceType()
+    {
+        return $this->scopeConfig->getValue(
+            self::XML_PATH_MSRP_DISPLAY_ACTUAL_PRICE_TYPE,
+            ScopeInterface::SCOPE_STORE,
+            $this->storeId
+        );
+    }
+
+    /**
+     * Return Msrp explanation message
+     *
+     * @return string
+     */
+    public function getExplanationMessage()
+    {
+        return $this->escaper->escapeHtml(
+            $this->scopeConfig->getValue(
+                self::XML_PATH_MSRP_EXPLANATION_MESSAGE,
+                ScopeInterface::SCOPE_STORE,
+                $this->storeId
+            ),
+            array('b', 'br', 'strong', 'i', 'u', 'p', 'span')
+        );
+    }
+
+    /**
+     * Return Msrp explanation message for "Whats This" window
+     *
+     * @return string
+     */
+    public function getExplanationMessageWhatsThis()
+    {
+        return $this->escaper->escapeHtml(
+            $this->scopeConfig->getValue(
+                self::XML_PATH_MSRP_EXPLANATION_MESSAGE_WHATS_THIS,
+                ScopeInterface::SCOPE_STORE,
+                $this->storeId
+            ),
+            array('b', 'br', 'strong', 'i', 'u', 'p', 'span')
+        );
+    }
+}
diff --git a/setup/module/Magento/Config/src/Dom/NodeMergingConfig.php b/app/code/Magento/Msrp/Model/Msrp.php
similarity index 50%
rename from setup/module/Magento/Config/src/Dom/NodeMergingConfig.php
rename to app/code/Magento/Msrp/Model/Msrp.php
index 1c5a0e2687e..de343665e5e 100644
--- a/setup/module/Magento/Config/src/Dom/NodeMergingConfig.php
+++ b/app/code/Magento/Msrp/Model/Msrp.php
@@ -17,52 +17,49 @@
  * 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.
- *
+ *   
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Config\Dom;
+namespace Magento\Msrp\Model;
 
-/**
- * Configuration of identifier attributes to be taken into account during merging
- */
-class NodeMergingConfig
+use Magento\Catalog\Model\Resource\Eav\AttributeFactory;
+use Magento\Catalog\Model\Product;
+
+class Msrp
 {
     /**
-     * @var NodePathMatcher
+     * @var array
      */
-    private $nodePathMatcher;
+    protected $mapApplyToProductType = null;
 
     /**
-     * Format: array('/node/path' => '<node_id_attribute>', ...)
-     *
-     * @var array
+     * @var AttributeFactory
      */
-    private $idAttributes = array();
+    protected $eavAttributeFactory;
 
     /**
-     * @param NodePathMatcher $nodePathMatcher
-     * @param array $idAttributes
+     * @param AttributeFactory $eavAttributeFactory
      */
-    public function __construct(NodePathMatcher $nodePathMatcher, array $idAttributes)
-    {
-        $this->nodePathMatcher = $nodePathMatcher;
-        $this->idAttributes = $idAttributes;
+    public function __construct(
+        AttributeFactory $eavAttributeFactory
+    ) {
+        $this->eavAttributeFactory = $eavAttributeFactory;
     }
 
     /**
-     * Retrieve name of an identifier attribute for a node
+     * Check whether Msrp applied to product Product Type
      *
-     * @param string $nodeXpath
-     * @return string|null
+     * @param \Magento\Catalog\Model\Product $product
+     * @return bool
      */
-    public function getIdAttribute($nodeXpath)
+    public function canApplyToProduct($product)
     {
-        foreach ($this->idAttributes as $pathPattern => $idAttribute) {
-            if ($this->nodePathMatcher->match($pathPattern, $nodeXpath)) {
-                return $idAttribute;
-            }
+        if ($this->mapApplyToProductType === null) {
+            /** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */
+            $attribute = $this->eavAttributeFactory->create()->loadByCode(Product::ENTITY, 'msrp');
+            $this->mapApplyToProductType = $attribute->getApplyTo();
         }
-        return null;
+        return in_array($product->getTypeId(), $this->mapApplyToProductType);
     }
 }
diff --git a/app/code/Magento/Sales/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php b/app/code/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php
similarity index 81%
rename from app/code/Magento/Sales/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php
rename to app/code/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php
index de383494690..81ae6ee288d 100644
--- a/app/code/Magento/Sales/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php
+++ b/app/code/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrp.php
@@ -21,28 +21,24 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Model\Observer\Frontend\Quote;
+namespace Magento\Msrp\Model\Observer\Frontend\Quote;
 
-use Magento\Catalog\Helper\Data as CatalogData;
+use Magento\Msrp\Model\Config;
 
 /**
  * Class SetCanApplyMsrp
  */
 class SetCanApplyMsrp
 {
-    /**
-     * Catalog data
-     *
-     * @var CatalogData
-     */
-    protected $catalogData;
+    /** @var Config */
+    protected $config;
 
     /**
-     * @param CatalogData $catalogData
+     * @param Config $config
      */
-    public function __construct(CatalogData $catalogData)
+    public function __construct(Config $config)
     {
-        $this->catalogData = $catalogData;
+        $this->config = $config;
     }
 
     /**
@@ -57,7 +53,7 @@ class SetCanApplyMsrp
         $quote = $observer->getEvent()->getQuote();
 
         $canApplyMsrp = false;
-        if ($this->catalogData->isMsrpEnabled()) {
+        if ($this->config->isEnabled()) {
             foreach ($quote->getAllAddresses() as $address) {
                 if ($address->getCanApplyMsrp()) {
                     $canApplyMsrp = true;
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type.php b/app/code/Magento/Msrp/Model/Product/Attribute/Source/Type.php
similarity index 81%
rename from app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type.php
rename to app/code/Magento/Msrp/Model/Product/Attribute/Source/Type.php
index 31f95e38e44..20267405d72 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type.php
+++ b/app/code/Magento/Msrp/Model/Product/Attribute/Source/Type.php
@@ -21,30 +21,27 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Msrp\Model\Product\Attribute\Source;
 
 /**
- * Catalog product MAP "Display Actual Price" attribute source
- *
- * @author     Magento Core Team <core@magentocommerce.com>
+ * Catalog product Msrp "Display Actual Price" attribute source
  */
-namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp;
-
 class Type extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
 {
     /**
      * Display Product Price on gesture
      */
-    const TYPE_ON_GESTURE = '1';
+    const TYPE_ON_GESTURE = 1;
 
     /**
      * Display Product Price in cart
      */
-    const TYPE_IN_CART = '2';
+    const TYPE_IN_CART = 2;
 
     /**
      * Display Product Price before order confirmation
      */
-    const TYPE_BEFORE_ORDER_CONFIRM = '3';
+    const TYPE_BEFORE_ORDER_CONFIRM = 3;
 
     /**
      * Get all options
@@ -55,9 +52,9 @@ class Type extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
     {
         if (!$this->_options) {
             $this->_options = array(
+                array('label' => __('On Gesture'), 'value' => self::TYPE_ON_GESTURE),
                 array('label' => __('In Cart'), 'value' => self::TYPE_IN_CART),
-                array('label' => __('Before Order Confirmation'), 'value' => self::TYPE_BEFORE_ORDER_CONFIRM),
-                array('label' => __('On Gesture'), 'value' => self::TYPE_ON_GESTURE)
+                array('label' => __('Before Order Confirmation'), 'value' => self::TYPE_BEFORE_ORDER_CONFIRM)
             );
         }
         return $this->_options;
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php b/app/code/Magento/Msrp/Model/Product/Attribute/Source/Type/Price.php
similarity index 71%
rename from app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php
rename to app/code/Magento/Msrp/Model/Product/Attribute/Source/Type/Price.php
index 5c3ebf471b8..7ce0ebcf797 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php
+++ b/app/code/Magento/Msrp/Model/Product/Attribute/Source/Type/Price.php
@@ -21,57 +21,44 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Msrp\Model\Product\Attribute\Source\Type;
 
 /**
  * Source model for 'msrp_display_actual_price_type' product attribute
- *
- * @author     Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type;
-
-class Price extends \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type
+class Price extends \Magento\Msrp\Model\Product\Attribute\Source\Type
 {
     /**
      * Get value from the store configuration settings
      */
-    const TYPE_USE_CONFIG = '4';
-
-    /**
-     * Core data
-     *
-     * @var \Magento\Core\Helper\Data
-     */
-    protected $_coreData = null;
+    const TYPE_USE_CONFIG = 0;
 
     /**
      * Entity attribute factory
      *
      * @var \Magento\Eav\Model\Resource\Entity\AttributeFactory
      */
-    protected $_entityAttributeFactory;
+    protected $entityAttributeFactory;
 
     /**
      * Eav resource helper
      *
      * @var \Magento\Eav\Model\Resource\Helper
      */
-    protected $_eavResourceHelper;
+    protected $eavResourceHelper;
 
     /**
      * Construct
      *
      * @param \Magento\Eav\Model\Resource\Entity\AttributeFactory $entityAttributeFactory
-     * @param \Magento\Core\Helper\Data $coreData
      * @param \Magento\Eav\Model\Resource\Helper $eavResourceHelper
      */
     public function __construct(
         \Magento\Eav\Model\Resource\Entity\AttributeFactory $entityAttributeFactory,
-        \Magento\Core\Helper\Data $coreData,
         \Magento\Eav\Model\Resource\Helper $eavResourceHelper
     ) {
-        $this->_entityAttributeFactory = $entityAttributeFactory;
-        $this->_coreData = $coreData;
-        $this->_eavResourceHelper = $eavResourceHelper;
+        $this->entityAttributeFactory = $entityAttributeFactory;
+        $this->eavResourceHelper = $eavResourceHelper;
     }
 
     /**
@@ -82,8 +69,10 @@ class Price extends \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type
     public function getAllOptions()
     {
         if (!$this->_options) {
-            $this->_options = parent::getAllOptions();
-            $this->_options[] = array('label' => __('Use config'), 'value' => self::TYPE_USE_CONFIG);
+            $this->_options = array_merge(
+                [['label' => __('Use config'), 'value' => self::TYPE_USE_CONFIG]],
+                parent::getAllOptions()
+            );
         }
         return $this->_options;
     }
@@ -103,7 +92,7 @@ class Price extends \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type
                 'unsigned' => false,
                 'default' => null,
                 'extra' => null,
-                'type' => $this->_eavResourceHelper->getDdlTypeByColumnType($attributeType),
+                'type' => $this->eavResourceHelper->getDdlTypeByColumnType($attributeType),
                 'nullable' => true,
             ],
         ];
@@ -117,6 +106,6 @@ class Price extends \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type
      */
     public function getFlatUpdateSelect($store)
     {
-        return $this->_entityAttributeFactory->create()->getFlatUpdateSelect($this->getAttribute(), $store);
+        return $this->entityAttributeFactory->create()->getFlatUpdateSelect($this->getAttribute(), $store);
     }
 }
diff --git a/app/code/Magento/Msrp/Model/Product/Options.php b/app/code/Magento/Msrp/Model/Product/Options.php
new file mode 100644
index 00000000000..bd777ab8c50
--- /dev/null
+++ b/app/code/Magento/Msrp/Model/Product/Options.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.
+ *   
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Model\Product;
+
+use Magento\Msrp\Model\Product\Attribute\Source\Type\Price as TypePrice;
+
+class Options
+{
+    /**
+     * @var \Magento\Msrp\Model\Config
+     */
+    protected $config;
+
+    /**
+     * @var \Magento\Msrp\Helper\Data
+     */
+    protected $msrpData;
+
+    /**
+     * @param \Magento\Msrp\Model\Config $config
+     * @param \Magento\Msrp\Helper\Data $msrpData
+     */
+    public function __construct(
+        \Magento\Msrp\Model\Config $config,
+        \Magento\Msrp\Helper\Data $msrpData
+    ) {
+        $this->config = $config;
+        $this->msrpData = $msrpData;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @param null $visibility
+     * @return bool|null
+     */
+    public function isEnabled($product, $visibility = null)
+    {
+        $visibilities = $this->getVisibilities($product);
+
+        $result = (bool)$visibilities ? true : null;
+        if ($result && $visibility !== null) {
+            if ($visibilities) {
+                $maxVisibility = max($visibilities);
+                $result = $result && $maxVisibility == $visibility;
+            } else {
+                $result = false;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product $product
+     * @return array
+     */
+    protected function getVisibilities($product)
+    {
+        /** @var \Magento\Catalog\Model\Product[] $collection */
+        $collection = $product->getTypeInstance()->getAssociatedProducts($product)?: [];
+        $visibilities = [];
+        /** @var \Magento\Catalog\Model\Product $item */
+        foreach ($collection as $item) {
+            if ($this->msrpData->canApplyMsrp($item)) {
+                $visibilities[] = $item->getMsrpDisplayActualPriceType() == TypePrice::TYPE_USE_CONFIG
+                    ? $this->config->getDisplayActualPriceType()
+                    : $item->getMsrpDisplayActualPriceType();
+            }
+        }
+        return $visibilities;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Quote/Address/Total/Msrp.php b/app/code/Magento/Msrp/Model/Quote/Address/Total.php
similarity index 68%
rename from app/code/Magento/Sales/Model/Quote/Address/Total/Msrp.php
rename to app/code/Magento/Msrp/Model/Quote/Address/Total.php
index a5b60bc196a..bd7d1cbcd65 100644
--- a/app/code/Magento/Sales/Model/Quote/Address/Total/Msrp.php
+++ b/app/code/Magento/Msrp/Model/Quote/Address/Total.php
@@ -21,29 +21,24 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Model\Quote\Address\Total;
+namespace Magento\Msrp\Model\Quote\Address;
 
 /**
  * Msrp items total
- * Collects flag if MSRP price is in use
- *
- * @author     Magento Core Team <core@magentocommerce.com>
  */
-class Msrp extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
+class Total extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
 {
     /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
+     * @var \Magento\Msrp\Helper\Data
      */
-    protected $_catalogData = null;
+    protected $msrpData = null;
 
     /**
-     * @param \Magento\Catalog\Helper\Data $catalogData
+     * @param \Magento\Msrp\Helper\Data $msrpData
      */
-    public function __construct(\Magento\Catalog\Helper\Data $catalogData)
+    public function __construct(\Magento\Msrp\Helper\Data $msrpData)
     {
-        $this->_catalogData = $catalogData;
+        $this->msrpData = $msrpData;
     }
 
     /**
@@ -63,11 +58,9 @@ class Msrp extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
 
         $canApplyMsrp = false;
         foreach ($items as $item) {
-            if (!$item->getParentItemId() && $this->_catalogData->canApplyMsrp(
-                $item->getProductId(),
-                \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_BEFORE_ORDER_CONFIRM,
-                true
-            )
+            if (!$item->getParentItemId()
+                    && $this->msrpData->isShowBeforeOrderConfirm($item->getProductId())
+                    && $this->msrpData->isMinimalPriceLessMsrp($item->getProductId())
             ) {
                 $canApplyMsrp = true;
                 break;
diff --git a/app/code/Magento/Msrp/Plugin/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php b/app/code/Magento/Msrp/Plugin/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
new file mode 100644
index 00000000000..4b5bd2ee3d5
--- /dev/null
+++ b/app/code/Magento/Msrp/Plugin/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php
@@ -0,0 +1,65 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Plugin\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab;
+
+use Magento\Msrp\Model\Product\Attribute\Source\Type\Price;
+
+class Attributes
+{
+    /**
+     * @param \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes $subject
+     * @param \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes $result
+     * @return \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes
+     */
+    public function afterSetForm(
+        \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes $subject,
+        \Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes $result
+    ) {
+        $mapEnabled = $subject->getForm()->getElement('msrp');
+        if ($mapEnabled && $subject->getCanEditPrice() !== false) {
+            $mapEnabled->setAfterElementHtml(
+                '<script type="text/javascript">' .
+                "
+                function changePriceTypeMap() {
+                    if ($('price_type').value == " . \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC . ") {
+                        $('msrp_display_actual_price_type').setValue(" . Price::TYPE_USE_CONFIG . ");
+                        $('msrp_display_actual_price_type').disable();
+                        $('msrp').setValue('');
+                        $('msrp').disable();
+                    } else {
+                        $('msrp_display_actual_price_type').enable();
+                        $('msrp').enable();
+                    }
+                }
+                document.observe('dom:loaded', function() {
+                    $('price_type').observe('change', changePriceTypeMap);
+                    changePriceTypeMap();
+                });
+                " .
+                '</script>'
+            );
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Catalog/Pricing/Price/MsrpPrice.php b/app/code/Magento/Msrp/Pricing/Price/MsrpPrice.php
similarity index 67%
rename from app/code/Magento/Catalog/Pricing/Price/MsrpPrice.php
rename to app/code/Magento/Msrp/Pricing/Price/MsrpPrice.php
index 452ffb0e734..bcd69364f78 100644
--- a/app/code/Magento/Catalog/Pricing/Price/MsrpPrice.php
+++ b/app/code/Magento/Msrp/Pricing/Price/MsrpPrice.php
@@ -22,11 +22,11 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Pricing\Price;
+namespace Magento\Msrp\Pricing\Price;
 
-use Magento\Catalog\Helper\Data;
 use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
 use Magento\Catalog\Model\Product;
+use Magento\Catalog\Pricing\Price\FinalPrice;
 
 /**
  * MSRP price model
@@ -39,24 +39,32 @@ class MsrpPrice extends FinalPrice implements MsrpPriceInterface
     const PRICE_CODE = 'msrp_price';
 
     /**
-     * @var \Magento\Catalog\Helper\Data
+     * @var \Magento\Msrp\Helper\Data
      */
-    protected $catalogDataHelper;
+    protected $msrpData;
+
+    /**
+     * @var \Magento\Msrp\Model\Config
+     */
+    protected $config;
 
     /**
      * @param Product $saleableItem
      * @param float $quantity
      * @param CalculatorInterface $calculator
-     * @param Data $catalogDataHelper
+     * @param \Magento\Msrp\Helper\Data $msrpData
+     * @param \Magento\Msrp\Model\Config $config
      */
     public function __construct(
         Product $saleableItem,
         $quantity,
         CalculatorInterface $calculator,
-        Data $catalogDataHelper
+        \Magento\Msrp\Helper\Data $msrpData,
+        \Magento\Msrp\Model\Config $config
     ) {
         parent::__construct($saleableItem, $quantity, $calculator);
-        $this->catalogDataHelper = $catalogDataHelper;
+        $this->msrpData = $msrpData;
+        $this->config = $config;
     }
 
     /**
@@ -66,27 +74,27 @@ class MsrpPrice extends FinalPrice implements MsrpPriceInterface
      */
     public function isShowPriceOnGesture()
     {
-        return $this->catalogDataHelper->isShowPriceOnGesture($this->product);
+        return $this->msrpData->isShowPriceOnGesture($this->product);
     }
 
     /**
-     * Get MAP message for price
+     * Get Msrp message for price
      *
      * @return string
      */
     public function getMsrpPriceMessage()
     {
-        return $this->catalogDataHelper->getMsrpPriceMessage($this->product);
+        return $this->msrpData->getMsrpPriceMessage($this->product);
     }
 
     /**
-     * Returns true in case MSRP is enabled
+     * Check if Minimum Advertised Price is enabled
      *
      * @return bool
      */
     public function isMsrpEnabled()
     {
-        return $this->catalogDataHelper->isMsrpEnabled();
+        return $this->config->isEnabled();
     }
 
     /**
@@ -97,6 +105,15 @@ class MsrpPrice extends FinalPrice implements MsrpPriceInterface
      */
     public function canApplyMsrp(Product $product)
     {
-        return $this->catalogDataHelper->canApplyMsrp($product);
+        return $this->msrpData->canApplyMsrp($product);
+    }
+
+    /**
+     * @param Product $product
+     * @return bool|float
+     */
+    public function isMinimalPriceLessMsrp(Product $product)
+    {
+        return $this->msrpData->isMinimalPriceLessMsrp($product);
     }
 }
diff --git a/app/code/Magento/Catalog/Pricing/Price/MsrpPriceInterface.php b/app/code/Magento/Msrp/Pricing/Price/MsrpPriceInterface.php
similarity index 92%
rename from app/code/Magento/Catalog/Pricing/Price/MsrpPriceInterface.php
rename to app/code/Magento/Msrp/Pricing/Price/MsrpPriceInterface.php
index 92e72a0c95d..0ef3c107b18 100644
--- a/app/code/Magento/Catalog/Pricing/Price/MsrpPriceInterface.php
+++ b/app/code/Magento/Msrp/Pricing/Price/MsrpPriceInterface.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Pricing\Price;
+namespace Magento\Msrp\Pricing\Price;
 
 use Magento\Catalog\Model\Product;
 
@@ -39,14 +39,14 @@ interface MsrpPriceInterface
     public function isShowPriceOnGesture();
 
     /**
-     * Get MAP message for price
+     * Get Msrp message for price
      *
      * @return string
      */
     public function getMsrpPriceMessage();
 
     /**
-     * Returns true in case MSRP is enabled
+     * Check if Minimum Advertised Price is enabled
      *
      * @return bool
      */
diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json
new file mode 100644
index 00000000000..0b4b89d2783
--- /dev/null
+++ b/app/code/Magento/Msrp/composer.json
@@ -0,0 +1,29 @@
+{
+    "name": "magento/module-msrp",
+    "description": "N/A",
+    "require": {
+        "php": "~5.4.11|~5.5.0",
+        "magento/module-bundle": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-configurable-product": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-downloadable": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-grouped-product": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/magento-composer-installer": "*"
+    },
+    "type": "magento2-module",
+    "version": "0.1.0-alpha97",
+    "extra": {
+        "map": [
+            [
+                "*",
+                "Magento/Msrp"
+            ]
+        ]
+    }
+}
diff --git a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php b/app/code/Magento/Msrp/data/msrp_setup/data-install-1.0.0.0.php
similarity index 67%
rename from app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php
rename to app/code/Magento/Msrp/data/msrp_setup/data-install-1.0.0.0.php
index 387cbe67440..f865e95cfe1 100644
--- a/app/code/Magento/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.0-1.6.0.0.1.php
+++ b/app/code/Magento/Msrp/data/msrp_setup/data-install-1.0.0.0.php
@@ -25,30 +25,32 @@
 /** @var $installer \Magento\Catalog\Model\Resource\Setup */
 $installer = $this;
 
-$productTypes = array(
+$productTypes = [
     \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
+    \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL,
+    \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE,
     \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE,
-    \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL
-);
+    \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE,
+];
 $productTypes = join(',', $productTypes);
 
 $installer->addAttribute(
     \Magento\Catalog\Model\Product::ENTITY,
-    'msrp_enabled',
+    'msrp',
     array(
-        'group' => 'Prices',
-        'backend' => 'Magento\Catalog\Model\Product\Attribute\Backend\Msrp',
+        'group' => 'Advanced Pricing',
+        'backend' => 'Magento\Catalog\Model\Product\Attribute\Backend\Price',
         'frontend' => '',
-        'label' => 'Apply MAP',
-        'input' => 'select',
-        'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
+        'label' => 'Manufacturer\'s Suggested Retail Price',
+        'type' => 'decimal',
+        'input' => 'price',
         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_WEBSITE,
         'visible' => true,
         'required' => false,
         'user_defined' => false,
-        'default' => '',
         'apply_to' => $productTypes,
-        'input_renderer' => 'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp\Enabled',
+        'input_renderer' => 'Magento\Msrp\Block\Adminhtml\Product\Helper\Form\Type',
+        'frontend_input_renderer' => 'Magento\Msrp\Block\Adminhtml\Product\Helper\Form\Type',
         'visible_on_front' => false,
         'used_in_product_listing' => true
     )
@@ -58,39 +60,22 @@ $installer->addAttribute(
     \Magento\Catalog\Model\Product::ENTITY,
     'msrp_display_actual_price_type',
     array(
-        'group' => 'Prices',
+        'group' => 'Advanced Pricing',
         'backend' => 'Magento\Catalog\Model\Product\Attribute\Backend\Boolean',
         'frontend' => '',
         'label' => 'Display Actual Price',
         'input' => 'select',
-        'source' => 'Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type',
-        'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_WEBSITE,
-        'visible' => true,
-        'required' => false,
-        'user_defined' => false,
-        'default' => '',
-        'apply_to' => $productTypes,
-        'input_renderer' => 'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp\Price',
-        'visible_on_front' => false,
-        'used_in_product_listing' => true
-    )
-);
-
-$installer->addAttribute(
-    \Magento\Catalog\Model\Product::ENTITY,
-    'msrp',
-    array(
-        'group' => 'Prices',
-        'backend' => 'Magento\Catalog\Model\Product\Attribute\Backend\Price',
-        'frontend' => '',
-        'label' => 'Manufacturer\'s Suggested Retail Price',
-        'type' => 'decimal',
-        'input' => 'price',
+        'source' => 'Magento\Msrp\Model\Product\Attribute\Source\Type\Price',
+        'source_model' => 'Magento\Msrp\Model\Product\Attribute\Source\Type\Price',
         'global' => \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_WEBSITE,
         'visible' => true,
         'required' => false,
         'user_defined' => false,
+        'default' => \Magento\Msrp\Model\Product\Attribute\Source\Type\Price::TYPE_USE_CONFIG,
+        'default_value' => \Magento\Msrp\Model\Product\Attribute\Source\Type\Price::TYPE_USE_CONFIG,
         'apply_to' => $productTypes,
+        'input_renderer' => 'Magento\Msrp\Block\Adminhtml\Product\Helper\Form\Type\Price',
+        'frontend_input_renderer' => 'Magento\Msrp\Block\Adminhtml\Product\Helper\Form\Type\Price',
         'visible_on_front' => false,
         'used_in_product_listing' => true
     )
diff --git a/app/code/Magento/Msrp/etc/adminhtml/di.xml b/app/code/Magento/Msrp/etc/adminhtml/di.xml
new file mode 100644
index 00000000000..91dd8dfaa76
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/adminhtml/di.xml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes">
+        <plugin name="bundle_msrp_plugin" type="Magento\Msrp\Plugin\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Attributes"/>
+    </type>
+</config>
diff --git a/app/code/Magento/Msrp/etc/adminhtml/system.xml b/app/code/Magento/Msrp/etc/adminhtml/system.xml
new file mode 100644
index 00000000000..529b8a0c51d
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/adminhtml/system.xml
@@ -0,0 +1,51 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/system_file.xsd">
+    <system>
+        <section id="sales">
+            <group id="msrp" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0">
+                <label>Minimum Advertised Price</label>
+                <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Enable MAP</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                    <comment>
+                        <![CDATA[<strong style="color:red">Warning!</strong> Enabling MAP by default will hide all product prices on the front end.]]>
+                    </comment>
+                </field>
+                <field id="display_price_type" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Display Actual Price</label>
+                    <source_model>Magento\Msrp\Model\Product\Attribute\Source\Type</source_model>
+                </field>
+                <field id="explanation_message" translate="label" type="textarea" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Default Popup Text Message</label>
+                </field>
+                <field id="explanation_message_whats_this" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Default "What's This" Text Message</label>
+                </field>
+            </group>
+        </section>
+    </system>
+</config>
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml b/app/code/Magento/Msrp/etc/catalog_attributes.xml
similarity index 82%
rename from dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml
rename to app/code/Magento/Msrp/etc/catalog_attributes.xml
index af7a39aee6a..c3f9eff5209 100644
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml
+++ b/app/code/Magento/Msrp/etc/catalog_attributes.xml
@@ -23,6 +23,9 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../app/code/Magento/Index/etc/indexers.xsd">
-    <indexer name="cataloginventory_stock" instance="Magento\CatalogInventory\Model\Indexer\Stock" />
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Catalog/etc/catalog_attributes.xsd">
+    <group name="sales_quote_item">
+        <attribute name="msrp"/>
+        <attribute name="msrp_display_actual_price_type"/>
+    </group>
 </config>
diff --git a/app/code/Magento/Msrp/etc/config.xml b/app/code/Magento/Msrp/etc/config.xml
new file mode 100644
index 00000000000..3459c3972f6
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/config.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Core/etc/config.xsd">
+    <default>
+        <sales>
+            <msrp>
+                <enabled>0</enabled>
+                <display_price_type>1</display_price_type>
+                <explanation_message>Our price is lower than the manufacturer's "minimum advertised price." As a result, we cannot show you the price in catalog or the product page. &lt;br /&gt;&lt;br /&gt; You have no obligation to purchase the product once you know the price. You can simply remove the item from your cart.</explanation_message>
+                <explanation_message_whats_this>Our price is lower than the manufacturer's "minimum advertised price." As a result, we cannot show you the price in catalog or the product page. &lt;br /&gt;&lt;br /&gt; You have no obligation to purchase the product once you know the price. You can simply remove the item from your cart.</explanation_message_whats_this>
+            </msrp>
+        </sales>
+    </default>
+</config>
diff --git a/app/code/Magento/Msrp/etc/di.xml b/app/code/Magento/Msrp/etc/di.xml
new file mode 100644
index 00000000000..4a2bea14874
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/di.xml
@@ -0,0 +1,64 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <virtualType name="Magento\Catalog\Pricing\Price\Pool">
+        <arguments>
+            <argument name="prices" xsi:type="array">
+                <item name="msrp_price" xsi:type="string">Magento\Msrp\Pricing\Price\MsrpPrice</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Bundle\Pricing\Price\Pool">
+        <arguments>
+            <argument name="prices" xsi:type="array">
+                <item name="msrp_price" xsi:type="string">Magento\Msrp\Pricing\Price\MsrpPrice</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Catalog\Helper\Product">
+        <arguments>
+            <argument name="reindexPriceIndexerData" xsi:type="array">
+                <item name="byDataChange" xsi:type="array">
+                    <item name="msrp" xsi:type="string">msrp</item>
+                    <item name="msrp_display_actual_price_type" xsi:type="string">msrp_display_actual_price_type</item>
+                </item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Framework\Module\Updater\SetupFactory">
+        <arguments>
+            <argument name="resourceTypes" xsi:type="array">
+                <item name="msrp_setup" xsi:type="string">Magento\Catalog\Model\Resource\Setup</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Msrp\Model\Product\Options" shared="true"/>
+    <type name="Magento\Msrp\Helper\Data" shared="true">
+        <arguments>
+            <argument name="productOptions" xsi:type="object">Magento\Msrp\Model\Product\Options\Proxy</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/Msrp/etc/frontend/events.xml b/app/code/Magento/Msrp/etc/frontend/events.xml
new file mode 100644
index 00000000000..cb7b517153f
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/frontend/events.xml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="sales_quote_collect_totals_after">
+        <observer name="catalog_msrp" instance="Magento\Msrp\Model\Observer\Frontend\Quote\SetCanApplyMsrp" method="execute" />
+    </event>
+</config>
diff --git a/app/code/Magento/UrlRedirect/etc/module.xml b/app/code/Magento/Msrp/etc/module.xml
similarity index 72%
rename from app/code/Magento/UrlRedirect/etc/module.xml
rename to app/code/Magento/Msrp/etc/module.xml
index dd2376b022c..cb683a46f66 100644
--- a/app/code/Magento/UrlRedirect/etc/module.xml
+++ b/app/code/Magento/Msrp/etc/module.xml
@@ -24,13 +24,21 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_UrlRedirect" schema_version="1.0.0.0" active="false">
+    <module name="Magento_Msrp" schema_version="1.0.0.0" active="true">
+        <sequence>
+            <module name="Magento_Catalog"/>
+        </sequence>
         <depends>
+            <module name="Magento_Bundle"/>
             <module name="Magento_Catalog"/>
-            <module name="Magento_Cms"/>
+            <module name="Magento_ConfigurableProduct"/>
             <module name="Magento_Core"/>
-            <module name="Magento_Backend"/>
+            <module name="Magento_Downloadable"/>
+            <module name="Magento_Eav"/>
+            <module name="Magento_GroupedProduct"/>
+            <module name="Magento_Sales"/>
             <module name="Magento_Store"/>
+            <module name="Magento_Tax"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Msrp/etc/sales.xml b/app/code/Magento/Msrp/etc/sales.xml
new file mode 100644
index 00000000000..69f42735b3e
--- /dev/null
+++ b/app/code/Magento/Msrp/etc/sales.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Sales/etc/sales.xsd">
+    <section name="quote">
+        <group name="totals">
+            <item name="msrp" instance="Magento\Msrp\Model\Quote\Address\Total" sort_order="600"/>
+        </group>
+    </section>
+</config>
diff --git a/app/code/Magento/Msrp/view/base/layout/catalog_product_prices.xml b/app/code/Magento/Msrp/view/base/layout/catalog_product_prices.xml
new file mode 100644
index 00000000000..38fd3db1aaf
--- /dev/null
+++ b/app/code/Magento/Msrp/view/base/layout/catalog_product_prices.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <referenceBlock name="render.product.prices">
+        <arguments>
+            <argument name="default" xsi:type="array">
+                <item name="prices" xsi:type="array">
+                    <item name="msrp_price" xsi:type="array">
+                        <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\PriceBox</item>
+                        <item name="render_template" xsi:type="string">Magento_Msrp::product/price/msrp.phtml</item>
+                    </item>
+                </item>
+            </argument>
+        </arguments>
+    </referenceBlock>
+</page>
diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/msrp_price.phtml b/app/code/Magento/Msrp/view/base/templates/product/price/msrp.phtml
similarity index 72%
rename from app/code/Magento/Catalog/view/base/templates/product/price/msrp_price.phtml
rename to app/code/Magento/Msrp/view/base/templates/product/price/msrp.phtml
index b1b449e3f7b..f7b9229ca41 100644
--- a/app/code/Magento/Catalog/view/base/templates/product/price/msrp_price.phtml
+++ b/app/code/Magento/Msrp/view/base/templates/product/price/msrp.phtml
@@ -30,28 +30,37 @@
 ?>
 <?php
 
-/** @var Magento\Catalog\Pricing\Price\MsrpPriceInterface $priceType */
+/** @var Magento\Msrp\Pricing\Price\MsrpPriceInterface $priceType */
 $priceType = $this->getPrice();
 
 /** @var $product \Magento\Catalog\Model\Product */
 $product = $this->getSaleableItem();
 $productId = $product->getId();
-// @todo: msrp works totally wrong, any excuses not accepted. will be refactored ASAP
-$msrpPrice = $this->renderAmount($priceType->getCustomAmount($product->getMsrp()),
+$msrpPrice = $this->renderAmount(
+    $priceType->getCustomAmount($product->getMsrp() ? : $product->getTypeInstance()->getChildrenMsrp($product)),
     [
-        'price_id'  => $this->getPriceId() ? $this->getPriceId() : 'old-price-' . $productId,
+        'price_id' => $this->getPriceId() ? $this->getPriceId() : 'old-price-' . $productId,
         'include_container' => false,
         'skip_adjustments' => true
     ]
 );
 $priceElementIdPrefix = $this->getPriceElementIdPrefix() ? $this->getPriceElementIdPrefix() : 'product-price-';
+
 $addToCartUrl = '';
 if ($product->isSaleable()) {
-    $addToCartUrl = $this->helper('\Magento\Checkout\Helper\Cart')
-        ->getAddUrl($product);
+    /** @var Magento\Catalog\Block\Product\AbstractProduct $addToCartUrlGenerator */
+    $addToCartUrlGenerator = $this->getLayout()->getBlockSingleton('Magento\Catalog\Block\Product\AbstractProduct');
+    $addToCartUrl = $addToCartUrlGenerator->getAddToCartUrl(
+        $product,
+        ['_query' => [
+            \Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED
+                => $this->helper('Magento\Core\Helper\PostData')->getEncodedUrl(
+                    $addToCartUrlGenerator->getAddToCartUrl($product)
+                )
+        ]]
+    );
 }
 ?>
-
 <?php if ($product->getMsrp()): ?>
     <span class="old-price"><?php echo $msrpPrice ?></span>
 <?php endif; ?>
@@ -62,7 +71,12 @@ if ($product->isSaleable()) {
     <?php $popupId = 'msrp-popup-' . $productId . $this->getRandomString(20); ?>
     <a href="#"
        id="<?php echo($popupId);?>"
-       data-mage-init='{"addToCart":{"cartForm": "#product_addtocart_form_from_popup",
+       data-mage-init='{"addToCart":{
+            <?php if ($this->getRequest()->getFullActionName() === 'catalog_product_view'): ?>
+                "addToCartButton": "#product_addtocart_form [type=submit]",
+            <?php else: ?>
+                "cartForm": "#product_addtocart_form_from_popup",
+            <?php endif; ?>
                                      "popupId": "#<?php echo $popupId; ?>",
                                      "productName": "<?php echo $product->getName() ?>",
                                      "realPrice": <?php echo $this->jsonEncode($this->getRealPriceHtml()) ?>,
@@ -70,7 +84,9 @@ if ($product->isSaleable()) {
                                      "priceElementId":"<?php echo $priceElementId ?>",
                                      "closeButtonId": "#map-popup-close",
                                      "popupCartButtonId": "#map-popup-button",
-                                     "addToCartUrl": "<?php echo $addToCartUrl; ?>"}}'><?php echo __('Click for price'); ?>
+                                     "addToCartUrl": "<?php echo $addToCartUrl; ?>"}}'
+    >
+        <?php echo __('Click for price'); ?>
     </a>
 <?php else: ?>
     <span class="msrp message">
diff --git a/app/code/Magento/Catalog/view/base/web/js/msrp.js b/app/code/Magento/Msrp/view/base/web/js/msrp.js
similarity index 75%
rename from app/code/Magento/Catalog/view/base/web/js/msrp.js
rename to app/code/Magento/Msrp/view/base/web/js/msrp.js
index e3604112a3a..85c1a66a587 100644
--- a/app/code/Magento/Catalog/view/base/web/js/msrp.js
+++ b/app/code/Magento/Msrp/view/base/web/js/msrp.js
@@ -21,8 +21,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 /*jshint browser:true jquery:true*/
-define(["jquery","jquery/ui","mage/dropdown"], function($){
-
+define(["jquery", "jquery/ui", "mage/dropdown"], function($) {
     $.widget('mage.addToCart', {
         options: {
             showAddToCart: true,
@@ -46,10 +45,10 @@ define(["jquery","jquery/ui","mage/dropdown"], function($){
                     $('#map-popup-price').html($(this.options.realPrice));
                     $('#map-popup-msrp > span.price').html(this.options.msrpPrice);
                     this.element.trigger('reloadPrice');
-                    var dialog = $( "#map-popup-click-for-price" );
-                    this._popupDialog(dialog,this.options.popupId);
+                    var dialog = $("#map-popup-click-for-price");
+                    this._popupDialog(dialog, this.options.popupId);
                     if (!this.options.showAddToCart) {
-                        $('#map-popup-content > .map-popup-checkout').hide();
+                        $('#product_addtocart_form_from_popup').hide();
                     }
                     return false;
                 }
@@ -57,33 +56,35 @@ define(["jquery","jquery/ui","mage/dropdown"], function($){
 
             $(this.options.helpLinkId).on('click', $.proxy(function(e) {
                 $('#map-popup-heading-what-this').text(this.options.productName);
-                var dialog = $( "#map-popup-what-this" );
-                this._popupDialog(dialog,this.options.helpLinkId);
+                var dialog = $("#map-popup-what-this");
+                this._popupDialog(dialog, this.options.helpLinkId);
                 return false;
             }, this));
-
-
         },
 
-        _popupDialog : function(target,trigger) {
-            if(!target.hasClass('ui-dialog-content')) {
+        _popupDialog: function(target, trigger) {
+            if (!target.hasClass('ui-dialog-content')) {
                 target.dropdownDialog({
-                    appendTo :".column.main",
-                    dialogContentClass : 'active',
+                    appendTo: ".column.main",
+                    dialogContentClass: 'active',
                     timeout: "2000",
                     autoPosition: true,
-                    "dialogClass" : "popup"
+                    "dialogClass": "popup"
                 });
             }
             $('.mage-dropdown-dialog > .ui-dialog-content').dropdownDialog("close");
-            target.dropdownDialog("option","position",{my: "right+50% top", collision: "none", at: "center bottom", of: trigger});
-            target.dropdownDialog("option","triggerTarget",trigger);
+            target.dropdownDialog("option", "position", {my: "right+50% top", collision: "none", at: "center bottom", of: trigger});
+            target.dropdownDialog("option", "triggerTarget", trigger);
             target.dropdownDialog("open");
 
         },
 
         _addToCartSubmit: function() {
             this.element.trigger('addToCart', this.element);
+            if (this.options.addToCartButton) {
+                $(this.options.addToCartButton).click();
+                return;
+            }
             if (this.options.addToCartUrl) {
                 $('.mage-dropdown-dialog > .ui-dialog-content').dropdownDialog("close");
                 $(this.options.cartForm).attr('action', this.options.addToCartUrl);
@@ -91,4 +92,4 @@ define(["jquery","jquery/ui","mage/dropdown"], function($){
             $(this.options.cartForm).submit();
         }
     });
-});
\ No newline at end of file
+});
diff --git a/app/code/Magento/Rss/view/frontend/layout/catalog_category_view.xml b/app/code/Magento/Msrp/view/frontend/layout/catalog_category_view.xml
similarity index 75%
rename from app/code/Magento/Rss/view/frontend/layout/catalog_category_view.xml
rename to app/code/Magento/Msrp/view/frontend/layout/catalog_category_view.xml
index 86285166f3b..f3392582488 100644
--- a/app/code/Magento/Rss/view/frontend/layout/catalog_category_view.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalog_category_view.xml
@@ -23,8 +23,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="page.main.title">
-        <block class="Magento\Catalog\Block\Category\View" name="rss.link" template="Magento_Rss::category/link.phtml"/>
-    </referenceBlock>
+<page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <update handle="msrp_popup"/>
 </page>
diff --git a/app/code/Magento/Msrp/view/frontend/layout/catalog_product_compare_index.xml b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_compare_index.xml
new file mode 100644
index 00000000000..81e2fc70446
--- /dev/null
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_compare_index.xml
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <update handle="msrp_popup"/>
+</page>
diff --git a/app/code/Magento/Msrp/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_view.xml
new file mode 100644
index 00000000000..6e35697c407
--- /dev/null
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_view.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <update handle="msrp_popup"/>
+    <!--<update handle="MAP_price_msrp_item"/>-->
+    <referenceBlock name="product.price.final">
+        <arguments>
+            <argument name="display_msrp_help_message" xsi:type="string">1</argument>
+        </arguments>
+    </referenceBlock>
+    <referenceBlock name="product.price.tier">
+        <arguments>
+            <argument name="display_msrp_help_message" xsi:type="string">1</argument>
+        </arguments>
+    </referenceBlock>
+</page>
diff --git a/app/code/Magento/Rss/view/adminhtml/layout/sales_order_grid_block.xml b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_view_type_downloadable.xml
similarity index 75%
rename from app/code/Magento/Rss/view/adminhtml/layout/sales_order_grid_block.xml
rename to app/code/Magento/Msrp/view/frontend/layout/catalog_product_view_type_downloadable.xml
index 871e6f5ba8b..05a07365711 100644
--- a/app/code/Magento/Rss/view/adminhtml/layout/sales_order_grid_block.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalog_product_view_type_downloadable.xml
@@ -24,14 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="sales.order.grid">
+    <referenceBlock name="product.info.downloadable.options">
         <arguments>
-            <argument name="rssList" xsi:type="array">
-                <item name="orders" xsi:type="array">
-                    <item name="url" xsi:type="string">rss/order/new</item>
-                    <item name="label" xsi:type="string" translate="true">New Order RSS</item>
-                </item>
-            </argument>
+            <argument name="display_msrp_help_message" xsi:type="string">1</argument>
         </arguments>
     </referenceBlock>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalogsearch_advanced_result.xml b/app/code/Magento/Msrp/view/frontend/layout/catalogsearch_advanced_result.xml
similarity index 96%
rename from app/code/Magento/Catalog/view/frontend/layout/catalogsearch_advanced_result.xml
rename to app/code/Magento/Msrp/view/frontend/layout/catalogsearch_advanced_result.xml
index f58e41ede00..316bbb5180c 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalogsearch_advanced_result.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalogsearch_advanced_result.xml
@@ -24,5 +24,5 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
+    <update handle="msrp_popup"/>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalogsearch_result_index.xml b/app/code/Magento/Msrp/view/frontend/layout/catalogsearch_result_index.xml
similarity index 96%
rename from app/code/Magento/Catalog/view/frontend/layout/catalogsearch_result_index.xml
rename to app/code/Magento/Msrp/view/frontend/layout/catalogsearch_result_index.xml
index f58e41ede00..316bbb5180c 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalogsearch_result_index.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/catalogsearch_result_index.xml
@@ -24,5 +24,5 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
+    <update handle="msrp_popup"/>
 </page>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_special.xml b/app/code/Magento/Msrp/view/frontend/layout/checkout_cart_index.xml
similarity index 64%
rename from app/code/Magento/Rss/view/frontend/layout/rss_catalog_special.xml
rename to app/code/Magento/Msrp/view/frontend/layout/checkout_cart_index.xml
index aeda0d2becc..88d9cc02049 100644
--- a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_special.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/checkout_cart_index.xml
@@ -23,14 +23,13 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\Special" name="rss.catalog.special" cacheable="false"/>
-        <block class="Magento\Framework\Pricing\Render" name="product.price.render.default">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <update handle="msrp_popup"/>
+    <referenceContainer name="checkout.cart.totals.container">
+        <block name="checkout.cart.totals.msrp" before="checkout.cart.totals" class="Magento\Msrp\Block\Total" template="cart/totals.phtml">
             <arguments>
-                <argument name="price_render_handle" xsi:type="string">catalog_product_prices</argument>
-                <!-- set "override" configuration settings here -->
+                <argument name="original_block_name" xsi:type="string">checkout.cart.totals</argument>
             </arguments>
         </block>
-    </container>
-</layout>
+    </referenceContainer>
+</page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_failure.xml b/app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_failure.xml
similarity index 96%
rename from app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_failure.xml
rename to app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_failure.xml
index f58e41ede00..316bbb5180c 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_failure.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_failure.xml
@@ -24,5 +24,5 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
+    <update handle="msrp_popup"/>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_success.xml b/app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_success.xml
similarity index 96%
rename from app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_success.xml
rename to app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_success.xml
index f58e41ede00..316bbb5180c 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/checkout_onepage_success.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/checkout_onepage_success.xml
@@ -24,5 +24,5 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
+    <update handle="msrp_popup"/>
 </page>
diff --git a/app/code/Magento/Msrp/view/frontend/layout/default.xml b/app/code/Magento/Msrp/view/frontend/layout/default.xml
new file mode 100644
index 00000000000..4c627d7a49b
--- /dev/null
+++ b/app/code/Magento/Msrp/view/frontend/layout/default.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <referenceContainer name="minicart.subtotal.container">
+        <block name="minicart.subtotal.msrp" before="minicart.subtotal" class="Magento\Msrp\Block\Total" template="cart/subtotal.phtml">
+            <arguments>
+                <argument name="original_block_name" xsi:type="string">minicart.subtotal</argument>
+            </arguments>
+        </block>
+    </referenceContainer>
+</page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/MAP_popup.xml b/app/code/Magento/Msrp/view/frontend/layout/msrp_popup.xml
similarity index 90%
rename from app/code/Magento/Catalog/view/frontend/layout/MAP_popup.xml
rename to app/code/Magento/Msrp/view/frontend/layout/msrp_popup.xml
index 1ad87ee2d44..e10bcac5433 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/MAP_popup.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/msrp_popup.xml
@@ -25,7 +25,7 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="content">
-        <block class="Magento\Framework\View\Element\Template" template="Magento_Catalog::msrp/popup.phtml" name="product.tooltip">
+        <block class="Magento\Msrp\Block\Popup" template="Magento_Msrp::popup.phtml" name="product.tooltip">
             <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog\PositionAfter" name="map.shortcut.buttons"/>
         </block>
     </referenceContainer>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/review_product_list.xml b/app/code/Magento/Msrp/view/frontend/layout/review_product_list.xml
similarity index 92%
rename from app/code/Magento/Catalog/view/frontend/layout/review_product_list.xml
rename to app/code/Magento/Msrp/view/frontend/layout/review_product_list.xml
index 8073b2b1cfe..0681cfb064e 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/review_product_list.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/review_product_list.xml
@@ -24,6 +24,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
-    <update handle="MAP_price_msrp_item"/>
+    <update handle="msrp_popup"/>
+    <!--<update handle="MAP_price_msrp_item"/>-->
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/Msrp/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
similarity index 84%
rename from app/code/Magento/Catalog/view/frontend/layout/checkout_cart_index.xml
rename to app/code/Magento/Msrp/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
index f58e41ede00..ebcf1cfc7a2 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/checkout_cart_index.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
@@ -24,5 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
+    <referenceBlock name="product.price.link">
+        <arguments>
+            <argument name="display_msrp_help_message" xsi:type="string">1</argument>
+        </arguments>
+    </referenceBlock>
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/wishlist_index_index.xml b/app/code/Magento/Msrp/view/frontend/layout/wishlist_index_index.xml
similarity index 92%
rename from app/code/Magento/Catalog/view/frontend/layout/wishlist_index_index.xml
rename to app/code/Magento/Msrp/view/frontend/layout/wishlist_index_index.xml
index c8ae02657dc..5aefce39725 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/wishlist_index_index.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/wishlist_index_index.xml
@@ -24,6 +24,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
-    <update handle="MAP_price_msrp_wishlist_item"/>
+    <update handle="msrp_popup"/>
+    <!--<update handle="MAP_price_msrp_wishlist_item"/>-->
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/wishlist_search_view.xml b/app/code/Magento/Msrp/view/frontend/layout/wishlist_search_view.xml
similarity index 92%
rename from app/code/Magento/Catalog/view/frontend/layout/wishlist_search_view.xml
rename to app/code/Magento/Msrp/view/frontend/layout/wishlist_search_view.xml
index c8ae02657dc..5aefce39725 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/wishlist_search_view.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/wishlist_search_view.xml
@@ -24,6 +24,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
-    <update handle="MAP_price_msrp_wishlist_item"/>
+    <update handle="msrp_popup"/>
+    <!--<update handle="MAP_price_msrp_wishlist_item"/>-->
 </page>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/wishlist_shared_index.xml b/app/code/Magento/Msrp/view/frontend/layout/wishlist_shared_index.xml
similarity index 92%
rename from app/code/Magento/Catalog/view/frontend/layout/wishlist_shared_index.xml
rename to app/code/Magento/Msrp/view/frontend/layout/wishlist_shared_index.xml
index c8ae02657dc..5aefce39725 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/wishlist_shared_index.xml
+++ b/app/code/Magento/Msrp/view/frontend/layout/wishlist_shared_index.xml
@@ -24,6 +24,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <update handle="MAP_popup"/>
-    <update handle="MAP_price_msrp_wishlist_item"/>
+    <update handle="msrp_popup"/>
+    <!--<update handle="MAP_price_msrp_wishlist_item"/>-->
 </page>
diff --git a/lib/web/requirejs-config.js b/app/code/Magento/Msrp/view/frontend/templates/cart/subtotal.phtml
similarity index 82%
rename from lib/web/requirejs-config.js
rename to app/code/Magento/Msrp/view/frontend/templates/cart/subtotal.phtml
index bd0f7696117..be1da4e6b47 100644
--- a/lib/web/requirejs-config.js
+++ b/app/code/Magento/Msrp/view/frontend/templates/cart/subtotal.phtml
@@ -1,3 +1,4 @@
+<?php
 /**
  * Magento
  *
@@ -20,15 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
-var config = {
-    shim: {
-        'jquery-ui': {
-            deps: ['jquery']
-        }
-    },
-    paths: {
-        'jquery-ui': 'jquery/jquery-ui',
-        'jquery': 'jquery/jquery'
-    }
-};
+?>
+<div class="subtotal">
+    <span class="mark msrp">
+        <?php echo __('Order total will be displayed before you submit the order'); ?>
+    </span>
+</div>
diff --git a/app/code/Magento/Msrp/view/frontend/templates/cart/totals.phtml b/app/code/Magento/Msrp/view/frontend/templates/cart/totals.phtml
new file mode 100644
index 00000000000..f28e5061c7f
--- /dev/null
+++ b/app/code/Magento/Msrp/view/frontend/templates/cart/totals.phtml
@@ -0,0 +1,27 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<div class="cart-totals">
+    <div class="msrp totals"><?php echo __('You will see the order total before you submit the order.'); ?></div>
+</div>
diff --git a/app/code/Magento/Catalog/view/frontend/templates/msrp/popup.phtml b/app/code/Magento/Msrp/view/frontend/templates/popup.phtml
similarity index 84%
rename from app/code/Magento/Catalog/view/frontend/templates/msrp/popup.phtml
rename to app/code/Magento/Msrp/view/frontend/templates/popup.phtml
index d74cdcd7c6c..c18907f8feb 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/msrp/popup.phtml
+++ b/app/code/Magento/Msrp/view/frontend/templates/popup.phtml
@@ -23,12 +23,9 @@
  */
 ?>
 <?php
-/**
- * Template for MAP popup
- *
- */
+/** @var \Magento\Msrp\Block\Popup $this */
 ?>
-<?php if ($this->helper('Magento\Catalog\Helper\Data')->isMsrpEnabled()): ?>
+<?php if ($this->isEnabled()): ?>
     <div id="map-popup-click-for-price" class="map popup">
         <div class="popup-header">
             <strong class="title" id="map-popup-heading-price"></strong>
@@ -38,15 +35,13 @@
                 <div class="price-box">
                     <div class="map msrp" id="map-popup-msrp-box">
                         <span class="label"><?php echo __('Price'); ?></span>
-
-                        <div class="old price" id="map-popup-msrp">
+                        <span class="old-price" id="map-popup-msrp">
                             <span class="price"></span>
-                        </div>
+                        </span>
                     </div>
                     <div class="map price" id="map-popup-price-box">
                         <span class="label"><?php echo __('Actual Price'); ?></span>
-
-                        <div id="map-popup-price" class="actual price"></div>
+                        <span id="map-popup-price" class="actual-price"></span>
                     </div>
                 </div>
                 <form action="" method="POST" id="product_addtocart_form_from_popup" class="form map checkout">
@@ -62,7 +57,7 @@
                 </form>
             </div>
             <div class="map text" id="map-popup-text">
-                <?php echo $this->helper('Magento\Catalog\Helper\Data')->getMsrpExplanationMessage(); ?>
+                <?php echo $this->getExplanationMessage(); ?>
             </div>
         </div>
     </div>
@@ -73,7 +68,7 @@
         </div>
         <div class="popup content">
             <div class="map help text" id="map-popup-text-what-this">
-                <?php echo $this->helper('Magento\Catalog\Helper\Data')->getMsrpExplanationMessageWhatsThis(); ?>
+                <?php echo $this->getExplanationMessageWhatsThis(); ?>
             </div>
         </div>
     </div>
diff --git a/app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_item.phtml b/app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_item.phtml
similarity index 99%
rename from app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_item.phtml
rename to app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_item.phtml
index f36db4e8b83..7cc3d0aa241 100644
--- a/app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_item.phtml
+++ b/app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_item.phtml
@@ -48,7 +48,7 @@
     <?php endif; ?>
     <?php if ($_catalogHelper->isShowPriceOnGesture($_product)): ?>
         <?php $priceElementId = 'product-price-' . $_id . $this->getIdSuffix(); ?>
-        <span id="<?php echo $priceElementId ?>" style="display:none"></span>
+        <span id="<?php echo $priceElementId ?>" style="display: none"></span>
         <?php $popupId = 'msrp-popup-' . $_id . $this->getRandomString(20); ?>
         <a href="#"
            id="<?php echo($popupId);?>"
diff --git a/app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_rss.phtml b/app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_rss.phtml
similarity index 92%
rename from app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_rss.phtml
rename to app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_rss.phtml
index e8f5b9803e2..814203da289 100644
--- a/app/code/Magento/Wishlist/view/frontend/templates/render/item/price_msrp_rss.phtml
+++ b/app/code/Magento/Msrp/view/frontend/templates/render/item/price_msrp_rss.phtml
@@ -30,7 +30,7 @@
  */
 ?>
 <div class="price-box msrp">
-    <?php if ($this->helper('Magento\Catalog\Helper\Data')->canApplyMsrp($this->getProduct())): ?>
+    <?php if ($this->helper('Magento\Msrp\Helper\Data')->canApplyMsrp($this->getProduct())): ?>
         <a href="<?php echo $this->getProduct()->getProductUrl() ?>"><?php echo __('Click for price'); ?></a>
     <?php endif; ?>
 </div>
diff --git a/app/code/Magento/Multishipping/Block/Checkout/Address/Select.php b/app/code/Magento/Multishipping/Block/Checkout/Address/Select.php
index 1492f75e879..2179c670bfb 100644
--- a/app/code/Magento/Multishipping/Block/Checkout/Address/Select.php
+++ b/app/code/Magento/Multishipping/Block/Checkout/Address/Select.php
@@ -74,9 +74,7 @@ class Select extends \Magento\Multishipping\Block\Checkout\AbstractMultishipping
      */
     protected function _prepareLayout()
     {
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle(__('Change Billing Address') . ' - ' . $headBlock->getDefaultTitle());
-        }
+        $this->pageConfig->setTitle(__('Change Billing Address') . ' - ' . $this->pageConfig->getDefaultTitle());
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Multishipping/Block/Checkout/Addresses.php b/app/code/Magento/Multishipping/Block/Checkout/Addresses.php
index 50378e2a5ed..fcc07d2ebac 100644
--- a/app/code/Magento/Multishipping/Block/Checkout/Addresses.php
+++ b/app/code/Magento/Multishipping/Block/Checkout/Addresses.php
@@ -89,10 +89,7 @@ class Addresses extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Ship to Multiple Addresses') . ' - ' . $headBlock->getDefaultTitle());
-        }
+        $this->pageConfig->setTitle(__('Ship to Multiple Addresses') . ' - ' . $this->pageConfig->getDefaultTitle());
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Multishipping/Block/Checkout/Billing.php b/app/code/Magento/Multishipping/Block/Checkout/Billing.php
index b5675674737..8333149513c 100644
--- a/app/code/Magento/Multishipping/Block/Checkout/Billing.php
+++ b/app/code/Magento/Multishipping/Block/Checkout/Billing.php
@@ -77,10 +77,7 @@ class Billing extends \Magento\Payment\Block\Form\Container
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Billing Information - %1', $headBlock->getDefaultTitle()));
-        }
+        $this->pageConfig->setTitle(__('Billing Information - %1', $this->pageConfig->getDefaultTitle()));
 
         return parent::_prepareLayout();
     }
diff --git a/app/code/Magento/Multishipping/Block/Checkout/Overview.php b/app/code/Magento/Multishipping/Block/Checkout/Overview.php
index 7355583ef19..f6261105eac 100644
--- a/app/code/Magento/Multishipping/Block/Checkout/Overview.php
+++ b/app/code/Magento/Multishipping/Block/Checkout/Overview.php
@@ -73,10 +73,7 @@ class Overview extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Review Order - %1', $headBlock->getDefaultTitle()));
-        }
+        $this->pageConfig->setTitle(__('Review Order - %1', $this->pageConfig->getDefaultTitle()));
         return parent::_prepareLayout();
     }
 
@@ -333,7 +330,7 @@ class Overview extends \Magento\Sales\Block\Items\AbstractItems
     public function renderTotals($totals, $colspan = null)
     {
         if ($colspan === null) {
-            $colspan = $this->_taxHelper->displayCartBothPrices() ? 5 : 3;
+            $colspan = 3;
         }
         $totals = $this->getChildBlock(
             'totals'
diff --git a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php
index f74e00187f2..9868b9bc686 100644
--- a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php
+++ b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php
@@ -87,9 +87,7 @@ class Shipping extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle(__('Shipping Methods') . ' - ' . $headBlock->getDefaultTitle());
-        }
+        $this->pageConfig->setTitle(__('Shipping Methods') . ' - ' . $this->pageConfig->getDefaultTitle());
         return parent::_prepareLayout();
     }
 
diff --git a/app/code/Magento/Multishipping/Controller/Checkout.php b/app/code/Magento/Multishipping/Controller/Checkout.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php
index bc038bcbe18..8c4693ee857 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php
@@ -43,10 +43,9 @@ class EditAddress extends \Magento\Multishipping\Controller\Checkout\Address
             )->setBackUrl(
                 $this->_url->getUrl('*/*/selectBilling')
             );
-
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
+            $this->_view->getPage()->getConfig()->setTitle(
+                $addressForm->getTitle() . ' - ' . $this->_view->getPage()->getConfig()->getDefaultTitle()
+            );
         }
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php
index 9123868193f..25529394897 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php
@@ -46,9 +46,9 @@ class EditBilling extends \Magento\Multishipping\Controller\Checkout\Address
             )->setBackUrl(
                 $this->_url->getUrl('*/checkout/overview')
             );
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
+            $this->_view->getPage()->getConfig()->setTitle(
+                $addressForm->getTitle() . ' - ' . $this->_view->getPage()->getConfig()->getDefaultTitle()
+            );
         }
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php
index 6a68b1c7f43..8d657085246 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php
@@ -45,9 +45,9 @@ class EditShipping extends \Magento\Multishipping\Controller\Checkout\Address
                 $this->_url->getUrl('*/*/*')
             );
 
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
+            $this->_view->getPage()->getConfig()->setTitle(
+                $addressForm->getTitle() . ' - ' . $this->_view->getPage()->getConfig()->getDefaultTitle()
+            );
 
             if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
                 $addressForm->setBackUrl($this->_url->getUrl('*/checkout/shipping'));
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php
index c18e5636670..ffc2459079a 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php
@@ -44,9 +44,9 @@ class NewBilling extends \Magento\Multishipping\Controller\Checkout\Address
                 $this->_url->getUrl('*/*/selectBilling')
             );
 
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
+            $this->_view->getPage()->getConfig()->setTitle(
+                $addressForm->getTitle() . ' - ' . $this->_view->getPage()->getConfig()->getDefaultTitle()
+            );
         }
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php
index 24675a291c5..994138ed403 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php
@@ -47,9 +47,9 @@ class NewShipping extends \Magento\Multishipping\Controller\Checkout\Address
                 $this->_url->getUrl('*/*/*')
             );
 
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
+            $this->_view->getPage()->getConfig()->setTitle(
+                $addressForm->getTitle() . ' - ' . $this->_view->getPage()->getConfig()->getDefaultTitle()
+            );
 
             if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
                 $addressForm->setBackUrl($this->_url->getUrl('*/checkout/addresses'));
diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json
index 1af5f787da7..3b6e72a0456 100644
--- a/app/code/Magento/Multishipping/composer.json
+++ b/app/code/Magento/Multishipping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml
index 5a792124164..1637e679a15 100644
--- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml
+++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview.phtml
@@ -67,22 +67,28 @@
                     <?php echo $_address->format('html') ?>
                 </address>
             </div>
-            <div class="box method">
-                <strong class="subtitle">
+            <div class="box box-order-shipping-method">
+                <strong class="box-title">
                     <span><?php echo __('Shipping Method') ?></span>
                     <a href="<?php echo $this->getEditShippingUrl() ?>" class="action edit"><span><?php echo __('Change') ?></span></a>
                 </strong>
                 <?php if($_rate=$this->getShippingAddressRate($_address)): ?>
-                    <p>
+                    <div class="box-content">
                         <?php echo $this->escapeHtml($_rate->getCarrierTitle()) ?> (<?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>)
                         <?php $_excl = $this->getShippingPriceExclTax($_address); ?>
                         <?php $_incl = $this->getShippingPriceInclTax($_address); ?>
 
-                        <?php echo $_excl; ?>
                         <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                            (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+                        <span class="price-including-tax" data-label="<?php echo __('Incl. Tax'); ?>">
+                        <?php endif; ?>
+                            <?php echo $_incl; ?>
+                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                        </span>
                         <?php endif; ?>
-                    </p>
+                        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                            <span class="price-excluding-tax" data-label="<?php echo __('Excl. Tax'); ?>"><?php echo $_excl; ?></span>
+                        <?php endif; ?>
+                    </div>
                 <?php endif; ?>
             </div>
             <div class="box items">
@@ -93,19 +99,11 @@
                 <table class="items data table order review" id="overview-table-<?php echo $_address->getId() ?>">
                     <thead>
                     <tr>
-                        <th rowspan="<?php echo $mergedCells; ?>" class="col item"><?php echo __('Product Name') ?></th>
-                        <th colspan="<?php echo $mergedCells; ?>" class="col price"><?php echo __('Price') ?></th>
-                        <th rowspan="<?php echo $mergedCells; ?>" class="col qty"><?php echo __('Qty') ?></th>
-                        <th colspan="<?php echo $mergedCells; ?>" class="col subtotal"><?php echo __('Subtotal') ?></th>
+                        <th class="col item"><?php echo __('Product Name') ?></th>
+                        <th class="col price"><?php echo __('Price') ?></th>
+                        <th class="col qty"><?php echo __('Qty') ?></th>
+                        <th class="col subtotal"><?php echo __('Subtotal') ?></th>
                     </tr>
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-                        <tr>
-                            <th class="col price excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                            <th class="col price incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-                            <th class="col subtotal excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                            <th class="col subtotal incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-                        </tr>
-                    <?php endif; ?>
                     </thead>
                     <tfoot>
                         <?php echo $this->renderTotals($this->getShippingAddressTotals($_address)); ?>
@@ -135,19 +133,11 @@
             <table class="items data table order review" id="virtual-overview-table">
                 <thead>
                     <tr>
-                        <th rowspan="<?php echo $mergedCells; ?>" class="col item"><?php echo __('Product Name') ?></th>
-                        <th colspan="<?php echo $mergedCells; ?>" class="col price"><?php echo __('Price') ?></th>
-                        <th rowspan="<?php echo $mergedCells; ?>" class="col qty"><?php echo __('Qty') ?></th>
-                        <th colspan="<?php echo $mergedCells; ?>" class="col subtotal"><?php echo __('Subtotal') ?></th>
-                    </tr>
-                    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-                    <tr>
-                        <th class="col price excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                        <th class="col price incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-                        <th class="col subtotal excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-                        <th class="col subtotal incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
+                        <th class="col item"><?php echo __('Product Name') ?></th>
+                        <th class="col price"><?php echo __('Price') ?></th>
+                        <th class="col qty"><?php echo __('Qty') ?></th>
+                        <th class="col subtotal"><?php echo __('Subtotal') ?></th>
                     </tr>
-                    <?php endif; ?>
                 </thead>
                 <tfoot>
                     <?php echo $this->renderTotals($this->getBillinAddressTotals()); ?>
diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview/item.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview/item.phtml
index 5c6d7e287d0..7d971445cf6 100644
--- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview/item.phtml
+++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/overview/item.phtml
@@ -32,36 +32,42 @@
 <?php /** @var $this Magento\Checkout\Block\Cart\Item\Renderer */ ?>
 <?php $_item = $this->getItem() ?>
 <tr>
-    <td class="col item"><?php echo $this->getRenderedBlock()->getItemHtml($_item) ?></td>
-<?php /* Excluding Tax */ ?>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col price excl tax">
-        <?php echo $this->getUnitPriceExclTaxHtml($_item); ?>
+    <td class="col item" data-th="<?php echo $this->escapeHtml(__('Product Name'));?>">
+        <?php echo $this->getRenderedBlock()->getItemHtml($_item) ?>
     </td>
-    <?php endif; ?>
-<?php /* // Excluding Tax */ ?>
-
-<?php /* Including Tax */ ?>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col price incll tax">
-        <?php echo $this->getUnitPriceInclTaxHtml($_item); ?>
+    <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price'));?>">
+        <?php /* Including Tax */ ?>
+            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+                <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+                    <?php echo $this->getUnitPriceInclTaxHtml($_item); ?>
+                </span>
+            <?php endif; ?>
+        <?php /* // Including Tax */ ?>
+        <?php /* Excluding Tax */ ?>
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+            <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+                <?php echo $this->getUnitPriceExclTaxHtml($_item); ?>
+            </span>
+        <?php endif; ?>
+        <?php /* // Excluding Tax */ ?>
     </td>
-    <?php endif; ?>
-<?php /* // Including Tax */ ?>
-    <td class="col qty"><?php echo $_item->getQty()*1 ?></td>
-<?php /* Excluding Tax Subtotal */ ?>
+
+
+    <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty'));?>"><?php echo $_item->getQty()*1 ?></td>
+    <td class="col subtotal" data-th="<?php echo $this->escapeHtml(__('Subtotal'));?>">
+    <?php /* Including Tax Subtotal */ ?>
+        <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
+        <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+            <?php echo $this->getRowTotalInclTaxHtml($_item); ?>
+        </span>
+        <?php endif; ?>
+    <?php /* //Including Tax Subtotal */ ?>
+    <?php /* Excluding Tax Subtotal */ ?>
     <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceExclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col subtotal excl tax">
-        <?php echo $this->getRowTotalExclTaxHtml($_item); ?>
-    </td>
+        <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+            <?php echo $this->getRowTotalExclTaxHtml($_item); ?>
+        </span>
     <?php endif; ?>
-<?php /* //Excluding Tax Subtotal */ ?>
-
-<?php /* Including Tax Subtotal */ ?>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartPriceInclTax() || $this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-    <td class="col subtotal incl tax">
-        <?php echo $this->getRowTotalInclTaxHtml($_item); ?>
+    <?php /* //Excluding Tax Subtotal */ ?>
     </td>
-    <?php endif; ?>
-<?php /* //Including Tax Subtotal */ ?>
 </tr>
diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml
index bbd4fa7ef9c..bbc00042218 100644
--- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml
+++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/shipping.phtml
@@ -44,42 +44,50 @@
                 </strong>
                 <address><?php echo $_address->format('html') ?></address>
             </div>
-            <div class="box method">
-                <strong class="subtitle">
+            <div class="box box-order-shipping-method">
+                <strong class="box-title">
                     <span><?php echo __('Shipping Method') ?></span>
                 </strong>
-                <?php if (!($_shippingRateGroups = $this->getShippingRates($_address))): ?>
-                    <p><?php echo __('Sorry, no quotes are available for this order at this time.') ?></p>
-                <?php else: ?>
-                <dl class="sp-methods items methods">
-                    <?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?>
-                        <dt class="item title"><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
-                        <dd class="item content options">
-                            <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
-                                <div class="field choice">
-                                   <?php if ($_rate->getErrorMessage()): ?>
-                                            <strong><?php echo $this->escapeHtml($_rate->getCarrierTitle()) ?>: <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?></strong>
-                                       <?php else: ?>
-                                            <?php if ($_sole) : ?>
-                                            <input type="radio" name="shipping_method[<?php echo $_address->getId() ?>]" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>" class="radio solo method" checked="checked"/>
-                                            <?php else: ?>
-                                            <input type="radio" name="shipping_method[<?php echo $_address->getId() ?>]" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod($_address)) echo ' checked="checked"' ?> class="radio" />
-                                            <?php endif; ?>
-                                            <label for="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
-                                            <?php $_excl = $this->getShippingPrice($_address, $_rate->getPrice(), $this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()); ?>
-                                            <?php $_incl = $this->getShippingPrice($_address, $_rate->getPrice(), true); ?>
-                                            <?php echo $_excl; ?>
-                                            <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
-                                                (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
-                                            <?php endif; ?>
-                                            </label>
-                                   <?php endif ?>
-                                </div>
-                            <?php endforeach; ?>
-                        </dd>
-                    <?php endforeach; ?>
-                </dl>
-                <?php endif; ?>
+                <div class="box-content">
+                    <?php if (!($_shippingRateGroups = $this->getShippingRates($_address))): ?>
+                        <p><?php echo __('Sorry, no quotes are available for this order at this time.') ?></p>
+                    <?php else: ?>
+                    <dl class="sp-methods items methods">
+                        <?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?>
+                            <dt class="item-title"><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
+                            <dd class="item-content options">
+                                <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
+                                    <div class="field choice">
+                                       <?php if ($_rate->getErrorMessage()): ?>
+                                                <strong><?php echo $this->escapeHtml($_rate->getCarrierTitle()) ?>: <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?></strong>
+                                           <?php else: ?>
+                                                <?php if ($_sole) : ?>
+                                                <input type="radio" name="shipping_method[<?php echo $_address->getId() ?>]" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>" class="radio solo method" checked="checked"/>
+                                                <?php else: ?>
+                                                <input type="radio" name="shipping_method[<?php echo $_address->getId() ?>]" value="<?php echo $_rate->getCode() ?>" id="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod($_address)) echo ' checked="checked"' ?> class="radio" />
+                                                <?php endif; ?>
+                                                <label for="s_method_<?php echo $_address->getId() ?>_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
+                                                <?php $_excl = $this->getShippingPrice($_address, $_rate->getPrice(), $this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()); ?>
+                                                <?php $_incl = $this->getShippingPrice($_address, $_rate->getPrice(), true); ?>
+                                                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                                                <span class="price-including-tax" data-label="<?php echo __('Incl. Tax'); ?>">
+                                                <?php endif; ?>
+                                                    <?php echo $_incl; ?>
+                                                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                                                </span>
+                                                <?php endif; ?>
+                                                <?php if ($this->helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?>
+                                                    <span class="price-excluding-tax" data-label="<?php echo __('Excl. Tax'); ?>"><?php echo $_excl; ?></span>
+                                                <?php endif; ?>
+                                                </label>
+                                       <?php endif ?>
+                                    </div>
+                                <?php endforeach; ?>
+                            </dd>
+                        <?php endforeach; ?>
+                    </dl>
+                    <?php endif; ?>
+                </div>
             </div>
             <div class="box items">
                 <strong class="subtitle">
diff --git a/app/code/Magento/Newsletter/Block/Adminhtml/Queue/Edit.php b/app/code/Magento/Newsletter/Block/Adminhtml/Queue/Edit.php
index 98e50289672..89e057e541d 100644
--- a/app/code/Magento/Newsletter/Block/Adminhtml/Queue/Edit.php
+++ b/app/code/Magento/Newsletter/Block/Adminhtml/Queue/Edit.php
@@ -43,25 +43,17 @@ class Edit extends \Magento\Backend\Block\Template
      */
     protected $_coreRegistry = null;
 
-    /**
-     * @var \Magento\Cms\Model\Wysiwyg\Config
-     */
-    protected $_wysiwygConfig;
-
     /**
      * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
-        \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
         $this->_coreRegistry = $registry;
-        $this->_wysiwygConfig = $wysiwygConfig;
         parent::__construct($context, $data);
     }
 
@@ -123,11 +115,6 @@ class Edit extends \Magento\Backend\Block\Template
      */
     protected function _prepareLayout()
     {
-        // Load Wysiwyg on demand and Prepare layout
-        if ($this->_wysiwygConfig->isEnabled()) {
-            $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
-        }
-
         $this->getToolbar()->addChild(
             'back_button',
             'Magento\Backend\Block\Widget\Button',
diff --git a/app/code/Magento/Newsletter/Block/Adminhtml/Template/Edit.php b/app/code/Magento/Newsletter/Block/Adminhtml/Template/Edit.php
index 656be4d4600..87368ac6925 100644
--- a/app/code/Magento/Newsletter/Block/Adminhtml/Template/Edit.php
+++ b/app/code/Magento/Newsletter/Block/Adminhtml/Template/Edit.php
@@ -78,10 +78,10 @@ class Edit extends \Magento\Backend\Block\Widget
     protected function _prepareLayout()
     {
         // Load Wysiwyg on demand and Prepare layout
-        $block = $this->getLayout()->getBlock('head');
-        if ($this->_wysiwygConfig->isEnabled() && $block) {
-            $block->setCanLoadTinyMce(true);
-        }
+//        $block = $this->getLayout()->getBlock('head');
+//        if ($this->_wysiwygConfig->isEnabled() && $block) {
+//            $block->setCanLoadTinyMce(true);
+//        }
 
         $this->getToolbar()->addChild(
             'back_button',
diff --git a/app/code/Magento/Newsletter/Controller/Manage/Index.php b/app/code/Magento/Newsletter/Controller/Manage/Index.php
index 2d0b45d0749..1484ef70dbc 100644
--- a/app/code/Magento/Newsletter/Controller/Manage/Index.php
+++ b/app/code/Magento/Newsletter/Controller/Manage/Index.php
@@ -39,7 +39,7 @@ class Index extends \Magento\Newsletter\Controller\Manage
         if ($block = $this->_view->getLayout()->getBlock('customer_newsletter')) {
             $block->setRefererUrl($this->_redirect->getRefererUrl());
         }
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Newsletter Subscription'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Newsletter Subscription'));
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Newsletter/Controller/Manage/Save.php b/app/code/Magento/Newsletter/Controller/Manage/Save.php
index 04eac75883c..1039725ef0e 100644
--- a/app/code/Magento/Newsletter/Controller/Manage/Save.php
+++ b/app/code/Magento/Newsletter/Controller/Manage/Save.php
@@ -47,7 +47,7 @@ class Save extends \Magento\Newsletter\Controller\Manage
                 $customerDetails = $this->_customerDetailsBuilder->setAddresses(null)
                     ->setCustomer($this->_customerBuilder->populate($customer)->setStoreId($storeId)->create())
                     ->create();
-                $this->_customerAccountService->updateCustomer($customerDetails);
+                $this->_customerAccountService->updateCustomer($customerId, $customerDetails);
 
                 if ((boolean)$this->getRequest()->getParam('is_subscribed', false)) {
                     $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php
index 797d72743de..af7de6fb3e5 100644
--- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php
+++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php
@@ -69,6 +69,7 @@ class CustomerPlugin
      *
      * @param CustomerAccountServiceInterface $subject
      * @param callable $updateCustomer
+     * @param string $customerId
      * @param CustomerDetails $customerDetails
      * @return bool
      *
@@ -77,9 +78,10 @@ class CustomerPlugin
     public function aroundUpdateCustomer(
         CustomerAccountServiceInterface $subject,
         callable $updateCustomer,
+        $customerId,
         CustomerDetails $customerDetails
     ) {
-        $result = $updateCustomer($customerDetails);
+        $result = $updateCustomer($customerId, $customerDetails);
 
         $this->subscriberFactory->create()->updateSubscription($customerDetails->getCustomer()->getId());
 
diff --git a/app/code/Magento/Newsletter/Model/Resource/Queue.php b/app/code/Magento/Newsletter/Model/Resource/Queue.php
index b53856a8e68..0139fa879f7 100644
--- a/app/code/Magento/Newsletter/Model/Resource/Queue.php
+++ b/app/code/Magento/Newsletter/Model/Resource/Queue.php
@@ -78,7 +78,7 @@ class Queue extends \Magento\Framework\Model\Resource\Db\AbstractDb
             throw new \Magento\Framework\Model\Exception(__('There are no subscribers selected.'));
         }
 
-        if (!$queue->getId() && $queue->getQueueStatus() != Magento_Newsletter_Model_Queue::STATUS_NEVER) {
+        if (!$queue->getId() && $queue->getQueueStatus() != \Magento\Newsletter\Model\Queue::STATUS_NEVER) {
             throw new \Magento\Framework\Model\Exception(__('You selected an invalid queue.'));
         }
 
diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json
index b21997e27c9..1299cb53107 100644
--- a/app/code/Magento/Newsletter/composer.json
+++ b/app/code/Magento/Newsletter/composer.json
@@ -3,21 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-email": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-email": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Newsletter/etc/module.xml b/app/code/Magento/Newsletter/etc/module.xml
index 3f4d2f1b350..c4d8cc2d1f1 100644
--- a/app/code/Magento/Newsletter/etc/module.xml
+++ b/app/code/Magento/Newsletter/etc/module.xml
@@ -40,7 +40,6 @@
             <module name="Magento_Backend"/>
             <module name="Magento_Cms"/>
             <module name="Magento_Email"/>
-            <module name="Magento_Theme"/>
             <module name="Magento_Cron"/>
             <module name="Magento_Eav"/>
         </depends>
diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_edit.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_edit.xml
index c4e203a5f3f..dd7cf98b9f3 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_edit.xml
+++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_edit.xml
@@ -25,18 +25,10 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="editor"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-fileuploader-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <link src="jquery/fileUploader/bootstrap.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Newsletter\Block\Adminhtml\Queue\Edit" name="queue_edit" template="queue/edit.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_preview.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_preview.xml
index 9b0b0a8f863..197b1ebde82 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_preview.xml
+++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_queue_preview.xml
@@ -23,12 +23,16 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="backend.page">
-        <action method="setTemplate">
-            <argument name="template" xsi:type="string">Magento_Newsletter::preview/iframeswitcher.phtml</argument>
-        </action>
-        <block class="Magento\Newsletter\Block\Adminhtml\Queue\Preview\Form" name="preview_form"/>
-        <block class="Magento\Backend\Block\Store\Switcher" name="store_switcher" template="Magento_Backend::store/switcher.phtml" />
-    </referenceBlock>
+<page layout="admin-1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="id" value="html-body"/>
+        <attribute name="class" value="preview-window"/>
+    </body>
+    <remove name="backend.page"/>
+    <referenceContainer name="root">
+        <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Newsletter::preview/iframeswitcher.phtml">
+            <block class="Magento\Newsletter\Block\Adminhtml\Queue\Preview\Form" name="preview_form"/>
+            <block class="Magento\Backend\Block\Store\Switcher" name="store_switcher" template="Magento_Backend::store/switcher.phtml" />
+        </block>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_edit.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_edit.xml
index 774d94f3e8b..bf235b36dbb 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_edit.xml
+++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_edit.xml
@@ -25,18 +25,10 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="editor"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-fileuploader-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <link src="jquery/fileUploader/bootstrap.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Newsletter\Block\Adminhtml\Template\Edit" name="template_edit" template="template/edit.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_preview.xml b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_preview.xml
index acb93d7f00b..197b1ebde82 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_preview.xml
+++ b/app/code/Magento/Newsletter/view/adminhtml/layout/newsletter_template_preview.xml
@@ -23,12 +23,16 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="backend.page">
-        <action method="setTemplate">
-            <argument name="template" xsi:type="string">Magento_Newsletter::preview/iframeswitcher.phtml</argument>
-        </action>
-        <block class="Magento\Newsletter\Block\Adminhtml\Template\Preview\Form" name="preview_form"/>
-        <block class="Magento\Backend\Block\Store\Switcher" name="store_switcher" template="Magento_Backend::store/switcher.phtml" />
-    </referenceBlock>
+<page layout="admin-1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="id" value="html-body"/>
+        <attribute name="class" value="preview-window"/>
+    </body>
+    <remove name="backend.page"/>
+    <referenceContainer name="root">
+        <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Newsletter::preview/iframeswitcher.phtml">
+            <block class="Magento\Newsletter\Block\Adminhtml\Queue\Preview\Form" name="preview_form"/>
+            <block class="Magento\Backend\Block\Store\Switcher" name="store_switcher" template="Magento_Backend::store/switcher.phtml" />
+        </block>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml
index af988e13cc2..5b6abc6b696 100644
--- a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml
+++ b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml
@@ -22,15 +22,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php
-/* @var $this \Magento\Backend\Block\Page */
-?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
-<head>
-<?php echo $this->getChildHtml('head') ?>
-</head>
-<body id="html-body" class="preview-window">
 <div id="preview" class="cms-revision-preview">
     <div class="toolbar">
         <?php if (!$this->isSingleStoreMode()) :?>
@@ -77,5 +68,3 @@ jQuery("#preview_iframe").load(function() {
 
 });
 </script>
-</body>
-</html>
diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json
index dfecdfa001f..65ed9dc6de6 100644
--- a/app/code/Magento/OfflinePayments/composer.json
+++ b/app/code/Magento/OfflinePayments/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json
index efc97818ad1..35d7460d1d6 100644
--- a/app/code/Magento/OfflineShipping/composer.json
+++ b/app/code/Magento/OfflineShipping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-sales-rule": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-sales-rule": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Ogone/composer.json b/app/code/Magento/Ogone/composer.json
index bd859235d5b..63095972229 100644
--- a/app/code/Magento/Ogone/composer.json
+++ b/app/code/Magento/Ogone/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/PageCache/Model/App/FrontController/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/App/FrontController/BuiltinPlugin.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php b/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php
old mode 100755
new mode 100644
diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json
index f8da46fc5f2..a6cd124ebca 100644
--- a/app/code/Magento/PageCache/composer.json
+++ b/app/code/Magento/PageCache/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/PageCache/view/frontend/layout/default.xml b/app/code/Magento/PageCache/view/frontend/layout/default.xml
index 9cd5fc1f8be..62bc801e271 100644
--- a/app/code/Magento/PageCache/view/frontend/layout/default.xml
+++ b/app/code/Magento/PageCache/view/frontend/layout/default.xml
@@ -27,8 +27,7 @@
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="pagecache_page_head_components" template="Magento_PageCache::js/components.phtml"/>
     </referenceBlock>
-    <referenceBlock name="head"></referenceBlock>
     <referenceContainer name="content">
         <block class="Magento\PageCache\Block\Javascript" template="Magento_PageCache::javascript.phtml" name="pageCache" as="pageCache"/>
     </referenceContainer>
-</page>
\ No newline at end of file
+</page>
diff --git a/app/code/Magento/PayPalRecurringPayment/composer.json b/app/code/Magento/PayPalRecurringPayment/composer.json
index 7b016f8c135..e45d930bccb 100644
--- a/app/code/Magento/PayPalRecurringPayment/composer.json
+++ b/app/code/Magento/PayPalRecurringPayment/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-paypal": "0.1.0-alpha96",
-        "magento/module-recurring-payment": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-paypal": "0.1.0-alpha97",
+        "magento/module-recurring-payment": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index a3d80826c45..ac92021012d 100644
--- a/app/code/Magento/Payment/composer.json
+++ b/app/code/Magento/Payment/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-centinel": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-centinel": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
index 24d54ec5ae5..19b1307085a 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
@@ -38,7 +38,7 @@ class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpr
             $this->_initCheckout();
             $this->_checkout->updateShippingMethod($this->getRequest()->getParam('shipping_method'));
             if ($isAjax) {
-                $this->_view->loadLayout('paypal_express_review_details');
+                $this->_view->loadLayout('paypal_express_review_details', true, true, false);
                 $this->getResponse()->setBody(
                     $this->_view->getLayout()->getBlock('page.block')->setQuote($this->_getQuote())->toHtml()
                 );
diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json
index d35eb98c64c..62d584462c6 100644
--- a/app/code/Magento/Paypal/composer.json
+++ b/app/code/Magento/Paypal/composer.json
@@ -3,25 +3,25 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-centinel": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-centinel": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_system_config_edit.xml b/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_system_config_edit.xml
index b480da881fa..5f054039c7e 100644
--- a/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_system_config_edit.xml
+++ b/app/code/Magento/Paypal/view/adminhtml/layout/adminhtml_system_config_edit.xml
@@ -24,11 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-paypal-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Paypal::styles.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="Magento_Paypal::styles.css"/>
+    </head>
 </page>
diff --git a/app/code/Magento/Paypal/view/frontend/layout/customer_account.xml b/app/code/Magento/Paypal/view/frontend/layout/customer_account.xml
index 1fab718a4ce..de0a08d5207 100644
--- a/app/code/Magento/Paypal/view/frontend/layout/customer_account.xml
+++ b/app/code/Magento/Paypal/view/frontend/layout/customer_account.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Billing Agreements</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Billing Agreements</title>
+    </head>
     <referenceBlock name="customer_account_navigation">
         <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-billing-agreements-link">
             <arguments>
diff --git a/app/code/Magento/Paypal/view/frontend/layout/paypal_payflowexpress_review.xml b/app/code/Magento/Paypal/view/frontend/layout/paypal_payflowexpress_review.xml
index 92732d9d1b4..a9275be1469 100644
--- a/app/code/Magento/Paypal/view/frontend/layout/paypal_payflowexpress_review.xml
+++ b/app/code/Magento/Paypal/view/frontend/layout/paypal_payflowexpress_review.xml
@@ -41,7 +41,7 @@
             </block>
         </block>
     </referenceContainer>
-    <referenceBlock name="head">
+    <referenceContainer name="after.body.start">
         <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Paypal::js/components.phtml"/>
-    </referenceBlock>
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml b/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml
index 85ffa6aa7d7..9bae2df213f 100644
--- a/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml
+++ b/app/code/Magento/Paypal/view/frontend/templates/billing/agreement/view.phtml
@@ -23,83 +23,97 @@
  */
 ?>
 <?php /* @var $this \Magento\Paypal\Block\Billing\Agreement\View */ ?>
-<div class="block block-billing-agreements-view">
-    <div class="block-title">
-        <strong><?php echo __('Billing Agreement # %1', $this->escapeHtml($this->getReferenceId())) ?></strong>
-        <?php if ($this->getCanCancel()): ?>
-            <button type="button" title="<?php echo __('Cancel') ?>" class="secondary action cancel" onclick="if( confirm('<?php echo __('Are you sure you want to do this?') ?>') ) { window.location.href = '<?php echo $this->getCancelUrl() ?>'; } return false;">
-                <span><?php echo __('Cancel') ?></span>
-            </button>
-        <?php endif; ?>
-    </div>
-    <div class="block-title"><strong><?php echo __('Agreement Information') ?></strong></div>
-    <div class="block-content">
-        <div class="table-wrapper billing-agreements-view">
-            <table class="data table table-billing-agreements-view">
-                <caption class="table caption"><?php echo __('Agreement Information') ?></caption>
-                <thead>
-                    <tr>
-                        <th scope="col" class="col id"><?php echo __('Reference ID:'); ?></th>
-                        <th scope="col" class="col status"><?php echo __('Status:'); ?></th>
-                        <th scope="col" class="col created"><?php echo __('Created:'); ?></th>
-                        <?php if($this->getAgreementUpdatedAt()): ?>
-                            <th scope="col" class="col updated"><?php echo __('Updated:'); ?></th>
-                        <?php endif; ?>
-                        <th scope="col" class="col payment"><?php echo __('Payment Method:'); ?></th>
-                    </tr>
-                </thead>
-                <tbody>
+    <div class="block block-billing-agreements-view">
+        <div class="block-title">
+            <strong><?php echo __('Billing Agreement # %1', $this->escapeHtml($this->getReferenceId())) ?></strong>
+            <?php if ($this->getCanCancel()): ?>
+                <button type="button" title="<?php echo __('Cancel') ?>" class="secondary action cancel" onclick="if( confirm('<?php echo __('Are you sure you want to do this?') ?>') ) { window.location.href = '<?php echo $this->getCancelUrl() ?>'; } return false;">
+                    <span><?php echo __('Cancel') ?></span>
+                </button>
+            <?php endif; ?>
+        </div>
+        <div class="block-title"><strong><?php echo __('Agreement Information') ?></strong></div>
+        <div class="block-content">
+            <div class="table-wrapper billing-agreements-view">
+                <table class="data table table-billing-agreements-view">
+                    <caption class="table caption"><?php echo __('Agreement Information') ?></caption>
+                    <thead>
+                        <tr>
+                            <th scope="col" class="col id"><?php echo __('Reference ID:'); ?></th>
+                            <th scope="col" class="col status"><?php echo __('Status:'); ?></th>
+                            <th scope="col" class="col created"><?php echo __('Created:'); ?></th>
+                            <?php if($this->getAgreementUpdatedAt()): ?>
+                                <th scope="col" class="col updated"><?php echo __('Updated:'); ?></th>
+                            <?php endif; ?>
+                            <th scope="col" class="col payment"><?php echo __('Payment Method:'); ?></th>
+                        </tr>
+                    </thead>
+                    <tbody>
                     <tr>
-                        <td data-th="<?php echo $this->escapeHtml(__('Reference ID:')); ?>" class="col id"><?php echo $this->escapeHtml($this->getReferenceId()); ?></td>
-                        <td data-th="<?php echo $this->escapeHtml(__('Status:')); ?>" class="col status"><?php echo $this->getAgreementStatus() ?></td>
-                        <td data-th="<?php echo $this->escapeHtml(__('Created:')); ?>" class="col created"><?php echo $this->escapeHtml($this->getAgreementCreatedAt()) ?></td>
-                        <?php if($this->getAgreementUpdatedAt()): ?>
-                            <td data-th="<?php echo $this->escapeHtml(__('Updated:')); ?>" class="col updated"><?php echo $this->escapeHtml($this->getAgreementUpdatedAt()); ?></td>
+                        <td data-th="<?php echo $this->escapeHtml(__('Reference ID:')); ?>"
+                            class="col id"><?php echo $this->escapeHtml($this->getReferenceId()); ?></td>
+                        <td data-th="<?php echo $this->escapeHtml(__('Status:')); ?>"
+                            class="col status"><?php echo $this->getAgreementStatus() ?></td>
+                        <td data-th="<?php echo $this->escapeHtml(__('Created:')); ?>"
+                            class="col created"><?php echo $this->escapeHtml($this->getAgreementCreatedAt()) ?></td>
+                        <?php if ($this->getAgreementUpdatedAt()): ?>
+                            <td data-th="<?php echo $this->escapeHtml(__('Updated:')); ?>"
+                                class="col updated"><?php echo $this->escapeHtml($this->getAgreementUpdatedAt()); ?></td>
                         <?php endif; ?>
-                        <td data-th="<?php echo $this->escapeHtml(__('Payment Method:')); ?>" class="col payment"><?php echo $this->getPaymentMethodTitle() ?></td>
+                        <td data-th="<?php echo $this->escapeHtml(__('Payment Method:')); ?>"
+                            class="col payment"><?php echo $this->getPaymentMethodTitle() ?></td>
                     </tr>
-                </tbody>
-            </table>
+                    </tbody>
+                </table>
+            </div>
         </div>
-        <?php $relatedOrders = $this->getRelatedOrders() ?>
-        <?php if(count($relatedOrders) > 0): ?>
-        <?php echo $this->getChildHtml('pager'); ?>
-        <h2 class="subtitle caption"><?php echo __('Related Orders') ?></h2>
-        <div class="table-wrapper billing-agreements-related">
-            <table class="data table table-billing-agreements-related" id="related-orders-table">
-                <caption class="table caption"><?php echo __('Related Orders') ?></caption>
-                <thead>
-                    <tr>
-                        <th scope="col" class="col id"><?php echo __('Order #') ?></th>
-                        <th scope="col" class="col date"><?php echo __('Date') ?></th>
-                        <th scope="col" class="col shipto"><?php echo __('Ship To') ?></th>
-                        <th scope="col" class="col total"><?php echo __('Order Total') ?></th>
-                        <th scope="col" class="col status"><?php echo __('Order Status') ?></th>
-                        <th scope="col" class="col actions">&nbsp;</th>
-                    </tr>
-                </thead>
-                <tbody>
-                <?php foreach ($relatedOrders as $order): ?>
-                    <tr>
-                        <th data-th="<?php echo $this->escapeHtml(__('Order #')); ?>" class="col id"><?php echo $this->getOrderItemValue($order, 'order_increment_id') ?></th>
-                        <th data-th="<?php echo $this->escapeHtml(__('Date')); ?>" class="col date"><?php echo $this->getOrderItemValue($order, 'created_at') ?></th>
-                        <th data-th="<?php echo $this->escapeHtml(__('Ship To')); ?>" class="col shipto"><?php echo $this->getOrderItemValue($order, 'shipping_address') ?></th>
-                        <th data-th="<?php echo $this->escapeHtml(__('Order Total')); ?>" class="col total"><?php echo $this->getOrderItemValue($order, 'order_total') ?></th>
-                        <th data-th="<?php echo $this->escapeHtml(__('Order Status')); ?>" class="col status"><?php echo $this->getOrderItemValue($order, 'status_label') ?></th>
-                        <th data-th="" class="col actions">
-                            <a href="<?php echo $this->getOrderItemValue($order, 'view_url') ?>"><?php echo __('View Order') ?></a>
-                        </th>
-                    </tr>
-                <?php endforeach; ?>
-                </tbody>
-            </table>
+    </div>
+    <?php $relatedOrders = $this->getRelatedOrders() ?>
+    <?php if(count($relatedOrders) > 0): ?>
+    <div class="block block-billing-orders-view">
+    <?php echo $this->getChildHtml('pager'); ?>
+        <div class="block-title"><span><?php echo __('Related Orders') ?></span></div>
+        <div class="block-content">
+            <div class="table-wrapper billing-agreements-related">
+                <table class="data table table-billing-agreements-related" id="related-orders-table">
+                    <caption class="table caption"><?php echo __('Related Orders') ?></caption>
+                    <thead>
+                        <tr>
+                            <th scope="col" class="col id"><?php echo __('Order #') ?></th>
+                            <th scope="col" class="col date"><?php echo __('Date') ?></th>
+                            <th scope="col" class="col shipto"><?php echo __('Ship To') ?></th>
+                            <th scope="col" class="col total"><?php echo __('Order Total') ?></th>
+                            <th scope="col" class="col status"><?php echo __('Order Status') ?></th>
+                            <th scope="col" class="col actions">&nbsp;</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                    <?php foreach ($relatedOrders as $order): ?>
+                        <tr>
+                            <td data-th="<?php echo $this->escapeHtml(__('Order #')); ?>"
+                                class="col id"><?php echo $this->getOrderItemValue($order, 'order_increment_id') ?></td>
+                            <td data-th="<?php echo $this->escapeHtml(__('Date')); ?>"
+                                class="col date"><?php echo $this->getOrderItemValue($order, 'created_at') ?></td>
+                            <td data-th="<?php echo $this->escapeHtml(__('Ship To')); ?>"
+                                class="col shipto"><?php echo $this->getOrderItemValue($order, 'shipping_address') ?></td>
+                            <td data-th="<?php echo $this->escapeHtml(__('Order Total')); ?>"
+                                class="col total"><?php echo $this->getOrderItemValue($order, 'order_total') ?></td>
+                            <td data-th="<?php echo $this->escapeHtml(__('Order Status')); ?>"
+                                class="col status"><?php echo $this->getOrderItemValue($order, 'status_label') ?></td>
+                            <td data-th="" class="col actions">
+                                <a href="<?php echo $this->getOrderItemValue($order, 'view_url') ?>" class="action view"><span><?php echo __('View Order') ?></span></a>
+                            </td>
+                        </tr>
+                    <?php endforeach; ?>
+                    </tbody>
+                </table>
+            </div>
         </div>
-        <?php endif; ?>
+    </div>
+    <?php endif; ?>
 
-        <div class="actions-toolbar">
-            <div class="secondary">
-                <a href="<?php echo $this->getBackUrl() ?>" class="action back"><?php echo __('Back to Billing Agreements') ?></a>
-            </div>
+    <div class="actions-toolbar">
+        <div class="secondary">
+            <a href="<?php echo $this->getBackUrl() ?>" class="action back"><?php echo __('Back to Billing Agreements') ?></a>
         </div>
     </div>
-</div>
diff --git a/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml b/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml
index 84b1ff4917a..c6fe52b7e8d 100644
--- a/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml
+++ b/app/code/Magento/Paypal/view/frontend/templates/billing/agreements.phtml
@@ -49,7 +49,7 @@
                         <td data-th="<?php echo $this->escapeHtml(__('Updated At')); ?>" class="col updated"><?php echo $this->getItemValue($item, 'updated_at') ?></td>
                         <td data-th="<?php echo $this->escapeHtml(__('Payment Method')); ?>" class="col payment"><?php echo $this->getItemValue($item, 'payment_method_label') ?></td>
                         <td data-th="" class="col actions">
-                            <a href="<?php echo $this->getItemValue($item, 'edit_url') ?>"><?php echo __('View') ?></a>
+                            <a href="<?php echo $this->getItemValue($item, 'edit_url') ?>" class="action view"><span><?php echo __('View') ?></span></a>
                         </td>
                     </tr>
                 <?php endforeach; ?>
diff --git a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml
index 5dd89e3a0af..6685cd820bb 100644
--- a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml
+++ b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml
@@ -27,29 +27,13 @@
 <hgroup class="page-title">
     <h1 class="title"><span class="base"><?php echo __('Review Order') ?></span></h1>
 </hgroup>
-<div class="paypal review view">
-    <?php if ($this->getShippingAddress()): ?>
-        <div class="block shipping information">
-            <div class="title"><strong><?php echo __('Shipping Information') ?></strong></div>
-            <div class="content">
-                <div class="box shipping address">
-                    <strong class="subtitle">
-                        <?php echo __('Shipping Address') ?>
-                        <?php if ($this->getCanEditShippingAddress()): ?>
-                            <a href="<?php echo $this->getEditUrl() ?>"
-                               class="action edit"><span><?php echo __('Edit') ?></span></a>
-                        <?php endif; ?>
-                    </strong>
-
-                    <div class="content">
-                        <address><?php echo $this->renderAddress($this->getShippingAddress()) ?></address>
-                    </div>
-                </div>
-
-                <div class="box shipping method">
-                    <strong class="subtitle"><?php echo __('Shipping Method') ?></strong>
-
-                    <div class="content">
+<div class="paypal-review view">
+    <div class="block block-order-details-view">
+        <div class="block-content">
+            <?php if ($this->getShippingAddress()): ?>
+                <div class="box box-order-shipping-method">
+                    <strong class="box-title"><span><?php echo __('Shipping Method') ?></span></strong>
+                    <div class="box-content">
                         <form method="post" id="shipping-method-form"
                               action="<?php echo $this->escapeHtml($this->getShippingMethodSubmitUrl()) ?>"
                               class="form">
@@ -76,9 +60,12 @@
                                             <?php endforeach; ?>
                                         </select>
                                     </div>
-                                    <div class="actions">
-                                        <button id="update-shipping-method-submit" type="submit" class="action update">
-                                            <span><?php echo __('Update Shipping Method') ?></span></button>
+                                    <div class="actions-toolbar">
+                                        <div class="primary">
+                                            <button id="update-shipping-method-submit" type="submit"
+                                                    class="action update primary">
+                                                <span><?php echo __('Update Shipping Method') ?></span></button>
+                                        </div>
                                     </div>
                                 <?php else: ?>
                                     <p><?php echo __('Sorry, no quotes are available for this order at this time.') ?></p>
@@ -89,45 +76,55 @@
                         </form>
                     </div>
                 </div>
-            </div>
-        </div>
-    <?php endif; ?>
-
-    <div class="block billing information">
-        <div class="title"><strong><?php echo __('Billing Information') ?></strong></div>
-        <div class="content">
-            <div class="box billing">
-                <strong class="subtitle">
-                    <?php echo __('Payment Method') ?>
-                    <?php if ($this->getEditUrl()): ?><a href="<?php echo $this->getEditUrl() ?>" class="action edit">
-                        <span><?php echo __('Edit Payment Information') ?></span></a><?php endif ?>
-                </strong>
-
-                <div class="content">
+                <div class="box box-order-shipping-address">
+                    <strong class="box-title"><span><?php echo __('Shipping Address') ?></span></strong>
+                    <div class="box-content">
+                        <address><?php echo $this->renderAddress($this->getShippingAddress()) ?></address>
+                    </div>
+                    <?php if ($this->getCanEditShippingAddress()): ?>
+                        <div class="box-actions">
+                            <a href="<?php echo $this->getEditUrl() ?>"
+                               class="action edit"><span><?php echo __('Edit') ?></span></a>
+                        </div>
+                    <?php endif; ?>
+                </div>
+            <?php endif; ?>
+            <div class="box box-order-billing-address">
+                <strong class="box-title"><span><?php echo __('Payment Method') ?></span></strong>
+                <div class="box-content">
                     <?php echo $this->escapeHtml($this->getPaymentMethodTitle()) ?>
                 </div>
+            <?php if ($this->getEditUrl()): ?>
+                <div class="box-actions">
+                    <a href="<?php echo $this->getEditUrl() ?>" class="action edit">
+                        <span><?php echo __('Edit Payment Information') ?></span>
+                    </a>
+                </div>
+            <?php endif ?>
             </div>
         </div>
     </div>
 
-    <div class="paypal review items">
-        <div class="paypal subtitle caption">
+    <div class="paypal-review-items">
+        <div class="paypal-review-title">
             <strong><?php echo __('Items in Your Shopping Cart') ?></strong>
             <a href="<?php echo $this->getUrl('checkout/cart') ?>"
                class="action edit"><span><?php echo __('Edit Shopping Cart') ?></span></a>
         </div>
 
-        <div id="details-reload">
+        <div id="details-reload" class="table-wrapper order-items">
             <?php echo $this->getChildHtml('details') ?>
         </div>
 
         <form method="post" id="order-review-form" action="<?php echo $this->getPlaceOrderUrl() ?>" class="form">
             <?php echo $this->getChildHtml('agreements'); ?>
-            <div class="actions" id="review-buttons-container">
-                <button type="button" id="review-button" value="<?php echo __('Place Order') ?>"
-                        class="action checkout"><span><?php echo __('Place Order') ?></span></button>
-                <button type="button" id="review-submit" value="<?php echo __('Place Order') ?>"
-                        class="action checkout"><span><?php echo __('Place Order') ?></span></button>
+            <div class="actions-toolbar" id="review-buttons-container">
+                <div class="primary">
+                    <button type="button" id="review-button" value="<?php echo __('Place Order') ?>"
+                            class="action checkout primary"><span><?php echo __('Place Order') ?></span></button>
+                    <button type="button" id="review-submit" value="<?php echo __('Place Order') ?>"
+                            class="action checkout primary"><span><?php echo __('Place Order') ?></span></button>
+                </div>
                 <span class="please-wait load indicator" id="review-please-wait" style="display: none;" data-text="<?php echo __('Submitting order information...') ?>">
                    <span><?php echo __('Submitting order information...') ?></span>
                 </span>
diff --git a/app/code/Magento/Paypal/view/frontend/templates/express/review/details.phtml b/app/code/Magento/Paypal/view/frontend/templates/express/review/details.phtml
index 682ff50e125..2d28f474647 100644
--- a/app/code/Magento/Paypal/view/frontend/templates/express/review/details.phtml
+++ b/app/code/Magento/Paypal/view/frontend/templates/express/review/details.phtml
@@ -26,25 +26,19 @@
  * @see \Magento\Paypal\Block\Express\Review\Details
  */
 ?>
-<table id="details-table" class="data table paypal review items">
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): $colspan = $rowspan = 2; else: $colspan = $rowspan = 1; endif; ?>
+<table id="details-table" class="data table table-paypal-review-items">
+    <caption class="table caption"><?php echo __('Items in Your Shopping Cart') ?></caption>
     <thead>
     <tr>
-        <th rowspan="<?php echo $rowspan ?>" class="col name"><?php echo __('Product Name') ?></th>
-        <th colspan="<?php echo $colspan ?>" class="col price"><?php echo __('Price') ?></th>
-        <th rowspan="<?php echo $rowspan ?>" class="col qty"><?php echo __('Qty') ?></th>
-        <th colspan="<?php echo $colspan ?>" class="col subtotal"><?php echo __('Subtotal') ?></th>
+        <th class="col name"><?php echo __('Product Name') ?></th>
+        <th class="col price"><?php echo __('Price') ?></th>
+        <th class="col qty"><?php echo __('Qty') ?></th>
+        <th class="col subtotal"><?php echo __('Subtotal') ?></th>
     </tr>
-    <?php if ($this->helper('Magento\Tax\Helper\Data')->displayCartBothPrices()): ?>
-        <tr>
-            <th class="col price excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-            <th class="col price incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-            <th class="col subtotal excl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(false) ?></th>
-            <th class="col subtotal incl tax"><?php echo $this->helper('Magento\Tax\Helper\Data')->getIncExcTaxLabel(true) ?></th>
-        </tr>
-    <?php endif; ?>
     </thead>
-    <?php echo $this->getChildHtml('totals'); ?>
+    <tfoot>
+        <?php echo $this->getChildHtml('totals'); ?>
+    </tfoot>
     <tbody>
     <?php foreach ($this->getItems() as $_item): ?>
         <?php echo $this->getItemHtml($_item) ?>
diff --git a/app/code/Magento/Paypal/view/frontend/templates/express/review/shipping/method.phtml b/app/code/Magento/Paypal/view/frontend/templates/express/review/shipping/method.phtml
index f99953d4aa4..1f5a98a2fa9 100644
--- a/app/code/Magento/Paypal/view/frontend/templates/express/review/shipping/method.phtml
+++ b/app/code/Magento/Paypal/view/frontend/templates/express/review/shipping/method.phtml
@@ -50,6 +50,6 @@
         <p><strong><?php echo $this->renderShippingRateOption($this->getCurrentShippingRate()) ?></strong></p>
     <?php endif; ?>
 </div>
-<div style="display:none" id="shipping_method_update">
+<div style="display: none" id="shipping_method_update">
     <p><?php echo __('Please update order data to get shipping methods and rates') ?></p>
 </div>
diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index b7beeaf0dba..a25825eaa2c 100644
--- a/app/code/Magento/Persistent/composer.json
+++ b/app/code/Magento/Persistent/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json
index 601bf0613c8..9f3c3216d07 100644
--- a/app/code/Magento/ProductAlert/composer.json
+++ b/app/code/Magento/ProductAlert/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
index 27bd0e404d5..843696fd476 100644
--- a/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
@@ -103,7 +103,7 @@ class RecurringPayment extends \Magento\Framework\App\Action\Action
             $this->_view->getLayout()->initMessages();
 
             $title = __('Recurring Payment #%1', $payment->getReferenceId());
-            $this->_view->getLayout()->getBlock('head')->setTitle($title);
+            $this->_view->getPage()->getConfig()->setTitle($title);
 
             $this->_view->renderLayout();
             return;
diff --git a/app/code/Magento/RecurringPayment/composer.json b/app/code/Magento/RecurringPayment/composer.json
index e582f45999e..b8bd1ab1c5e 100644
--- a/app/code/Magento/RecurringPayment/composer.json
+++ b/app/code/Magento/RecurringPayment/composer.json
@@ -3,22 +3,22 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/RecurringPayment/view/frontend/layout/sales_recurringpayment_index.xml b/app/code/Magento/RecurringPayment/view/frontend/layout/sales_recurringpayment_index.xml
index c51e9954930..4567ba63e35 100644
--- a/app/code/Magento/RecurringPayment/view/frontend/layout/sales_recurringpayment_index.xml
+++ b/app/code/Magento/RecurringPayment/view/frontend/layout/sales_recurringpayment_index.xml
@@ -25,11 +25,9 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <update handle="customer_account"/>
-    <referenceBlock name="head">
-        <action method="setTitle">
-            <argument translate="true" name="title" xsi:type="string">Recurring Payments</argument>
-        </action>
-    </referenceBlock>
+    <head>
+        <title>Recurring Payments</title>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\RecurringPayment\Block\Payments" name="sales.recurring.payments" template="recurring/payments.phtml" cacheable="false">
             <block class="Magento\RecurringPayment\Block\Payment\Grid" name="sales.recurring.payments.grid" as="grid" template="recurring/grid.phtml" cacheable="false">
diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json
index 21509183ce0..47d42e8dced 100644
--- a/app/code/Magento/Reports/composer.json
+++ b/app/code/Magento/Reports/composer.json
@@ -3,27 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-log": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-review": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-downloadable": "0.1.0-alpha96",
-        "magento/module-sales-rule": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-log": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-review": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-downloadable": "0.1.0-alpha97",
+        "magento/module-sales-rule": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Reports/view/frontend/layout/default.xml b/app/code/Magento/Reports/view/frontend/layout/default.xml
index 1f4fd3bab33..79f92ecebdb 100644
--- a/app/code/Magento/Reports/view/frontend/layout/default.xml
+++ b/app/code/Magento/Reports/view/frontend/layout/default.xml
@@ -24,10 +24,6 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceContainer name="sidebar.additional">
-        <block class="Magento\Reports\Block\Product\Viewed" name="reports.product.viewed" template="product_viewed.phtml"/>
-        <block class="Magento\Reports\Block\Product\Compared" name="reports.product.compared" template="product_compared.phtml"/>
-    </referenceContainer>
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="reports_page_head_components" template="Magento_Reports::js/components.phtml"/>
     </referenceBlock>
diff --git a/app/code/Magento/RequireJs/Block/Html/Head/Config.php b/app/code/Magento/RequireJs/Block/Html/Head/Config.php
index 0c01fa9ba8a..e86339c0416 100644
--- a/app/code/Magento/RequireJs/Block/Html/Head/Config.php
+++ b/app/code/Magento/RequireJs/Block/Html/Head/Config.php
@@ -24,12 +24,10 @@
 
 namespace Magento\RequireJs\Block\Html\Head;
 
-use Magento\Theme\Block\Html\Head\AssetBlockInterface;
-
 /**
  * Block responsible for including RequireJs config on the page
  */
-class Config extends \Magento\Framework\View\Element\AbstractBlock implements AssetBlockInterface
+class Config extends \Magento\Framework\View\Element\AbstractBlock
 {
     /**
      * @var \Magento\Framework\RequireJs\Config
@@ -42,38 +40,40 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock implements As
     private $fileManager;
 
     /**
-     * @var \Magento\Framework\View\Asset\LocalInterface
+     * @var \Magento\Framework\View\Page\Config
      */
-    private $asset;
+    protected $pageConfig;
 
     /**
      * @param \Magento\Framework\View\Element\Context $context
      * @param \Magento\Framework\RequireJs\Config $config
      * @param \Magento\RequireJs\Model\FileManager $fileManager
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Context $context,
         \Magento\Framework\RequireJs\Config $config,
         \Magento\RequireJs\Model\FileManager $fileManager,
+        \Magento\Framework\View\Page\Config $pageConfig,
         array $data = array()
     ) {
         parent::__construct($context, $data);
         $this->config = $config;
         $this->fileManager = $fileManager;
+        $this->pageConfig = $pageConfig;
     }
 
     /**
      * Include RequireJs configuration as an asset on the page
      *
-     * @return \Magento\Framework\View\Asset\LocalInterface
+     * @return $this
      */
-    public function getAsset()
+    protected function _prepareLayout()
     {
-        if (!$this->asset) {
-            $this->asset = $this->fileManager->createRequireJsAsset();
-        }
-        return $this->asset;
+        $asset = $this->fileManager->createRequireJsAsset();
+        $this->pageConfig->getAssetCollection()->add($asset->getFilePath(), $asset);
+        return parent::_prepareLayout();
     }
 
     /**
diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json
index 7f4749db302..5f6b598c277 100644
--- a/app/code/Magento/RequireJs/composer.json
+++ b/app/code/Magento/RequireJs/composer.json
@@ -3,12 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/RequireJs/etc/module.xml b/app/code/Magento/RequireJs/etc/module.xml
index a380d363d63..39fe576cae9 100644
--- a/app/code/Magento/RequireJs/etc/module.xml
+++ b/app/code/Magento/RequireJs/etc/module.xml
@@ -24,9 +24,5 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_RequireJs" schema_version="1.0.0.0" active="true">
-        <depends>
-            <module name="Magento_Theme"/>
-        </depends>
-    </module>
+    <module name="Magento_RequireJs" schema_version="1.0.0.0" active="true"/>
 </config>
diff --git a/app/code/Magento/Review/Block/Adminhtml/Grid.php b/app/code/Magento/Review/Block/Adminhtml/Grid.php
index 693eb214466..f5afd8e24aa 100644
--- a/app/code/Magento/Review/Block/Adminhtml/Grid.php
+++ b/app/code/Magento/Review/Block/Adminhtml/Grid.php
@@ -310,7 +310,10 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
             )
         );
 
-        $this->addRssList('rss/catalog/review', __('Pending Reviews RSS'));
+        $block = $this->getLayout()->getBlock('grid.bottom.links');
+        if ($block) {
+            $this->setChild('grid.bottom.links', $block);
+        }
 
         return parent::_prepareColumns();
     }
diff --git a/app/code/Magento/Review/Block/Adminhtml/Rss.php b/app/code/Magento/Review/Block/Adminhtml/Rss.php
new file mode 100644
index 00000000000..1f0b689ca04
--- /dev/null
+++ b/app/code/Magento/Review/Block/Adminhtml/Rss.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Block\Adminhtml;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class Rss
+ * @package Magento\Catalog\Block\Adminhtml\Rss
+ */
+class Rss extends \Magento\Backend\Block\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\Review
+     */
+    protected $rssModel;
+
+    /**
+     * @param \Magento\Backend\Block\Context $context
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Review\Model\Rss $rssModel
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Context $context,
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Review\Model\Rss $rssModel,
+        array $data = array()
+    ) {
+        $this->storeManager = $storeManager;
+        $this->rssModel = $rssModel;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRssData()
+    {
+        $newUrl = $this->getUrl('rss/catalog/review', array('_secure' => true, '_nosecret' => true));
+        $title = __('Pending product review(s)');
+
+        $data = array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+
+        foreach ($this->rssModel->getProductCollection() as $item) {
+            if ($item->getStoreId()) {
+                $this->_urlBuilder->setScope($item->getStoreId());
+            }
+
+            $url = $this->getUrl('catalog/product/view', array('id' => $item->getId()));
+            $reviewUrl = $this->getUrl('review/product/edit/', array(
+                'id' => $item->getReviewId(),
+                '_secure' => true,
+                '_nosecret' => true
+            ));
+
+            $storeName = $this->storeManager->getStore($item->getStoreId())->getName();
+            $description = '<p>' . __('Product: <a href="%1" target="_blank">%2</a> <br/>', $url, $item->getName())
+                . __('Summary of review: %1 <br/>', $item->getTitle()) . __('Review: %1 <br/>', $item->getDetail())
+                . __('Store: %1 <br/>', $storeName)
+                . __('Click <a href="%1">here</a> to view the review.', $reviewUrl)
+                . '</p>';
+
+            $data['entries'][] = array(
+                'title' => __('Product: "%1" reviewed by: %2', $item->getName(), $item->getNickname()),
+                'link' => $item->getProductUrl(),
+                'description' => $description
+            );
+        }
+
+        return $data;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCacheLifetime()
+    {
+        return 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFeeds()
+    {
+        return array();
+    }
+}
diff --git a/app/code/Magento/Review/Block/Adminhtml/Rss/Grid/Link.php b/app/code/Magento/Review/Block/Adminhtml/Rss/Grid/Link.php
new file mode 100644
index 00000000000..244169b16c1
--- /dev/null
+++ b/app/code/Magento/Review/Block/Adminhtml/Rss/Grid/Link.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Block\Adminhtml\Rss\Grid;
+
+/**
+ * Class Link
+ * @package Magento\Review\Block\Adminhtml\Grid\Rss
+ */
+class Link extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'rss/grid/link.phtml';
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function _construct()
+    {
+        $this->setId('grid.rss.link');
+        parent::_construct();
+    }
+
+    /**
+     * @return string
+     */
+    public function getLink()
+    {
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
+    }
+
+    /**
+     * @return string
+     */
+    public function getLabel()
+    {
+        return __('Pending Reviews RSS');
+    }
+
+    /**
+     * Check whether status notification is allowed
+     *
+     * @return bool
+     */
+    public function isRssAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * @return string
+     */
+    protected function getLinkParams()
+    {
+        return array('type' => 'review');
+    }
+}
diff --git a/app/code/Magento/Review/Block/Product/View.php b/app/code/Magento/Review/Block/Product/View.php
index 418c4a0ed41..e734ce8c4b9 100644
--- a/app/code/Magento/Review/Block/Product/View.php
+++ b/app/code/Magento/Review/Block/Product/View.php
@@ -58,6 +58,7 @@ class View extends \Magento\Catalog\Block\Product\View
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
      * @param \Magento\Customer\Model\Session $customerSession
      * @param TaxCalculationServiceInterface $taxCalculationService
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      * @param \Magento\Review\Model\Resource\Review\CollectionFactory $collectionFactory
      * @param array $data
      */
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
index 025f8c620ec..99bc5b153a2 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
@@ -38,8 +38,6 @@ class NewAction extends \Magento\Review\Controller\Adminhtml\Product
         $this->_view->loadLayout();
         $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
 
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
         $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Add'));
         $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Product\Grid'));
 
diff --git a/app/code/Magento/Review/Controller/Customer/Index.php b/app/code/Magento/Review/Controller/Customer/Index.php
index f54fa22e80b..1a41248ce2d 100644
--- a/app/code/Magento/Review/Controller/Customer/Index.php
+++ b/app/code/Magento/Review/Controller/Customer/Index.php
@@ -43,7 +43,7 @@ class Index extends \Magento\Review\Controller\Customer
             $block->setRefererUrl($this->_redirect->getRefererUrl());
         }
 
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Product Reviews'));
+        $this->_view->getPage()->getConfig()->setTitle(__('My Product Reviews'));
 
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Review/Controller/Customer/View.php b/app/code/Magento/Review/Controller/Customer/View.php
index 14d2be50a4f..e7d3a9ab166 100644
--- a/app/code/Magento/Review/Controller/Customer/View.php
+++ b/app/code/Magento/Review/Controller/Customer/View.php
@@ -37,7 +37,7 @@ class View extends \Magento\Review\Controller\Customer
         if ($navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation')) {
             $navigationBlock->setActive('review/customer');
         }
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Review Details'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Review Details'));
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Review/Model/Rss.php b/app/code/Magento/Review/Model/Rss.php
new file mode 100644
index 00000000000..ba4aa200665
--- /dev/null
+++ b/app/code/Magento/Review/Model/Rss.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Model;
+
+/**
+ * Class Rss
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class Rss extends \Magento\Framework\Model\AbstractModel
+{
+    /**
+     * @var \Magento\Review\Model\ReviewFactory
+     */
+    protected $reviewFactory;
+
+    /**
+     * Application Event Dispatcher
+     *
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param ReviewFactory $reviewFactory
+     */
+    public function __construct(
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Review\Model\ReviewFactory $reviewFactory
+    ) {
+        $this->reviewFactory = $reviewFactory;
+        $this->eventManager = $eventManager;
+    }
+
+    /**
+     * @return $this|\Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
+     */
+    public function getProductCollection()
+    {
+        /** @var $reviewModel \Magento\Review\Model\Review */
+        $reviewModel = $this->reviewFactory->create();
+        $collection = $reviewModel->getProductCollection()
+            ->addStatusFilter($reviewModel->getPendingStatus())
+            ->addAttributeToSelect('name', 'inner')
+            ->setDateOrder();
+
+        $this->eventManager->dispatch('rss_catalog_review_collection_select', array('collection' => $collection));
+        return $collection;
+    }
+}
diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json
index 68fbc4e7a88..29c172fbb70 100644
--- a/app/code/Magento/Review/composer.json
+++ b/app/code/Magento/Review/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-newsletter": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-newsletter": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Review/etc/adminhtml/di.xml b/app/code/Magento/Review/etc/adminhtml/di.xml
index c229601f510..0482a31f2ad 100644
--- a/app/code/Magento/Review/etc/adminhtml/di.xml
+++ b/app/code/Magento/Review/etc/adminhtml/di.xml
@@ -44,4 +44,11 @@
             <argument name="session" xsi:type="object">Magento\Backend\Model\Session</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
+        <arguments>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="review" xsi:type="string">Magento\Review\Block\Adminhtml\Rss</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Review/view/adminhtml/layout/review_product_index.xml b/app/code/Magento/Review/view/adminhtml/layout/review_product_index.xml
new file mode 100644
index 00000000000..be6d69b0ef0
--- /dev/null
+++ b/app/code/Magento/Review/view/adminhtml/layout/review_product_index.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <referenceContainer name="adminhtml.grid">
+        <block class="Magento\Framework\View\Element\Text\ListText" name="grid.bottom.links">
+            <block class="Magento\Review\Block\Adminhtml\Rss\Grid\Link" name="grid.rss.link"/>
+        </block>
+    </referenceContainer>
+</page>
diff --git a/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml b/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml
new file mode 100644
index 00000000000..22803a95352
--- /dev/null
+++ b/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml
@@ -0,0 +1,29 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+/** @var $this \Magento\Review\Block\Adminhtml\Grid\Rss\Link */
+?>
+<?php if ($this->isRssAllowed() && $this->getLink()): ?>
+<a href="<?php echo $this->getLink() ?>" class="link-feed"><?php echo $this->getLabel() ?></a>
+<?php endif; ?>
diff --git a/app/code/Magento/Rss/App/Action/Plugin/Authentication.php b/app/code/Magento/Rss/App/Action/Plugin/Authentication.php
index 6adeaff209b..62f8f85ec24 100644
--- a/app/code/Magento/Rss/App/Action/Plugin/Authentication.php
+++ b/app/code/Magento/Rss/App/Action/Plugin/Authentication.php
@@ -29,30 +29,33 @@ use Magento\Framework\App\RequestInterface;
 use Magento\Framework\App\ResponseInterface;
 use Magento\Backend\App\AbstractAction;
 
+/**
+ * Class Authentication
+ * @package Magento\Rss\App\Action\Plugin
+ */
 class Authentication extends \Magento\Backend\App\Action\Plugin\Authentication
 {
     /**
      * @var \Magento\Framework\HTTP\Authentication
      */
-    protected $_httpAuthentication;
+    protected $httpAuthentication;
 
     /**
      * @var \Magento\Framework\Logger
      */
-    protected $_logger;
+    protected $logger;
 
     /**
      * @var \Magento\Framework\AuthorizationInterface
      */
-    protected $_authorization;
+    protected $authorization;
 
     /**
      * @var array
      */
-    protected $_aclResources = array(
+    protected $aclResources = array(
         'authenticate' => 'Magento_Rss::rss',
-        'catalog' => array('notifystock' => 'Magento_Catalog::products', 'review' => 'Magento_Review::reviews_all'),
-        'order' => 'Magento_Sales::sales_order'
+        'feed' => 'Magento_Rss::rss'
     );
 
     /**
@@ -75,9 +78,9 @@ class Authentication extends \Magento\Backend\App\Action\Plugin\Authentication
         \Magento\Framework\Logger $logger,
         \Magento\Framework\AuthorizationInterface $authorization
     ) {
-        $this->_httpAuthentication = $httpAuthentication;
-        $this->_logger = $logger;
-        $this->_authorization = $authorization;
+        $this->httpAuthentication = $httpAuthentication;
+        $this->logger = $logger;
+        $this->authorization = $authorization;
         parent::__construct($auth, $url, $response, $actionFlag, $messageManager);
     }
 
@@ -92,15 +95,12 @@ class Authentication extends \Magento\Backend\App\Action\Plugin\Authentication
      */
     public function aroundDispatch(AbstractAction $subject, \Closure $proceed, RequestInterface $request)
     {
-        $resource = isset(
-            $this->_aclResources[$request->getControllerName()]
-        ) ? isset(
-            $this->_aclResources[$request->getControllerName()][$request->getActionName()]
-        ) ? $this->_aclResources[$request
-            ->getControllerName()][$request
-            ->getActionName()] : $this
-            ->_aclResources[$request
-            ->getControllerName()] : null;
+        $resource = isset($this->aclResources[$request->getControllerName()])
+            ? isset($this->aclResources[$request->getControllerName()][$request->getActionName()])
+                ? $this->aclResources[$request->getControllerName()][$request->getActionName()]
+                : $this->aclResources[$request->getControllerName()]
+            : null;
+
         if (!$resource) {
             return parent::aroundDispatch($subject, $proceed, $request);
         }
@@ -109,17 +109,17 @@ class Authentication extends \Magento\Backend\App\Action\Plugin\Authentication
 
         // Try to login using HTTP-authentication
         if (!$session->isLoggedIn()) {
-            list($login, $password) = $this->_httpAuthentication->getCredentials();
+            list($login, $password) = $this->httpAuthentication->getCredentials();
             try {
                 $this->_auth->login($login, $password);
             } catch (\Magento\Backend\Model\Auth\Exception $e) {
-                $this->_logger->logException($e);
+                $this->logger->logException($e);
             }
         }
 
         // Verify if logged in and authorized
-        if (!$session->isLoggedIn() || !$this->_authorization->isAllowed($resource)) {
-            $this->_httpAuthentication->setAuthenticationFailed('RSS Feeds');
+        if (!$session->isLoggedIn() || !$this->authorization->isAllowed($resource)) {
+            $this->httpAuthentication->setAuthenticationFailed('RSS Feeds');
             return $this->_response;
         }
 
diff --git a/app/code/Magento/Rss/Block/Catalog/AbstractCatalog.php b/app/code/Magento/Rss/Block/Catalog/AbstractCatalog.php
deleted file mode 100644
index 1746023b450..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/AbstractCatalog.php
+++ /dev/null
@@ -1,103 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-class AbstractCatalog extends \Magento\Rss\Block\AbstractBlock
-{
-    /**
-     * Block alias fallback
-     */
-    const DEFAULT_TYPE = 'default';
-
-    /**
-     * Stored price block instances
-     * @var array
-     */
-    protected $_priceBlock = array();
-
-    /**
-     * Whether to show "As low as" as a link
-     * @var bool
-     */
-    protected $_useLinkForAsLowAs = true;
-
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_rss';
-
-    /**
-     * Catalog data
-     *
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $_catalogData = null;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Helper\Data $catalogData,
-        array $data = array()
-    ) {
-        $this->_catalogData = $catalogData;
-        parent::__construct($context, $httpContext, $data);
-        $this->_isScopePrivate = true;
-    }
-
-    /**
-     * Get rendered price html
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param bool $displayMinimalPrice
-     * @return string
-     */
-    public function renderPriceHtml(\Magento\Catalog\Model\Product $product, $displayMinimalPrice = false)
-    {
-        /** @var \Magento\Framework\Pricing\Render $priceRender */
-        $priceRender = $this->getLayout()->getBlock('product.price.render.default');
-
-        $price = '';
-        if ($priceRender) {
-            $price = $priceRender->render(
-                \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
-                $product,
-                [
-                    'display_minimal_price'  => $displayMinimalPrice,
-                    'use_link_for_as_low_as' => $this->_useLinkForAsLowAs,
-                    'zone'                   => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST
-                ]
-            );
-        }
-
-        return $price;
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/Category.php b/app/code/Magento/Rss/Block/Catalog/Category.php
deleted file mode 100644
index 218e7e02421..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/Category.php
+++ /dev/null
@@ -1,238 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Review form block
- */
-class Category extends \Magento\Rss\Block\Catalog\AbstractCatalog
-{
-    /**
-     * @var \Magento\Catalog\Model\Layer
-     */
-    protected $_catalogLayer;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Visibility
-     */
-    protected $_visibility;
-
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Resource\Product\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $_imageHelper;
-
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $customerSession;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param \Magento\Catalog\Model\Layer\Category $catalogLayer
-     * @param \Magento\Catalog\Model\Product\Visibility $visibility
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $collectionFactory
-     * @param \Magento\Catalog\Helper\Image $imageHelper
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Helper\Data $catalogData,
-        \Magento\Catalog\Model\Layer\Category $catalogLayer,
-        \Magento\Catalog\Model\Product\Visibility $visibility,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Catalog\Model\Resource\Product\CollectionFactory $collectionFactory,
-        \Magento\Catalog\Helper\Image $imageHelper,
-        \Magento\Customer\Model\Session $customerSession,
-        array $data = array()
-    ) {
-        $this->_imageHelper = $imageHelper;
-        $this->_catalogLayer = $catalogLayer;
-        $this->_visibility = $visibility;
-        $this->_rssFactory = $rssFactory;
-        $this->_categoryFactory = $categoryFactory;
-        $this->_collectionFactory = $collectionFactory;
-        $this->customerSession = $customerSession;
-        parent::__construct($context, $httpContext, $catalogData, $data);
-    }
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        /*
-        * setting cache to save the rss for 10 minutes
-        */
-        $this->setCacheKey(
-            'rss_catalog_category_'
-            . $this->getRequest()->getParam('cid') . '_'
-            . $this->getRequest()->getParam('store_id') . '_'
-            . $this->customerSession->getId()
-        );
-        $this->setCacheLifetime(600);
-    }
-
-    /**
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $categoryId = $this->getRequest()->getParam('cid');
-        $storeId = $this->_getStoreId();
-        /** @var $rssModel \Magento\Rss\Model\Rss */
-        $rssModel = $this->_rssFactory->create();
-        if ($categoryId) {
-            $category = $this->_categoryFactory->create();
-            $category->load($categoryId);
-            if ($category && $category->getId()) {
-                /** @var $layer \Magento\Catalog\Model\Layer */
-                $layer = $this->_catalogLayer->setStore($storeId);
-                //want to load all products no matter anchor or not
-                $category->setIsAnchor(true);
-                $newUrl = $category->getUrl();
-                $title = $category->getName();
-                $rssModel->_addHeader(
-                    array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8')
-                );
-
-                $_collection = $category->getCollection();
-                $_collection->addAttributeToSelect(
-                    'url_key'
-                )->addAttributeToSelect(
-                    'name'
-                )->addAttributeToSelect(
-                    'is_anchor'
-                )->addAttributeToFilter(
-                    'is_active',
-                    1
-                )->addIdFilter(
-                    $category->getChildren()
-                )->load();
-                /** @var $productCollection \Magento\Catalog\Model\Resource\Product\Collection */
-                $productCollection = $this->_collectionFactory->create();
-
-                $currentCategory = $layer->setCurrentCategory($category);
-                $layer->prepareProductCollection($productCollection);
-                $productCollection->addCountToCategories($_collection);
-
-                $category->getProductCollection()->setStoreId($storeId);
-                /*
-                only load latest 50 products
-                */
-                $_productCollection = $currentCategory->getProductCollection()->addAttributeToSort(
-                    'updated_at',
-                    'desc'
-                )->setVisibility(
-                    $this->_visibility->getVisibleInCatalogIds()
-                )->setCurPage(
-                    1
-                )->setPageSize(
-                    50
-                );
-
-                if ($_productCollection->getSize() > 0) {
-                    $args = array('rssObj' => $rssModel);
-                    foreach ($_productCollection as $_product) {
-                        $args['product'] = $_product;
-                        $this->addNewItemXmlCallback($args);
-                    }
-                }
-            }
-        }
-        return $rssModel->createRssXml();
-    }
-
-    /**
-     * Preparing data and adding to rss object
-     *
-     * @param array $args
-     * @return void
-     */
-    public function addNewItemXmlCallback($args)
-    {
-        /** @var $product \Magento\Catalog\Model\Product */
-        $product = $args['product'];
-        $product->setAllowedInRss(true);
-        $product->setAllowedPriceInRss(true);
-
-        $this->_eventManager->dispatch('rss_catalog_category_xml_callback', $args);
-
-        if (!$product->getAllowedInRss()) {
-            return;
-        }
-
-        $description = '<table><tr>' .
-            '<td><a href="' .
-            $product->getProductUrl() .
-            '"><img src="' .
-            $this->_imageHelper->init(
-                $product,
-                'thumbnail'
-            )->resize(
-                75,
-                75
-            ) .
-            '" border="0" align="left" height="75" width="75"></a></td>' .
-            '<td  style="text-decoration:none;">' .
-            $product->getDescription();
-
-        if ($product->getAllowedPriceInRss()) {
-            $description .= $this->renderPriceHtml($product, true);
-        }
-
-        $description .= '</td></tr></table>';
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $args['rssObj'];
-        $data = array(
-            'title' => $product->getName(),
-            'link' => $product->getProductUrl(),
-            'description' => $description
-        );
-
-        $rssObj->_addEntry($data);
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/NewCatalog.php b/app/code/Magento/Rss/Block/Catalog/NewCatalog.php
deleted file mode 100644
index 1ef4d9d0f91..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/NewCatalog.php
+++ /dev/null
@@ -1,236 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Review form block
- */
-class NewCatalog extends \Magento\Rss\Block\Catalog\AbstractCatalog
-{
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Visibility
-     */
-    protected $_visibility;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $_resourceIterator;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $_imageHelper;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Catalog\Model\Product\Visibility $visibility
-     * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param \Magento\Catalog\Helper\Image $imageHelper
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Helper\Data $catalogData,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Catalog\Model\Product\Visibility $visibility,
-        \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        \Magento\Catalog\Helper\Image $imageHelper,
-        array $data = array()
-    ) {
-        $this->_imageHelper = $imageHelper;
-        $this->_rssFactory = $rssFactory;
-        $this->_productFactory = $productFactory;
-        $this->_visibility = $visibility;
-        $this->_resourceIterator = $resourceIterator;
-        parent::__construct($context, $httpContext, $catalogData, $data);
-    }
-
-    /**
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $storeId = $this->_getStoreId();
-        $storeModel = $this->_storeManager->getStore($storeId);
-        $newUrl = $this->_urlBuilder->getUrl('rss/catalog/new/store_id/' . $storeId);
-        $title = __('New Products from %1', $storeModel->getFrontendName());
-        $lang = $this->_scopeConfig->getValue(
-            'general/locale/code',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $storeModel
-        );
-
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $rssObj->_addHeader(
-            array(
-                'title' => $title,
-                'description' => $title,
-                'link' => $newUrl,
-                'charset' => 'UTF-8',
-                'language' => $lang
-            )
-        );
-
-        /** @var $product \Magento\Catalog\Model\Product */
-        $product = $this->_productFactory->create();
-        $todayStartOfDayDate = $this->_localeDate->date()->setTime(
-            '00:00:00'
-        )->toString(
-            \Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT
-        );
-
-        $todayEndOfDayDate = $this->_localeDate->date()->setTime(
-            '23:59:59'
-        )->toString(
-            \Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT
-        );
-
-        /** @var $products \Magento\Catalog\Model\Resource\Product\Collection */
-        $products = $product->getCollection();
-        $products->setStoreId($storeId);
-        $products->addStoreFilter()->addAttributeToFilter(
-            'news_from_date',
-            array(
-                'or' => array(
-                    0 => array('date' => true, 'to' => $todayEndOfDayDate),
-                    1 => array('is' => new \Zend_Db_Expr('null'))
-                )
-            ),
-            'left'
-        )->addAttributeToFilter(
-            'news_to_date',
-            array(
-                'or' => array(
-                    0 => array('date' => true, 'from' => $todayStartOfDayDate),
-                    1 => array('is' => new \Zend_Db_Expr('null'))
-                )
-            ),
-            'left'
-        )->addAttributeToFilter(
-            array(
-                array('attribute' => 'news_from_date', 'is' => new \Zend_Db_Expr('not null')),
-                array('attribute' => 'news_to_date', 'is' => new \Zend_Db_Expr('not null'))
-            )
-        )->addAttributeToSort(
-            'news_from_date',
-            'desc'
-        )->addAttributeToSelect(
-            array('name', 'short_description', 'description'),
-            'inner'
-        )->addAttributeToSelect(
-            array(
-                'price',
-                'special_price',
-                'special_from_date',
-                'special_to_date',
-                'msrp_enabled',
-                'msrp_display_actual_price_type',
-                'msrp',
-                'thumbnail'
-            ),
-            'left'
-        )->applyFrontendPriceLimitations();
-        $products->setVisibility($this->_visibility->getVisibleInCatalogIds());
-
-        /*
-        using resource iterator to load the data one by one
-        instead of loading all at the same time. loading all data at the same time can cause the big memory allocation.
-        */
-        $this->_resourceIterator->walk(
-            $products->getSelect(),
-            array(array($this, 'addNewItemXmlCallback')),
-            array('rssObj' => $rssObj, 'product' => $product)
-        );
-
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * Preparing data and adding to rss object
-     *
-     * @param array $args
-     * @return void
-     */
-    public function addNewItemXmlCallback($args)
-    {
-        /** @var $product \Magento\Catalog\Model\Product */
-        $product = $args['product'];
-        $product->setAllowedInRss(true);
-        $product->setAllowedPriceInRss(true);
-        $this->_eventManager->dispatch('rss_catalog_new_xml_callback', $args);
-
-        if (!$product->getAllowedInRss()) {
-            //Skip adding product to RSS
-            return;
-        }
-
-        $allowedPriceInRss = $product->getAllowedPriceInRss();
-        //$product->unsetData()->load($args['row']['entity_id']);
-        $product->setData($args['row']);
-        $description = '<table><tr>' .
-            '<td><a href="' .
-            $product->getProductUrl() .
-            '"><img src="' .
-            $this->_imageHelper->init(
-                $product,
-                'thumbnail'
-            )->resize(
-                75,
-                75
-            ) .
-            '" border="0" align="left" height="75" width="75"></a></td>' .
-            '<td  style="text-decoration:none;">' .
-            $product->getDescription();
-
-        if ($allowedPriceInRss) {
-            $description .= $this->renderPriceHtml($product, true);
-        }
-
-        $description .= '</td>' . '</tr></table>';
-
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $args['rssObj'];
-        $rssObj->_addEntry(
-            array('title' => $product->getName(), 'link' => $product->getProductUrl(), 'description' => $description)
-        );
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/NotifyStock.php b/app/code/Magento/Rss/Block/Catalog/NotifyStock.php
deleted file mode 100644
index e715156ccf4..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/NotifyStock.php
+++ /dev/null
@@ -1,159 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Catalog low stock RSS block
- */
-class NotifyStock extends \Magento\Backend\Block\AbstractBlock
-{
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\CatalogInventory\Model\Resource\StockFactory
-     */
-    protected $_stockFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Attribute\Source\Status
-     */
-    protected $_productStatus;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $_resourceIterator;
-
-    /**
-     * @param \Magento\Backend\Block\Context $context
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\CatalogInventory\Model\Resource\StockFactory $stockFactory
-     * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus
-     * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Context $context,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\CatalogInventory\Model\Resource\StockFactory $stockFactory,
-        \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
-        \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        array $data = array()
-    ) {
-        $this->_rssFactory = $rssFactory;
-        $this->_productFactory = $productFactory;
-        $this->_stockFactory = $stockFactory;
-        $this->_productStatus = $productStatus;
-        $this->_resourceIterator = $resourceIterator;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Render RSS
-     *
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $newUrl = $this->getUrl('rss/catalog/notifystock', array('_secure' => true, '_nosecret' => true));
-        $title = __('Low Stock Products');
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $rssObj->_addHeader(
-            array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8')
-        );
-
-        $globalNotifyStockQty = (double)$this->_scopeConfig->getValue(
-            \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_NOTIFY_STOCK_QTY,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $this->_productFactory->create();
-        /* @var $collection \Magento\Catalog\Model\Resource\Product\Collection */
-        $collection = $product->getCollection();
-        /** @var $resourceStock \Magento\CatalogInventory\Model\Resource\Stock */
-        $resourceStock = $this->_stockFactory->create();
-        $resourceStock->addLowStockFilter(
-            $collection,
-            array('qty', 'notify_stock_qty', 'low_stock_date', 'use_config' => 'use_config_notify_stock_qty')
-        );
-        $collection->addAttributeToSelect(
-            'name',
-            true
-        )->addAttributeToFilter(
-            'status',
-            array('in' => $this->_productStatus->getVisibleStatusIds())
-        )->setOrder(
-            'low_stock_date'
-        );
-        $this->_eventManager->dispatch(
-            'rss_catalog_notify_stock_collection_select',
-            array('collection' => $collection)
-        );
-
-        /*
-        using resource iterator to load the data one by one
-        instead of loading all at the same time. loading all data at the same time can cause the big memory allocation.
-        */
-        $this->_resourceIterator->walk(
-            $collection->getSelect(),
-            array(array($this, 'addNotifyItemXmlCallback')),
-            array('rssObj' => $rssObj, 'product' => $product, 'globalQty' => $globalNotifyStockQty)
-        );
-
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * Adds single product to feed
-     *
-     * @param array $args
-     * @return void
-     */
-    public function addNotifyItemXmlCallback($args)
-    {
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $args['product'];
-        $product->setData($args['row']);
-        $url = $this->getUrl(
-            'catalog/product/edit',
-            array('id' => $product->getId(), '_secure' => true, '_nosecret' => true)
-        );
-        $qty = 1 * $product->getQty();
-        $description = __('%1 has reached a quantity of %2.', $product->getName(), $qty);
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $args['rssObj'];
-        $rssObj->_addEntry(array('title' => $product->getName(), 'link' => $url, 'description' => $description));
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/Review.php b/app/code/Magento/Rss/Block/Catalog/Review.php
deleted file mode 100644
index 0204ebbd3e5..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/Review.php
+++ /dev/null
@@ -1,139 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Review form block
- */
-class Review extends \Magento\Backend\Block\AbstractBlock
-{
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $_resourceIterator;
-
-    /**
-     * @var \Magento\Review\Model\ReviewFactory
-     */
-    protected $_reviewFactory;
-
-    /**
-     * @var \Magento\Framework\StoreManagerInterface
-     */
-    protected $_storeManager;
-
-    /**
-     * @param \Magento\Backend\Block\Context $context
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param \Magento\Review\Model\ReviewFactory $reviewFactory
-     * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Context $context,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        \Magento\Review\Model\ReviewFactory $reviewFactory,
-        \Magento\Framework\StoreManagerInterface $storeManager,
-        array $data = array()
-    ) {
-        $this->_rssFactory = $rssFactory;
-        $this->_resourceIterator = $resourceIterator;
-        $this->_reviewFactory = $reviewFactory;
-        $this->_storeManager = $storeManager;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Render XML response
-     *
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $newUrl = $this->getUrl('rss/catalog/review', array('_secure' => true, '_nosecret' => true));
-        $title = __('Pending product review(s)');
-
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $rssObj->_addHeader(
-            array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8')
-        );
-
-        /** @var $reviewModel \Magento\Review\Model\Review */
-        $reviewModel = $this->_reviewFactory->create();
-        $collection = $reviewModel->getProductCollection()
-            ->addStatusFilter($reviewModel->getPendingStatus())
-            ->addAttributeToSelect('name', 'inner')
-            ->setDateOrder();
-
-        $this->_eventManager->dispatch('rss_catalog_review_collection_select', array('collection' => $collection));
-
-        $this->_resourceIterator->walk(
-            $collection->getSelect(),
-            array(array($this, 'addReviewItemXmlCallback')),
-            array('rssObj' => $rssObj, 'reviewModel' => $reviewModel)
-        );
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * Format single RSS element
-     *
-     * @param array $args
-     * @return void
-     */
-    public function addReviewItemXmlCallback($args)
-    {
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $args['rssObj'];
-        $row = $args['row'];
-        /** @var \Magento\Review\Model\Review $reviewModel */
-        $reviewModel = $args['reviewModel'];
-        $productUrl = $reviewModel->getProductUrl($row['entity_id'], $row['store_id']);
-        $reviewUrl = $this->getUrl(
-            'review/product/edit/',
-            array('id' => $row['review_id'], '_secure' => true, '_nosecret' => true)
-        );
-        $storeName = $this->_storeManager->getStore($row['store_id'])->getName();
-        $description = '<p>' . __('Product: <a href="%1" target="_blank">%2</a> <br/>', $productUrl, $row['name'])
-            . __('Summary of review: %1 <br/>', $row['title']) . __('Review: %1 <br/>', $row['detail'])
-            . __('Store: %1 <br/>', $storeName)
-            . __('Click <a href="%1">here</a> to view the review.', $reviewUrl)
-            . '</p>';
-        $rssObj->_addEntry(
-            array(
-                'title' => __('Product: "%1" reviewed by: %2', $row['name'], $row['nickname']),
-                'link' => 'test',
-                'description' => $description
-            )
-        );
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/Salesrule.php b/app/code/Magento/Rss/Block/Catalog/Salesrule.php
deleted file mode 100644
index 908c9f41327..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/Salesrule.php
+++ /dev/null
@@ -1,141 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Review form block
- */
-class Salesrule extends \Magento\Rss\Block\AbstractBlock
-{
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\SalesRule\Model\Resource\Rule\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory,
-        array $data = array()
-    ) {
-        $this->_rssFactory = $rssFactory;
-        $this->_collectionFactory = $collectionFactory;
-        parent::__construct($context, $httpContext, $data);
-    }
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        /*
-         * setting cache to save the rss for 10 minutes
-         */
-        $this->setCacheKey('rss_catalog_salesrule_' . $this->getStoreId() . '_' . $this->_getCustomerGroupId());
-        $this->setCacheLifetime(600);
-    }
-
-    /**
-     * Generate RSS XML with sales rules data
-     *
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $storeId = $this->_getStoreId();
-        $storeModel = $this->_storeManager->getStore($storeId);
-        $websiteId = $storeModel->getWebsiteId();
-        $customerGroup = $this->_getCustomerGroupId();
-        $now = date('Y-m-d');
-        $url = $this->_urlBuilder->getUrl('');
-        $newUrl = $this->_urlBuilder->getUrl('rss/catalog/salesrule');
-        $title = __('%1 - Discounts and Coupons', $storeModel->getName());
-        $lang = $this->_scopeConfig->getValue(
-            'general/locale/code',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $storeModel
-        );
-
-        /** @var $rssObject \Magento\Rss\Model\Rss */
-        $rssObject = $this->_rssFactory->create();
-        $rssObject->_addHeader(
-            array(
-                'title' => $title,
-                'description' => $title,
-                'link' => $newUrl,
-                'charset' => 'UTF-8',
-                'language' => $lang
-            )
-        );
-
-        /** @var $collection \Magento\SalesRule\Model\Resource\Rule\Collection */
-        $collection = $this->_collectionFactory->create();
-        $collection->addWebsiteGroupDateFilter(
-            $websiteId,
-            $customerGroup,
-            $now
-        )->addFieldToFilter(
-            'is_rss',
-            1
-        )->setOrder(
-            'from_date',
-            'desc'
-        );
-        $collection->load();
-
-        /** @var $ruleModel \Magento\SalesRule\Model\Rule */
-        foreach ($collection as $ruleModel) {
-            $description = '<table><tr>' . '<td style="text-decoration:none;">' . $ruleModel->getDescription()
-                . '<br/>Discount Start Date: ' . $this->formatDate(
-                    $ruleModel->getFromDate(),
-                    'medium'
-                );
-            if ($ruleModel->getToDate()) {
-                $description .= '<br/>Discount End Date: ' . $this->formatDate($ruleModel->getToDate(), 'medium');
-            }
-            if ($ruleModel->getCouponCode()) {
-                $description .= '<br/> Coupon Code: ' . $ruleModel->getCouponCode();
-            }
-            $description .= '</td></tr></table>';
-            $rssObject->_addEntry(
-                array('title' => $ruleModel->getName(), 'description' => $description, 'link' => $url)
-            );
-        }
-
-        return $rssObject->createRssXml();
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Catalog/Special.php b/app/code/Magento/Rss/Block/Catalog/Special.php
deleted file mode 100644
index 2d723672447..00000000000
--- a/app/code/Magento/Rss/Block/Catalog/Special.php
+++ /dev/null
@@ -1,277 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Review form block
- */
-class Special extends \Magento\Rss\Block\Catalog\AbstractCatalog
-{
-    /**
-     * \Magento\Framework\Stdlib\DateTime\DateInterface object for date comparsions
-     *
-     * @var \Magento\Framework\Stdlib\DateTime\Date
-     */
-    protected static $_currentDate = null;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $_productFactory;
-
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $_resourceIterator;
-
-    /**
-     * @var \Magento\Framework\Pricing\PriceCurrencyInterface
-     */
-    protected $_priceCurrency;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $_imageHelper;
-
-    /**
-     * @var \Magento\Catalog\Helper\Output
-     */
-    protected $_outputHelper;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Helper\Data $catalogData
-     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param \Magento\Catalog\Helper\Image $imageHelper
-     * @param \Magento\Catalog\Helper\Output $outputHelper
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Helper\Data $catalogData,
-        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        \Magento\Catalog\Helper\Image $imageHelper,
-        \Magento\Catalog\Helper\Output $outputHelper,
-        array $data = array()
-    ) {
-        $this->_outputHelper = $outputHelper;
-        $this->_imageHelper = $imageHelper;
-        $this->_priceCurrency = $priceCurrency;
-        $this->_productFactory = $productFactory;
-        $this->_rssFactory = $rssFactory;
-        $this->_resourceIterator = $resourceIterator;
-        parent::__construct($context, $httpContext, $catalogData, $data);
-    }
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        /*
-         * setting cache to save the rss for 10 minutes
-         */
-        $this->setCacheKey('rss_catalog_special_' . $this->_getStoreId() . '_' . $this->_getCustomerGroupId());
-        $this->setCacheLifetime(600);
-    }
-
-    /**
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        //store id is store view id
-        $storeId = $this->_getStoreId();
-        $websiteId = $this->_storeManager->getStore($storeId)->getWebsiteId();
-
-        //customer group id
-        $customerGroupId = $this->_getCustomerGroupId();
-
-        /** @var $product \Magento\Catalog\Model\Product */
-        $product = $this->_productFactory->create();
-        $product->setStoreId($storeId);
-        $specials = $product->getResourceCollection()->addPriceDataFieldFilter(
-            '%s < %s',
-            array('final_price', 'price')
-        )->addPriceData(
-            $customerGroupId,
-            $websiteId
-        )->addAttributeToSelect(
-            array(
-                'name',
-                'short_description',
-                'description',
-                'price',
-                'thumbnail',
-                'special_price',
-                'special_to_date',
-                'msrp_enabled',
-                'msrp_display_actual_price_type',
-                'msrp'
-            ),
-            'left'
-        )->addAttributeToSort(
-            'name',
-            'asc'
-        );
-
-        $newUrl = $this->_urlBuilder->getUrl('rss/catalog/special/store_id/' . $storeId);
-        $title = __('%1 - Special Products', $this->_storeManager->getStore()->getFrontendName());
-        $lang = $this->_scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $rssObj->_addHeader(
-            array(
-                'title' => $title,
-                'description' => $title,
-                'link' => $newUrl,
-                'charset' => 'UTF-8',
-                'language' => $lang
-            )
-        );
-
-        $results = array();
-        /*
-        using resource iterator to load the data one by one
-        instead of loading all at the same time. loading all data at the same time can cause the big memory allocation.
-        */
-        $this->_resourceIterator->walk(
-            $specials->getSelect(),
-            array(array($this, 'addSpecialXmlCallback')),
-            array('rssObj' => $rssObj, 'results' => &$results)
-        );
-
-        if (sizeof($results) > 0) {
-            foreach ($results as $result) {
-                // render a row for RSS feed
-                $product->setData($result);
-                $html = sprintf(
-                    '<table><tr>' .
-                    '<td><a href="%s"><img src="%s" alt="" border="0" align="left" height="75" width="75" /></a></td>' .
-                    '<td style="text-decoration:none;">%s',
-                    $product->getProductUrl(),
-                    $this->_imageHelper->init($product, 'thumbnail')->resize(75, 75),
-                    $this->_outputHelper->productAttribute($product, $product->getDescription(), 'description')
-                );
-
-                // add price data if needed
-                if ($product->getAllowedPriceInRss()) {
-                    if ($this->_catalogData->canApplyMsrp($product)) {
-                        $html .= '<br/><a href="' . $product->getProductUrl() . '">' . __('Click for price') . '</a>';
-                    } else {
-                        $special = '';
-                        if ($result['use_special']) {
-                            $special = '<br />' . __(
-                                'Special Expires On: %1',
-                                $this->formatDate(
-                                    $result['special_to_date'],
-                                    \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM
-                                )
-                            );
-                        }
-                        $html .= sprintf(
-                            '<p>%s %s%s</p>',
-                            __('Price: %1', $this->_priceCurrency->convertAndFormat($result['price'])),
-                            __('Special Price: %1', $this->_priceCurrency->convertAndFormat($result['final_price'])),
-                            $special
-                        );
-                    }
-                }
-
-                $html .= '</td></tr></table>';
-
-                $rssObj->_addEntry(
-                    array('title' => $product->getName(), 'link' => $product->getProductUrl(), 'description' => $html)
-                );
-            }
-        }
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * Preparing data and adding to rss object
-     *
-     * @param array $args
-     * @return void
-     */
-    public function addSpecialXmlCallback($args)
-    {
-        if (!isset(self::$_currentDate)) {
-            self::$_currentDate = new \Magento\Framework\Stdlib\DateTime\Date();
-        }
-
-        // dispatch event to determine whether the product will eventually get to the result
-        $product = new \Magento\Framework\Object(array('allowed_in_rss' => true, 'allowed_price_in_rss' => true));
-        $args['product'] = $product;
-        $this->_eventManager->dispatch('rss_catalog_special_xml_callback', $args);
-        if (!$product->getAllowedInRss()) {
-            return;
-        }
-
-        // add row to result and determine whether special price is active (less or equal to the final price)
-        $row = $args['row'];
-        $row['use_special'] = false;
-        $row['allowed_price_in_rss'] = $product->getAllowedPriceInRss();
-        if (isset(
-            $row['special_to_date']
-        ) && $row['final_price'] <= $row['special_price'] && $row['allowed_price_in_rss']
-        ) {
-            $compareDate = self::$_currentDate->compareDate(
-                $row['special_to_date'],
-                \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT
-            );
-            if (-1 === $compareDate || 0 === $compareDate) {
-                $row['use_special'] = true;
-            }
-        }
-
-        $args['results'][] = $row;
-    }
-
-    /**
-     * Function for comparing two items in collection
-     *
-     * @param array $a
-     * @param array $b
-     * @return bool
-     */
-    public function sortByStartDate($a, $b)
-    {
-        return $a['start_date'] > $b['start_date'] ? -1 : ($a['start_date'] < $b['start_date'] ? 1 : 0);
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Feeds.php b/app/code/Magento/Rss/Block/Feeds.php
new file mode 100644
index 00000000000..15933a453e6
--- /dev/null
+++ b/app/code/Magento/Rss/Block/Feeds.php
@@ -0,0 +1,103 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Block;
+
+/**
+ * Class Feeds
+ * @package Magento\Rss\Block
+ */
+class Feeds extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'feeds.phtml';
+
+    /**
+     * @var \Magento\Framework\App\Rss\RssManagerInterface
+     */
+    protected $rssManager;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Rss\RssManagerInterface $rssManager
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Rss\RssManagerInterface $rssManager,
+        array $data = array()
+    ) {
+        $this->rssManager = $rssManager;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Add Link elements to head
+     *
+     * @return $this
+     */
+    protected function _prepareLayout()
+    {
+        $head = $this->getLayout()->getBlock('head');
+        $feeds = $this->getFeeds();
+        if ($head && !empty($feeds)) {
+            foreach ($feeds as $feed) {
+                if (!isset($feed['group'])) {
+                    $head->addRss($feed['label'], $feed['link']);
+                } else {
+                    foreach ($feed['feeds'] as $item) {
+                        $head->addRss($item['label'], $item['link']);
+                    }
+                }
+            }
+        }
+        return parent::_prepareLayout();
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        $providers = $this->rssManager->getProviders();
+        $feeds = array();
+        $groups = array();
+        foreach ($providers as $provider) {
+            $item = $provider->getFeeds();
+            if (empty($item)) {
+                continue;
+            }
+
+            if (isset($item['group'])) {
+                $groups[] = $item;
+            } else {
+                $feeds[] = $item;
+            }
+        }
+        $feeds = array_merge($feeds, $groups);
+
+        return $feeds;
+    }
+}
diff --git a/app/code/Magento/Rss/Block/ListBlock.php b/app/code/Magento/Rss/Block/ListBlock.php
deleted file mode 100644
index d488a9ee78b..00000000000
--- a/app/code/Magento/Rss/Block/ListBlock.php
+++ /dev/null
@@ -1,252 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block;
-
-/**
- * Review form block
- */
-class ListBlock extends \Magento\Framework\View\Element\Template
-{
-    const XML_PATH_RSS_METHODS = 'rss';
-
-    /**
-     * @var array
-     */
-    protected $_rssFeeds = array();
-
-    /**
-     * @var \Magento\Framework\App\Http\Context
-     */
-    protected $httpContext;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        array $data = array()
-    ) {
-        $this->httpContext = $httpContext;
-        $this->_categoryFactory = $categoryFactory;
-        parent::__construct($context, $data);
-        $this->_isScopePrivate = true;
-    }
-
-    /**
-     * Add Link elements to head
-     *
-     * @return $this
-     */
-    protected function _prepareLayout()
-    {
-        $head = $this->getLayout()->getBlock('head');
-        $feeds = $this->getRssMiscFeeds();
-        if ($head && !empty($feeds)) {
-            foreach ($feeds as $feed) {
-                $head->addRss($feed['label'], $feed['url']);
-            }
-        }
-        return parent::_prepareLayout();
-    }
-
-    /**
-     * Retrieve rss feeds
-     *
-     * @return bool|array
-     */
-    public function getRssFeeds()
-    {
-        return empty($this->_rssFeeds) ? false : $this->_rssFeeds;
-    }
-
-    /**
-     * Add new rss feed
-     *
-     * @param string $url
-     * @param string $label
-     * @param array $param
-     * @param bool $customerGroup
-     * @return $this
-     */
-    public function addRssFeed($url, $label, $param = array(), $customerGroup = false)
-    {
-        $param = array_merge($param, array('store_id' => $this->getCurrentStoreId()));
-        if ($customerGroup) {
-            $param = array_merge($param, array('cid' => $this->getCurrentCustomerGroupId()));
-        }
-        $this->_rssFeeds[] = new \Magento\Framework\Object(
-            array('url' => $this->_urlBuilder->getUrl($url, $param), 'label' => $label)
-        );
-        return $this;
-    }
-
-    /**
-     * Rest rss feed
-     *
-     * @return void
-     */
-    public function resetRssFeed()
-    {
-        $this->_rssFeeds = array();
-    }
-
-    /**
-     * Get current store id
-     *
-     * @return int
-     */
-    public function getCurrentStoreId()
-    {
-        return $this->_storeManager->getStore()->getId();
-    }
-
-    /**
-     * Get current customer group id
-     *
-     * @return int
-     */
-    public function getCurrentCustomerGroupId()
-    {
-        return $this->httpContext->getValue(\Magento\Customer\Helper\Data::CONTEXT_GROUP);
-    }
-
-    /**
-     * Retrieve rss catalog feeds
-     *
-     * array structure:
-     *
-     * @return array
-     */
-    public function getRssCatalogFeeds()
-    {
-        $this->resetRssFeed();
-        $this->categoriesRssFeed();
-        return $this->getRssFeeds();
-    }
-
-    /**
-     * Get rss misc feeds
-     *
-     * @return array|bool
-     */
-    public function getRssMiscFeeds()
-    {
-        $this->resetRssFeed();
-        $this->newProductRssFeed();
-        $this->specialProductRssFeed();
-        $this->salesRuleProductRssFeed();
-        return $this->getRssFeeds();
-    }
-
-    /**
-     * New product rss feed
-     *
-     * @return void
-     */
-    public function newProductRssFeed()
-    {
-        $path = self::XML_PATH_RSS_METHODS . '/catalog/new';
-        if ((bool)$this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $this->addRssFeed($path, __('New Products'));
-        }
-    }
-
-    /**
-     * Special product rss feed
-     *
-     * @return void
-     */
-    public function specialProductRssFeed()
-    {
-        $path = self::XML_PATH_RSS_METHODS . '/catalog/special';
-        if ((bool)$this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $this->addRssFeed($path, __('Special Products'), array(), true);
-        }
-    }
-
-    /**
-     * Sales rule product rss feed
-     *
-     * @return void
-     */
-    public function salesRuleProductRssFeed()
-    {
-        $path = self::XML_PATH_RSS_METHODS . '/catalog/salesrule';
-        if ((bool)$this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $this->addRssFeed($path, __('Coupons/Discounts'), array(), true);
-        }
-    }
-
-    /**
-     * Categories rss feed
-     *
-     * @return void
-     */
-    public function categoriesRssFeed()
-    {
-        $path = self::XML_PATH_RSS_METHODS . '/catalog/category';
-        if ((bool)$this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            /** @var $category \Magento\Catalog\Model\Category */
-            $category = $this->_categoryFactory->create();
-            $treeModel = $category->getTreeModel()->loadNode($this->_storeManager->getStore()->getRootCategoryId());
-            $nodes = $treeModel->loadChildren()->getChildren();
-
-            $nodeIds = array();
-            foreach ($nodes as $node) {
-                $nodeIds[] = $node->getId();
-            }
-
-            /* @var $collection \Magento\Catalog\Model\Resource\Category\Collection */
-            $collection = $category->getCollection();
-            $collection->addIdFilter(
-                $nodeIds
-            )->addAttributeToSelect(
-                'url_key'
-            )->addAttributeToSelect(
-                'name'
-            )->addAttributeToSelect(
-                'is_anchor'
-            )->addAttributeToFilter(
-                'is_active',
-                1
-            )->addAttributeToSort(
-                'name'
-            )->load();
-
-            foreach ($collection as $category) {
-                $this->addRssFeed('rss/catalog/category', $category->getName(), array('cid' => $category->getId()));
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Order/NewOrder.php b/app/code/Magento/Rss/Block/Order/NewOrder.php
deleted file mode 100644
index 9d5ea8bd4b5..00000000000
--- a/app/code/Magento/Rss/Block/Order/NewOrder.php
+++ /dev/null
@@ -1,138 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Order;
-
-/**
- * Review form block
- */
-class NewOrder extends \Magento\Backend\Block\AbstractBlock
-{
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Sales\Model\OrderFactory
-     */
-    protected $_orderFactory;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $_resourceIterator;
-
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime
-     */
-    protected $_dateTime;
-
-    /**
-     * @param \Magento\Backend\Block\Context $context
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Sales\Model\OrderFactory $orderFactory
-     * @param \Magento\Framework\Model\Resource\Iterator $resourceIterator
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Context $context,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Sales\Model\OrderFactory $orderFactory,
-        \Magento\Framework\Model\Resource\Iterator $resourceIterator,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
-        array $data = array()
-    ) {
-        $this->_rssFactory = $rssFactory;
-        $this->_orderFactory = $orderFactory;
-        $this->_resourceIterator = $resourceIterator;
-        $this->_dateTime = $dateTime;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        /** @var $order \Magento\Sales\Model\Order */
-        $order = $this->_orderFactory->create();
-        $passDate = $this->_dateTime->formatDate(mktime(0, 0, 0, date('m'), date('d') - 7));
-        $newUrl = $this->getUrl('rss/order/new', array('_secure' => true, '_nosecret' => true));
-        $title = __('New Orders');
-
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $rssObj->_addHeader(
-            array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8')
-        );
-
-        /** @var $collection \Magento\Sales\Model\Resource\Order\Collection */
-        $collection = $order->getCollection();
-        $collection->addAttributeToFilter(
-            'created_at',
-            array('date' => true, 'from' => $passDate)
-        )->addAttributeToSort(
-            'created_at',
-            'desc'
-        );
-
-        $detailBlock = $this->_layout->getBlockSingleton('Magento\Rss\Block\Order\Details');
-        $this->_eventManager->dispatch('rss_order_new_collection_select', array('collection' => $collection));
-        $this->_resourceIterator->walk(
-            $collection->getSelect(),
-            array(array($this, 'addNewOrderXmlCallback')),
-            array('rssObj' => $rssObj, 'order' => $order, 'detailBlock' => $detailBlock)
-        );
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * @param array $args
-     * @return void
-     */
-    public function addNewOrderXmlCallback($args)
-    {
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $args['rssObj'];
-        /** @var $order \Magento\Sales\Model\Order */
-        $order = $args['order'];
-        /** @var $detailBlock \Magento\Rss\Block\Order\Details */
-        $detailBlock = $args['detailBlock'];
-        $order->reset()->load($args['row']['entity_id']);
-        if ($order && $order->getId()) {
-            $title = __(
-                'Order #%1 created at %2',
-                $order->getIncrementId(),
-                $this->formatDate($order->getCreatedAt())
-            );
-            $url = $this->getUrl(
-                'sales/order/view',
-                array('_secure' => true, 'order_id' => $order->getId(), '_nosecret' => true)
-            );
-            $detailBlock->setOrder($order);
-            $rssObj->_addEntry(array('title' => $title, 'link' => $url, 'description' => $detailBlock->toHtml()));
-        }
-    }
-}
diff --git a/app/code/Magento/Rss/Block/Order/Status.php b/app/code/Magento/Rss/Block/Order/Status.php
deleted file mode 100644
index d6db2c12030..00000000000
--- a/app/code/Magento/Rss/Block/Order/Status.php
+++ /dev/null
@@ -1,131 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Block\Order;
-
-/**
- * Review form block
- */
-class Status extends \Magento\Framework\View\Element\Template
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry;
-
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Rss\Model\Resource\OrderFactory
-     */
-    protected $_orderFactory;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Rss\Model\Resource\OrderFactory $orderFactory
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Rss\Model\Resource\OrderFactory $orderFactory,
-        array $data = array()
-    ) {
-        $this->_coreRegistry = $registry;
-        $this->_rssFactory = $rssFactory;
-        $this->_orderFactory = $orderFactory;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        /*
-         * setting cache to save the rss for 10 minutes
-         */
-        $this->setCacheKey('rss_order_status_' . $this->getRequest()->getParam('data'));
-        $this->setCacheLifetime(600);
-    }
-
-    /**
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        /** @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        $order = $this->_coreRegistry->registry('current_order');
-        if (!$order) {
-            return '';
-        }
-        $title = __('Order # %1 Notification(s)', $order->getIncrementId());
-        $newUrl = $this->_urlBuilder->getUrl('sales/order/view', array('order_id' => $order->getId()));
-        $rssObj->_addHeader(
-            array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8')
-        );
-        /** @var $resourceModel \Magento\Rss\Model\Resource\Order */
-        $resourceModel = $this->_orderFactory->create();
-        $results = $resourceModel->getAllCommentCollection($order->getId());
-        if ($results) {
-            foreach ($results as $result) {
-                $urlAppend = 'view';
-                $type = $result['entity_type_code'];
-                if ($type && $type != 'order') {
-                    $urlAppend = $type;
-                }
-                $type = __(ucwords($type));
-                $title = __('Details for %1 #%2', $type, $result['increment_id']);
-                $description = '<p>' . __(
-                    'Notified Date: %1<br/>',
-                    $this->formatDate($result['created_at'])
-                ) . __(
-                    'Comment: %1<br/>',
-                    $result['comment']
-                ) . '</p>';
-                $url = $this->_urlBuilder->getUrl('sales/order/' . $urlAppend, array('order_id' => $order->getId()));
-                $rssObj->_addEntry(array('title' => $title, 'link' => $url, 'description' => $description));
-            }
-        }
-        $title = __('Order #%1 created at %2', $order->getIncrementId(), $this->formatDate($order->getCreatedAt()));
-        $url = $this->_urlBuilder->getUrl('sales/order/view', array('order_id' => $order->getId()));
-        $description = '<p>' . __(
-            'Current Status: %1<br/>',
-            $order->getStatusLabel()
-        ) . __(
-            'Total: %1<br/>',
-            $order->formatPrice($order->getGrandTotal())
-        ) . '</p>';
-        $rssObj->_addEntry(array('title' => $title, 'link' => $url, 'description' => $description));
-        return $rssObj->createRssXml();
-    }
-}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Feed.php b/app/code/Magento/Rss/Controller/Adminhtml/Feed.php
new file mode 100644
index 00000000000..f7b52bc2f5a
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Adminhtml/Feed.php
@@ -0,0 +1,65 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Adminhtml;
+
+/**
+ * Class Feed
+ * @package Magento\Rss\Controller
+ */
+class Feed extends Authenticate
+{
+    /**
+     * @var \Magento\Rss\Model\RssManager
+     */
+    protected $rssManager;
+
+    /**
+     * @var \Magento\Rss\Model\RssFactory
+     */
+    protected $rssFactory;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Rss\Model\RssManager $rssManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Rss\Model\RssFactory $rssFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Rss\Model\RssManager $rssManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Rss\Model\RssFactory $rssFactory
+    ) {
+        parent::__construct($context);
+        $this->_objectManager->get('Magento\Backend\Model\UrlInterface')->turnOffSecretKey();
+        $this->rssManager = $rssManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->rssFactory = $rssFactory;
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php b/app/code/Magento/Rss/Controller/Adminhtml/Feed/Index.php
similarity index 52%
rename from app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php
rename to app/code/Magento/Rss/Controller/Adminhtml/Feed/Index.php
index 1fadb7035ff..e9491cc3c31 100644
--- a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php
+++ b/app/code/Magento/Rss/Controller/Adminhtml/Feed/Index.php
@@ -22,19 +22,44 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Adminhtml\Catalog;
+namespace Magento\Rss\Controller\Adminhtml\Feed;
 
-class Review extends \Magento\Rss\Controller\Adminhtml\Authenticate
+use \Magento\Framework\App\Action\NotFoundException;
+
+/**
+ * Class Index
+ * @package Magento\Rss\Controller\Feed
+ */
+class Index extends \Magento\Rss\Controller\Adminhtml\Feed
 {
     /**
-     * Review action
+     * Index action
      *
      * @return void
+     * @throws NotFoundException
      */
     public function execute()
     {
+        if (!$this->scopeConfig->getValue('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            throw new NotFoundException();
+        }
+
+        $type = $this->getRequest()->getParam('type');
+        try {
+            $provider = $this->rssManager->getProvider($type);
+        } catch (\InvalidArgumentException $e) {
+            throw new NotFoundException($e->getMessage());
+        }
+
+        if (!$provider->isAllowed()) {
+            throw new NotFoundException();
+        }
+
+        /** @var $rss \Magento\Rss\Model\Rss */
+        $rss = $this->rssFactory->create();
+        $rss->setDataProvider($provider);
+
         $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
+        $this->getResponse()->setBody($rss->createRssXml());
     }
 }
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php b/app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
deleted file mode 100644
index 149b62f1014..00000000000
--- a/app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
+++ /dev/null
@@ -1,40 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Controller\Adminhtml\Order;
-
-class NewAction extends \Magento\Rss\Controller\Adminhtml\Authenticate
-{
-    /**
-     * New orders action
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-}
diff --git a/app/code/Magento/Rss/Controller/Catalog.php b/app/code/Magento/Rss/Controller/Feed.php
similarity index 55%
rename from app/code/Magento/Rss/Controller/Catalog.php
rename to app/code/Magento/Rss/Controller/Feed.php
index a3dc1debe8e..b089d377f6b 100644
--- a/app/code/Magento/Rss/Controller/Catalog.php
+++ b/app/code/Magento/Rss/Controller/Feed.php
@@ -24,62 +24,41 @@
 namespace Magento\Rss\Controller;
 
 /**
- * RSS Controller for Catalog feeds
+ * Class Feed
+ * @package Magento\Rss\Controller
  */
-class Catalog extends \Magento\Framework\App\Action\Action
+class Feed extends \Magento\Framework\App\Action\Action
 {
+    /**
+     * @var \Magento\Rss\Model\RssManager
+     */
+    protected $rssManager;
+
+    /**
+     * @var \Magento\Rss\Model\RssFactory
+     */
+    protected $rssFactory;
+
     /**
      * @var \Magento\Framework\App\Config\ScopeConfigInterface
      */
-    protected $_scopeConfig;
+    protected $scopeConfig;
 
     /**
      * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Rss\Model\RssManager $rssManager
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Rss\Model\RssFactory $rssFactory
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+        \Magento\Rss\Model\RssManager $rssManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Rss\Model\RssFactory $rssFactory
     ) {
-        $this->_scopeConfig = $scopeConfig;
+        $this->rssManager = $rssManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->rssFactory = $rssFactory;
         parent::__construct($context);
     }
-
-    /**
-     * Render or forward to "no route" action if this type of RSS is disabled
-     *
-     * @param string $code
-     * @return void
-     */
-    protected function _genericAction($code)
-    {
-        if ($this->_isEnabled($code)) {
-            $this->_render();
-        } else {
-            $this->_forward('nofeed', 'index', 'rss');
-        }
-    }
-
-    /**
-     * Whether specified type of RSS is enabled
-     *
-     * @param string $code
-     * @return bool
-     */
-    protected function _isEnabled($code)
-    {
-        return $this->_scopeConfig->isSetFlag("rss/catalog/{$code}", \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
-    }
-
-    /**
-     * Render as XML-document using layout handle without inheriting any other handles
-     *
-     * @return void
-     */
-    protected function _render()
-    {
-        $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=UTF-8');
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
 }
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php b/app/code/Magento/Rss/Controller/Feed/Index.php
similarity index 53%
rename from app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php
rename to app/code/Magento/Rss/Controller/Feed/Index.php
index e7abd7228b0..9d75a3d85dc 100644
--- a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php
+++ b/app/code/Magento/Rss/Controller/Feed/Index.php
@@ -22,19 +22,44 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Adminhtml\Catalog;
+namespace Magento\Rss\Controller\Feed;
 
-class Notifystock extends \Magento\Rss\Controller\Adminhtml\Authenticate
+use \Magento\Framework\App\Action\NotFoundException;
+
+/**
+ * Class Index
+ * @package Magento\Rss\Controller\Feed
+ */
+class Index extends \Magento\Rss\Controller\Feed
 {
     /**
-     * Notify stock action
+     * Index action
      *
      * @return void
+     * @throws NotFoundException
      */
     public function execute()
     {
+        if (!$this->scopeConfig->getValue('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            throw new NotFoundException();
+        }
+
+        $type = $this->getRequest()->getParam('type');
+        try {
+            $provider = $this->rssManager->getProvider($type);
+        } catch (\InvalidArgumentException $e) {
+            throw new NotFoundException($e->getMessage());
+        }
+
+        if (!$provider->isAllowed()) {
+            throw new NotFoundException();
+        }
+
+        /** @var $rss \Magento\Rss\Model\Rss */
+        $rss = $this->rssFactory->create();
+        $rss->setDataProvider($provider);
+
         $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
+        $this->getResponse()->setBody($rss->createRssXml());
     }
 }
diff --git a/app/code/Magento/Rss/Controller/Index.php b/app/code/Magento/Rss/Controller/Index.php
index b232d3651fb..546f3d73fa5 100644
--- a/app/code/Magento/Rss/Controller/Index.php
+++ b/app/code/Magento/Rss/Controller/Index.php
@@ -23,6 +23,10 @@
  */
 namespace Magento\Rss\Controller;
 
+/**
+ * Class Index
+ * @package Magento\Rss\Controller
+ */
 class Index extends \Magento\Framework\App\Action\Action
 {
     /**
@@ -30,31 +34,15 @@ class Index extends \Magento\Framework\App\Action\Action
      */
     protected $_scopeConfig;
 
-    /**
-     * @var \Magento\Rss\Helper\Data
-     */
-    protected $_rssHelper;
-
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $_customerSession;
-
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Rss\Helper\Data $rssHelper
-     * @param \Magento\Customer\Model\Session $customerSession
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Rss\Helper\Data $rssHelper,
-        \Magento\Customer\Model\Session $customerSession
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     ) {
         $this->_scopeConfig = $scopeConfig;
-        $this->_rssHelper = $rssHelper;
-        $this->_customerSession = $customerSession;
         parent::__construct($context);
     }
 }
diff --git a/app/code/Magento/Rss/Helper/Order.php b/app/code/Magento/Rss/Helper/Order.php
deleted file mode 100644
index 8ad2bb23acf..00000000000
--- a/app/code/Magento/Rss/Helper/Order.php
+++ /dev/null
@@ -1,133 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Helper;
-
-/**
- * Order rss helper
- */
-class Order extends \Magento\Framework\App\Helper\AbstractHelper
-{
-    /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $_scopeConfig;
-
-    /**
-     * @var \Magento\Sales\Model\OrderFactory
-     */
-    protected $_orderFactory;
-
-    /**
-     * @param \Magento\Framework\App\Helper\Context $context
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Sales\Model\OrderFactory $orderFactory
-     */
-    public function __construct(
-        \Magento\Framework\App\Helper\Context $context,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Sales\Model\OrderFactory $orderFactory
-    ) {
-        $this->_scopeConfig = $scopeConfig;
-        $this->_orderFactory = $orderFactory;
-        parent::__construct($context);
-    }
-
-    /**
-     * Check whether status notification is allowed
-     *
-     * @return bool
-     */
-    public function isStatusNotificationAllow()
-    {
-        if ($this->_scopeConfig->getValue('rss/order/status_notified', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve order status history url
-     *
-     * @param \Magento\Sales\Model\Order $order
-     * @return string
-     */
-    public function getStatusHistoryRssUrl($order)
-    {
-        return $this->_getUrl(
-            'rss/order/status',
-            array('_secure' => true, '_query' => array('data' => $this->getStatusUrlKey($order)))
-        );
-    }
-
-    /**
-     * Retrieve order status url key
-     *
-     * @param \Magento\Sales\Model\Order $order
-     * @return string
-     */
-    public function getStatusUrlKey($order)
-    {
-        $data = array(
-            'order_id' => $order->getId(),
-            'increment_id' => $order->getIncrementId(),
-            'customer_id' => $order->getCustomerId()
-        );
-        return base64_encode(json_encode($data));
-    }
-
-    /**
-     * Retrieve order instance by specified status url key
-     *
-     * @param string $key
-     * @return \Magento\Sales\Model\Order|null
-     */
-    public function getOrderByStatusUrlKey($key)
-    {
-        $data = json_decode(base64_decode($key), true);
-        if (!is_array(
-            $data
-        ) || !isset(
-            $data['order_id']
-        ) || !isset(
-            $data['increment_id']
-        ) || !isset(
-            $data['customer_id']
-        )
-        ) {
-            return null;
-        }
-
-        /** @var $order \Magento\Sales\Model\Order */
-        $order = $this->_orderFactory->create();
-        $order->load($data['order_id']);
-        if ($order->getId() &&
-            $order->getIncrementId() == $data['increment_id'] &&
-            $order->getCustomerId() == $data['customer_id']
-        ) {
-            return $order;
-        }
-
-        return null;
-    }
-}
diff --git a/app/code/Magento/Rss/Model/Rss.php b/app/code/Magento/Rss/Model/Rss.php
index ddeba3753ea..9e1399521ad 100644
--- a/app/code/Magento/Rss/Model/Rss.php
+++ b/app/code/Magento/Rss/Model/Rss.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Rss\Model;
 
+use Magento\Framework\App\Rss\DataProviderInterface;
+
 /**
  * Auth session model
  *
@@ -31,50 +33,62 @@ namespace Magento\Rss\Model;
 class Rss
 {
     /**
-     * @var array
+     * @var DataProviderInterface
      */
-    protected $_feedArray = array();
+    protected $dataProvider;
 
     /**
-     * @param array $data
-     * @return $this
-     * @codeCoverageIgnore
+     * @var \Magento\Framework\App\CacheInterface
      */
-    public function _addHeader($data = array())
-    {
-        $this->_feedArray = $data;
-        return $this;
-    }
+    protected $cache;
 
     /**
-     * @param array $entries
-     * @return $this
-     * @codeCoverageIgnore
+     * @param \Magento\Framework\App\CacheInterface $cache
      */
-    public function _addEntries($entries)
+    public function __construct(\Magento\Framework\App\CacheInterface $cache)
     {
-        $this->_feedArray['entries'] = $entries;
-        return $this;
+        $this->cache = $cache;
     }
 
     /**
-     * @param array $entry
-     * @return $this
-     * @codeCoverageIgnore
+     * @return array
      */
-    public function _addEntry($entry)
+    public function getFeeds()
     {
-        $this->_feedArray['entries'][] = $entry;
-        return $this;
+        if (is_null($this->dataProvider)) {
+            return array();
+        }
+        $cache = false;
+        if ($this->dataProvider->getCacheKey() && $this->dataProvider->getCacheLifetime()) {
+            $cache = $this->cache->load($this->dataProvider->getCacheKey());
+        }
+
+        if ($cache) {
+            return unserialize($cache);
+        }
+
+        $data = $this->dataProvider->getRssData();
+
+        if ($this->dataProvider->getCacheKey() && $this->dataProvider->getCacheLifetime()) {
+            $this->cache->save(
+                serialize($data),
+                $this->dataProvider->getCacheKey(),
+                array('rss'),
+                $this->dataProvider->getCacheLifetime()
+            );
+        }
+
+        return $data;
     }
 
     /**
-     * @return array
-     * @codeCoverageIgnore
+     * @param DataProviderInterface $dataProvider
+     * @return $this
      */
-    public function getFeedArray()
+    public function setDataProvider(DataProviderInterface $dataProvider)
     {
-        return $this->_feedArray;
+        $this->dataProvider = $dataProvider;
+        return $this;
     }
 
     /**
@@ -82,11 +96,7 @@ class Rss
      */
     public function createRssXml()
     {
-        try {
-            $rssFeedFromArray = \Zend_Feed::importArray($this->getFeedArray(), 'rss');
-            return $rssFeedFromArray->saveXML();
-        } catch (\Exception $e) {
-            return __('Error in processing xml. %1', $e->getMessage());
-        }
+        $rssFeedFromArray = \Zend_Feed::importArray($this->getFeeds(), 'rss');
+        return $rssFeedFromArray->saveXML();
     }
 }
diff --git a/app/code/Magento/Rss/Model/RssManager.php b/app/code/Magento/Rss/Model/RssManager.php
new file mode 100644
index 00000000000..860884178c7
--- /dev/null
+++ b/app/code/Magento/Rss/Model/RssManager.php
@@ -0,0 +1,90 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Model;
+
+use \Magento\Framework\App\Rss\DataProviderInterface;
+use \Magento\Framework\App\Rss\RssManagerInterface;
+
+/**
+ * Rss Manager
+ *
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class RssManager implements RssManagerInterface
+{
+    /**
+     * @var \Magento\Framework\App\Rss\DataProviderInterface[]
+     */
+    protected $providers;
+
+    /**
+     * @param \Magento\Framework\ObjectManager $objectManager
+     * @param array $dataProviders
+     */
+    public function __construct(\Magento\Framework\ObjectManager $objectManager, array $dataProviders = array())
+    {
+        $this->objectManager = $objectManager;
+        $this->providers = $dataProviders;
+    }
+
+    /**
+     * Return Rss Data Provider by Rss Feed Id.
+     *
+     * @param string $type
+     * @return DataProviderInterface
+     * @throws \InvalidArgumentException
+     */
+    public function getProvider($type)
+    {
+        if (!isset($this->providers[$type])) {
+            throw new \InvalidArgumentException('Unknown provider with type: ' . $type);
+        }
+
+        $provider = $this->providers[$type];
+
+        if (is_string($provider)) {
+            $provider = $this->objectManager->get($provider);
+        }
+
+        if (!$provider instanceof DataProviderInterface) {
+            throw new \InvalidArgumentException('Provider should implement DataProviderInterface');
+        }
+
+        $this->providers[$type] = $provider;
+
+        return $this->providers[$type];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProviders()
+    {
+        $result = array();
+        foreach (array_keys($this->providers) as $type) {
+            $result[] = $this->getProvider($type);
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Rss/Model/UrlBuilder.php b/app/code/Magento/Rss/Model/UrlBuilder.php
new file mode 100644
index 00000000000..f1a6fb5da9d
--- /dev/null
+++ b/app/code/Magento/Rss/Model/UrlBuilder.php
@@ -0,0 +1,68 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Model;
+
+use Magento\Framework\App\Rss\UrlBuilderInterface;
+
+/**
+ * Class UrlBuilder
+ * @package Magento\Rss\Model
+ */
+class UrlBuilder implements UrlBuilderInterface
+{
+    /**
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $config;
+
+    /**
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+    ) {
+        $this->urlBuilder = $urlBuilder;
+        $this->config = $scopeConfig;
+    }
+
+    /**
+     * @param array $queryParams
+     * @return string
+     */
+    public function getUrl(array $queryParams = array())
+    {
+        if (!$this->config->getValue('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            return '';
+        }
+
+        return $this->urlBuilder->getUrl('rss/feed/index', $queryParams);
+    }
+}
diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json
index cfe36e2b75e..f4380ee4515 100644
--- a/app/code/Magento/Rss/composer.json
+++ b/app/code/Magento/Rss/composer.json
@@ -3,20 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-sales-rule": "0.1.0-alpha96",
-        "magento/module-review": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-gift-message": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Rss/etc/adminhtml/system.xml b/app/code/Magento/Rss/etc/adminhtml/system.xml
index ec0fadeb971..a1c4b25f4fe 100644
--- a/app/code/Magento/Rss/etc/adminhtml/system.xml
+++ b/app/code/Magento/Rss/etc/adminhtml/system.xml
@@ -37,32 +37,6 @@
                     <backend_model>Magento\Rss\Model\System\Config\Backend\Links</backend_model>
                 </field>
             </group>
-            <group id="catalog" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Catalog</label>
-                <field id="new" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>New Products</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
-                </field>
-                <field id="special" translate="label" type="select" sortOrder="11" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Special Products</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
-                </field>
-                <field id="salesrule" translate="label" type="select" sortOrder="12" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Coupons/Discounts</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
-                </field>
-                <field id="category" translate="label" type="select" sortOrder="14" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Top Level Category</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
-                </field>
-            </group>
-            <group id="order" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Order</label>
-                <field id="status_notified" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Customer Order Status Notification</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
-                </field>
-            </group>
         </section>
     </system>
 </config>
diff --git a/app/code/Magento/Index/etc/adminhtml/menu.xml b/app/code/Magento/Rss/etc/di.xml
similarity index 76%
rename from app/code/Magento/Index/etc/adminhtml/menu.xml
rename to app/code/Magento/Rss/etc/di.xml
index db158e3ffaa..983eb527581 100644
--- a/app/code/Magento/Index/etc/adminhtml/menu.xml
+++ b/app/code/Magento/Rss/etc/di.xml
@@ -23,8 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/menu.xsd">
-    <menu>
-        <add id="Magento_Index::system_index" title="Index Management" module="Magento_Index" sortOrder="20" parent="Magento_Backend::system_tools" action="adminhtml/process/list" resource="Magento_Index::index"/>
-    </menu>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Framework\App\Rss\RssManagerInterface" type="Magento\Rss\Model\RssManager"/>
+    <preference for="Magento\Framework\App\Rss\UrlBuilderInterface" type="Magento\Rss\Model\UrlBuilder"/>
 </config>
diff --git a/app/code/Magento/Rss/etc/module.xml b/app/code/Magento/Rss/etc/module.xml
index d66af033852..81e93a9cbbf 100644
--- a/app/code/Magento/Rss/etc/module.xml
+++ b/app/code/Magento/Rss/etc/module.xml
@@ -25,22 +25,9 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
     <module name="Magento_Rss" schema_version="1.6.0.0" active="true">
-        <sequence>
-            <module name="Magento_Catalog"/>
-            <module name="Magento_CatalogInventory"/>
-            <module name="Magento_Sales"/>
-            <module name="Magento_SalesRule"/>
-        </sequence>
         <depends>
             <module name="Magento_Store"/>
-            <module name="Magento_Catalog"/>
-            <module name="Magento_CatalogInventory"/>
-            <module name="Magento_Sales"/>
-            <module name="Magento_SalesRule"/>
-            <module name="Magento_Review"/>
-            <module name="Magento_Customer"/>
             <module name="Magento_Backend"/>
-            <module name="Magento_GiftMessage"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Rss/view/frontend/layout/default.xml b/app/code/Magento/Rss/view/frontend/layout/default.xml
index 7774ecf6e37..518aa72b134 100644
--- a/app/code/Magento/Rss/view/frontend/layout/default.xml
+++ b/app/code/Magento/Rss/view/frontend/layout/default.xml
@@ -32,8 +32,5 @@
             </arguments>
         </block>
     </referenceBlock>
-    <referenceBlock name="sales.order.info.buttons">
-        <block class="Magento\Rss\Block\Order\Info\Buttons\Rss" name="sales.order.info.button.rss"/>
-    </referenceBlock>
-    <block class="Magento\Rss\Block\ListBlock" name="head_rss" ifconfig="rss/config/active"/>
+    <block class="Magento\Rss\Block\Feeds" name="head_rss" ifconfig="rss/config/active"/>
 </page>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_category.xml b/app/code/Magento/Rss/view/frontend/layout/rss_catalog_category.xml
deleted file mode 100644
index 0d7a43a7776..00000000000
--- a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_category.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\Category" name="rss.catalog.category" cacheable="false"/>
-        <block class="Magento\Framework\Pricing\Render" name="product.price.render.default">
-            <arguments>
-                <argument name="price_render_handle" xsi:type="string">catalog_product_prices</argument>
-                <!-- set "override" configuration settings here -->
-            </arguments>
-        </block>
-    </container>
-</layout>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_new.xml b/app/code/Magento/Rss/view/frontend/layout/rss_catalog_new.xml
deleted file mode 100644
index 4be11a90b5c..00000000000
--- a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_new.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\NewCatalog" name="rss.catalog.new" cacheable="false">
-            <block class="Magento\Framework\Pricing\Render" name="product.price.render.default">
-                <arguments>
-                    <argument name="price_render_handle" xsi:type="string">catalog_product_prices</argument>
-                    <!-- set "override" configuration settings here -->
-                </arguments>
-            </block>
-        </block>
-    </container>
-</layout>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_index_index.xml b/app/code/Magento/Rss/view/frontend/layout/rss_index_index.xml
index 61423c030fe..a0f91e6bc78 100644
--- a/app/code/Magento/Rss/view/frontend/layout/rss_index_index.xml
+++ b/app/code/Magento/Rss/view/frontend/layout/rss_index_index.xml
@@ -30,6 +30,6 @@
         </action>
     </referenceBlock>
     <referenceContainer name="content">
-        <block class="Magento\Rss\Block\ListBlock" name="rss.list" template="list.phtml"/>
+        <block class="Magento\Rss\Block\Feeds" name="rss.feeds"/>
     </referenceContainer>
 </page>
diff --git a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml
new file mode 100644
index 00000000000..45b2bda318a
--- /dev/null
+++ b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml
@@ -0,0 +1,49 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<table class="data table rss">
+    <tbody>
+        <th colspan="2"><?php echo __('Miscellaneous Feeds') ?></th>
+    <?php foreach($this->getFeeds() as $feed): ?>
+        <?php if (!isset($feed['group'])): ?>
+        <tr>
+            <td class="col feed"><?php echo $feed['label'] ?></td>
+            <td class="col action">
+                <a href="<?php echo $feed['link'] ?>" class="action get"><span><?php echo __('Get Feed'); ?></span></a>
+            </td>
+        </tr>
+        <?php else: ?>
+            <th colspan="2"><?php echo $feed['group'] ?></th>
+            <?php foreach ($feed['feeds'] as $item) :?>
+                <tr>
+                    <td class="col feed"><?php echo $item['label'] ?></td>
+                    <td class="col action">
+                        <a href="<?php echo $item['link'] ?>" class="action get"><span><?php echo __('Get Feed'); ?></span></a>
+                    </td>
+                </tr>
+            <?php endforeach; ?>
+        <?php endif; ?>
+    <?php endforeach; ?>
+    </tbody>
+</table>
diff --git a/app/code/Magento/Rss/view/frontend/templates/list.phtml b/app/code/Magento/Rss/view/frontend/templates/list.phtml
deleted file mode 100644
index 7ecf666c38a..00000000000
--- a/app/code/Magento/Rss/view/frontend/templates/list.phtml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php
-    $_categories = $this->getRssCatalogFeeds();
-    $_misc = $this->getRssMiscFeeds();
-?>
-<?php if ($_categories || $_misc): ?>
-<?php if($_misc): ?>
-<table class="data table rss">
-    <thead>
-        <tr>
-            <th colspan="2"><?php echo __('Miscellaneous Feeds') ?></th>
-        </tr>
-    </thead>
-    <tbody>
-        <?php foreach ($_misc as $_feed): ?>
-        <tr>
-            <td class="col feed"><?php echo $_feed->getLabel() ?></td>
-            <td class="col action"><a href="<?php echo $_feed->getUrl() ?>" class="action get"><span><?php echo __('Get Feed'); ?></span></a></td>
-        </tr>
-        <?php endforeach; ?>
-    </tbody>
-</table>
-<?php endif; ?>
-<?php if($_categories): ?>
-<table class="data table category rss">
-    <thead>
-        <tr>
-            <th colspan="2"><?php echo __('Category Feeds') ?></th>
-        </tr>
-    </thead>
-    <tbody>
-        <?php foreach ($_categories as $_category): ?>
-        <tr>
-            <td class="col feed"><?php echo $this->escapeHtml($_category->getLabel()) ?></td>
-            <td class="col action"><a href="<?php echo $_category->getUrl() ?>" class="action get"><span><?php echo __('Get Feed'); ?></span></a></td>
-        </tr>
-        <?php endforeach; ?>
-    </tbody>
-</table>
-<?php endif; ?>
-<?php else: ?>
-    <p><?php echo __('There are no Rss Feeds.'); ?></p>
-<?php endif; ?>
diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json
index e39949448c9..bb7975eda0f 100644
--- a/app/code/Magento/Rule/composer.json
+++ b/app/code/Magento/Rule/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Rss/Block/Order/Details.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Details.php
similarity index 89%
rename from app/code/Magento/Rss/Block/Order/Details.php
rename to app/code/Magento/Sales/Block/Adminhtml/Order/Details.php
index 71007d30d9c..059e2bf7153 100644
--- a/app/code/Magento/Rss/Block/Order/Details.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Details.php
@@ -21,8 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Block\Order;
+namespace Magento\Sales\Block\Adminhtml\Order;
 
+/**
+ * Class Details
+ * @package Magento\Sales\Block\Adminhtml\Order
+ */
 class Details extends \Magento\Framework\View\Element\Template
 {
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php
index 9ce8319710b..fb5ac2078ac 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php
@@ -90,16 +90,24 @@ class Tax extends \Magento\Tax\Block\Sales\Order\Tax
      */
     public function getFullTaxInfo()
     {
-        /** @var $source \Magento\Sales\Model\Order */
-        $source = $this->getOrder();
-        $taxClassAmount = array();
-        if ($source instanceof \Magento\Sales\Model\Order) {
-            $taxClassAmount = $this->_taxHelper->getCalculatedTaxes($source);
-            if (empty($taxClassAmount)) {
-                $rates = $this->_taxOrderFactory->create()->getCollection()->loadByOrder($source)->toArray();
-                $taxClassAmount = $this->_taxCalculation->reproduceProcess($rates['items']);
-            }
+        $source = $this->getSource();
+        if (!$source instanceof \Magento\Sales\Model\Order\Invoice
+            && !$source instanceof \Magento\Sales\Model\Order\Creditmemo
+        ) {
+            $source = $this->getOrder();
         }
+
+        $taxClassAmount = [];
+        if (empty($source)) {
+            return $taxClassAmount;
+        }
+
+        $taxClassAmount = $this->_taxHelper->getCalculatedTaxes($source);
+        if (empty($taxClassAmount)) {
+            $rates = $this->_taxOrderFactory->create()->getCollection()->loadByOrder($source)->toArray();
+            $taxClassAmount = $this->_taxCalculation->reproduceProcess($rates['items']);
+        }
+
         return $taxClassAmount;
     }
 
diff --git a/app/code/Magento/Rss/Block/Order/Info/Buttons/Rss.php b/app/code/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/Link.php
similarity index 57%
rename from app/code/Magento/Rss/Block/Order/Info/Buttons/Rss.php
rename to app/code/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/Link.php
index fca08312b50..3af2a95d326 100644
--- a/app/code/Magento/Rss/Block/Order/Info/Buttons/Rss.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/Link.php
@@ -21,67 +21,69 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-namespace Magento\Rss\Block\Order\Info\Buttons;
+namespace Magento\Sales\Block\Adminhtml\Rss\Order\Grid;
 
 /**
- * Block with rss feed link in Order view page
+ * Class Link
+ * @package Magento\Sales\Block\Adminhtml\Rss\Order\Grid
  */
-class Rss extends \Magento\Framework\View\Element\Template
+class Link extends \Magento\Framework\View\Element\Template
 {
     /**
-     * Template of the block
-     *
      * @var string
      */
-    protected $_template = 'order/info/buttons/rss.phtml';
+    protected $_template = 'rss/order/grid/link.phtml';
 
     /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
      */
-    protected $registry;
-
-    /**
-     * @var \Magento\Rss\Helper\Order
-     */
-    protected $orderHelper;
+    protected $rssUrlBuilder;
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Rss\Helper\Order $orderHelper
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Rss\Helper\Order $orderHelper,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
         array $data = array()
     ) {
-        $this->registry = $registry;
-        $this->orderHelper = $orderHelper;
+        $this->rssUrlBuilder = $rssUrlBuilder;
         parent::__construct($context, $data);
     }
 
     /**
-     * Retrieve current order model instance
-     *
-     * @return \Magento\Sales\Model\Order
+     * @return string
      */
-    public function getOrder()
+    public function getLink()
     {
-        return $this->registry->registry('current_order');
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
     }
 
     /**
-     * Getting order helper
+     * @return string
+     */
+    public function getLabel()
+    {
+        return __('New Order RSS');
+    }
+
+    /**
+     * Check whether status notification is allowed
      *
-     * @return \Magento\Rss\Helper\Order
+     * @return bool
+     */
+    public function isRssAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * @return string
      */
-    public function getOrderHelper()
+    protected function getLinkParams()
     {
-        return $this->orderHelper;
+        return array('type' => 'new_order');
     }
 }
diff --git a/app/code/Magento/Sales/Block/Order/Creditmemo.php b/app/code/Magento/Sales/Block/Order/Creditmemo.php
index 0f0541372ff..085ad674d94 100644
--- a/app/code/Magento/Sales/Block/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Block/Order/Creditmemo.php
@@ -70,10 +70,7 @@ class Creditmemo extends \Magento\Sales\Block\Order\Creditmemo\Items
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/History.php b/app/code/Magento/Sales/Block/Order/History.php
index adb3a827084..7d5fe477ef5 100644
--- a/app/code/Magento/Sales/Block/Order/History.php
+++ b/app/code/Magento/Sales/Block/Order/History.php
@@ -48,17 +48,11 @@ class History extends \Magento\Framework\View\Element\Template
      */
     protected $_orderConfig;
 
-    /**
-     * @var \Magento\Framework\View\Page\Config
-     */
-    protected $pageConfig;
-
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
      * @param \Magento\Sales\Model\Resource\Order\CollectionFactory $orderCollectionFactory
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Sales\Model\Order\Config $orderConfig
-     * @param \Magento\Framework\View\Page\Config $pageConfig
      * @param array $data
      */
     public function __construct(
@@ -66,13 +60,11 @@ class History extends \Magento\Framework\View\Element\Template
         \Magento\Sales\Model\Resource\Order\CollectionFactory $orderCollectionFactory,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Sales\Model\Order\Config $orderConfig,
-        \Magento\Framework\View\Page\Config $pageConfig,
         array $data = array()
     ) {
         $this->_orderCollectionFactory = $orderCollectionFactory;
         $this->_customerSession = $customerSession;
         $this->_orderConfig = $orderConfig;
-        $this->pageConfig = $pageConfig;
         parent::__construct($context, $data);
         $this->_isScopePrivate = true;
     }
diff --git a/app/code/Magento/Sales/Block/Order/Info.php b/app/code/Magento/Sales/Block/Order/Info.php
index c2b26e61ada..a19be6098fb 100644
--- a/app/code/Magento/Sales/Block/Order/Info.php
+++ b/app/code/Magento/Sales/Block/Order/Info.php
@@ -69,9 +69,7 @@ class Info extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/Info/Buttons/Rss.php b/app/code/Magento/Sales/Block/Order/Info/Buttons/Rss.php
new file mode 100644
index 00000000000..09f3f9878e2
--- /dev/null
+++ b/app/code/Magento/Sales/Block/Order/Info/Buttons/Rss.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Block\Order\Info\Buttons;
+
+/**
+ * Block of links in Order view page
+ */
+class Rss extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'order/info/buttons/rss.phtml';
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return string
+     */
+    public function getLink()
+    {
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
+    }
+
+    /**
+     * @return string
+     */
+    public function getLabel()
+    {
+        return __('Subscribe to Order Status');
+    }
+
+    /**
+     * Check whether status notification is allowed
+     *
+     * @return bool
+     */
+    public function isRssAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag(
+            'rss/order/status',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    /**
+     * Retrieve order status url key
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return string
+     */
+    protected function getUrlKey($order)
+    {
+        $data = array(
+            'order_id' => $order->getId(),
+            'increment_id' => $order->getIncrementId(),
+            'customer_id' => $order->getCustomerId()
+        );
+        return base64_encode(json_encode($data));
+    }
+
+    /**
+     * @return string
+     */
+    protected function getLinkParams()
+    {
+        $order = $this->orderFactory->create()->load($this->_request->getParam('order_id'));
+        return array(
+            'type' => 'order_status',
+            '_secure' => true,
+            '_query' => array('data' => $this->getUrlKey($order))
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Block/Order/Invoice.php b/app/code/Magento/Sales/Block/Order/Invoice.php
index 037cd75b9cd..321b5a7c7c5 100644
--- a/app/code/Magento/Sales/Block/Order/Invoice.php
+++ b/app/code/Magento/Sales/Block/Order/Invoice.php
@@ -68,10 +68,7 @@ class Invoice extends \Magento\Sales\Block\Order\Invoice\Items
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php
index a30638626c6..671c8364935 100644
--- a/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php
+++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Creditmemo.php
@@ -64,9 +64,7 @@ class Creditmemo extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php
index 057812db8f2..3d99d510c79 100644
--- a/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php
+++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Invoice.php
@@ -64,10 +64,7 @@ class Invoice extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php b/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php
index b38f500aa84..d5d9b9e364c 100644
--- a/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php
+++ b/app/code/Magento/Sales/Block/Order/PrintOrder/Shipment.php
@@ -102,10 +102,7 @@ class Shipment extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/PrintShipment.php b/app/code/Magento/Sales/Block/Order/PrintShipment.php
index 9c9324543e0..e3625aa7fa6 100644
--- a/app/code/Magento/Sales/Block/Order/PrintShipment.php
+++ b/app/code/Magento/Sales/Block/Order/PrintShipment.php
@@ -65,9 +65,7 @@ class PrintShipment extends \Magento\Sales\Block\Items\AbstractItems
      */
     protected function _prepareLayout()
     {
-        if ($headBlock = $this->getLayout()->getBlock('head')) {
-            $headBlock->setTitle(__('Print Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Print Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Block/Order/View.php b/app/code/Magento/Sales/Block/Order/View.php
index ac0eb229aae..b16c4eefc6c 100644
--- a/app/code/Magento/Sales/Block/Order/View.php
+++ b/app/code/Magento/Sales/Block/Order/View.php
@@ -76,10 +76,7 @@ class View extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php
index 1eb233b34c0..afc24d33c9d 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php
@@ -57,7 +57,7 @@ abstract class Email extends \Magento\Backend\App\Action
             return;
         }
 
-        $this->_objectManager->create('Magento\Sales\Model\InvoiceNotifier')
+        $this->_objectManager->create('Magento\Sales\Model\Order\InvoiceNotifier')
             ->notify($invoice);
 
         $this->messageManager->addSuccess(__('We sent the message.'));
diff --git a/app/code/Magento/Sales/Controller/Guest/Form.php b/app/code/Magento/Sales/Controller/Guest/Form.php
index 5fa77e29291..c876697444f 100644
--- a/app/code/Magento/Sales/Controller/Guest/Form.php
+++ b/app/code/Magento/Sales/Controller/Guest/Form.php
@@ -38,7 +38,7 @@ class Form extends \Magento\Framework\App\Action\Action
             return;
         }
         $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Orders and Returns'));
+        $this->_view->getPage()->getConfig()->setTitle(__('Orders and Returns'));
         $this->_objectManager->get('Magento\Sales\Helper\Guest')->getBreadcrumbs();
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Sales/Controller/Order/History.php b/app/code/Magento/Sales/Controller/Order/History.php
index 309886cd40f..a7433b38e04 100644
--- a/app/code/Magento/Sales/Controller/Order/History.php
+++ b/app/code/Magento/Sales/Controller/Order/History.php
@@ -38,7 +38,7 @@ class History extends \Magento\Framework\App\Action\Action implements OrderInter
         $this->_view->loadLayout();
         $this->_view->getLayout()->initMessages();
 
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Orders'));
+        $this->_view->getPage()->getConfig()->setTitle(__('My Orders'));
 
         $block = $this->_view->getLayout()->getBlock('customer.account.link.back');
         if ($block) {
diff --git a/app/code/Magento/Sales/Model/Order/Address/Validator.php b/app/code/Magento/Sales/Model/Order/Address/Validator.php
index 13b8b8a5d11..1f04edb7f86 100644
--- a/app/code/Magento/Sales/Model/Order/Address/Validator.php
+++ b/app/code/Magento/Sales/Model/Order/Address/Validator.php
@@ -40,7 +40,7 @@ class Validator
         'street' => 'Street',
         'city' => 'City',
         'email' => 'Email',
-        'telephone' => 'Telephone',
+        'telephone' => 'Phone Number',
         'country_id' => 'Country',
         'firstname' => 'First Name',
         'address_type' => 'Address Type'
diff --git a/app/code/Magento/Sales/Model/OrderRepository/Plugin/Authorization.php b/app/code/Magento/Sales/Model/OrderRepository/Plugin/Authorization.php
new file mode 100644
index 00000000000..8898aabb57e
--- /dev/null
+++ b/app/code/Magento/Sales/Model/OrderRepository/Plugin/Authorization.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+ 
+namespace Magento\Sales\Model\OrderRepository\Plugin;
+
+use \Magento\Authorization\Model\UserContextInterface;
+use \Magento\Framework\Exception\NoSuchEntityException;
+
+class Authorization
+{
+    /**
+     * @var UserContextInterface
+     */
+    protected $userContext;
+
+    /**
+     * @param UserContextInterface $userContext
+     */
+    public function __construct(
+        \Magento\Authorization\Model\UserContextInterface $userContext
+    ) {
+        $this->userContext = $userContext;
+    }
+
+    /**
+     * Checks if order is allowed
+     *
+     * @param \Magento\Sales\Model\OrderRepository $subject
+     * @param \Magento\Sales\Model\Order $order
+     * @return \Magento\Sales\Model\Order
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function afterGet(
+        \Magento\Sales\Model\OrderRepository $subject,
+        \Magento\Sales\Model\Order $order
+    ) {
+        if (!$this->isAllowed($order)) {
+            throw NoSuchEntityException::singleField('orderId', $order->getId());
+        }
+        return $order;
+    }
+
+    /**
+     * Checks if order is allowed for current customer
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return bool
+     */
+    protected function isAllowed(\Magento\Sales\Model\Order $order)
+    {
+        return $this->userContext->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER
+            ? $order->getCustomerId() == $this->userContext->getUserId()
+            : true;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Address.php b/app/code/Magento/Sales/Model/Resource/Order/Address.php
index f71ab9835cb..1a72291fc08 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Address.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Address.php
@@ -95,7 +95,7 @@ class Address extends \Magento\Sales\Model\Resource\Entity
             'lastname' => __('Last Name'),
             'region_id' => __('State/Province'),
             'street' => __('Street Address'),
-            'telephone' => __('Telephone'),
+            'telephone' => __('Phone Number'),
             'postcode' => __('Zip/Postal Code')
         );
         asort($attributes);
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php
index 8b77a19de46..33b3d2cb7b4 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php
@@ -23,8 +23,10 @@
  */
 namespace Magento\Sales\Model\Resource\Order;
 
-use Magento\Framework\App\Resource;
 use Magento\Framework\Stdlib\DateTime;
+use Magento\Sales\Model\Resource\Attribute;
+use Magento\Framework\App\Resource as AppResource;
+use Magento\Sales\Model\Increment as SalesIncrement;
 use Magento\Sales\Model\Resource\Entity as SalesResource;
 use Magento\Sales\Model\Resource\Order\Creditmemo\Grid as CreditmemoGrid;
 
@@ -51,4 +53,23 @@ class Creditmemo extends SalesResource
     {
         $this->_init('sales_flat_creditmemo', 'entity_id');
     }
+
+    /**
+     * Constructor
+     *
+     * @param AppResource $resource
+     * @param DateTime $dateTime
+     * @param Attribute $attribute
+     * @param SalesIncrement $salesIncrement
+     * @param CreditmemoGrid $gridAggregator
+     */
+    public function __construct(
+        AppResource $resource,
+        DateTime $dateTime,
+        Attribute $attribute,
+        SalesIncrement $salesIncrement,
+        CreditmemoGrid $gridAggregator
+    ) {
+        parent::__construct($resource, $dateTime, $attribute, $salesIncrement, $gridAggregator);
+    }
 }
diff --git a/app/code/Magento/Rss/Model/Resource/Order.php b/app/code/Magento/Sales/Model/Resource/Order/Rss/OrderStatus.php
similarity index 84%
rename from app/code/Magento/Rss/Model/Resource/Order.php
rename to app/code/Magento/Sales/Model/Resource/Order/Rss/OrderStatus.php
index a8f8edef120..005372e9f9c 100644
--- a/app/code/Magento/Rss/Model/Resource/Order.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Rss/OrderStatus.php
@@ -21,14 +21,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Model\Resource;
+namespace Magento\Sales\Model\Resource\Order\Rss;
 
 /**
  * Order Rss Resource Model
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Order
+class OrderStatus
 {
     /**
      * @var \Magento\Framework\App\Resource
@@ -51,15 +51,15 @@ class Order
      */
     public function getAllCommentCollection($orderId)
     {
-        /** @var $res \Magento\Framework\App\Resource */
-        $res = $this->_resource;
-        $read = $res->getConnection('core_read');
+        /** @var $resource \Magento\Framework\App\Resource */
+        $resource = $this->_resource;
+        $read = $resource->getConnection('core_read');
 
         $fields = array('notified' => 'is_customer_notified', 'comment', 'created_at');
         $commentSelects = array();
         foreach (array('invoice', 'shipment', 'creditmemo') as $entityTypeCode) {
-            $mainTable = $res->getTableName('sales_flat_' . $entityTypeCode);
-            $slaveTable = $res->getTableName('sales_flat_' . $entityTypeCode . '_comment');
+            $mainTable = $resource->getTableName('sales_flat_' . $entityTypeCode);
+            $slaveTable = $resource->getTableName('sales_flat_' . $entityTypeCode . '_comment');
             $select = $read->select()->from(
                 array('main' => $mainTable),
                 array('entity_id' => 'order_id', 'entity_type_code' => new \Zend_Db_Expr("'{$entityTypeCode}'"))
@@ -74,7 +74,7 @@ class Order
             $commentSelects[] = '(' . $select . ')';
         }
         $select = $read->select()->from(
-            $res->getTableName('sales_flat_order_status_history'),
+            $resource->getTableName('sales_flat_order_status_history'),
             array('entity_id' => 'parent_id', 'entity_type_code' => new \Zend_Db_Expr("'order'")) + $fields
         )->where(
             'parent_id = ?',
@@ -87,7 +87,7 @@ class Order
         $commentSelect = $read->select()->union($commentSelects, \Zend_Db_Select::SQL_UNION_ALL);
 
         $select = $read->select()->from(
-            array('orders' => $res->getTableName('sales_flat_order')),
+            array('orders' => $resource->getTableName('sales_flat_order')),
             array('increment_id')
         )->join(
             array('t' => $commentSelect),
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php
index f260907b671..1879a8ab1f0 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php
@@ -23,9 +23,9 @@
  */
 namespace Magento\Sales\Model\Resource\Order;
 
-use Magento\Framework\App\Resource;
 use Magento\Framework\Stdlib\DateTime;
 use Magento\Sales\Model\Resource\Attribute;
+use Magento\Framework\App\Resource as AppResource;
 use Magento\Sales\Model\Increment as SalesIncrement;
 use Magento\Sales\Model\Resource\Entity as SalesResource;
 use Magento\Sales\Model\Resource\Order\Shipment\Grid as ShipmentGrid;
@@ -60,4 +60,23 @@ class Shipment extends SalesResource
     {
         $this->_init('sales_flat_shipment', 'entity_id');
     }
+
+    /**
+     * Constructor
+     *
+     * @param AppResource $resource
+     * @param DateTime $dateTime
+     * @param Attribute $attribute
+     * @param SalesIncrement $salesIncrement
+     * @param ShipmentGrid $gridAggregator
+     */
+    public function __construct(
+        AppResource $resource,
+        DateTime $dateTime,
+        Attribute $attribute,
+        SalesIncrement $salesIncrement,
+        ShipmentGrid $gridAggregator
+    ) {
+        parent::__construct($resource, $dateTime, $attribute, $salesIncrement, $gridAggregator);
+    }
 }
diff --git a/app/code/Magento/Sales/Model/Rss/NewOrder.php b/app/code/Magento/Sales/Model/Rss/NewOrder.php
new file mode 100644
index 00000000000..6d763f59050
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Rss/NewOrder.php
@@ -0,0 +1,171 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Rss;
+
+use \Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class NewOrder
+ * @package Magento\Sales\Model\Rss
+ */
+class NewOrder implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Url Builder
+     *
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
+     */
+    protected $localeDate;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime
+     */
+    protected $dateTime;
+
+    /**
+     * System event manager
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * Parent layout of the block
+     *
+     * @var \Magento\Framework\View\LayoutInterface
+     */
+    protected $layout;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     * @param \Magento\Framework\Stdlib\DateTime $dateTime
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param \Magento\Framework\View\LayoutInterface $layout
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
+        \Magento\Framework\Stdlib\DateTime $dateTime,
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Framework\View\LayoutInterface $layout
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->urlBuilder = $urlBuilder;
+        $this->localeDate = $localeDate;
+        $this->dateTime = $dateTime;
+        $this->eventManager = $eventManager;
+        $this->layout = $layout;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+    }
+
+    /**
+     * Check if RSS feed allowed
+     *
+     * @return mixed
+     */
+    public function isAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * Get RSS feed items
+     *
+     * @return array
+     */
+    public function getRssData()
+    {
+        $passDate = $this->dateTime->formatDate(mktime(0, 0, 0, date('m'), date('d') - 7));
+        $newUrl = $this->rssUrlBuilder->getUrl(array('_secure' => true, '_nosecret' => true, 'type' => 'new_order'));
+        $title = __('New Orders');
+        $data = array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+
+        /** @var $order \Magento\Sales\Model\Order */
+        $order = $this->orderFactory->create();
+        /** @var $collection \Magento\Sales\Model\Resource\Order\Collection */
+        $collection = $order->getResourceCollection();
+        $collection->addAttributeToFilter('created_at', array('date' => true, 'from' => $passDate))
+            ->addAttributeToSort('created_at', 'desc');
+        $this->eventManager->dispatch('rss_order_new_collection_select', array('collection' => $collection));
+
+        $detailBlock = $this->layout->getBlockSingleton('Magento\Sales\Block\Adminhtml\Order\Details');
+        foreach ($collection as $item) {
+            $title = __('Order #%1 created at %2', $item->getIncrementId(), $this->localeDate->formatDate(
+                $item->getCreatedAt()
+            ));
+            $url = $this->urlBuilder->getUrl(
+                'sales/order/view',
+                array('_secure' => true, 'order_id' => $item->getId(), '_nosecret' => true)
+            );
+            $detailBlock->setOrder($item);
+
+            $data['entries'][] = (array('title' => $title, 'link' => $url, 'description' => $detailBlock->toHtml()));
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        return 'rss_new_orders_data';
+    }
+
+    /**
+     * @return int
+     */
+    public function getCacheLifetime()
+    {
+        return 60;
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        return array();
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Rss/OrderStatus.php b/app/code/Magento/Sales/Model/Rss/OrderStatus.php
new file mode 100644
index 00000000000..e134b478101
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Rss/OrderStatus.php
@@ -0,0 +1,237 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Rss;
+
+use \Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Class OrderStatus
+ * @package Magento\Sales\Model\Rss
+ */
+class OrderStatus implements DataProviderInterface
+{
+    /**
+     * Url Builder
+     *
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Sales\Model\Order
+     */
+    protected $order;
+
+    /**
+     * @var \Magento\Sales\Model\Resource\Order\Rss\OrderStatusFactory
+     */
+    protected $orderResourceFactory;
+
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
+     */
+    protected $localeDate;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $config;
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @param \Magento\Framework\ObjectManager $objectManager
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @param \Magento\Sales\Model\Resource\Order\Rss\OrderStatusFactory $orderResourceFactory
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManager $objectManager,
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\App\RequestInterface $request,
+        \Magento\Sales\Model\Resource\Order\Rss\OrderStatusFactory $orderResourceFactory,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+    ) {
+        $this->objectManager = $objectManager;
+        $this->urlBuilder = $urlBuilder;
+        $this->request = $request;
+        $this->orderResourceFactory = $orderResourceFactory;
+        $this->localeDate = $localeDate;
+        $this->orderFactory = $orderFactory;
+        $this->config = $scopeConfig;
+    }
+
+    /**
+     * Check if RSS feed allowed
+     *
+     * @return bool
+     */
+    public function isAllowed ()
+    {
+        if ($this->config->getValue('rss/order/status', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return array
+     */
+    public function getRssData()
+    {
+        $this->order = $this->getOrder();
+        if (is_null($this->order)) {
+            throw new \InvalidArgumentException('Order not found.');
+        }
+        return array_merge($this->getHeader(), $this->getEntries());
+    }
+
+    /**
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        $order = $this->getOrder();
+        return 'rss_order_status_data_' . md5($order->getId() . $order->getIncrementId() . $order->getCustomerId());
+    }
+
+    /**
+     * @return int
+     */
+    public function getCacheLifetime()
+    {
+        return 600;
+    }
+
+    /**
+     * @return \Magento\Sales\Model\Order
+     */
+    protected function getOrder()
+    {
+        if ($this->order) {
+            return $this->order;
+        }
+
+        $data = json_decode(base64_decode((string)$this->request->getParam('data')), true);
+        if (!is_array($data)) {
+            return null;
+        }
+
+        if (!isset($data['order_id']) || !isset($data['increment_id']) || !isset($data['customer_id'])) {
+            return null;
+        }
+
+        /** @var $order \Magento\Sales\Model\Order */
+        $order = $this->orderFactory->create();
+        $order->load($data['order_id']);
+
+        if ($order->getIncrementId() != $data['increment_id'] || $order->getCustomerId() != $data['customer_id']) {
+            $order = null;
+        }
+        $this->order = $order;
+
+        return $this->order;
+    }
+
+    /**
+     * Get RSS feed items
+     *
+     * @return array
+     */
+    protected function getEntries()
+    {
+        /** @var $resourceModel \Magento\Sales\Model\Resource\Order\Rss\OrderStatus */
+        $resourceModel = $this->orderResourceFactory->create();
+        $results = $resourceModel->getAllCommentCollection($this->order->getId());
+        $entries = array();
+        if ($results) {
+            foreach ($results as $result) {
+                $urlAppend = 'view';
+                $type = $result['entity_type_code'];
+                if ($type && $type != 'order') {
+                    $urlAppend = $type;
+                }
+                $type = __(ucwords($type));
+                $title = __('Details for %1 #%2', $type, $result['increment_id']);
+                $description = '<p>' . __('Notified Date: %1', $this->localeDate->formatDate($result['created_at']))
+                    . '<br/>'
+                    . __('Comment: %1<br/>', $result['comment']) . '</p>';
+                $url = $this->urlBuilder->getUrl(
+                    'sales/order/' . $urlAppend,
+                    array('order_id' => $this->order->getId())
+                );
+                $entries[] = array('title' => $title, 'link' => $url, 'description' => $description);
+            }
+        }
+        $title = __('Order #%1 created at %2', $this->order->getIncrementId(), $this->localeDate->formatDate(
+            $this->order->getCreatedAt()
+        ));
+        $url = $this->urlBuilder->getUrl('sales/order/view', array('order_id' => $this->order->getId()));
+        $description = '<p>' . __('Current Status: %1<br/>', $this->order->getStatusLabel()) .
+            __('Total: %1<br/>', $this->order->formatPrice($this->order->getGrandTotal())) . '</p>';
+
+        $entries[] = array('title' => $title, 'link' => $url, 'description' => $description);
+
+        return array('entries' => $entries);
+    }
+
+    /**
+     * Get data for Header esction of RSS feed
+     *
+     * @return array
+     */
+    protected function getHeader()
+    {
+        $title = __('Order # %1 Notification(s)', $this->order->getIncrementId());
+        $newUrl = $this->urlBuilder->getUrl('sales/order/view', array('order_id' => $this->order->getId()));
+
+        return array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        return array();
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Service/Quote.php b/app/code/Magento/Sales/Model/Service/Quote.php
old mode 100755
new mode 100644
index 4614bb1f2d0..2555c195b18
--- a/app/code/Magento/Sales/Model/Service/Quote.php
+++ b/app/code/Magento/Sales/Model/Service/Quote.php
@@ -207,7 +207,7 @@ class Quote
                 ->setAddresses($addresses)
                 ->create();
             if ($customerData->getId()) {
-                $this->_customerAccountService->updateCustomer($customerDetails);
+                $this->_customerAccountService->updateCustomer($customerData->getId(), $customerDetails);
             } else { //for new customers
                 $customerData = $this->_customerAccountService->createCustomerWithPasswordHash(
                     $customerDetails,
diff --git a/app/code/Magento/Sales/Service/V1/Data/OrderPayment.php b/app/code/Magento/Sales/Service/V1/Data/OrderPayment.php
index 905811baca4..f38b6dc5fe8 100644
--- a/app/code/Magento/Sales/Service/V1/Data/OrderPayment.php
+++ b/app/code/Magento/Sales/Service/V1/Data/OrderPayment.php
@@ -108,7 +108,7 @@ class OrderPayment extends DataObject
     /**
      * Returns additional_information
      *
-     * @return string
+     * @return string[]
      */
     public function getAdditionalInformation()
     {
diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json
index 11a1592eeeb..46bc9944d9b 100644
--- a/app/code/Magento/Sales/composer.json
+++ b/app/code/Magento/Sales/composer.json
@@ -3,31 +3,31 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-authorization": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-sales-rule": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-gift-message": "0.1.0-alpha96",
-        "magento/module-reports": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-wishlist": "0.1.0-alpha96",
-        "magento/module-email": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-authorization": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-sales-rule": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-gift-message": "0.1.0-alpha97",
+        "magento/module-reports": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-wishlist": "0.1.0-alpha97",
+        "magento/module-email": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Index/etc/adminhtml/di.xml b/app/code/Magento/Sales/etc/adminhtml/di.xml
similarity index 84%
rename from app/code/Magento/Index/etc/adminhtml/di.xml
rename to app/code/Magento/Sales/etc/adminhtml/di.xml
index 5805634b012..97317ecabac 100644
--- a/app/code/Magento/Index/etc/adminhtml/di.xml
+++ b/app/code/Magento/Sales/etc/adminhtml/di.xml
@@ -24,10 +24,10 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <type name="Magento\Framework\Notification\MessageList">
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
         <arguments>
-            <argument name="messages" xsi:type="array">
-                <item name="indexer" xsi:type="string">Magento\Index\Model\System\Message\IndexOutdated</item>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="new_order" xsi:type="string">Magento\Sales\Model\Rss\NewOrder</item>
             </argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/Sales/etc/adminhtml/system.xml b/app/code/Magento/Sales/etc/adminhtml/system.xml
index de77855178a..9482c3bc435 100644
--- a/app/code/Magento/Sales/etc/adminhtml/system.xml
+++ b/app/code/Magento/Sales/etc/adminhtml/system.xml
@@ -380,5 +380,14 @@
                 </field>
             </group>
         </section>
+        <section id="rss">
+            <group id="order" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Order</label>
+                <field id="status" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Customer Order Status Notification</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
+                </field>
+            </group>
+        </section>
     </system>
 </config>
diff --git a/app/code/Magento/Sales/etc/catalog_attributes.xml b/app/code/Magento/Sales/etc/catalog_attributes.xml
index 841b36ed79c..2c5ce2a5050 100644
--- a/app/code/Magento/Sales/etc/catalog_attributes.xml
+++ b/app/code/Magento/Sales/etc/catalog_attributes.xml
@@ -42,8 +42,5 @@
         <attribute name="special_price"/>
         <attribute name="cost"/>
         <attribute name="gift_message_available"/>
-        <attribute name="msrp_enabled"/>
-        <attribute name="msrp"/>
-        <attribute name="msrp_display_actual_price_type"/>
     </group>
 </config>
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index 8e4b14a1f75..b8ed1b169b0 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -96,4 +96,11 @@
     <type name="Magento\Sales\Controller\OrderInterface">
         <plugin name="authentication" type="\Magento\Sales\Controller\Order\Plugin\Authentication"/>
     </type>
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
+        <arguments>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="order_status" xsi:type="string">Magento\Sales\Model\Rss\OrderStatus</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/etc/frontend/events.xml b/app/code/Magento/Sales/etc/frontend/events.xml
index 643294e1f54..bea720e8c9e 100644
--- a/app/code/Magento/Sales/etc/frontend/events.xml
+++ b/app/code/Magento/Sales/etc/frontend/events.xml
@@ -30,7 +30,4 @@
     <event name="sales_quote_address_collect_totals_after">
         <observer name="sales_customer_validate_vat_number" instance="Magento\Sales\Model\Observer\Frontend\Quote\RestoreCustomerGroupId" method="execute" />
     </event>
-    <event name="sales_quote_collect_totals_after">
-        <observer name="catalog_msrp" instance="Magento\Sales\Model\Observer\Frontend\Quote\SetCanApplyMsrp" method="execute" />
-    </event>
 </config>
diff --git a/app/code/Magento/Sales/etc/sales.xml b/app/code/Magento/Sales/etc/sales.xml
index 35fb3bc9724..36f24f63227 100644
--- a/app/code/Magento/Sales/etc/sales.xml
+++ b/app/code/Magento/Sales/etc/sales.xml
@@ -29,7 +29,6 @@
             <item name="nominal" instance="Magento\Sales\Model\Quote\Address\Total\Nominal" sort_order="50"/>
             <item name="subtotal" instance="Magento\Sales\Model\Quote\Address\Total\Subtotal" sort_order="100"/>
             <item name="shipping" instance="Magento\Sales\Model\Quote\Address\Total\Shipping" sort_order="250"/>
-            <item name="msrp" instance="Magento\Sales\Model\Quote\Address\Total\Msrp" sort_order="600"/>
             <item name="grand_total" instance="Magento\Sales\Model\Quote\Address\Total\Grand" sort_order="550"/>
         </group>
         <group name="nominal_totals">
diff --git a/app/code/Magento/Sales/etc/webapi_rest/di.xml b/app/code/Magento/Sales/etc/webapi_rest/di.xml
index 278cf983026..f345c03e02d 100644
--- a/app/code/Magento/Sales/etc/webapi_rest/di.xml
+++ b/app/code/Magento/Sales/etc/webapi_rest/di.xml
@@ -27,4 +27,7 @@
     <type name="Magento\Sales\Model\QuoteRepository">
         <plugin name="authorization" type="\Magento\Sales\Model\QuoteRepository\Plugin\Authorization" />
     </type>
+    <type name="Magento\Sales\Model\OrderRepository">
+        <plugin name="authorization" type="\Magento\Sales\Model\OrderRepository\Plugin\Authorization" />
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/etc/webapi_soap/di.xml b/app/code/Magento/Sales/etc/webapi_soap/di.xml
index 278cf983026..f345c03e02d 100644
--- a/app/code/Magento/Sales/etc/webapi_soap/di.xml
+++ b/app/code/Magento/Sales/etc/webapi_soap/di.xml
@@ -27,4 +27,7 @@
     <type name="Magento\Sales\Model\QuoteRepository">
         <plugin name="authorization" type="\Magento\Sales\Model\QuoteRepository\Plugin\Authorization" />
     </type>
+    <type name="Magento\Sales\Model\OrderRepository">
+        <plugin name="authorization" type="\Magento\Sales\Model\OrderRepository\Plugin\Authorization" />
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/sql/sales_setup/install-1.6.0.0.php b/app/code/Magento/Sales/sql/sales_setup/install-1.6.0.0.php
index 7f353ff784e..4f14d633525 100644
--- a/app/code/Magento/Sales/sql/sales_setup/install-1.6.0.0.php
+++ b/app/code/Magento/Sales/sql/sales_setup/install-1.6.0.0.php
@@ -1143,7 +1143,7 @@ $table = $installer->getConnection()->newTable(
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
     255,
     array(),
-    'Telephone'
+    'Phone Number'
 )->addColumn(
     'country_id',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
@@ -4404,7 +4404,7 @@ $table = $installer->getConnection()->newTable(
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
     255,
     array(),
-    'Telephone'
+    'Phone Number'
 )->addColumn(
     'fax',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
index c1b114f7706..9bb9a23d8f9 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml
@@ -31,19 +31,13 @@
             <argument translate="true" name="id" xsi:type="string">order-header</argument>
         </action>
     </referenceBlock>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-adminhtml-sales-js-bootstrap-order-create-index-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Sales::js/bootstrap/order-create-index.js</argument>
-            </arguments>
-        </block>
+    <referenceContainer name="after.body.start">
         <block class="Magento\Backend\Block\Template" name="optional_zip_countries" as="optional_zip_countries" template="Magento_Directory::js/optional_zip_countries.phtml"/>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    </referenceContainer>
+    <head>
+        <link src="Magento_Sales::js/bootstrap/order-create-index.js"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
     <referenceContainer name="js">
         <block class="Magento\Backend\Block\Template" template="Magento_Sales::order/create/js.phtml" name="create"/>
     </referenceContainer>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
index a1736952fe9..165fd71b57d 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
@@ -214,6 +214,9 @@
                     </arguments>
                 </block>
             </block>
+            <block class="Magento\Framework\View\Element\Text\ListText" name="grid.bottom.links">
+                <block class="Magento\Sales\Block\Adminhtml\Rss\Order\Grid\Link" name="grid.rss.link"/>
+            </block>
         </block>
     </referenceBlock>
 </page>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
index cde71209712..0eb9462c8a6 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
@@ -24,13 +24,9 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-adminhtml-sales-js-bootstrap-order-create-index-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Sales::js/bootstrap/order-create-index.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_Sales::js/bootstrap/order-create-index.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Sales\Block\Adminhtml\Order\View" name="sales_order_edit"/>
     </referenceContainer>
@@ -68,7 +64,7 @@
                 <argument name="name" xsi:type="string">order_invoices</argument>
                 <argument name="block" xsi:type="string">sales_order_invoice.grid.container</argument>
             </action>
-        <block class = "Magento\Sales\Block\Adminhtml\Order\View\Tab\Creditmemos" name="sales_order_creditmemo.grid.container"/>
+            <block class = "Magento\Sales\Block\Adminhtml\Order\View\Tab\Creditmemos" name="sales_order_creditmemo.grid.container"/>
             <action method="addTab">
                 <argument name="name" xsi:type="string">order_creditmemos</argument>
                 <argument name="block" xsi:type="string">sales_order_creditmemo.grid.container</argument>
diff --git a/app/code/Magento/Rss/view/frontend/templates/order/details.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml
similarity index 100%
rename from app/code/Magento/Rss/view/frontend/templates/order/details.phtml
rename to app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/rss/order/grid/link.phtml b/app/code/Magento/Sales/view/adminhtml/templates/rss/order/grid/link.phtml
new file mode 100644
index 00000000000..38e90694c04
--- /dev/null
+++ b/app/code/Magento/Sales/view/adminhtml/templates/rss/order/grid/link.phtml
@@ -0,0 +1,29 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+/** @var $this \Magento\Sales\Block\Adminhtml\Rss\Order\Grid\Link */
+?>
+<?php if ($this->isRssAllowed() && $this->getLink()): ?>
+<a href="<?php echo $this->getLink() ?>" class="link-feed"><?php echo $this->getLabel() ?></a>
+<?php endif; ?>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_guest_creditmemo.xml b/app/code/Magento/Sales/view/frontend/layout/sales_guest_creditmemo.xml
index 36ab59e11d2..96e1113168a 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_guest_creditmemo.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_guest_creditmemo.xml
@@ -44,5 +44,8 @@
             </block>
         </block>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <update handle="sales_order_guest_info_links"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_guest_invoice.xml b/app/code/Magento/Sales/view/frontend/layout/sales_guest_invoice.xml
index c845e7382d4..e650152f108 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_guest_invoice.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_guest_invoice.xml
@@ -44,5 +44,8 @@
             </block>
         </block>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <update handle="sales_order_guest_info_links"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_guest_shipment.xml b/app/code/Magento/Sales/view/frontend/layout/sales_guest_shipment.xml
index f5a2ff1c5fe..cb18545d9d6 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_guest_shipment.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_guest_shipment.xml
@@ -29,5 +29,8 @@
             <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/>
         </block>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <update handle="sales_order_guest_info_links"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_guest_view.xml b/app/code/Magento/Sales/view/frontend/layout/sales_guest_view.xml
index 11efb475646..3e8dd9f3c34 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_guest_view.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_guest_view.xml
@@ -32,8 +32,7 @@
         </container>
     </referenceContainer>
     <referenceContainer name="content">
-        <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"/>
-        <block class="Magento\Sales\Block\Order\View" name="sales.order.view" after="sales.order.info" cacheable="false">
+        <block class="Magento\Sales\Block\Order\View" name="sales.order.view" cacheable="false">
             <block class="Magento\Sales\Block\Order\Items" name="order_items" template="order/items.phtml">
                 <block class="Magento\Framework\View\Element\RendererList" name="sales.order.items.renderers" as="renderer.list" />
                 <block class="Magento\Sales\Block\Order\Totals" name="order_totals" template="order/totals.phtml">
@@ -45,6 +44,10 @@
                 </block>
             </block>
         </block>
+        <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info"/>
+    </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
     </referenceContainer>
     <update handle="sales_order_guest_info_links"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml
index 0b89a18b9db..716d4983412 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_creditmemo.xml
@@ -49,6 +49,9 @@
             </block>
         </block>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <update handle="sales_order_info_links"/>
     <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Core::template.phtml"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml
index 50ba2bf8de0..f10a51b09d1 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_invoice.xml
@@ -50,6 +50,9 @@
         </block>
         <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info" after="-" />
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <update handle="sales_order_info_links"/>
     <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Core::template.phtml"/>
 </page>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml
index ee3aafe4591..53a6acf1a68 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_shipment.xml
@@ -32,6 +32,9 @@
             <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/>
         </container>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <referenceContainer name="content">
         <block class="Magento\Sales\Block\Order\Info" as="info" name="sales.order.info" after="sales.order.shipment" />
     </referenceContainer>
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml
index 22fe53c376d..3426274e70b 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_view.xml
@@ -34,6 +34,9 @@
             <block class="Magento\Sales\Block\Order\Info\Buttons" as="buttons" name="sales.order.info.buttons" cacheable="false"/>
         </container>
     </referenceContainer>
+    <referenceContainer name="sales.order.info.buttons">
+        <block class="Magento\Sales\Block\Order\Info\Buttons\Rss" as="buttons.rss" name="sales.order.info.buttons.rss" cacheable="false"/>
+    </referenceContainer>
     <referenceContainer name="content">
         <block class="Magento\Sales\Block\Order\View" name="order.comments" template="order/order_comments.phtml" before="sales.order.info.links" />
         <block class="Magento\Sales\Block\Order\View" name="sales.order.view" cacheable="false">
diff --git a/app/code/Magento/Sales/view/frontend/templates/items/price/row.phtml b/app/code/Magento/Sales/view/frontend/templates/items/price/row.phtml
index 7768e182d3a..f3354f7cd0a 100644
--- a/app/code/Magento/Sales/view/frontend/templates/items/price/row.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/items/price/row.phtml
@@ -25,7 +25,7 @@
 /** @var \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer $this */
 $_item = $this->getItem();
 ?>
-<span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+<span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
     <span class="cart-price">
         <?php echo $this->getOrder()->formatPrice($this->getItem()->getRowTotal()) ?>
     </span>
diff --git a/app/code/Magento/Sales/view/frontend/templates/items/price/unit.phtml b/app/code/Magento/Sales/view/frontend/templates/items/price/unit.phtml
index 3ee30e95401..7075d0df03d 100644
--- a/app/code/Magento/Sales/view/frontend/templates/items/price/unit.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/items/price/unit.phtml
@@ -25,7 +25,7 @@
 /** @var \Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer $this */
 $_item = $this->getItem();
 ?>
-<span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+<span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
     <span class="cart-price">
         <?php echo $this->getOrder()->formatPrice($this->getItem()->getPrice()) ?>
     </span>
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/info/buttons/rss.phtml b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons/rss.phtml
new file mode 100644
index 00000000000..87acdf56c07
--- /dev/null
+++ b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons/rss.phtml
@@ -0,0 +1,31 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+/** @var $this \Magento\Sales\Block\Order\Info\Buttons\Rss */
+?>
+<?php if ($this->isRssAllowed() && $this->getLink()): ?>
+<a href="<?php echo $this->getLink() ?>" class="action rss">
+    <span><?php echo $this->getLabel() ?></span>
+</a>
+<?php endif; ?>
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml
index 2677ee2b0fe..0ca19d4cd61 100644
--- a/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/order/items/renderer/default.phtml
@@ -70,7 +70,6 @@ $_item = $this->getItem();
     </td>
     <td class="col sku" data-th="<?php echo $this->escapeHtml(__('SKU')); ?>"><?php echo $this->prepareSku($this->getSku()) ?></td>
     <td class="col price" data-th="<?php echo $this->escapeHtml(__('Price')); ?>">
-
         <?php echo $this->getItemPriceHtml(); ?>
     </td>
     <td class="col qty" data-th="<?php echo $this->escapeHtml(__('Qty')); ?>">
diff --git a/app/code/Magento/SalesRule/Block/Rss/Discounts.php b/app/code/Magento/SalesRule/Block/Rss/Discounts.php
new file mode 100644
index 00000000000..53b24bc09be
--- /dev/null
+++ b/app/code/Magento/SalesRule/Block/Rss/Discounts.php
@@ -0,0 +1,191 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Block\Rss;
+
+use Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Review form block
+ */
+class Discounts extends \Magento\Framework\View\Element\AbstractBlock implements DataProviderInterface
+{
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\SalesRule\Model\Rss\Discounts
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Http\Context
+     */
+    protected $httpContext;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\App\Http\Context $httpContext
+     * @param \Magento\SalesRule\Model\Rss\Discounts $rssModel
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\App\Http\Context $httpContext,
+        \Magento\SalesRule\Model\Rss\Discounts $rssModel,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        $this->storeManager = $context->getStoreManager();
+        $this->rssModel = $rssModel;
+        $this->httpContext = $httpContext;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _construct()
+    {
+        $this->setCacheKey('rss_catalog_salesrule_' . $this->getStoreId() . '_' . $this->getCustomerGroupId());
+        parent::_construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRssData()
+    {
+        $storeId = $this->getStoreId();
+        $storeModel = $this->storeManager->getStore($storeId);
+        $websiteId = $storeModel->getWebsiteId();
+        $customerGroupId = $this->getCustomerGroupId();
+        $url = $this->_urlBuilder->getUrl('');
+        $newUrl = $this->rssUrlBuilder->getUrl(array(
+            'type' => 'discounts',
+            'store_id' => $storeId,
+            'cid' => $customerGroupId
+        ));
+        $title = __('%1 - Discounts and Coupons', $storeModel->getName());
+        $lang = $this->_scopeConfig->getValue(
+            'general/locale/code',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $storeModel
+        );
+
+        $data = array(
+            'title' => $title,
+            'description' => $title,
+            'link' => $newUrl,
+            'charset' => 'UTF-8',
+            'language' => $lang
+        );
+
+        /** @var $rule \Magento\SalesRule\Model\Rule */
+        foreach ($this->rssModel->getDiscountCollection($websiteId, $customerGroupId) as $rule) {
+
+            $toDate = $rule->getToDate()
+                ? '<br/>Discount End Date: ' . $this->formatDate($rule->getToDate(), 'medium')
+                : '';
+            $couponCode = $rule->getCouponCode() ? '<br/> Coupon Code: ' . $rule->getCouponCode() : '';
+
+            $description = sprintf(
+                '<table><tr><td style="text-decoration:none;">%s<br/>Discount Start Date: %s %s %s</td></tr></table>',
+                $rule->getDescription(),
+                $this->formatDate($rule->getFromDate(), 'medium'),
+                $toDate,
+                $couponCode
+            );
+
+            $data['entries'][] = array('title' => $rule->getName(), 'description' => $description, 'link' => $url);
+        }
+
+        return $data;
+    }
+
+    /**
+     * Get customer group id
+     *
+     * @return int
+     */
+    protected function getCustomerGroupId()
+    {
+        $customerGroupId =   (int) $this->getRequest()->getParam('cid');
+        if ($customerGroupId == null) {
+            $customerGroupId = $this->httpContext->getValue(\Magento\Customer\Helper\Data::CONTEXT_GROUP);
+        }
+        return $customerGroupId;
+    }
+
+    /**
+     * @return int
+     */
+    protected function getStoreId()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        if ($storeId == null) {
+            $storeId = $this->storeManager->getStore()->getId();
+        }
+        return $storeId;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCacheLifetime()
+    {
+        return 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag(
+            'rss/catalog/discounts',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFeeds()
+    {
+        $data = array();
+        if ($this->isAllowed()) {
+            $url = $this->rssUrlBuilder->getUrl(array(
+                    'type' => 'discounts',
+                    'store_id' => $this->getStoreId(),
+                    'cid' => $this->getCustomerGroupId()
+            ));
+            $data = array('label' => __('Coupons/Discounts'), 'link' => $url);
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/SalesRule/Model/Rss/Discounts.php b/app/code/Magento/SalesRule/Model/Rss/Discounts.php
new file mode 100644
index 00000000000..8a00d801bd4
--- /dev/null
+++ b/app/code/Magento/SalesRule/Model/Rss/Discounts.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Model\Rss;
+
+/**
+ * Class Discounts
+ * @package Magento\SalesRule\Model\Rss
+ */
+class Discounts
+{
+    /**
+     * @var \Magento\SalesRule\Model\Resource\Rule\CollectionFactory
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime
+     */
+    protected $dateTime;
+
+    /**
+     * @param \Magento\Framework\Stdlib\DateTime $dateTime
+     * @param \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory
+     */
+    public function __construct(
+        \Magento\Framework\Stdlib\DateTime $dateTime,
+        \Magento\SalesRule\Model\Resource\Rule\CollectionFactory $collectionFactory
+    ) {
+        $this->dateTime = $dateTime;
+        $this->collectionFactory = $collectionFactory;
+    }
+
+    /**
+     * @param int $websiteId
+     * @param int $customerGroupId
+     * @return \Magento\SalesRule\Model\Resource\Rule\Collection
+     */
+    public function getDiscountCollection($websiteId, $customerGroupId)
+    {
+        /** @var $collection \Magento\SalesRule\Model\Resource\Rule\Collection */
+        $collection = $this->collectionFactory->create();
+        $collection->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $this->dateTime->now(true))
+            ->addFieldToFilter('is_rss', 1)
+            ->setOrder('from_date', 'desc');
+        $collection->load();
+        return $collection;
+    }
+}
diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json
index 3b59c828b0b..19d2b6b920a 100644
--- a/app/code/Magento/SalesRule/composer.json
+++ b/app/code/Magento/SalesRule/composer.json
@@ -3,26 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-rule": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-reports": "0.1.0-alpha96",
-        "magento/module-catalog-rule": "0.1.0-alpha96",
-        "magento/module-widget": "0.1.0-alpha96",
-        "magento/module-cron": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-rule": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-reports": "0.1.0-alpha97",
+        "magento/module-catalog-rule": "0.1.0-alpha97",
+        "magento/module-widget": "0.1.0-alpha97",
+        "magento/module-cron": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/SalesRule/etc/adminhtml/system.xml b/app/code/Magento/SalesRule/etc/adminhtml/system.xml
index f5b67efce90..2f4dd4572c0 100644
--- a/app/code/Magento/SalesRule/etc/adminhtml/system.xml
+++ b/app/code/Magento/SalesRule/etc/adminhtml/system.xml
@@ -54,5 +54,13 @@
                 </field>
             </group>
         </section>
+        <section id="rss">
+            <group id="catalog">
+                <field id="discounts" translate="label" type="select" sortOrder="12" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Coupons/Discounts</label>
+                    <source_model>Magento\Backend\Model\Config\Source\Enabledisable</source_model>
+                </field>
+            </group>
+        </section>
     </system>
 </config>
diff --git a/app/code/Magento/SalesRule/etc/di.xml b/app/code/Magento/SalesRule/etc/di.xml
index 964c0212e85..3a553a18754 100644
--- a/app/code/Magento/SalesRule/etc/di.xml
+++ b/app/code/Magento/SalesRule/etc/di.xml
@@ -35,4 +35,11 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
+        <arguments>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="discounts" xsi:type="string">Magento\SalesRule\Block\Rss\Discounts</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml
index 9e9c3db7462..cbab317e559 100644
--- a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml
+++ b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml
@@ -24,14 +24,6 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <action method="setCanLoadRulesJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-    </referenceBlock>
     <referenceContainer name="left">
         <block class="Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tabs" name="promo_quote_edit_tabs">
             <block class="Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab\Main" name="promo_quote_edit_tab_main"/>
diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json
index 8cf61460aab..976cf398f14 100644
--- a/app/code/Magento/Sendfriend/composer.json
+++ b/app/code/Magento/Sendfriend/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Shipping/Block/Order/Shipment.php b/app/code/Magento/Shipping/Block/Order/Shipment.php
index 2011584c586..bd22549f640 100644
--- a/app/code/Magento/Shipping/Block/Order/Shipment.php
+++ b/app/code/Magento/Shipping/Block/Order/Shipment.php
@@ -76,10 +76,7 @@ class Shipment extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
-        }
+        $this->pageConfig->setTitle(__('Order # %1', $this->getOrder()->getRealOrderId()));
         $this->setChild('payment_info', $this->_paymentHelper->getInfoBlock($this->getOrder()->getPayment()));
     }
 
diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json
index c5b41daf742..aa103114a72 100644
--- a/app/code/Magento/Shipping/composer.json
+++ b/app/code/Magento/Shipping/composer.json
@@ -3,23 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-contact": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-payment": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-contact": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-payment": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "ext-gd": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Sitemap/Block/Adminhtml/Edit/Form.php b/app/code/Magento/Sitemap/Block/Adminhtml/Edit/Form.php
index a4ea2096d8b..41c7da86708 100644
--- a/app/code/Magento/Sitemap/Block/Adminhtml/Edit/Form.php
+++ b/app/code/Magento/Sitemap/Block/Adminhtml/Edit/Form.php
@@ -102,7 +102,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'label' => __('Path'),
                 'name' => 'sitemap_path',
                 'required' => true,
-                'note' => __('example: "sitemap/" or "/" for base path (path must be writeable)'),
+                'note' => __('example: "/sitemap/" or "/" for base path (path must be writeable)'),
                 'value' => $model->getSitemapPath()
             )
         );
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
index a5dce81be68..f7a5909ced6 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
@@ -44,12 +44,13 @@ class Save extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
 
             //validate path to generate
             if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) {
+                $data['sitemap_path'] = '/' . ltrim($data['sitemap_path'], '/');
                 $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename'];
                 /** @var $validator \Magento\Core\Model\File\Validator\AvailablePath */
                 $validator = $this->_objectManager->create('Magento\Core\Model\File\Validator\AvailablePath');
-                /** @var $helper \Magento\Catalog\Helper\Catalog */
-                $helper = $this->_objectManager->get('Magento\Catalog\Helper\Catalog');
-                $validator->setPaths($helper->getSitemapValidPaths());
+                /** @var $helper \Magento\Sitemap\Helper\Data */
+                $helper = $this->_objectManager->get('Magento\Sitemap\Helper\Data');
+                $validator->setPaths($helper->getValidPaths());
                 if (!$validator->isValid($path)) {
                     foreach ($validator->getMessages() as $message) {
                         $this->messageManager->addError($message);
diff --git a/app/code/Magento/Sitemap/Helper/Data.php b/app/code/Magento/Sitemap/Helper/Data.php
index 786978c81a3..e4a42f16144 100644
--- a/app/code/Magento/Sitemap/Helper/Data.php
+++ b/app/code/Magento/Sitemap/Helper/Data.php
@@ -28,8 +28,20 @@
  */
 namespace Magento\Sitemap\Helper;
 
+use Magento\Store\Model\ScopeInterface;
+
 class Data extends \Magento\Framework\App\Helper\AbstractHelper
 {
+    /**
+     * Config path to sitemap valid paths
+     */
+    const XML_PATH_SITEMAP_VALID_PATHS = 'sitemap/file/valid_paths';
+
+    /**
+     * Config path to valid file paths
+     */
+    const XML_PATH_PUBLIC_FILES_VALID_PATHS = 'general/file/public_files_valid_paths';
+
     /**#@+
      * Limits xpath config settings
      */
@@ -98,7 +110,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return $this->_scopeConfig->getValue(
             self::XML_PATH_MAX_LINES,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -113,7 +125,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return $this->_scopeConfig->getValue(
             self::XML_PATH_MAX_FILE_SIZE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -128,7 +140,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_CATEGORY_CHANGEFREQ,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -143,7 +155,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_PRODUCT_CHANGEFREQ,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -158,7 +170,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_PAGE_CHANGEFREQ,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -173,7 +185,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_CATEGORY_PRIORITY,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -188,7 +200,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_PRODUCT_PRIORITY,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -203,7 +215,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_PAGE_PRIORITY,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -218,7 +230,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return $this->_scopeConfig->getValue(
             self::XML_PATH_SUBMISSION_ROBOTS,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
@@ -233,8 +245,21 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     {
         return (string)$this->_scopeConfig->getValue(
             self::XML_PATH_PRODUCT_IMAGES_INCLUDE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $storeId
         );
     }
+
+    /**
+     * Get list valid paths for generate a sitemap XML file
+     *
+     * @return string[]
+     */
+    public function getValidPaths()
+    {
+        return array_merge(
+            $this->_scopeConfig->getValue(self::XML_PATH_SITEMAP_VALID_PATHS, ScopeInterface::SCOPE_STORE),
+            $this->_scopeConfig->getValue(self::XML_PATH_PUBLIC_FILES_VALID_PATHS, ScopeInterface::SCOPE_STORE)
+        );
+    }
 }
diff --git a/app/code/Magento/Sitemap/Model/Resource/Catalog/Category.php b/app/code/Magento/Sitemap/Model/Resource/Catalog/Category.php
index b081b5ec32a..57b0b71c2e3 100644
--- a/app/code/Magento/Sitemap/Model/Resource/Catalog/Category.php
+++ b/app/code/Magento/Sitemap/Model/Resource/Catalog/Category.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Sitemap\Model\Resource\Catalog;
 
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
 /**
  * Sitemap resource catalog collection model
  *
@@ -94,31 +96,29 @@ class Category extends \Magento\Framework\Model\Resource\Db\AbstractDb
             return false;
         }
 
-        $this->_select = $this->_getWriteAdapter()->select()->from(
+        $adapter = $this->_getWriteAdapter();
+
+        $this->_select = $adapter->select()->from(
             $this->getMainTable()
         )->where(
             $this->getIdFieldName() . '=?',
             $store->getRootCategoryId()
         );
-        $categoryRow = $this->_getWriteAdapter()->fetchRow($this->_select);
+        $categoryRow = $adapter->fetchRow($this->_select);
 
         if (!$categoryRow) {
             return false;
         }
 
-        $urConditions = array(
-            'e.entity_id = ur.category_id',
-            $this->_getWriteAdapter()->quoteInto('ur.store_id=?', $store->getId()),
-            'ur.product_id IS NULL',
-            $this->_getWriteAdapter()->quoteInto('ur.is_system=?', 1)
-        );
-        $this->_select = $this->_getWriteAdapter()->select()->from(
-            array('e' => $this->getMainTable()),
-            array($this->getIdFieldName(), 'updated_at')
+        $this->_select = $adapter->select()->from(
+            ['e' => $this->getMainTable()],
+            [$this->getIdFieldName(), 'updated_at']
         )->joinLeft(
-            array('ur' => $this->getTable('core_url_rewrite')),
-            join(' AND ', $urConditions),
-            array('url' => 'request_path')
+            ['url_rewrite' => $this->getTable('url_rewrite')],
+            'e.entity_id = url_rewrite.entity_id AND url_rewrite.is_autogenerated = 1'
+            . $adapter->quoteInto(' AND url_rewrite.store_id = ?', $store->getId())
+            . $adapter->quoteInto(' AND url_rewrite.entity_type = ?', CategoryUrlRewriteGenerator::ENTITY_TYPE),
+            ['url' => 'request_path']
         )->where(
             'e.path LIKE ?',
             $categoryRow['path'] . '/%'
@@ -126,7 +126,7 @@ class Category extends \Magento\Framework\Model\Resource\Db\AbstractDb
 
         $this->_addFilter($storeId, 'is_active', 1);
 
-        $query = $this->_getWriteAdapter()->query($this->_select);
+        $query = $adapter->query($this->_select);
         while ($row = $query->fetch()) {
             $category = $this->_prepareCategory($row);
             $categories[$category->getId()] = $category;
diff --git a/app/code/Magento/Sitemap/Model/Resource/Catalog/Product.php b/app/code/Magento/Sitemap/Model/Resource/Catalog/Product.php
index 4efb8c625e1..06bab65ea2c 100644
--- a/app/code/Magento/Sitemap/Model/Resource/Catalog/Product.php
+++ b/app/code/Magento/Sitemap/Model/Resource/Catalog/Product.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Sitemap\Model\Resource\Catalog;
 
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+
 /**
  * Sitemap resource product collection model
  *
@@ -269,13 +271,9 @@ class Product extends \Magento\Framework\Model\Resource\Db\AbstractDb
             return false;
         }
 
-        $urConditions = array(
-            'e.entity_id = ur.product_id',
-            'ur.category_id IS NULL',
-            $this->_getWriteAdapter()->quoteInto('ur.store_id = ?', $store->getId()),
-            $this->_getWriteAdapter()->quoteInto('ur.is_system = ?', 1)
-        );
-        $this->_select = $this->_getWriteAdapter()->select()->from(
+        $adapter = $this->_getWriteAdapter();
+
+        $this->_select = $adapter->select()->from(
             array('e' => $this->getMainTable()),
             array($this->getIdFieldName(), 'updated_at')
         )->joinInner(
@@ -283,9 +281,11 @@ class Product extends \Magento\Framework\Model\Resource\Db\AbstractDb
             'e.entity_id = w.product_id',
             array()
         )->joinLeft(
-            array('ur' => $this->getTable('core_url_rewrite')),
-            join(' AND ', $urConditions),
-            array('url' => 'request_path')
+            ['url_rewrite' => $this->getTable('url_rewrite')],
+            'e.entity_id = url_rewrite.entity_id AND url_rewrite.is_autogenerated = 1'
+            . $adapter->quoteInto(' AND url_rewrite.store_id = ?', $store->getId())
+            . $adapter->quoteInto(' AND url_rewrite.entity_type = ?', ProductUrlRewriteGenerator::ENTITY_TYPE),
+            ['url' => 'request_path']
         )->where(
             'w.website_id = ?',
             $store->getWebsiteId()
@@ -320,7 +320,7 @@ class Product extends \Magento\Framework\Model\Resource\Db\AbstractDb
             }
         }
 
-        $query = $this->_getWriteAdapter()->query($this->_select);
+        $query = $adapter->query($this->_select);
         while ($row = $query->fetch()) {
             $product = $this->_prepareProduct($row, $store->getId());
             $products[$product->getId()] = $product;
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index dd6a0d89646..cd9d94f3055 100644
--- a/app/code/Magento/Sitemap/composer.json
+++ b/app/code/Magento/Sitemap/composer.json
@@ -3,17 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog-url-rewrite": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Sitemap/etc/config.xml b/app/code/Magento/Sitemap/etc/config.xml
index 62fc8afdf37..336b3dcda2b 100644
--- a/app/code/Magento/Sitemap/etc/config.xml
+++ b/app/code/Magento/Sitemap/etc/config.xml
@@ -52,6 +52,13 @@
             <search_engines>
                 <submission_robots>0</submission_robots>
             </search_engines>
+            <file>
+                <valid_paths>
+                    <available>
+                        <any_path>/*/*.xml</any_path>
+                    </available>
+                </valid_paths>
+            </file>
         </sitemap>
     </default>
 </config>
diff --git a/app/code/Magento/Sitemap/etc/module.xml b/app/code/Magento/Sitemap/etc/module.xml
index e181bcab0dc..69a571641c3 100644
--- a/app/code/Magento/Sitemap/etc/module.xml
+++ b/app/code/Magento/Sitemap/etc/module.xml
@@ -35,6 +35,7 @@
             <module name="Magento_Eav"/>
             <module name="Magento_Cms"/>
             <module name="Magento_Backend"/>
+            <module name="Magento_CatalogUrlRewrite"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Store/Block/Store/Switcher.php b/app/code/Magento/Store/Block/Store/Switcher.php
index 1404e6503b5..6b2887f80f6 100644
--- a/app/code/Magento/Store/Block/Store/Switcher.php
+++ b/app/code/Magento/Store/Block/Store/Switcher.php
@@ -105,7 +105,11 @@ class Switcher extends \Magento\Framework\View\Element\Template
             if (!$store->getIsActive()) {
                 continue;
             }
-            $store->setLocaleCode($this->_scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store->getId()));
+            $store->setLocaleCode($this->_scopeConfig->getValue(
+                \Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $store->getId()
+            ));
             $this->_stores[$store->getGroupId()][$store->getId()] = $store;
         }
 
@@ -120,7 +124,10 @@ class Switcher extends \Magento\Framework\View\Element\Template
     public function getStoreCount()
     {
         $stores = array();
-        $localeCode = $this->_scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+        $localeCode = $this->_scopeConfig->getValue(
+            \Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
         foreach ($this->_groups as $group) {
             if (!isset($this->_stores[$group->getId()])) {
                 continue;
diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php
index edd7a335cbc..36c507d575b 100644
--- a/app/code/Magento/Store/Block/Switcher.php
+++ b/app/code/Magento/Store/Block/Switcher.php
@@ -112,7 +112,7 @@ class Switcher extends \Magento\Framework\View\Element\Template
                     continue;
                 }
                 $localeCode = $this->_scopeConfig->getValue(
-                    'general/locale/code',
+                    \Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE,
                     \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
                     $store
                 );
@@ -144,7 +144,7 @@ class Switcher extends \Magento\Framework\View\Element\Template
 
             $groups = array();
             $localeCode = $this->_scopeConfig->getValue(
-                'general/locale/code',
+                \Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE,
                 \Magento\Store\Model\ScopeInterface::SCOPE_STORE
             );
             foreach ($rawGroups as $group) {
@@ -235,6 +235,9 @@ class Switcher extends \Magento\Framework\View\Element\Template
      */
     public function getTargetStorePostData(\Magento\Store\Model\Store $store)
     {
-        return $this->_postDataHelper->getPostData($this->getHomeUrl(), array('___store' => $store->getCode()));
+        return $this->_postDataHelper->getPostData(
+            $this->getHomeUrl(),
+            ['___store' => $store->getCode(), '___from_store' => $this->getStoreCode()]
+        );
     }
 }
diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php
index 9d10c2a019c..798a0d19d25 100644
--- a/app/code/Magento/Store/Model/Store.php
+++ b/app/code/Magento/Store/Model/Store.php
@@ -23,9 +23,7 @@
  */
 namespace Magento\Store\Model;
 
-use Magento\Directory\Model\Currency\Filter;
 use Magento\Framework\Model\AbstractModel;
-use Magento\Framework\StoreManagerInterface;
 
 /**
  * Store model
@@ -327,7 +325,7 @@ class Store extends AbstractModel implements
      * @param \Magento\Core\Model\Resource\Config\Data $configDataResource
      * @param \Magento\Framework\App\Filesystem $filesystem
      * @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
-     * @param StoreManagerInterface $storeManager
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
      * @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
      * @param \Magento\Framework\Stdlib\CookieManager $cookieManager,
@@ -1120,19 +1118,10 @@ class Store extends AbstractModel implements
     /**
      * Protect delete from non admin area
      *
-     * Register indexing event before delete store
-     *
      * @return $this
      */
     protected function _beforeDelete()
     {
-        \Magento\Framework\App\ObjectManager::getInstance()->get(
-            'Magento\Index\Model\Indexer'
-        )->logEvent(
-            $this,
-            self::ENTITY,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        );
         $this->_configDataResource->clearScopeData(\Magento\Store\Model\ScopeInterface::SCOPE_STORES, $this->getId());
 
         return parent::_beforeDelete();
@@ -1150,23 +1139,6 @@ class Store extends AbstractModel implements
         return $this;
     }
 
-    /**
-     * Init indexing process after store delete commit
-     *
-     * @return $this
-     */
-    protected function _afterDeleteCommit()
-    {
-        parent::_afterDeleteCommit();
-        \Magento\Framework\App\ObjectManager::getInstance()->get(
-            'Magento\Index\Model\Indexer'
-        )->indexEvents(
-            self::ENTITY,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        );
-        return $this;
-    }
-
     /**
      * Reinit and reset Config Data
      *
diff --git a/setup/module/Magento/Config/src/Dom/ValidationException.php b/app/code/Magento/Store/Ui/DataType/Store.php
similarity index 84%
rename from setup/module/Magento/Config/src/Dom/ValidationException.php
rename to app/code/Magento/Store/Ui/DataType/Store.php
index dfd1fd906cb..fb85859d82b 100644
--- a/setup/module/Magento/Config/src/Dom/ValidationException.php
+++ b/app/code/Magento/Store/Ui/DataType/Store.php
@@ -21,12 +21,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Store\Ui\DataType;
+
+use Magento\Ui\DataType\AbstractDataType;
 
 /**
- * \Exception that should be thrown by DOM model when incoming xml is not valid.
+ * Class Store
  */
-namespace Magento\Config\Dom;
-
-class ValidationException extends \InvalidArgumentException
+class Store extends AbstractDataType
 {
+    //
 }
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index 0e66134e8ad..622ac35b3bd 100644
--- a/app/code/Magento/Store/composer.json
+++ b/app/code/Magento/Store/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-index": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-ui": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Store/etc/module.xml b/app/code/Magento/Store/etc/module.xml
index e5b8467b5b2..a898f5d68bd 100644
--- a/app/code/Magento/Store/etc/module.xml
+++ b/app/code/Magento/Store/etc/module.xml
@@ -31,7 +31,7 @@
         <depends>
             <module name="Magento_Core"/>
             <module name="Magento_Directory"/>
-            <module name="Magento_Index"/>
+            <module name="Magento_Ui"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_salesrule.xml b/app/code/Magento/Store/view/base/layout/ui_components.xml
similarity index 69%
rename from app/code/Magento/Rss/view/frontend/layout/rss_catalog_salesrule.xml
rename to app/code/Magento/Store/view/base/layout/ui_components.xml
index c30898a0820..c2d046e0e4d 100644
--- a/app/code/Magento/Rss/view/frontend/layout/rss_catalog_salesrule.xml
+++ b/app/code/Magento/Store/view/base/layout/ui_components.xml
@@ -24,7 +24,14 @@
  */
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\Salesrule" name="rss.catalog.salesrule" cacheable="false"/>
-    </container>
+    <block class="Magento\Ui\Filter\Type\Select" name="filter_store">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/select/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\DataType\Text" name="store">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/text/default.phtml</argument>
+        </arguments>
+    </block>
 </layout>
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/requirejs-config.js b/app/code/Magento/Store/view/base/requirejs-config.js
similarity index 86%
rename from app/code/Magento/ConfigurableProduct/view/frontend/requirejs-config.js
rename to app/code/Magento/Store/view/base/requirejs-config.js
index 3c0b6a3062c..98a4d16f626 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/requirejs-config.js
+++ b/app/code/Magento/Store/view/base/requirejs-config.js
@@ -22,12 +22,7 @@
  */
 
 var config = {
-    shim: {
-        'jquery.parsequery': {
-            deps: ['jquery']
-        }
-    },
     paths: {
-        'jquery.parsequery': 'jquery/jquery.parsequery'
+        'ui/template/filter/store/item': 'Magento_Store/templates/filter/store/item'
     }
-};
+};
\ No newline at end of file
diff --git a/app/code/Magento/Store/view/base/web/js/listing/filter/store.js b/app/code/Magento/Store/view/base/web/js/listing/filter/store.js
new file mode 100644
index 00000000000..b5c840579bd
--- /dev/null
+++ b/app/code/Magento/Store/view/base/web/js/listing/filter/store.js
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'Magento_Ui/js/listing/filter/abstract',
+    'underscore'
+], function (AbstractControl, _) {
+    'use strict';
+
+    /**
+     * Recursively loops through array of objects ({label: '...', value: '...'}
+     *     or {label: '...', items: [...]}), looking for label, corresponding to value.
+     * @param  {Array} arr
+     * @param  {String} selected
+     * @return {String} found label
+     */
+    function findIn(arr, selected) {
+        var found;
+
+        arr.some(function(obj){
+            found = 'value' in obj ?
+                obj.value == selected && obj.label :
+                findIn(obj.items, selected);
+
+            return found;
+        });
+
+        return found;
+    }
+
+    return AbstractControl.extend({
+
+        /**
+         * Invokes initialize method of parent class and initializes properties of instance.
+         * @param {Object} data - Item of "fields" array from grid configuration
+         * @param {Object} config - Filter configuration
+         */
+        initialize: function (data) {
+            this.constructor.__super__.initialize.apply(this, arguments);
+
+            this.caption = 'Select...';
+
+            this.observe('selected', '');
+
+            this.options = this.options || [];
+        },
+
+        /**
+         * Checkes if current state is empty.
+         * @return {Boolean}
+         */
+        isEmpty: function(){
+            return !this.selected();
+        },
+
+        /**
+         * Returns string value of current state for UI
+         * @return {String}
+         */
+        display: function (selected) {
+            var label = findIn(this.options, selected);
+            
+            return label;
+        },
+
+        /**
+         * Returns dump of instance's current state
+         * @returns {Object} - object which represents current state of instance
+         */
+        dump: function () {
+            var selected = this.selected();
+
+            this.output(this.display(selected));
+
+            return {
+                field: this.index,
+                value: selected
+            }
+        },
+
+        /**
+         * Resets state properties of instance and calls dump method.
+         * @returns {Object} - object which represents current state of instance
+         */
+        reset: function () {
+            this.selected(null);
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Store/view/base/web/templates/filter/store.html b/app/code/Magento/Store/view/base/web/templates/filter/store.html
new file mode 100644
index 00000000000..3ea1a1b9a0f
--- /dev/null
+++ b/app/code/Magento/Store/view/base/web/templates/filter/store.html
@@ -0,0 +1,13 @@
+<div class="field">
+    <label class="label" data-bind="attr: {for: index}">
+        <span data-bind="text: title"></span>
+    </label>
+    <div class="control">
+        <select data-bind="value: selected">
+            <option></option>
+            <!-- ko foreach: { data: options, as: 'option' } -->
+                <!-- ko template: 'ui/filter/store/item' --><!-- /ko -->
+            <!-- /ko -->
+        </select>
+    </div>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Store/view/base/web/templates/filter/store/item.html b/app/code/Magento/Store/view/base/web/templates/filter/store/item.html
new file mode 100644
index 00000000000..a4acd63f609
--- /dev/null
+++ b/app/code/Magento/Store/view/base/web/templates/filter/store/item.html
@@ -0,0 +1,9 @@
+<!-- ko ifnot: 'items' in option  -->
+    <option data-bind="attr: { label: option.label, value: option.value }"></option>
+<!-- /ko -->
+<!-- ko if: 'items' in option  -->
+    <optgroup data-bind="attr: { label: option.label }"></optgroup>
+    <!-- ko foreach: { data: option.items, as: 'option' } -->
+        <!-- ko template: 'ui/filter/store/item' --><!-- /ko -->
+    <!-- /ko -->
+<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml
index eaacc32d75d..258fcec1469 100644
--- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml
+++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml
@@ -30,22 +30,28 @@
  */
 ?>
 <?php if(count($this->getGroups())>1): ?>
-<div class="switcher store">
-    <strong class="label"><span><?php echo __('Select Store') ?></span></strong>
-    <div class="actions dropdown options">
+<div class="switcher store switcher-store" id="switcher-store">
+    <strong class="label switcher-label"><span><?php echo __('Select Store') ?></span></strong>
+    <div class="actions dropdown options switcher-options">
         <?php foreach ($this->getGroups() as $_group): ?>
         <?php if ($_group->getId()==$this->getCurrentGroupId()): ?>
-            <div class="action toggle" data-toggle="dropdown">
+            <div class="action toggle switcher-trigger" data-toggle="dropdown" id="switcher-store-trigger">
                 <strong>
                     <span><?php echo $this->escapeHtml($_group->getName()) ?></span>
                 </strong>
             </div>
         <?php endif; ?>
         <?php endforeach; ?>
-        <ul class="dropdown">
+        <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{
+            "appendTo":"#switcher-store > .options",
+            "triggerTarget":"#switcher-store-trigger",
+            "closeOnMouseLeave": false,
+            "triggerClass":"active",
+            "parentClass":"active",
+            "buttons":null}}'>
             <?php foreach ($this->getGroups() as $_group): ?>
             <?php if (!($_group->getId()==$this->getCurrentGroupId())): ?>
-                <li>
+                <li class="switcher-option">
                     <a href="#" data-post='<?php echo $this->getTargetStorePostData($_group->getDefaultStore()); ?>'>
                         <?php echo $this->escapeHtml($_group->getName()) ?>
                     </a>
diff --git a/app/code/Magento/Tax/Block/Checkout/Cart/Sidebar/Totals.php b/app/code/Magento/Tax/Block/Checkout/Cart/Sidebar/Totals.php
index 37886ded4b9..4b185ca8ea8 100644
--- a/app/code/Magento/Tax/Block/Checkout/Cart/Sidebar/Totals.php
+++ b/app/code/Magento/Tax/Block/Checkout/Cart/Sidebar/Totals.php
@@ -44,7 +44,6 @@ class Totals extends SidebarTotals
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Tax\Helper\Data $taxHelper
@@ -53,7 +52,6 @@ class Totals extends SidebarTotals
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Tax\Helper\Data $taxHelper,
@@ -62,7 +60,7 @@ class Totals extends SidebarTotals
     ) {
         $this->_taxData = $taxHelper;
         $this->_taxConfig = $taxConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $data);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Block/Checkout/Discount.php b/app/code/Magento/Tax/Block/Checkout/Discount.php
index b6f57421ead..9ebb94c007d 100644
--- a/app/code/Magento/Tax/Block/Checkout/Discount.php
+++ b/app/code/Magento/Tax/Block/Checkout/Discount.php
@@ -35,7 +35,6 @@ class Discount extends \Magento\Checkout\Block\Total\DefaultTotal
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -44,7 +43,6 @@ class Discount extends \Magento\Checkout\Block\Total\DefaultTotal
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
@@ -52,7 +50,7 @@ class Discount extends \Magento\Checkout\Block\Total\DefaultTotal
         array $data = array()
     ) {
         $this->_taxConfig = $taxConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $salesConfig, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Tax/Block/Checkout/Grandtotal.php b/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
index 282d5919d97..20619fdec5a 100644
--- a/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
+++ b/app/code/Magento/Tax/Block/Checkout/Grandtotal.php
@@ -42,7 +42,6 @@ class Grandtotal extends \Magento\Checkout\Block\Total\DefaultTotal
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -51,7 +50,6 @@ class Grandtotal extends \Magento\Checkout\Block\Total\DefaultTotal
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
@@ -59,7 +57,7 @@ class Grandtotal extends \Magento\Checkout\Block\Total\DefaultTotal
         array $data = array()
     ) {
         $this->_taxConfig = $taxConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $salesConfig, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Tax/Block/Checkout/Shipping.php b/app/code/Magento/Tax/Block/Checkout/Shipping.php
index 73f797462d3..edd6d15ab2c 100644
--- a/app/code/Magento/Tax/Block/Checkout/Shipping.php
+++ b/app/code/Magento/Tax/Block/Checkout/Shipping.php
@@ -42,7 +42,6 @@ class Shipping extends \Magento\Checkout\Block\Total\DefaultTotal
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -51,7 +50,6 @@ class Shipping extends \Magento\Checkout\Block\Total\DefaultTotal
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
@@ -59,7 +57,7 @@ class Shipping extends \Magento\Checkout\Block\Total\DefaultTotal
         array $data = array()
     ) {
         $this->_taxConfig = $taxConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $salesConfig, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php b/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
index aa3985569f2..5acde1bddc2 100644
--- a/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
+++ b/app/code/Magento/Tax/Block/Checkout/Shipping/Price.php
@@ -34,7 +34,6 @@ class Price extends \Magento\Checkout\Block\Shipping\Price
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param PriceCurrencyInterface $priceCurrency
@@ -43,7 +42,6 @@ class Price extends \Magento\Checkout\Block\Shipping\Price
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         PriceCurrencyInterface $priceCurrency,
@@ -53,7 +51,6 @@ class Price extends \Magento\Checkout\Block\Shipping\Price
         $this->taxHelper = $taxHelper;
         parent::__construct(
             $context,
-            $catalogData,
             $customerSession,
             $checkoutSession,
             $priceCurrency,
@@ -114,6 +111,16 @@ class Price extends \Magento\Checkout\Block\Shipping\Price
         return $this->taxHelper->displayShippingPriceIncludingTax();
     }
 
+    /**
+     * Return flag whether to display shipping price excluding tax
+     *
+     * @return bool
+     */
+    public function displayShippingPriceExclTax()
+    {
+        return $this->taxHelper->displayShippingPriceExcludingTax();
+    }
+
     /**
      * Return flag whether to display shipping price including and excluding tax
      *
diff --git a/app/code/Magento/Tax/Block/Checkout/Subtotal.php b/app/code/Magento/Tax/Block/Checkout/Subtotal.php
index fa5ca966748..bc89332da11 100644
--- a/app/code/Magento/Tax/Block/Checkout/Subtotal.php
+++ b/app/code/Magento/Tax/Block/Checkout/Subtotal.php
@@ -42,7 +42,6 @@ class Subtotal extends \Magento\Checkout\Block\Total\DefaultTotal
 
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Catalog\Helper\Data $catalogData
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Sales\Model\Config $salesConfig
@@ -51,7 +50,6 @@ class Subtotal extends \Magento\Checkout\Block\Total\DefaultTotal
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Catalog\Helper\Data $catalogData,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\Config $salesConfig,
@@ -59,7 +57,7 @@ class Subtotal extends \Magento\Checkout\Block\Total\DefaultTotal
         array $data = array()
     ) {
         $this->_taxConfig = $taxConfig;
-        parent::__construct($context, $catalogData, $customerSession, $checkoutSession, $salesConfig, $data);
+        parent::__construct($context, $customerSession, $checkoutSession, $salesConfig, $data);
         $this->_isScopePrivate = true;
     }
 
diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php
index 748cc3ed8d4..1e6989db36b 100644
--- a/app/code/Magento/Tax/Helper/Data.php
+++ b/app/code/Magento/Tax/Helper/Data.php
@@ -721,87 +721,84 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      *  )
      * )
      *
-     * @param \Magento\Sales\Model\Order $source
+     * @param \Magento\Sales\Model\Order|\Magento\Sales\Model\Order\Invoice|\Magento\Sales\Model\Order\Creditmemo $source
      * @return array
      */
     public function getCalculatedTaxes($source)
     {
-        if ($this->_coreRegistry->registry('current_invoice')) {
-            $current = $this->_coreRegistry->registry('current_invoice');
-        } elseif ($this->_coreRegistry->registry('current_creditmemo')) {
-            $current = $this->_coreRegistry->registry('current_creditmemo');
-        } else {
-            $current = $source;
+        $taxClassAmount = [];
+        if (empty($source)) {
+            return $taxClassAmount;
         }
-
-        $taxClassAmount = array();
-        if ($current && $source) {
-            if ($current == $source) {
-                $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($current->getId());
-                $appliedTaxes = $orderTaxDetails->getAppliedTaxes();
-                foreach ($appliedTaxes as $appliedTax) {
-                    $taxCode = $appliedTax->getCode();
-                    $taxClassAmount[$taxCode]['tax_amount'] = $appliedTax->getAmount();
-                    $taxClassAmount[$taxCode]['base_tax_amount'] = $appliedTax->getBaseAmount();
-                    $taxClassAmount[$taxCode]['title'] = $appliedTax->getTitle();
-                    $taxClassAmount[$taxCode]['percent'] = $appliedTax->getPercent();
-                }
-            } else {
-                $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($source->getId());
-
-                // Apply any taxes for shipping
-                $shippingTaxAmount = $current->getShippingTaxAmount();
-                $originalShippingTaxAmount = $source->getShippingTaxAmount();
-                if ($shippingTaxAmount && $originalShippingTaxAmount &&
-                    $shippingTaxAmount != 0 && $originalShippingTaxAmount != 0) {
-                    //An invoice or credit memo can have a different qty than its order
-                    $shippingRatio = $shippingTaxAmount / $originalShippingTaxAmount;
-                    $itemTaxDetails = $orderTaxDetails->getItems();
-                    foreach ($itemTaxDetails as $itemTaxDetail) {
-                        //Aggregate taxable items associated with shipping
-                        if ($itemTaxDetail->getType() == \Magento\Sales\Model\Quote\Address::TYPE_SHIPPING) {
-                            $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $shippingRatio);
-                        }
+        $current = $source;
+        if ($source instanceof \Magento\Sales\Model\Order\Invoice
+            || $source instanceof \Magento\Sales\Model\Order\Creditmemo
+        ) {
+            $source = $current->getOrder();
+        }
+        if ($current == $source) {
+            $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($current->getId());
+            $appliedTaxes = $orderTaxDetails->getAppliedTaxes();
+            foreach ($appliedTaxes as $appliedTax) {
+                $taxCode = $appliedTax->getCode();
+                $taxClassAmount[$taxCode]['tax_amount'] = $appliedTax->getAmount();
+                $taxClassAmount[$taxCode]['base_tax_amount'] = $appliedTax->getBaseAmount();
+                $taxClassAmount[$taxCode]['title'] = $appliedTax->getTitle();
+                $taxClassAmount[$taxCode]['percent'] = $appliedTax->getPercent();
+            }
+        } else {
+            $orderTaxDetails = $this->orderTaxService->getOrderTaxDetails($source->getId());
+
+            // Apply any taxes for shipping
+            $shippingTaxAmount = $current->getShippingTaxAmount();
+            $originalShippingTaxAmount = $source->getShippingTaxAmount();
+            if ($shippingTaxAmount && $originalShippingTaxAmount &&
+                $shippingTaxAmount != 0 && $originalShippingTaxAmount != 0) {
+                //An invoice or credit memo can have a different qty than its order
+                $shippingRatio = $shippingTaxAmount / $originalShippingTaxAmount;
+                $itemTaxDetails = $orderTaxDetails->getItems();
+                foreach ($itemTaxDetails as $itemTaxDetail) {
+                    //Aggregate taxable items associated with shipping
+                    if ($itemTaxDetail->getType() == \Magento\Sales\Model\Quote\Address::TYPE_SHIPPING) {
+                        $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $shippingRatio);
                     }
                 }
+            }
 
-                // Apply any taxes for the items
-                /** @var $item \Magento\Sales\Model\Order\Invoice\Item|\Magento\Sales\Model\Order\Creditmemo\Item */
-                foreach ($current->getItemsCollection() as $item) {
-                    $orderItem = $item->getOrderItem();
-                    $orderItemId = $orderItem->getId();
-                    $orderItemTax = $orderItem->getTaxAmount();
-                    $itemTax = $item->getTaxAmount();
-                    if (!$itemTax || !$orderItemTax) {
-                        continue;
-                    }
-                    //An invoiced item or credit memo item can have a different qty than its order item qty
-                    $itemRatio = $itemTax / $orderItemTax;
-                    $itemTaxDetails = $orderTaxDetails->getItems();
-                    foreach ($itemTaxDetails as $itemTaxDetail) {
-                        //Aggregate taxable items associated with an item
-                        if ($itemTaxDetail->getItemId() == $orderItemId
-                            || $itemTaxDetail->getAssociatedItemId() == $orderItemId) {
-                            $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $itemRatio);
-                        }
+            // Apply any taxes for the items
+            /** @var $item \Magento\Sales\Model\Order\Invoice\Item|\Magento\Sales\Model\Order\Creditmemo\Item */
+            foreach ($current->getItemsCollection() as $item) {
+                $orderItem = $item->getOrderItem();
+                $orderItemId = $orderItem->getId();
+                $orderItemTax = $orderItem->getTaxAmount();
+                $itemTax = $item->getTaxAmount();
+                if (!$itemTax || !$orderItemTax) {
+                    continue;
+                }
+                //An invoiced item or credit memo item can have a different qty than its order item qty
+                $itemRatio = $itemTax / $orderItemTax;
+                $itemTaxDetails = $orderTaxDetails->getItems();
+                foreach ($itemTaxDetails as $itemTaxDetail) {
+                    //Aggregate taxable items associated with an item
+                    if ($itemTaxDetail->getItemId() == $orderItemId
+                        || $itemTaxDetail->getAssociatedItemId() == $orderItemId) {
+                        $taxClassAmount = $this->_aggregateTaxes($taxClassAmount, $itemTaxDetail, $itemRatio);
                     }
                 }
             }
+        }
 
-            // Finish
-            foreach ($taxClassAmount as $key => $tax) {
-                if ($tax['tax_amount'] == 0 && $tax['base_tax_amount'] == 0) {
-                    unset($taxClassAmount[$key]);
-                } else {
-                    $taxClassAmount[$key]['tax_amount'] = $this->priceCurrency->round($tax['tax_amount']);
-                    $taxClassAmount[$key]['base_tax_amount'] = $this->priceCurrency->round($tax['base_tax_amount']);
-                }
+        // Finish
+        foreach ($taxClassAmount as $key => $tax) {
+            if ($tax['tax_amount'] == 0 && $tax['base_tax_amount'] == 0) {
+                unset($taxClassAmount[$key]);
+            } else {
+                $taxClassAmount[$key]['tax_amount'] = $this->priceCurrency->round($tax['tax_amount']);
+                $taxClassAmount[$key]['base_tax_amount'] = $this->priceCurrency->round($tax['base_tax_amount']);
             }
-
-            $taxClassAmount = array_values($taxClassAmount);
         }
 
-        return $taxClassAmount;
+        return array_values($taxClassAmount);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Model/System/Message/Notifications.php b/app/code/Magento/Tax/Model/System/Message/Notifications.php
index 9eb167aa289..76cd03df1b5 100644
--- a/app/code/Magento/Tax/Model/System/Message/Notifications.php
+++ b/app/code/Magento/Tax/Model/System/Message/Notifications.php
@@ -236,15 +236,15 @@ class Notifications implements \Magento\Framework\Notification\MessageInterface
         if (!empty($this->storesWithInvalidDisplaySettings) && !$this->taxConfig->isWrongDisplaySettingsIgnored()) {
             $messageDetails .= '<strong>';
             $messageDetails .= __('Warning tax configuration can result in rounding errors. ');
-            $messageDetails .= '</strong><br>';
+            $messageDetails .= '</strong><p>';
             $messageDetails .= __('Store(s) affected: ');
             $messageDetails .= implode(', ', $this->storesWithInvalidDisplaySettings);
-            $messageDetails .= '<br><div style="text-align:right">';
+            $messageDetails .= '</p><p>';
             $messageDetails .= __(
                 'Click on the link to <a href="%1">ignore this notification</a>',
                 $this->getIgnoreTaxNotificationUrl('price_display')
             );
-            $messageDetails .= "</div><br>";
+            $messageDetails .= "</p>";
         }
 
         if (!empty($this->storesWithInvalidDiscountSettings) && !$this->taxConfig->isWrongDiscountSettingsIgnored()) {
@@ -253,23 +253,24 @@ class Notifications implements \Magento\Framework\Notification\MessageInterface
                 'Warning tax discount configuration might result in different discounts
                                 than a customer might expect. '
             );
-            $messageDetails .= '</strong><br>';
+            $messageDetails .= '</strong><p>';
             $messageDetails .= __('Store(s) affected: ');
             $messageDetails .= implode(', ', $this->storesWithInvalidDiscountSettings);
-            $messageDetails .= '<br><div style="text-align:right">';
+            $messageDetails .= '</p><p>';
             $messageDetails .= __(
                 'Click on the link to <a href="%1">ignore this notification</a>',
                 $this->getIgnoreTaxNotificationUrl('discount')
             );
-            $messageDetails .= "</div><br>";
+            $messageDetails .= "</p>";
         }
 
-        $messageDetails .= '<br>';
+        $messageDetails .= '<p>';
         $messageDetails .= __('Please see <a href="%1">documentation</a> for more details. ', $this->getInfoUrl());
         $messageDetails .= __(
             'Click here to go to <a href="%1">Tax Configuration</a> and change your settings.',
             $this->getManageUrl()
         );
+        $messageDetails .= '</p>';
 
         return $messageDetails;
     }
diff --git a/app/code/Magento/Tax/Pricing/Render/Adjustment.php b/app/code/Magento/Tax/Pricing/Render/Adjustment.php
index faca5958b2f..da74b8d7799 100644
--- a/app/code/Magento/Tax/Pricing/Render/Adjustment.php
+++ b/app/code/Magento/Tax/Pricing/Render/Adjustment.php
@@ -62,20 +62,15 @@ class Adjustment extends AbstractAdjustment
     {
         if ($this->displayBothPrices()) {
             if ($this->getZone() !== \Magento\Framework\Pricing\Render::ZONE_ITEM_OPTION) {
-                $this->amountRender->setPriceDisplayLabel(__('Excl. Tax'));
+                $this->amountRender->setPriceDisplayLabel(__('Incl. Tax'));
             }
-            $this->amountRender->setPriceWrapperCss('price-excluding-tax');
+            $this->amountRender->setPriceWrapperCss('price-including-tax');
             $this->amountRender->setPriceId(
-                $this->buildIdWithPrefix('price-excluding-tax-')
-            );
-            $this->amountRender->setDisplayValue(
-                $this->amountRender->getDisplayValue() -
-                $this->amountRender->getAmount()->getAdjustmentAmount($this->getAdjustmentCode())
+                $this->buildIdWithPrefix('price-including-tax-')
             );
         } elseif ($this->displayPriceExcludingTax()) {
             $this->amountRender->setDisplayValue(
-                $this->amountRender->getDisplayValue() -
-                $this->amountRender->getAmount()->getAdjustmentAmount($this->getAdjustmentCode())
+                $this->amountRender->getAmount()->getValue($this->getAdjustmentCode())
             );
         }
         return $this->toHtml();
@@ -105,12 +100,16 @@ class Adjustment extends AbstractAdjustment
     /**
      * Obtain display amount excluding tax
      *
+     * @param bool $includeContainer
      * @return string
      */
-    public function getDisplayAmountExclTax()
+    public function getDisplayAmountExclTax($includeContainer = false)
     {
         // todo use 'excludeWith' method instead hard-coded list here
-        return $this->convertAndFormatCurrency($this->amountRender->getAmount()->getValue(['tax', 'weee']), false);
+        return $this->convertAndFormatCurrency(
+            $this->amountRender->getAmount()->getValue(['tax', 'weee']),
+            $includeContainer
+        );
     }
 
     /**
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index 4930e4c4262..b21fa5a1319 100644
--- a/app/code/Magento/Tax/composer.json
+++ b/app/code/Magento/Tax/composer.json
@@ -3,24 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-reports": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-configurable-product": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-reports": "0.1.0-alpha97",
+        "magento/module-configurable-product": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Tax/etc/module.xml b/app/code/Magento/Tax/etc/module.xml
index 01f07f004fb..ec92570a5fd 100644
--- a/app/code/Magento/Tax/etc/module.xml
+++ b/app/code/Magento/Tax/etc/module.xml
@@ -42,7 +42,6 @@
             <module name="Magento_Eav"/>
             <module name="Magento_Sales"/>
             <module name="Magento_Reports"/>
-            <module name="Magento_Theme"/>
             <module name="Magento_ConfigurableProduct"/>
         </depends>
     </module>
diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_edit.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_edit.xml
index e4a91ea35ca..47a33655917 100644
--- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_edit.xml
+++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_edit.xml
@@ -24,23 +24,11 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-tax-js-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Tax::js/bootstrap.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-editablemultiselect-css-jquery-multiselect-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/editableMultiselect/css/jquery.multiselect.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="Magento_Tax::js/bootstrap.js"/>
+        <css src="jquery/editableMultiselect/css/jquery.multiselect.css"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Tax\Block\Adminhtml\Rule\Edit"/>
         <block class="Magento\Tax\Block\Adminhtml\Rule\Edit\Form" name="tax-rule-edit" template="rule/edit.phtml"/>
diff --git a/app/code/Magento/Tax/view/base/layout/catalog_product_prices.xml b/app/code/Magento/Tax/view/base/layout/catalog_product_prices.xml
index 28f07d0436d..708621c8c5c 100644
--- a/app/code/Magento/Tax/view/base/layout/catalog_product_prices.xml
+++ b/app/code/Magento/Tax/view/base/layout/catalog_product_prices.xml
@@ -36,16 +36,6 @@
                     </item>
                 </item>
             </argument>
-            <argument name="downloadable" xsi:type="array">
-                <item name="adjustments" xsi:type="array">
-                    <item name="link_price" xsi:type="array">
-                        <item name="tax" xsi:type="array">
-                            <item name="adjustment_render_class" xsi:type="string">Magento\Tax\Pricing\Render\Adjustment</item>
-                            <item name="adjustment_render_template" xsi:type="string">Magento_Tax::pricing/adjustment/downloadable.phtml</item>
-                        </item>
-                    </item>
-                </item>
-            </argument>
             <argument name="bundle" xsi:type="array">
                 <item name="adjustments" xsi:type="array">
                     <item name="bundle_option" xsi:type="array">
diff --git a/app/code/Magento/Tax/view/base/templates/pricing/adjustment.phtml b/app/code/Magento/Tax/view/base/templates/pricing/adjustment.phtml
index 448e736b231..aefc514ab47 100644
--- a/app/code/Magento/Tax/view/base/templates/pricing/adjustment.phtml
+++ b/app/code/Magento/Tax/view/base/templates/pricing/adjustment.phtml
@@ -26,9 +26,8 @@
 <?php /** @var \Magento\Tax\Pricing\Render\Adjustment $this */ ?>
 
 <?php if ($this->displayBothPrices()): ?>
-    <span id="<?php echo $this->buildIdWithPrefix('price-including-tax-') ?>"
-          data-label="<?php echo __('Incl. Tax') ?>"
-          class="price-wrapper price-including-tax">
-    <span class="price" ><?php echo $this->getDisplayAmount(false) ?></span>
-</span>
+    <span id="<?php echo $this->buildIdWithPrefix('price-excluding-tax-') ?>"
+          data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>"
+          class="price-wrapper price-excluding-tax">
+        <span class="price"><?php echo $this->getDisplayAmountExclTax() ?></span></span>
 <?php endif; ?>
diff --git a/app/code/Magento/Tax/view/base/templates/pricing/adjustment/bundle.phtml b/app/code/Magento/Tax/view/base/templates/pricing/adjustment/bundle.phtml
index 41016de88c9..ddd887804d4 100644
--- a/app/code/Magento/Tax/view/base/templates/pricing/adjustment/bundle.phtml
+++ b/app/code/Magento/Tax/view/base/templates/pricing/adjustment/bundle.phtml
@@ -27,10 +27,10 @@
 <?php if ($this->displayPriceIncludingTax()): ?>
     <?php echo $this->getDisplayAmount() ?>
 <?php elseif ($this->displayPriceExcludingTax()): ?>
-    <?php echo $this->getDisplayAmountExclTax() ?><
-<?php elseif ($this->displayBothPrices()): ?>
     <?php echo $this->getDisplayAmountExclTax() ?>
+<?php elseif ($this->displayBothPrices()): ?>
+    <?php echo $this->getDisplayAmount() ?>
     <?php if ($this->getDisplayAmountExclTax() !== $this->getDisplayAmount()): ?>
-        (+<?php echo $this->getDisplayAmount() ?> Incl. Tax)
+        (+<?php echo $this->getDisplayAmountExclTax() ?> Excl. Tax)
     <?php endif; ?>
-<?php endif; ?>
\ No newline at end of file
+<?php endif; ?>
diff --git a/app/code/Magento/Tax/view/base/templates/pricing/adjustment/downloadable.phtml b/app/code/Magento/Tax/view/base/templates/pricing/adjustment/downloadable.phtml
deleted file mode 100644
index f093a456179..00000000000
--- a/app/code/Magento/Tax/view/base/templates/pricing/adjustment/downloadable.phtml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-
-<?php /** @var \Magento\Tax\Pricing\Render\Adjustment $this */ ?>
-<span class="price-notice">+
-    <?php if ($this->displayPriceIncludingTax()): ?>
-        <span class="price" id="<?php echo $this->buildIdWithPrefix('link-price-including-tax-') ?>">
-            <?php echo $this->getDisplayAmount() ?></span>
-    <?php elseif ($this->displayPriceExcludingTax()): ?>
-    <span class="price" id="<?php echo $this->buildIdWithPrefix('link-price-excluding-tax-') ?>">
-        <?php echo $this->getDisplayAmountExclTax() ?></span>
-    <?php elseif ($this->displayBothPrices()): ?>
-        <span class="price" id="<?php echo $this->buildIdWithPrefix('link-price-both-tax-') ?>">
-            <?php echo $this->getDisplayAmountExclTax() ?>
-        <?php if ($this->getDisplayAmountExclTax() !== $this->getDisplayAmount()): ?>
-            (+<?php echo $this->getDisplayAmount() ?> Incl. Tax)
-        <?php endif; ?>
-        </span>
-    <?php endif; ?>
-</span>
diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/cart/item/price/sidebar.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
index 79e3ace1251..3067835400c 100644
--- a/app/code/Magento/Tax/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
@@ -25,27 +25,16 @@
 /** @var $this \Magento\Tax\Block\Item\Price\Renderer */
 ?>
 <?php $_item = $this->getItem() ?>
-<div class="pricing details<?php echo $this->displayBothPrices() ? ' complex' : ''; ?>">
-<?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
-    <div class="rate">
-    <?php if ($this->displayBothPrices()): ?>
-        <span class="label excl tax"><?php echo __('Excl. Tax'); ?></span>
-    <?php else: ?>
-        <span class="label display"><?php echo __('Price'); ?></span>
+<div class="price-container">
+    <span class="price-label"><?php echo __('Price')?></span>
+    <?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
+        <span class="price-wrapper price-including-tax" data-label="<?php echo __('Incl. Tax')?>">
+            <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl) ?>
+        </span>
     <?php endif; ?>
-        <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>
+    <?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
+        <span class="price-wrapper price-excluding-tax" data-label="<?php echo __('Excl. Tax')?>">
+            <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_item->getCalculationPrice()) ?>
+        </span>
     <?php endif; ?>
-    </div>
-
-    <?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
-    <?php $_incl = $this->helper('Magento\Checkout\Helper\Data')->getPriceInclTax($_item); ?>
-    <div class="rate">
-        <?php if ($this->displayBothPrices()): ?>
-            <span class="label tax incl"><?php echo __('Incl. Tax'); ?></span>
-        <?php else: ?>
-            <span class="label display"><?php echo __('Price'); ?></span>
-        <?php endif; ?>
-            <span class="value display"><?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($_incl) ?></span>
-    </div>
-<?php endif; ?>
 </div>
diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/cart/minicart/totals.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/cart/minicart/totals.phtml
index 7233ae8212b..3ca0dc83bd5 100644
--- a/app/code/Magento/Tax/view/frontend/templates/checkout/cart/minicart/totals.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/checkout/cart/minicart/totals.phtml
@@ -25,16 +25,21 @@
 /** @var $this Magento\Tax\Block\Checkout\Cart\Sidebar\Totals */
 ?>
 
-<div class="amount">
+<div class="amount price-container">
     <?php if ($this->getDisplaySubtotalExclTax()): ?>
-        <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalExclTax()); ?>
+        <span class="price-wrapper">
+            <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalExclTax()); ?>
+        </span>
     <?php elseif ($this->getDisplaySubtotalInclTax()): ?>
-        <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalInclTax()); ?>
+        <span class="price-wrapper">
+            <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalInclTax()); ?>
+        </span>
     <?php else: ?>
-        <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalExclTax()); ?>
-        <span class="amount incl tax">
+        <span class="price-wrapper price-including-tax" data-label="<?php echo __('Incl. Tax'); ?>">
             <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalInclTax()) ?>
-            <?php echo $this->getIncExcTaxLabel(true) ?>
+        </span>
+        <span class="price-wrapper price-excluding-tax" data-label="<?php echo __('Excl. Tax'); ?>">
+            <?php echo $this->helper('Magento\Checkout\Helper\Data')->formatPrice($this->getSubtotalExclTax()); ?>
         </span>
     <?php endif; ?>
 </div>
diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/shipping/price.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/shipping/price.phtml
index 58246b11f91..1445ac4bf5b 100644
--- a/app/code/Magento/Tax/view/frontend/templates/checkout/shipping/price.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/checkout/shipping/price.phtml
@@ -26,11 +26,17 @@
 
 <?php $_excl = $this->getShippingPriceExclTax(); ?>
 <?php $_incl = $this->getShippingPriceInclTax(); ?>
-<?php if ($this->displayShippingPriceInclTax()): ?>
-    <?php echo $_incl; ?>
+<?php if ($this->displayShippingPriceExclTax()): ?>
+    <span class="price"><?php echo $_excl; ?></span>
 <?php else: ?>
-    <?php echo $_excl; ?>
+<?php if ($this->displayShippingBothPrices() && $_incl != $_excl): ?>
+    <span class="price-including-tax" data-label="<?php echo __('Incl. Tax'); ?>">
+<?php endif; ?>
+    <span class="price"><?php echo $_incl; ?></span>
+<?php if ($this->displayShippingBothPrices() && $_incl != $_excl): ?>
+    </span>
+<?php endif; ?>
 <?php endif; ?>
 <?php if ($this->displayShippingBothPrices() && $_incl != $_excl): ?>
-    (<?php echo __('Incl. Tax'); ?> <?php echo $_incl; ?>)
+    <span class="price-excluding-tax" data-label="<?php echo __('Excl. Tax'); ?>"><span class="price"><?php echo $_excl; ?></span></span>
 <?php endif; ?>
diff --git a/app/code/Magento/Tax/view/frontend/templates/item/price/row.phtml b/app/code/Magento/Tax/view/frontend/templates/item/price/row.phtml
index 5a8143977d0..3ed34a61988 100644
--- a/app/code/Magento/Tax/view/frontend/templates/item/price/row.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/item/price/row.phtml
@@ -27,16 +27,16 @@
 $_item = $this->getItem();
 ?>
 <?php if (($this->displayPriceInclTax() || $this->displayBothPrices()) && !$_item->getNoSubtotal()): ?>
-    <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
-        <span class="cart price">
+    <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+        <span class="cart-price">
             <?php echo $this->formatPrice($_item->getRowTotalInclTax()) ?>
         </span>
     </span>
 <?php endif; ?>
 
 <?php if (($this->displayPriceExclTax() || $this->displayBothPrices()) && !$_item->getNoSubtotal()): ?>
-    <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
-        <span class="cart price">
+    <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+        <span class="cart-price">
             <?php echo $this->formatPrice($_item->getRowTotal()) ?>
         </span>
     </span>
diff --git a/app/code/Magento/Tax/view/frontend/templates/item/price/total_after_discount.phtml b/app/code/Magento/Tax/view/frontend/templates/item/price/total_after_discount.phtml
index d51574e8f28..e9eb0936c76 100644
--- a/app/code/Magento/Tax/view/frontend/templates/item/price/total_after_discount.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/item/price/total_after_discount.phtml
@@ -26,4 +26,4 @@
 $_item = $this->getItem();
 ?>
 <?php $_order = $this->getItem()->getOrderItem()->getOrder() ?>
-<?php echo $_order->formatPrice($this->getTotalAmount($_item))?>
\ No newline at end of file
+<?php echo $_order->formatPrice($this->getTotalAmount($_item))?>
diff --git a/app/code/Magento/Tax/view/frontend/templates/item/price/unit.phtml b/app/code/Magento/Tax/view/frontend/templates/item/price/unit.phtml
index 59ed24ece87..9155710c3d7 100644
--- a/app/code/Magento/Tax/view/frontend/templates/item/price/unit.phtml
+++ b/app/code/Magento/Tax/view/frontend/templates/item/price/unit.phtml
@@ -28,17 +28,17 @@ $_item = $this->getItem();
 ?>
 
 <?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
-    <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
+    <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
         <?php $_incl = $_item->getPriceInclTax(); ?>
-        <span class="cart price">
+        <span class="cart-price">
             <?php echo $this->formatPrice($_incl) ?>
         </span>
     </span>
 <?php endif; ?>
 
 <?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
-    <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
-        <span class="cart price">
+    <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+        <span class="cart-price">
             <?php echo $this->formatPrice($this->getItemDisplayPriceExclTax()) ?>
         </span>
     </span>
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index 26f2e3476ae..549e0fd2d5f 100644
--- a/app/code/Magento/TaxImportExport/composer.json
+++ b/app/code/Magento/TaxImportExport/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Theme/Block/Html.php b/app/code/Magento/Theme/Block/Html.php
deleted file mode 100644
index 4a9e34d2f3e..00000000000
--- a/app/code/Magento/Theme/Block/Html.php
+++ /dev/null
@@ -1,258 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Theme\Block;
-
-use Magento\Framework\View\Element\Template;
-
-/**
- * Html page block
- */
-class Html extends \Magento\Framework\View\Element\Template
-{
-    /**
-     * @var \Magento\Framework\Locale\ResolverInterface
-     */
-    protected $_localeResolver;
-
-    /**
-     * The list of available URLs
-     *
-     * @var array
-     */
-    protected $_urls = array();
-
-    /**
-     * @var string
-     */
-    protected $_title = '';
-
-    /**
-     * @param Template\Context $context
-     * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
-     * @param array $data
-     */
-    public function __construct(
-        Template\Context $context,
-        \Magento\Framework\Locale\ResolverInterface $localeResolver,
-        array $data = array()
-    ) {
-        parent::__construct($context, $data);
-        $this->_localeResolver = $localeResolver;
-    }
-
-    /**
-     * Add block data
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-
-        $this->_urls = array(
-            'base' => $this->_storeManager->getStore()->getBaseUrl('web'),
-            'baseSecure' => $this->_storeManager->getStore()->getBaseUrl('web', true),
-            'current' => $this->_request->getRequestUri()
-        );
-
-        $this->addBodyClass($this->_request->getFullActionName('-'));
-
-        if ($this->_cacheState->isEnabled(self::CACHE_GROUP)) {
-            $this->_sidResolver->setUseSessionVar(true);
-        }
-    }
-
-    /**
-     * Retrieve base URL
-     *
-     * @return string
-     */
-    public function getBaseUrl()
-    {
-        return $this->_urls['base'];
-    }
-
-    /**
-     * Retrieve base secure URL
-     *
-     * @return mixed
-     */
-    public function getBaseSecureUrl()
-    {
-        return $this->_urls['baseSecure'];
-    }
-
-    /**
-     * Retrieve current URL
-     *
-     * @return mixed
-     */
-    public function getCurrentUrl()
-    {
-        return $this->_urls['current'];
-    }
-
-    /**
-     * Print Logo URL (Conf -> Sales -> Invoice and Packing Slip Design)
-     *
-     * @return string
-     */
-    public function getPrintLogoUrl()
-    {
-        // load html logo
-        $logo = $this->_scopeConfig->getValue(
-            'sales/identity/logo_html',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        if (!empty($logo)) {
-            $logo = 'sales/store/logo_html/' . $logo;
-        }
-
-        // load default logo
-        if (empty($logo)) {
-            $logo = $this->_scopeConfig->getValue(
-                'sales/identity/logo',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-            if (!empty($logo)) {
-                // prevent tiff format displaying in html
-                if (strtolower(substr($logo, -5)) === '.tiff' || strtolower(substr($logo, -4)) === '.tif') {
-                    $logo = '';
-                } else {
-                    $logo = 'sales/store/logo/' . $logo;
-                }
-            }
-        }
-
-        // buld url
-        if (!empty($logo)) {
-            $logo = $this->_urlBuilder
-                    ->getBaseUrl(array('_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA)) . $logo;
-        } else {
-            $logo = '';
-        }
-
-        return $logo;
-    }
-
-    /**
-     * Retrieve logo text for print page
-     *
-     * @return string
-     */
-    public function getPrintLogoText()
-    {
-        return $this->_scopeConfig->getValue(
-            'sales/identity/address',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-    }
-
-    /**
-     * Set header title
-     *
-     * @param string $title
-     * @return $this
-     */
-    public function setHeaderTitle($title)
-    {
-        $this->_title = $title;
-        return $this;
-    }
-
-    /**
-     * Retrieve header title
-     *
-     * @return string
-     */
-    public function getHeaderTitle()
-    {
-        return $this->_title;
-    }
-
-    /**
-     * Add CSS class to page body tag
-     *
-     * @param string $className
-     * @return $this
-     */
-    public function addBodyClass($className)
-    {
-        $className = preg_replace('#[^a-z0-9]+#', '-', strtolower($className));
-        $this->setBodyClass($this->getBodyClass() . ' ' . $className);
-        return $this;
-    }
-
-    /**
-     * Retrieve base language
-     *
-     * @return string
-     */
-    public function getLang()
-    {
-        if (!$this->hasData('lang')) {
-            $this->setData('lang', substr($this->_localeResolver->getLocaleCode(), 0, 2));
-        }
-        return $this->getData('lang');
-    }
-
-    /**
-     * Retrieve body class
-     *
-     * @return string
-     */
-    public function getBodyClass()
-    {
-        return $this->_getData('body_class');
-    }
-
-    /**
-     * Retrieve absolute footer html
-     *
-     * @return string
-     */
-    public function getAbsoluteFooter()
-    {
-        return $this->_scopeConfig->getValue(
-            'design/footer/absolute_footer',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-    }
-
-    /**
-     * Processing block html after rendering
-     *
-     * @param   string $html
-     * @return  string
-     */
-    protected function _afterToHtml($html)
-    {
-        if ($this->_cacheState->isEnabled(self::CACHE_GROUP)) {
-            $this->_sidResolver->setUseSessionVar(false);
-            \Magento\Framework\Profiler::start('CACHE_URL');
-            $html = $this->_urlBuilder->sessionUrlVar($html);
-            \Magento\Framework\Profiler::stop('CACHE_URL');
-        }
-        return $html;
-    }
-}
diff --git a/app/code/Magento/Theme/Block/Html/Head.php b/app/code/Magento/Theme/Block/Html/Head.php
deleted file mode 100644
index e61ccd27114..00000000000
--- a/app/code/Magento/Theme/Block/Html/Head.php
+++ /dev/null
@@ -1,479 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Theme\Block\Html;
-
-/**
- * Html page head block
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class Head extends \Magento\Framework\View\Element\Template
-{
-    /**
-     * Current template name
-     *
-     * @var string
-     */
-    protected $_template = 'html/head.phtml';
-
-    /**
-     * Chunks of title (necessary for backend)
-     *
-     * @var array
-     */
-    protected $_titleChunks;
-
-    /**
-     * Page title without prefix and suffix when not chunked
-     *
-     * @var string
-     */
-    protected $_pureTitle;
-
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
-
-    /**
-     * @var \Magento\Framework\View\Asset\MergeService
-     */
-    private $_assetMergeService;
-
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService
-     */
-    private $_assetMinifyService;
-
-    /**
-     * @var \Magento\Framework\View\Asset\GroupedCollection
-     */
-    private $_pageAssets;
-
-    /**
-     * Core file storage database
-     *
-     * @var \Magento\Core\Helper\File\Storage\Database
-     */
-    protected $_fileStorageDatabase;
-
-    /**
-     * @var \Magento\Framework\Locale\ResolverInterface
-     */
-    protected $_localeResolver;
-
-    /**
-     * @var \Magento\Translation\Block\Js
-     */
-    protected $jsTranslation;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase
-     * @param \Magento\Framework\ObjectManager $objectManager
-     * @param \Magento\Framework\View\Asset\GroupedCollection $assets
-     * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
-     * @param \Magento\Framework\View\Asset\MinifyService $assetMinifyService
-     * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
-     * @param \Magento\Translation\Block\Js $jsTranslation
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase,
-        \Magento\Framework\ObjectManager $objectManager,
-        \Magento\Framework\View\Asset\GroupedCollection $assets,
-        \Magento\Framework\View\Asset\MergeService $assetMergeService,
-        \Magento\Framework\View\Asset\MinifyService $assetMinifyService,
-        \Magento\Framework\Locale\ResolverInterface $localeResolver,
-        \Magento\Translation\Block\Js $jsTranslation,
-        array $data = array()
-    ) {
-        parent::__construct($context, $data);
-        $this->_fileStorageDatabase = $fileStorageDatabase;
-        $this->_objectManager = $objectManager;
-        $this->_assetMergeService = $assetMergeService;
-        $this->_assetMinifyService = $assetMinifyService;
-        $this->_pageAssets = $assets;
-        $this->_localeResolver = $localeResolver;
-        $this->jsTranslation = $jsTranslation;
-    }
-
-    /**
-     * Add RSS element to HEAD entity
-     *
-     * @param string $title
-     * @param string $href
-     * @return $this
-     */
-    public function addRss($title, $href)
-    {
-        $asset = $this->_objectManager->create('Magento\Framework\View\Asset\Remote', array('url' => (string)$href));
-
-        $this->_pageAssets->add(
-            "link/{$href}",
-            $asset,
-            array('attributes' => 'rel="alternate" type="application/rss+xml" title="' . $title . '"')
-        );
-
-        return $this;
-    }
-
-    /**
-     * Render HTML for the added head items
-     *
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     *
-     * @return string
-     */
-    public function getCssJsHtml()
-    {
-        foreach ($this->getLayout()->getChildBlocks($this->getNameInLayout()) as $block) {
-            /** @var $block \Magento\Framework\View\Element\AbstractBlock */
-            if ($block instanceof \Magento\Theme\Block\Html\Head\AssetBlockInterface) {
-                /** @var \Magento\Framework\View\Asset\AssetInterface $asset */
-                $asset = $block->getAsset();
-                $this->_pageAssets->add($block->getNameInLayout(), $asset, (array)$block->getProperties());
-            }
-        }
-
-        $result = '';
-        /** @var $group \Magento\Framework\View\Asset\PropertyGroup */
-        foreach ($this->_pageAssets->getGroups() as $group) {
-            $contentType = $group->getProperty(\Magento\Framework\View\Asset\GroupedCollection::PROPERTY_CONTENT_TYPE);
-            $canMerge = $group->getProperty(\Magento\Framework\View\Asset\GroupedCollection::PROPERTY_CAN_MERGE);
-            $attributes = $group->getProperty('attributes');
-            $ieCondition = $group->getProperty('ie_condition');
-            $flagName = $group->getProperty('flag_name');
-
-            if ($flagName && !$this->getData($flagName)) {
-                continue;
-            }
-
-            $groupAssets = $group->getAll();
-            $groupAssets = $this->_assetMinifyService->getAssets($groupAssets);
-            if ($canMerge && count($groupAssets) > 1) {
-                $groupAssets = $this->_assetMergeService->getMergedAssets($groupAssets, $contentType);
-            }
-
-            if (!empty($attributes)) {
-                if (is_array($attributes)) {
-                    $attributesString = '';
-                    foreach ($attributes as $name => $value) {
-                        $attributesString .= ' ' . $name . '="' . $this->escapeHtml($value) . '"';
-                    }
-                    $attributes = $attributesString;
-                } else {
-                    $attributes = ' ' . $attributes;
-                }
-            }
-
-            if ($contentType == 'js') {
-                $groupTemplate = '<script' . $attributes . ' type="text/javascript" src="%s"></script>' . "\n";
-            } else {
-                if ($contentType == 'css') {
-                    $attributes = ' rel="stylesheet" type="text/css"' . ($attributes ?: ' media="all"');
-                }
-                $groupTemplate = '<link' . $attributes . ' href="%s" />' . "\n";
-            }
-
-            $groupHtml = $this->_renderHtml($groupTemplate, $groupAssets);
-
-            if (!empty($ieCondition)) {
-                $groupHtml = '<!--[if ' . $ieCondition . ']>' . "\n" . $groupHtml . '<![endif]-->' . "\n";
-            }
-
-            $result .= $groupHtml;
-        }
-        return $result;
-    }
-
-    /**
-     * Render HTML tags referencing corresponding URLs
-     *
-     * @param string $template
-     * @param array $assets
-     * @return string
-     */
-    protected function _renderHtml($template, $assets)
-    {
-        $result = '';
-        try {
-            /** @var $asset \Magento\Framework\View\Asset\AssetInterface */
-            foreach ($assets as $asset) {
-                $result .= sprintf($template, $asset->getUrl());
-            }
-        } catch (\Magento\Framework\Exception $e) {
-            $this->_logger->logException($e);
-            $result .= sprintf($template, $this->_getNotFoundUrl());
-        }
-        return $result;
-    }
-
-    /**
-     * Retrieve Content Type
-     *
-     * @return string
-     */
-    public function getContentType()
-    {
-        if (empty($this->_data['content_type'])) {
-            $this->_data['content_type'] = $this->getMediaType() . '; charset=' . $this->getCharset();
-        }
-        return $this->_data['content_type'];
-    }
-
-    /**
-     * Retrieve Media Type
-     *
-     * @return string
-     */
-    public function getMediaType()
-    {
-        if (empty($this->_data['media_type'])) {
-            $this->_data['media_type'] = $this->_scopeConfig->getValue(
-                'design/head/default_media_type',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['media_type'];
-    }
-
-    /**
-     * Retrieve Charset
-     *
-     * @return string
-     */
-    public function getCharset()
-    {
-        if (empty($this->_data['charset'])) {
-            $this->_data['charset'] = $this->_scopeConfig->getValue(
-                'design/head/default_charset',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['charset'];
-    }
-
-    /**
-     * Set title element text
-     *
-     * @param string|array $title
-     * @return \Magento\Theme\Block\Html\Head
-     */
-    public function setTitle($title)
-    {
-        if (is_array($title)) {
-            $this->_titleChunks = $title;
-            $title = implode(' / ', $title);
-        } else {
-            $this->_pureTitle = $title;
-        }
-
-        $this->_data['title'] = $this->_scopeConfig->getValue(
-            'design/head/title_prefix',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        ) . ' ' . $title . ' ' . $this->_scopeConfig->getValue(
-            'design/head/title_suffix',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-
-        return $this;
-    }
-
-    /**
-     * Retrieve title element text (encoded)
-     *
-     * @return string
-     */
-    public function getTitle()
-    {
-        if (empty($this->_data['title'])) {
-            $this->_data['title'] = $this->getDefaultTitle();
-        }
-        return htmlspecialchars(html_entity_decode(trim($this->_data['title']), ENT_QUOTES, 'UTF-8'));
-    }
-
-    /**
-     * Same as getTitle(), but return only first item from chunk for backend pages
-     *
-     * @return mixed
-     */
-    public function getShortTitle()
-    {
-        if (!empty($this->_titleChunks)) {
-            return reset($this->_titleChunks);
-        } else {
-            return $this->_pureTitle;
-        }
-    }
-
-    /**
-     * Retrieve default title text
-     *
-     * @return string
-     */
-    public function getDefaultTitle()
-    {
-        return $this->_scopeConfig->getValue(
-            'design/head/default_title',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-    }
-
-    /**
-     * Retrieve content for description tag
-     *
-     * @return string
-     */
-    public function getDescription()
-    {
-        if (empty($this->_data['description'])) {
-            $this->_data['description'] = $this->_scopeConfig->getValue(
-                'design/head/default_description',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['description'];
-    }
-
-    /**
-     * Retrieve content for keywords tag
-     *
-     * @return string
-     */
-    public function getKeywords()
-    {
-        if (empty($this->_data['keywords'])) {
-            $this->_data['keywords'] = $this->_scopeConfig->getValue(
-                'design/head/default_keywords',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['keywords'];
-    }
-
-    /**
-     * Retrieve URL to robots file
-     *
-     * @return string
-     */
-    public function getRobots()
-    {
-        if (empty($this->_data['robots'])) {
-            $this->_data['robots'] = $this->_scopeConfig->getValue(
-                'design/search_engine_robots/default_robots',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['robots'];
-    }
-
-    /**
-     * Get miscellaneous scripts/styles to be included in head before head closing tag
-     *
-     * @return string
-     */
-    public function getIncludes()
-    {
-        if (empty($this->_data['includes'])) {
-            $this->_data['includes'] = $this->_scopeConfig->getValue(
-                'design/head/includes',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-        }
-        return $this->_data['includes'];
-    }
-
-    /**
-     * Getter for path to Favicon
-     *
-     * @return string
-     */
-    public function getFaviconFile()
-    {
-        if (empty($this->_data['favicon_file'])) {
-            $this->_data['favicon_file'] = $this->_getFaviconFile();
-        }
-        return $this->_data['favicon_file'];
-    }
-
-    /**
-     * Retrieve path to Favicon
-     *
-     * @return string
-     */
-    protected function _getFaviconFile()
-    {
-        $folderName = \Magento\Backend\Model\Config\Backend\Image\Favicon::UPLOAD_DIR;
-        $scopeConfig = $this->_scopeConfig->getValue(
-            'design/head/shortcut_icon',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        $path = $folderName . '/' . $scopeConfig;
-        $faviconFile = $this->_storeManager->getStore()
-                ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $path;
-
-        if (!is_null($scopeConfig) && $this->_isFile($path)) {
-            $url = $faviconFile;
-        } else {
-            $url = $this->getViewFileUrl('Magento_Theme::favicon.ico');
-        }
-        return $url;
-    }
-
-    /**
-     * If DB file storage is on - find there, otherwise - just file_exists
-     *
-     * @param string $filename relative file path
-     * @return bool
-     */
-    protected function _isFile($filename)
-    {
-        if ($this->_fileStorageDatabase->checkDbUsage() && !$this->getMediaDirectory()->isFile($filename)) {
-            $this->_fileStorageDatabase->saveFileToFilesystem($filename);
-        }
-        return $this->getMediaDirectory()->isFile($filename);
-    }
-
-    /**
-     * Retrieve locale code
-     *
-     * @return string
-     */
-    public function getLocale()
-    {
-        return substr($this->_localeResolver->getLocaleCode(), 0, 2);
-    }
-
-    /**
-     * Get translation js script
-     *
-     * @return string
-     */
-    public function getTranslatorScript()
-    {
-        return $this->jsTranslation->render();
-    }
-}
diff --git a/app/code/Magento/Theme/Block/Html/Title.php b/app/code/Magento/Theme/Block/Html/Title.php
index ebf789c77fd..2fcff7721a6 100644
--- a/app/code/Magento/Theme/Block/Html/Title.php
+++ b/app/code/Magento/Theme/Block/Html/Title.php
@@ -27,6 +27,15 @@ use Magento\Framework\View\Element\Template;
 
 /**
  * Html page title block
+ *
+ * @method $this setTitleId($titleId)
+ * @method $this setTitleClass($titleClass)
+ * @method $this setTitlePrefix($titlePrefix)
+ * @method $this setTitleSuffix($titleSuffix)
+ * @method string getTitleId()
+ * @method string getTitleClass()
+ * @method string getTitlePrefix()
+ * @method string getTitleSuffix()
  */
 class Title extends \Magento\Framework\View\Element\Template
 {
@@ -35,26 +44,7 @@ class Title extends \Magento\Framework\View\Element\Template
      *
      * @var string
      */
-    protected $_pageTitle;
-
-    /**
-     * @var \Magento\Framework\View\Page\Config
-     */
-    protected $pageConfig;
-
-    /**
-     * @param Template\Context $context
-     * @param \Magento\Framework\View\Page\Config $pageConfig
-     * @param array $data
-     */
-    public function __construct(
-        Template\Context $context,
-        \Magento\Framework\View\Page\Config $pageConfig,
-        array $data = array()
-    ) {
-        $this->pageConfig = $pageConfig;
-        parent::__construct($context, $data);
-    }
+    protected $pageTitle;
 
     /**
      * Provide own page title or pick it from Head Block
@@ -63,10 +53,10 @@ class Title extends \Magento\Framework\View\Element\Template
      */
     public function getPageTitle()
     {
-        if (!empty($this->_pageTitle)) {
-            return $this->_pageTitle;
+        if (!empty($this->pageTitle)) {
+            return $this->pageTitle;
         }
-        return $this->getLayout()->getBlock('head')->getShortTitle();
+        return $this->pageConfig->getShortTitle();
     }
 
     /**
@@ -77,8 +67,6 @@ class Title extends \Magento\Framework\View\Element\Template
      */
     public function setPageTitle($pageTitle)
     {
-        $this->_pageTitle = $pageTitle;
-        $this->pageConfig->setTitle($pageTitle);
-        return $this;
+        $this->pageTitle = $pageTitle;
     }
 }
diff --git a/app/code/Magento/Theme/Model/Favicon/Favicon.php b/app/code/Magento/Theme/Model/Favicon/Favicon.php
new file mode 100644
index 00000000000..bcf5b496ca1
--- /dev/null
+++ b/app/code/Magento/Theme/Model/Favicon/Favicon.php
@@ -0,0 +1,127 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Model\Favicon;
+
+/**
+ * Favicon implementation
+ */
+class Favicon implements \Magento\Framework\View\Page\FaviconInterface
+{
+    /**
+     * @var string
+     */
+    protected $faviconFile;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Core\Helper\File\Storage\Database
+     */
+    protected $fileStorageDatabase;
+
+    /**
+     * @var \Magento\Framework\Filesystem\Directory\ReadInterface
+     */
+    protected $mediaDirectory;
+
+    /**
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase
+     * @param \Magento\Framework\App\Filesystem $filesystem
+     */
+    public function __construct(
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Core\Helper\File\Storage\Database $fileStorageDatabase,
+        \Magento\Framework\App\Filesystem $filesystem
+    ) {
+        $this->storeManager = $storeManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->fileStorageDatabase = $fileStorageDatabase;
+        $this->mediaDirectory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MEDIA_DIR);
+    }
+
+    /**
+     * @return string
+     */
+    public function getFaviconFile()
+    {
+        if (null === $this->faviconFile) {
+            $this->faviconFile = $this->prepareFaviconFile();
+        }
+        return $this->faviconFile;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDefaultFavicon()
+    {
+        return 'Magento_Theme::favicon.ico';
+    }
+
+    /**
+     * @return string
+     */
+    protected function prepareFaviconFile()
+    {
+        $folderName = \Magento\Backend\Model\Config\Backend\Image\Favicon::UPLOAD_DIR;
+        $scopeConfig = $this->scopeConfig->getValue(
+            'design/head/shortcut_icon',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+        $path = $folderName . '/' . $scopeConfig;
+        $faviconUrl = $this->storeManager->getStore()
+                ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $path;
+
+        if (!is_null($scopeConfig) && $this->checkIsFile($path)) {
+            return $faviconUrl;
+        }
+
+        return false;
+    }
+
+    /**
+     * If DB file storage is on - find there, otherwise - just file_exists
+     *
+     * @param string $filename relative file path
+     * @return bool
+     */
+    protected function checkIsFile($filename)
+    {
+        if ($this->fileStorageDatabase->checkDbUsage() && !$this->mediaDirectory->isFile($filename)) {
+            $this->fileStorageDatabase->saveFileToFilesystem($filename);
+        }
+        return $this->mediaDirectory->isFile($filename);
+    }
+}
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index 7df27d08ce9..eae6bdbc4cc 100644
--- a/app/code/Magento/Theme/composer.json
+++ b/app/code/Magento/Theme/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-translation": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-translation": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Theme/etc/module.xml b/app/code/Magento/Theme/etc/module.xml
index 4cb1528cf6d..2653ba37153 100644
--- a/app/code/Magento/Theme/etc/module.xml
+++ b/app/code/Magento/Theme/etc/module.xml
@@ -35,7 +35,7 @@
             <module name="Magento_Customer"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Cms"/>
-            <module name="Magento_Translation"/>
+            <module name="Magento_Translation" type="soft"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Theme/view/adminhtml/layout/admin-1column.xml b/app/code/Magento/Theme/view/adminhtml/layout/admin-1column.xml
index 553178f7cda..3a3f67f29c7 100644
--- a/app/code/Magento/Theme/view/adminhtml/layout/admin-1column.xml
+++ b/app/code/Magento/Theme/view/adminhtml/layout/admin-1column.xml
@@ -26,15 +26,16 @@
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
     <container name="root">
         <container name="backend.page">
+            <container name="after.body.start" as="after.body.start" label="Page Top" before="-"/>
             <container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper">
-                <container name="notification.window" as="notification_window"/>
-                <container name="global.notices" as="global_notices"/>
-                <container name="page.header.wrapper" as="page_header_wrapper" htmlTag="div" htmlClass="page-header-wrapper">
+                <container name="notification.window" as="notification_window" before="-"/>
+                <container name="global.notices" as="global_notices" after="notification.window"/>
+                <container name="page.header.wrapper" as="page_header_wrapper" after="global.notices" htmlTag="div" htmlClass="page-header-wrapper">
                     <container name="header" htmlTag="header" htmlClass="page-header"/>
                 </container>
-                <container name="page.menu" as="page.menu"/>
+                <container name="page.menu" as="page.menu" after="page.header.wrapper"/>
                 <container name="notifications" as="notifications" after="page.menu"/>
-                <container name="page.breadcrumbs" as="page.breadcrumbs"/>
+                <container name="page.breadcrumbs" after="notifications" as="page.breadcrumbs"/>
 
                 <container name="page.formkey" as="page.formkey"/>
                 <container name="page.js.translate" as="page.js.translate"/>
@@ -50,11 +51,11 @@
                     </container>
                 </container>
                 <container name="js" as="js" label="JavaScript"/>
-                <container name="page.footer.wrapper" as="page_footer_wrapper" htmlTag="div" htmlClass="page-footer-wrapper">
+                <container name="page.footer.wrapper" as="page_footer_wrapper" after="page.content" htmlTag="div" htmlClass="page-footer-wrapper">
                     <container name="footer" htmlTag="footer" htmlClass="page-footer"/>
                 </container>
             </container>
-            <container name="before.body.end" as="before_body_end" label="Before Body End"/>
+            <container name="before.body.end" as="before_body_end" label="Before Body End" after="-"/>
         </container>
     </container>
 </layout>
diff --git a/app/code/Magento/Theme/view/adminhtml/layout/admin-2columns-left.xml b/app/code/Magento/Theme/view/adminhtml/layout/admin-2columns-left.xml
index 97dbcaa0e3f..1699e607438 100644
--- a/app/code/Magento/Theme/view/adminhtml/layout/admin-2columns-left.xml
+++ b/app/code/Magento/Theme/view/adminhtml/layout/admin-2columns-left.xml
@@ -26,15 +26,16 @@
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
     <container name="root">
         <container name="backend.page">
+            <container name="after.body.start" as="after.body.start" label="Page Top" before="-"/>
             <container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper">
-                <container name="notification.window" as="notification_window"/>
-                <container name="global.notices" as="global_notices"/>
-                <container name="page.header.wrapper" as="page_header_wrapper" htmlTag="div" htmlClass="page-header-wrapper">
+                <container name="notification.window" as="notification_window" before="-"/>
+                <container name="global.notices" as="global_notices" after="notification.window"/>
+                <container name="page.header.wrapper" as="page_header_wrapper" after="global.notices" htmlTag="div" htmlClass="page-header-wrapper">
                     <container name="header" htmlTag="header" htmlClass="page-header"/>
                 </container>
-                <container name="page.menu" as="page.menu"/>
+                <container name="page.menu" as="page.menu" after="page.header.wrapper"/>
                 <container name="notifications" as="notifications" after="page.menu"/>
-                <container name="page.breadcrumbs" as="page.breadcrumbs"/>
+                <container name="page.breadcrumbs" after="notifications" as="page.breadcrumbs"/>
 
                 <container name="page.formkey" as="page.formkey"/>
                 <container name="page.js.translate" as="page.js.translate"/>
@@ -49,17 +50,17 @@
                         <container name="main.col" as="main-col" htmlId="container" htmlTag="div" htmlClass="main-col">
                             <container name="content" as="content"/>
                         </container>
-                        <container name="side.col" as="side-col" htmlId="page:left" htmlTag="div" htmlClass="side-col">
+                        <container name="side.col" as="side-col" after="main.col" htmlId="page:left" htmlTag="div" htmlClass="side-col">
                             <container name="left" as="left"/>
                         </container>
                     </container>
                 </container>
                 <container name="js" as="js" label="JavaScript"/>
-                <container name="page.footer.wrapper" as="page_footer_wrapper" htmlTag="div">
+                <container name="page.footer.wrapper" as="page_footer_wrapper" after="page.content" htmlTag="div" htmlClass="page-footer-wrapper">
                     <container name="footer" htmlTag="footer" htmlClass="page-footer"/>
                 </container>
             </container>
-            <container name="before.body.end" as="before_body_end" label="Before Body End"/>
+            <container name="before.body.end" as="before_body_end" label="Before Body End" after="-"/>
         </container>
     </container>
 </layout>
diff --git a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_edit.xml b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_edit.xml
index 90c87ce8668..2552de7210d 100644
--- a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_edit.xml
+++ b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_theme_edit.xml
@@ -24,39 +24,13 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <action method="setCanLoadTinyMce">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-fileuploader-css-jquery-fileupload-ui-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/fileUploader/css/jquery.fileupload-ui.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-theme-css-theme-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Theme::css/theme.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="prototype-windows-themes-default-css">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/windows/themes/default.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="magento-theme-js-bootstrap-js">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Theme::js/bootstrap.js</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
+        <css src="Magento_Theme::css/theme.css"/>
+        <css src="prototype/windows/themes/default.css"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+        <link src="Magento_Theme::js/bootstrap.js"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Theme\Block\Adminhtml\System\Design\Theme\Edit" name="theme_edit"/>
     </referenceContainer>
diff --git a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_wysiwyg_files_index.xml b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_wysiwyg_files_index.xml
index 32769a0aa4c..07ec1aa5999 100644
--- a/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_wysiwyg_files_index.xml
+++ b/app/code/Magento/Theme/view/adminhtml/layout/adminhtml_system_design_wysiwyg_files_index.xml
@@ -25,7 +25,6 @@
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <remove name="footer"/>
-    <remove name="head"/>
     <referenceContainer name="left">
         <block class="Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Tree" name="wysiwyg_files.tree" template="Magento_Cms::browser/tree.phtml"/>
     </referenceContainer>
diff --git a/app/code/Magento/Theme/view/adminhtml/templates/empty.phtml b/app/code/Magento/Theme/view/adminhtml/templates/empty.phtml
deleted file mode 100644
index 46b4460deb7..00000000000
--- a/app/code/Magento/Theme/view/adminhtml/templates/empty.phtml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?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.
- *
- * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
-<head>
-<?php echo $this->getChildHtml('head') ?>
-</head>
-<body class="page-popup<?php echo $this->getBodyClass()?$this->getBodyClass() : ''?>">
-<div>
-    <?php echo $this->getChildHtml('after_body_start') ?>
-    <?php echo $this->getChildHtml('global_messages') ?>
-    <?php echo $this->getChildHtml('content') ?>
-    <?php echo $this->getChildHtml('before_body_end') ?>
-</div>
-<?php echo $this->getAbsoluteFooter() ?>
-</body>
-</html>
diff --git a/app/code/Magento/Theme/view/base/layout/empty.xml b/app/code/Magento/Theme/view/base/layout/empty.xml
index cf6f0a936ed..160be1b0bf4 100644
--- a/app/code/Magento/Theme/view/base/layout/empty.xml
+++ b/app/code/Magento/Theme/view/base/layout/empty.xml
@@ -25,17 +25,17 @@
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
     <container name="root">
-        <container name="after.body.start" as="after.body.start" label="Page Top"/>
+        <container name="after.body.start" as="after.body.start" before="-" label="Page Top"/>
         <container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper">
-            <container name="global.notices" as="global_notices"/>
+            <container name="global.notices" as="global_notices" before="-"/>
             <container name="main.content" htmlTag="section" htmlId="maincontent" htmlClass="page main">
                 <container name="columns.top" label="Before Main Columns"/>
                 <container name="columns" htmlTag="div" htmlClass="columns">
                     <container name="main" label="Main Content Container" htmlTag="div" htmlClass="column main"/>
                 </container>
             </container>
-            <container name="page.bottom" as="page_bottom" label="Before Page Footer Container" htmlTag="div" htmlClass="page bottom"/>
-            <container name="before.body.end" as="before_body_end" label="Page Bottom"/>
+            <container name="page.bottom" as="page_bottom" label="Before Page Footer Container" after="main.content" htmlTag="div" htmlClass="page bottom"/>
+            <container name="before.body.end" as="before_body_end" after="-" label="Page Bottom"/>
         </container>
     </container>
 </layout>
diff --git a/app/code/Magento/Theme/view/base/templates/root.phtml b/app/code/Magento/Theme/view/base/templates/root.phtml
index 3308150a6f5..69698b5ae3b 100644
--- a/app/code/Magento/Theme/view/base/templates/root.phtml
+++ b/app/code/Magento/Theme/view/base/templates/root.phtml
@@ -23,17 +23,12 @@
  */
 ?>
 <!doctype html>
-<html xmlns="http://www.w3.org/1999/xhtml"<?php echo $htmlAttributes ?>>
-<head>
-    <meta charset="utf-8"/>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
-    <?php echo $headContent ?>
-</head>
-<body data-container="body" data-mage-init='{"loaderAjax": {}, "loader": {}}'<?php
-    echo !empty($bodyClasses) ? ' class="' . $bodyClasses . '"' : '';
-    echo !empty($bodyAttributes) ? $bodyAttributes : '';
-?>>
-<?php echo $layoutContent ?>
-</body>
+<html xmlns="http://www.w3.org/1999/xhtml" <?php echo $htmlAttributes ?>>
+    <head <?php echo $headAttributes ?>>
+        <?php echo $requireJs ?>
+        <?php echo $headContent ?>
+    </head>
+    <body data-container="body" data-mage-init='{"loaderAjax": {}, "loader": {}}' <?php echo $bodyAttributes ?>>
+        <?php echo $layoutContent ?>
+    </body>
 </html>
diff --git a/app/code/Magento/Theme/view/frontend/layout/1column.xml b/app/code/Magento/Theme/view/frontend/layout/1column.xml
index 8d7ec286aad..e68b01cbe0f 100644
--- a/app/code/Magento/Theme/view/frontend/layout/1column.xml
+++ b/app/code/Magento/Theme/view/frontend/layout/1column.xml
@@ -26,8 +26,8 @@
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
     <update handle="empty"/>
     <referenceContainer name="page.wrapper">
-        <container name="header.container" as="header_container" label="Page Header Container"  htmlTag="header" htmlClass="page-header" after="global.notices"/>
+        <container name="header.container" as="header_container" label="Page Header Container"  htmlTag="header" htmlClass="page-header" before="main.content"/>
         <container name="page.top" as="page_top" label="After Page Header" after="header.container"/>
-        <container name="footer-container" as="footer" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer" />
+        <container name="footer-container" as="footer" before="before.body.end" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer" />
     </referenceContainer>
 </layout>
diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml
index 92aabd50f31..1c36826b22d 100644
--- a/app/code/Magento/Theme/view/frontend/layout/default.xml
+++ b/app/code/Magento/Theme/view/frontend/layout/default.xml
@@ -25,10 +25,13 @@
 -->
 <page layout="3columns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <!-- Temporary solution -->
-    <block class="Magento\Theme\Block\Html\Head" name="head" as="head" before="-">
+    <block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::js/require_js.phtml" />
+    <referenceContainer name="after.body.start">
+        <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/>
         <block class="Magento\Framework\View\Element\Js\Cookie" name="js_cookies" template="Magento_Theme::js/cookie.phtml"/>
-    </block>
-    <block class="Magento\Theme\Block\Html\Body" name="body.class"/>
+        <block class="Magento\Theme\Block\Html\Notices" name="global_notices" template="html/notices.phtml"/>
+    </referenceContainer>
+
     <referenceBlock name="top.links">
         <block class="Magento\Theme\Block\Html\Header" name="header" as="header" before="-">
             <arguments>
@@ -37,10 +40,6 @@
         </block>
     </referenceBlock>
 
-    <referenceContainer name="after.body.start">
-        <block class="Magento\Theme\Block\Html\Notices" name="global_notices" template="html/notices.phtml"/>
-    </referenceContainer>
-
     <referenceContainer name="header.container">
         <container name="header.panel" label="Page Header Panel" htmlTag="div" htmlClass="panel header">
             <block class="Magento\Framework\View\Element\Template" name="skip_to_content" template="Magento_Theme::html/skip.phtml">
@@ -87,15 +86,17 @@
         <container name="page.bottom" label="Before Page Footer" htmlTag="div" htmlClass="content"/>
     </referenceContainer>
     <referenceContainer name="footer-container">
-        <container name="footer" as="footer" label="Page Footer" htmlTag="div" htmlClass="footer content">
-            <block class="Magento\Store\Block\Switcher" name="store_switcher" as="store_switcher" template="switch/stores.phtml"/>
-            <block class="Magento\Framework\View\Element\Html\Links" name="footer_links">
-                <arguments>
-                    <argument name="css_class" xsi:type="string">footer links</argument>
-                </arguments>
-            </block>
-            <block class="Magento\Theme\Block\Html\Footer" name="copyright" template="html/copyright.phtml"/>
-            <block class="Magento\Framework\View\Element\Template" name="report.bugs" template="Magento_Theme::html/bugreport.phtml" />
+        <container name="footer.wrapper" as="footer-wrapper" label="Page Footer Wrapper" htmlTag="div" htmlClass="page-footer">
+            <container name="footer" as="footer" label="Page Footer" htmlTag="div" htmlClass="footer content">
+                <block class="Magento\Store\Block\Switcher" name="store_switcher" as="store_switcher" template="switch/stores.phtml"/>
+                <block class="Magento\Framework\View\Element\Html\Links" name="footer_links">
+                    <arguments>
+                        <argument name="css_class" xsi:type="string">footer links</argument>
+                    </arguments>
+                </block>
+                <block class="Magento\Theme\Block\Html\Footer" name="copyright" template="html/copyright.phtml"/>
+                <block class="Magento\Framework\View\Element\Template" name="report.bugs" template="Magento_Theme::html/bugreport.phtml" />
+            </container>
         </container>
     </referenceContainer>
 
diff --git a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml
index 02fcae5ac29..4b58bfeed28 100644
--- a/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml
+++ b/app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml
@@ -24,40 +24,20 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head.components">
-        <block class="Magento\Framework\View\Element\Template" name="theme_page_head_components" template="Magento_Theme::js/components.phtml"/>
-    </referenceBlock>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-calendar-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/calendar.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="requirejs">
-            <arguments>
-                <argument name="file" xsi:type="string">requirejs/require.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="app-config" after="jquery">
-            <arguments>
-                <argument name="file" xsi:type="string">app-config.js</argument>
-            </arguments>
-        </block>
+    <head>
+        <meta name="x_ua_compatible" content="IE=edge,chrome=1"/>
+        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
+        <css src="mage/calendar.css" />
+        <script src="requirejs/require.js" />
         <!-- /**
         TODO: remove jQuery. jQuery could be loaded through RequireJS. But only in case ALL MODULES ARE AMD MODULES.
         Detail: http://requirejs.org/docs/jquery.html#noconflictmap
         */ -->
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery" after="requirejs">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/jquery.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="jquery-no-conflict" after="jquery">
-            <arguments>
-                <argument name="file" xsi:type="string">mage/jquery-no-conflict.js</argument>
-            </arguments>
-        </block>
-
-        <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Theme::js/components.phtml"/>
-    </referenceBlock>
+        <script src="jquery/jquery.js" />
+        <script src="app-config.js" />
+        <script src="mage/jquery-no-conflict.js" />
+    </head>
+    <referenceContainer name="after.body.start">
+        <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Theme::js/components.phtml" before="-" />
+    </referenceContainer>
 </page>
diff --git a/app/code/Magento/Theme/view/frontend/layout/print.xml b/app/code/Magento/Theme/view/frontend/layout/print.xml
deleted file mode 100644
index 510a30bedce..00000000000
--- a/app/code/Magento/Theme/view/frontend/layout/print.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Theme\Block\Html" template="print.phtml">
-            <block class="Magento\Theme\Block\Html\Head" name="head" as="head"/>
-            <container name="after_body_start" as="after_body_start" label="Page Top"/>
-            <container name="main" as="main" label="Main Content Container" htmlTag="div" htmlClass="column main">
-                <container name="content.top" label="Main Content Top"/>
-                <container name="content" label="Main Content Area"/>
-                <container name="content.aside" label="Main Content Aside"/>
-                <container name="content.bottom" label="Main Content Bottom"/>
-            </container>
-        </block>
-    </container>
-    <update handle="default_head_blocks"/>
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="css-print-css">
-            <arguments>
-                <argument name="file" xsi:type="string">css/print.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
-</layout>
diff --git a/app/code/Magento/Theme/view/frontend/templates/html/head.phtml b/app/code/Magento/Theme/view/frontend/templates/html/head.phtml
deleted file mode 100644
index d25e01c66b8..00000000000
--- a/app/code/Magento/Theme/view/frontend/templates/html/head.phtml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<meta http-equiv="Content-Type" content="<?php echo $this->getContentType() ?>"/>
-<title><?php echo $this->getTitle() ?></title>
-<meta name="description" content="<?php echo $this->escapeHtml($this->getDescription())?>"/>
-<meta name="keywords" content="<?php echo $this->escapeHtml($this->getKeywords())?>"/>
-<meta name="robots" content="<?php echo $this->escapeHtml($this->getRobots())?>"/>
-<link rel="icon" href="<?php echo $this->getFaviconFile(); ?>" type="image/x-icon"/>
-<link rel="shortcut icon" href="<?php echo $this->getFaviconFile(); ?>" type="image/x-icon"/>
-<script type="text/javascript">
-    var require = {
-    	"baseUrl": "<?php echo $this->getViewFileUrl('/') ?>",
-    	"paths": {
-    		"jquery/ui": "jquery/jquery-ui"
-    	}
-    };
-</script>
-<?php echo $this->getCssJsHtml() ?>
-<?php echo $this->getChildHtml() ?>
-<?php echo $this->getIncludes() ?>
-<?php echo $this->getTranslatorScript(); ?>
diff --git a/app/code/Magento/Theme/view/frontend/templates/js/require_js.phtml b/app/code/Magento/Theme/view/frontend/templates/js/require_js.phtml
new file mode 100644
index 00000000000..633765081d1
--- /dev/null
+++ b/app/code/Magento/Theme/view/frontend/templates/js/require_js.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<script type="text/javascript">
+    var require = {
+        "baseUrl": "<?php echo $this->getViewFileUrl('/') ?>",
+        "paths": {
+            "jquery/ui": "jquery/jquery-ui"
+        }
+    };
+</script>
diff --git a/app/code/Magento/Theme/view/frontend/templates/popup.phtml b/app/code/Magento/Theme/view/frontend/templates/popup.phtml
deleted file mode 100644
index 7a21517ac00..00000000000
--- a/app/code/Magento/Theme/view/frontend/templates/popup.phtml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php
-/**
- * Template for \Magento\Theme\Block\Html
- */
-$bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
-?>
-<!doctype html>
-<html lang="<?php echo $this->getLang() ?>" class="no-js">
-<head>
-    <meta charset="utf-8"/>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
-    <?php echo $this->getChildHtml('head') ?>
-</head>
-<body class="page popup<?php echo $bodyCss ?>"
-      data-container="body"
-      <?php echo $this->getAddAttribute() ?>
-      data-mage-init='{"loaderAjax": {}, "loader": {}}'>
-    <?php echo $this->getChildHtml('after_body_start') ?>
-    <div class="page-wrapper">
-        <?php echo $this->getChildHtml('main') ?>
-    </div>
-    <?php echo $this->getChildHtml('before_body_end') ?>
-    <?php echo $this->getAbsoluteFooter() ?>
-</body>
-</html>
diff --git a/app/code/Magento/Theme/view/frontend/templates/print.phtml b/app/code/Magento/Theme/view/frontend/templates/print.phtml
deleted file mode 100644
index d303d183fd2..00000000000
--- a/app/code/Magento/Theme/view/frontend/templates/print.phtml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php
-/**
- * Template for \Magento\Theme\Block\Html
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
-<head>
-<?php echo $this->getChildHtml('head') ?>
-</head>
-<body class="page print<?php echo $this->getBodyClass()?$this->getBodyClass():'' ?>"
-      data-container="body"
-      <?php echo $this->getAddAttribute() ?>
-      data-mage-init='{"loaderAjax": {}, "loader": {}}'>
-    <?php echo $this->getChildHtml('after_body_start') ?>
-    <div class="page print wrapper">
-        <header class="header print">
-            <img src="<?php echo $this->getPrintLogoUrl() ? $this->getPrintLogoUrl() : $this->getViewFileUrl('images/logo.gif') ?>" class="logo" alt="" />
-            <?php if ($this->getPrintLogoText()):?>
-                <address><?php echo nl2br($this->escapeHtml($this->getPrintLogoText())) ?></address>
-            <?php endif;?>
-        </header>
-        <div class="page print main">
-            <?php echo $this->getChildHtml('main') ?>
-        </div>
-        <footer class="page print footer">
-            <div class="actions">
-                <button type="button" title="<?php echo __('Close Window') ?>" class="action close" onclick="window.close();"><span><?php echo __('Close Window') ?></span></button>
-            </div>
-        </footer>
-        <?php echo $this->getChildHtml('before_body_end') ?>
-    </div>
-    <?php echo $this->getAbsoluteFooter() ?>
-</body>
-</html>
diff --git a/app/code/Magento/Translation/Block/Js.php b/app/code/Magento/Translation/Block/Js.php
index 428e70f58a5..f6e8315ebf4 100644
--- a/app/code/Magento/Translation/Block/Js.php
+++ b/app/code/Magento/Translation/Block/Js.php
@@ -24,11 +24,11 @@
 
 namespace Magento\Translation\Block;
 
-use Magento\Framework\View\Element\BlockInterface;
+use Magento\Framework\View\Element\Template;
 use \Magento\Translation\Model\Js as DataProvider;
 use \Magento\Framework\Translate\InlineInterface as InlineTranslator;
 
-class Js
+class Js extends \Magento\Framework\View\Element\Template
 {
     /**
      * Data provider model
@@ -45,27 +45,29 @@ class Js
     protected $translateInline;
 
     /**
+     * @param Template\Context $context
      * @param DataProvider $dataProvider
      * @param InlineTranslator $translateInline
+     * @param array $data
      */
     public function __construct(
+        Template\Context $context,
         DataProvider $dataProvider,
-        InlineTranslator $translateInline
+        InlineTranslator $translateInline,
+        array $data = array()
     ) {
+        parent::__construct($context, $data);
         $this->dataProvider = $dataProvider;
         $this->translateInline = $translateInline;
     }
 
     /**
-     * Render js translation
-     *
      * @return string
      */
-    public function render()
+    public function getTranslatedJson()
     {
         $json = \Zend_Json::encode($this->dataProvider->getTranslateData());
         $this->translateInline->processResponseBody($json, false);
-        $script = 'require(["jquery", "mage/translate"], function($){ $.mage.translate.add(' . $json . '); })';
-        return '<script type="text/javascript">//<![CDATA[' . "\n{$script}\n" . '//]]></script>';
+        return $json;
     }
 }
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index 57882625cfc..ecb509392ce 100644
--- a/app/code/Magento/Translation/composer.json
+++ b/app/code/Magento/Translation/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml
new file mode 100644
index 00000000000..29d8cd3f19d
--- /dev/null
+++ b/app/code/Magento/Translation/view/base/templates/translate.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php /** @var $this \Magento\Translation\Block\Js */ ?>
+<script type="text/javascript">
+//<![CDATA[
+    require(
+        ["jquery", "mage/translate"], function($){ $.mage.translate.add( <?php echo $this->getTranslatedJson() ?> ); }
+    )
+// ]]>
+</script>
diff --git a/app/code/Magento/Ui/AbstractView.php b/app/code/Magento/Ui/AbstractView.php
new file mode 100644
index 00000000000..3c701535fa2
--- /dev/null
+++ b/app/code/Magento/Ui/AbstractView.php
@@ -0,0 +1,293 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui;
+
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigInterface;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Asset\Repository;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Abstract class AbstractView
+ */
+abstract class AbstractView extends Template implements UiComponentInterface
+{
+    /**
+     * @var ConfigBuilderInterface
+     */
+    protected $configurationBuilder;
+
+    /**
+     * Root view component
+     *
+     * @var UiComponentInterface
+     */
+    protected $rootComponent;
+
+    /**
+     * View configuration data
+     *
+     * @var ConfigInterface
+     */
+    protected $configuration;
+
+    /**
+     * Render context
+     *
+     * @var Context
+     */
+    protected $renderContext;
+
+    /**
+     * @var ConfigFactory
+     */
+    protected $configurationFactory;
+
+    /**
+     * Content type factory
+     *
+     * @var ContentTypeFactory
+     */
+    protected $contentTypeFactory;
+
+    /**
+     * Asset service
+     *
+     * @var Repository
+     */
+    protected $assetRepo;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param Context $renderContext
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param ConfigFactory $configFactory
+     * @param ConfigBuilderInterface $configBuilder
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        Context $renderContext,
+        ContentTypeFactory $contentTypeFactory,
+        ConfigFactory $configFactory,
+        ConfigBuilderInterface $configBuilder,
+        array $data = []
+    ) {
+        $this->renderContext = $renderContext;
+        $this->contentTypeFactory = $contentTypeFactory;
+        $this->assetRepo = $context->getAssetRepository();
+        $this->configurationFactory = $configFactory;
+        $this->configurationBuilder = $configBuilder;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Update data
+     *
+     * @param array $arguments
+     * @return void
+     */
+    public function update(array $arguments = [])
+    {
+        if ($arguments) {
+            $this->_data = array_merge_recursive($this->_data, $arguments);
+        }
+    }
+
+    /**
+     * Prepare component data
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        //
+    }
+
+    /**
+     * Render content
+     *
+     * @return string
+     */
+    public function render()
+    {
+        $result = $this->contentTypeFactory->get($this->renderContext->getAcceptType())
+            ->render($this, $this->getContentTemplate());
+        return $result;
+    }
+
+    /**
+     * Render label
+     *
+     * @return mixed|string
+     */
+    public function renderLabel()
+    {
+        $result = $this->contentTypeFactory->get($this->renderContext->getAcceptType())
+            ->render($this, $this->getLabelTemplate());
+        return $result;
+    }
+
+    /**
+     * Render element
+     *
+     * @param string $elementName
+     * @param array $arguments
+     * @return mixed|string
+     */
+    public function renderElement($elementName, array $arguments)
+    {
+        $element = $this->renderContext->getRender()->createUiComponent($elementName);
+        $prevData = $element->getData();
+        $element->update($arguments);
+        $result = $element->render();
+        $element->setData($prevData);
+        return $result;
+    }
+
+    /**
+     * Render component label
+     *
+     * @param string $elementName
+     * @param array $arguments
+     * @return string
+     */
+    public function renderElementLabel($elementName, array $arguments)
+    {
+        $element = $this->renderContext->getRender()->createUiComponent($elementName);
+        $prevData = $element->getData();
+        $element->update($arguments);
+        $result = $element->renderLabel();
+        $element->setData($prevData);
+        return $result;
+    }
+
+    /**
+     * Shortcut for rendering as HTML
+     * (used for backward compatibility with standard rendering mechanism via layout interface)
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        return $this->render();
+    }
+
+    /**
+     * Getting label template
+     *
+     * @return string|false
+     */
+    public function getLabelTemplate()
+    {
+        return 'Magento_Ui::label/default.phtml';
+    }
+
+    /**
+     * Getting content template
+     *
+     * @return string|false
+     */
+    public function getContentTemplate()
+    {
+        return $this->getData('content_template');
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    protected function getDefaultConfiguration()
+    {
+        return [];
+    }
+
+    /**
+     * Get render engine
+     *
+     * @return ContentType\ContentTypeInterface
+     */
+    protected function getRenderEngine()
+    {
+        return $this->contentTypeFactory->get($this->renderContext->getAcceptType());
+    }
+
+    /**
+     * Get name component instance
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->configuration->getName();
+    }
+
+    /**
+     * Get parent name component instance
+     *
+     * @return string
+     */
+    public function getParentName()
+    {
+        return $this->configuration->getParentName();
+    }
+
+    /**
+     * Get configuration builder
+     *
+     * @return ConfigBuilderInterface
+     */
+    public function getConfigurationBuilder()
+    {
+        return $this->configurationBuilder;
+    }
+
+    /**
+     * Get component configuration
+     *
+     * @return ConfigInterface
+     */
+    public function getConfiguration()
+    {
+        return $this->configuration;
+    }
+
+    /**
+     * Get render context
+     *
+     * @return Context
+     */
+    public function getRenderContext()
+    {
+        return $this->renderContext;
+    }
+}
diff --git a/app/code/Magento/Ui/Configuration.php b/app/code/Magento/Ui/Configuration.php
new file mode 100644
index 00000000000..38b4d40836e
--- /dev/null
+++ b/app/code/Magento/Ui/Configuration.php
@@ -0,0 +1,127 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui;
+
+use Magento\Framework\View\Element\UiComponent\ConfigInterface;
+
+/**
+ * Class Configuration
+ */
+class Configuration implements ConfigInterface
+{
+    /**
+     * Configuration data
+     *
+     * @var array
+     */
+    protected $configuration = [];
+
+    /**
+     * Name of owner
+     *
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * Name of parent owner
+     *
+     * @var string
+     */
+    protected $parentName;
+
+    /**
+     * Constructor
+     *
+     * @param string $name
+     * @param  string $parentName
+     * @param array $configuration
+     */
+    public function __construct($name, $parentName, $configuration = [])
+    {
+        $this->name = $name;
+        $this->parentName = $parentName;
+        $this->configuration = $configuration;
+    }
+
+    /**
+     * Get configuration data
+     *
+     * @param string|null $key
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        if ($key === null) {
+            return (array)$this->configuration;
+        }
+        return isset($this->configuration[$key]) ? $this->configuration[$key] : null;
+    }
+
+    /**
+     * Add configuration data
+     *
+     * @param string $key
+     * @param mixed $data
+     * @return mixed
+     */
+    public function addData($key, $data)
+    {
+        if (!isset($this->configuration[$key])) {
+            $this->configuration[$key] = $data;
+        }
+    }
+
+    /**
+     * Update configuration data
+     *
+     * @param string $key
+     * @param mixed $data
+     * @return mixed
+     */
+    public function updateData($key, $data)
+    {
+        $this->configuration[$key] = $data;
+    }
+
+    /**
+     * Get owner name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Get owner parent name
+     *
+     * @return string
+     */
+    public function getParentName()
+    {
+        return $this->parentName;
+    }
+}
diff --git a/app/code/Magento/Ui/ConfigurationStorage.php b/app/code/Magento/Ui/ConfigurationStorage.php
new file mode 100644
index 00000000000..7a23aa4a902
--- /dev/null
+++ b/app/code/Magento/Ui/ConfigurationStorage.php
@@ -0,0 +1,294 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui;
+
+use Magento\Framework\Data\Collection as DataCollection;
+use Magento\Framework\View\Element\UiComponent\ConfigInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface;
+
+/**
+ * Class ConfigurationStorage
+ */
+class ConfigurationStorage implements ConfigStorageInterface
+{
+    /**
+     * Components configuration storage
+     *
+     * @var array
+     */
+    protected $componentStorage = [];
+
+    /**
+     * Data storage
+     *
+     * @var array
+     */
+    protected $dataStorage = [];
+
+    /**
+     * Meta storage
+     *
+     * @var array
+     */
+    protected $metaStorage = [];
+
+    /**
+     * Data collection storage
+     *
+     * @var DataCollection[]
+     */
+    protected $collectionStorage = [];
+
+    /**
+     * Global data storage
+     *
+     * @var array
+     */
+    protected $globalDataStorage = [];
+
+    /**
+     * Add components configuration
+     *
+     * @param ConfigInterface $configuration
+     * @return void
+     */
+    public function addComponentsData(ConfigInterface $configuration)
+    {
+        if (!isset($this->componentStorage[$configuration->getName()])) {
+            $this->componentStorage[$configuration->getName()] = $configuration;
+        }
+    }
+
+    /**
+     * Remove components configuration
+     *
+     * @param ConfigInterface $configuration
+     * @return void
+     */
+    public function removeComponentsData(ConfigInterface $configuration)
+    {
+        unset($this->componentStorage[$configuration->getName()]);
+    }
+
+    /**
+     * Get components configuration
+     *
+     * @param string|null $name
+     * @return ConfigInterface|null|array
+     */
+    public function getComponentsData($name = null)
+    {
+        if ($name === null) {
+            return $this->componentStorage;
+        }
+        return isset($this->componentStorage[$name]) ? $this->componentStorage[$name] : null;
+    }
+
+    /**
+     * Add data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function addData($key, array $data)
+    {
+        if (!isset($this->dataStorage[$key])) {
+            $this->dataStorage[$key] = $data;
+        }
+    }
+
+    /**
+     * Remove data in storage
+     *
+     * @param string $key
+     * @return void
+     */
+    public function removeData($key)
+    {
+        unset($this->dataStorage[$key]);
+    }
+
+    /**
+     * Get data from storage
+     *
+     * @param string|null $key
+     * @return array|null
+     */
+    public function getData($key = null)
+    {
+        if ($key === null) {
+            return $this->dataStorage;
+        }
+        return isset($this->dataStorage[$key]) ? $this->dataStorage[$key] : null;
+    }
+
+    /**
+     * Update data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function updateData($key, array $data)
+    {
+        if (isset($this->dataStorage[$key])) {
+            $this->dataStorage[$key] = $data;
+        }
+    }
+
+    /**
+     * Add meta data
+     *
+     * @param string $key
+     * @param array $data
+     * @return mixed
+     */
+    public function addMeta($key, array $data)
+    {
+        if (!isset($this->metaStorage[$key])) {
+            $this->metaStorage[$key] = $data;
+        }
+    }
+
+    /**
+     * Remove meta data
+     *
+     * @param string $key
+     * @return array
+     */
+    public function removeMeta($key)
+    {
+        unset($this->metaStorage[$key]);
+    }
+
+    /**
+     * Get meta data
+     *
+     * @param string|null $key
+     * @return array
+     */
+    public function getMeta($key = null)
+    {
+        if ($key === null) {
+            return $this->metaStorage;
+        }
+        return isset($this->metaStorage[$key]) ? $this->metaStorage[$key] : null;
+    }
+
+    /**
+     * Update meta data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function updateMeta($key, array $data)
+    {
+        if (isset($this->metaStorage[$key])) {
+            $this->metaStorage[$key] = $data;
+        }
+    }
+
+    /**
+     * Set data collection
+     *
+     * @param string $key
+     * @param DataCollection $dataCollection
+     * @return void
+     */
+    public function addDataCollection($key, DataCollection $dataCollection)
+    {
+        if (!isset($this->collectionStorage[$key])) {
+            $this->collectionStorage[$key] = $dataCollection;
+        }
+    }
+
+    /**
+     * Get data collection
+     *
+     * @param string|null $key
+     * @return DataCollection|null
+     */
+    public function getDataCollection($key = null)
+    {
+        if ($key === null) {
+            return $this->collectionStorage;
+        }
+        return isset($this->collectionStorage[$key]) ? $this->collectionStorage[$key] : null;
+    }
+
+    /**
+     * Update data collection in storage
+     *
+     * @param string $key
+     * @param DataCollection $dataCollection
+     * @return mixed
+     */
+    public function updateDataCollection($key, DataCollection $dataCollection)
+    {
+        if (isset($this->collectionStorage[$key])) {
+            $this->collectionStorage[$key] = $dataCollection;
+        }
+    }
+
+    /**
+     * Add cloud data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function addGlobalData($key, array $data)
+    {
+        if (!isset($this->globalDataStorage[$key])) {
+            $this->globalDataStorage[$key] = $data;
+        }
+    }
+
+    /**
+     * Remove cloud data in storage
+     *
+     * @param string $key
+     * @return void
+     */
+    public function removeGlobalData($key)
+    {
+        unset($this->globalDataStorage[$key]);
+    }
+
+    /**
+     * Get cloud data from storage
+     *
+     * @param string|null $key
+     * @return array|null
+     */
+    public function getGlobalData($key = null)
+    {
+        if ($key === null) {
+            return $this->globalDataStorage;
+        }
+        return isset($this->globalDataStorage[$key]) ? $this->globalDataStorage[$key] : null;
+    }
+}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Grid/Massaction.php b/app/code/Magento/Ui/ContentType/Builders/ConfigJson.php
similarity index 62%
rename from app/code/Magento/Index/Block/Adminhtml/Process/Grid/Massaction.php
rename to app/code/Magento/Ui/ContentType/Builders/ConfigJson.php
index 614cf12b015..8459ffe530f 100644
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Grid/Massaction.php
+++ b/app/code/Magento/Ui/ContentType/Builders/ConfigJson.php
@@ -21,32 +21,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Ui\ContentType\Builders;
+
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigInterface;
 
 /**
- * Mass-action block for process/list grid
- *
- * @author      Magento Core Team <core@magentocommerce.com>
+ * Class ConfigJson
  */
-namespace Magento\Index\Block\Adminhtml\Process\Grid;
-
-class Massaction extends \Magento\Backend\Block\Widget\Grid\Massaction\Extended
+class ConfigJson implements ConfigBuilderInterface
 {
     /**
-     * Get ids for only visible indexers
+     * Config data to JSON by output
      *
+     * @param ConfigInterface $configuration
      * @return string
      */
-    public function getGridIdsJson()
+    public function toJson(ConfigInterface $configuration)
     {
-        if (!$this->getUseSelectAll()) {
-            return '';
-        }
-
-        $ids = array();
-        foreach ($this->getParentBlock()->getCollection() as $process) {
-            $ids[] = $process->getId();
-        }
+        $result = $configuration->getData();
+        $result['name'] = $configuration->getName();
+        $result['parent_name'] = $configuration->getParentName();
 
-        return implode(',', $ids);
+        return json_encode($result);
     }
 }
diff --git a/app/code/Magento/Ui/ContentType/Builders/ConfigStorageJson.php b/app/code/Magento/Ui/ContentType/Builders/ConfigStorageJson.php
new file mode 100644
index 00000000000..d987e2b1cd8
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/Builders/ConfigStorageJson.php
@@ -0,0 +1,70 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType\Builders;
+
+use Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigStorageInterface;
+
+/**
+ * Class ConfigStorageBuilder
+ */
+class ConfigStorageJson implements ConfigStorageBuilderInterface
+{
+    /**
+     * Config storage data to JSON by output
+     *
+     * @param ConfigStorageInterface $storage
+     * @param string $parentName
+     * @return string
+     */
+    public function toJson(ConfigStorageInterface $storage, $parentName = null)
+    {
+        $result = [
+            'config' => []
+        ];
+        $result['meta'] = $storage->getMeta($parentName);
+        if ($parentName !== null) {
+            $rootComponent = $storage->getComponentsData($parentName);
+            $result['name'] = $rootComponent->getName();
+            $result['parent_name'] = $rootComponent->getParentName();
+            $result['data'] = $storage->getData($parentName);
+            $result['config']['components'][$rootComponent->getName()] = $rootComponent->getData();
+        } else {
+            $components = $storage->getComponentsData();
+            if (!empty($components)) {
+                /** @var ConfigInterface $component */
+                foreach ($components as $name => $component) {
+                    $result['config']['components'][$name] = $component->getData();
+                }
+            }
+            $result['data'] = $storage->getData();
+        }
+
+        $result['config'] += $storage->getGlobalData();
+        $result['dump']['extenders'] = [];
+
+        return json_encode($result);
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/ContentTypeFactory.php b/app/code/Magento/Ui/ContentType/ContentTypeFactory.php
new file mode 100644
index 00000000000..66ccd9f4833
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/ContentTypeFactory.php
@@ -0,0 +1,90 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+use Magento\Framework\ObjectManager;
+
+/**
+ * Class ContentTypeFactory
+ */
+class ContentTypeFactory
+{
+    /**
+     * Default content type
+     */
+    const DEFAULT_TYPE = 'html';
+
+    /**
+     * Content types
+     *
+     * @var array
+     */
+    protected $types = [
+        'html' => 'Magento\Ui\ContentType\Html',
+        'json' => 'Magento\Ui\ContentType\Json',
+        'xml' => 'Magento\Ui\ContentType\Xml',
+    ];
+
+    /**
+     * Object manager
+     *
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManager $objectManager
+     * @param array $types
+     */
+    public function __construct(ObjectManager $objectManager, array $types = [])
+    {
+        $this->types = array_merge($this->types, $types);
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Get content type object instance
+     *
+     * @param string $type
+     * @return ContentTypeInterface
+     * @throws \InvalidArgumentException
+     */
+    public function get($type = ContentTypeFactory::DEFAULT_TYPE)
+    {
+        if (!isset($this->types[$type])) {
+            throw new \InvalidArgumentException(sprintf("Wrong content type '%s', renderer not exists.", $type));
+        }
+
+        $contentRender = $this->objectManager->get($this->types[$type]);
+        if (!$contentRender instanceof ContentTypeInterface) {
+            throw new \InvalidArgumentException(
+                sprintf('"%s" must implement the interface ContentTypeInterface.', $this->types[$type])
+            );
+        }
+
+        return $contentRender;
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/ContentTypeInterface.php b/app/code/Magento/Ui/ContentType/ContentTypeInterface.php
new file mode 100644
index 00000000000..187a16796c0
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/ContentTypeInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface ContentTypeInterface
+ */
+interface ContentTypeInterface
+{
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $view
+     * @param string $template
+     * @return mixed
+     */
+    public function render(UiComponentInterface $view, $template = '');
+}
diff --git a/app/code/Magento/Ui/ContentType/Html.php b/app/code/Magento/Ui/ContentType/Html.php
new file mode 100644
index 00000000000..7771aca4ebb
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/Html.php
@@ -0,0 +1,79 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\FileSystem;
+use Magento\Framework\View\TemplateEnginePool;
+
+/**
+ * Class Html
+ */
+class Html implements ContentTypeInterface
+{
+    /**
+     * @var \Magento\Framework\View\FileSystem
+     */
+    protected $filesystem;
+
+    /**
+     * @var \Magento\Framework\View\TemplateEnginePool
+     */
+    protected $templateEnginePool;
+
+    /**
+     * Constructor
+     *
+     * @param FileSystem $filesystem
+     * @param TemplateEnginePool $templateEnginePool
+     */
+    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool)
+    {
+        $this->filesystem = $filesystem;
+        $this->templateEnginePool = $templateEnginePool;
+    }
+
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $view
+     * @param string $template
+     * @return string
+     */
+    public function render(UiComponentInterface $view, $template = '')
+    {
+        $templateEngine = false;
+        if ($template) {
+            $extension = pathinfo($template, PATHINFO_EXTENSION);
+            $templateEngine = $this->templateEnginePool->get($extension);
+        }
+        if ($templateEngine) {
+            $path = $this->filesystem->getTemplateFileName($template);
+            $result = $templateEngine->render($view, $path);
+        } else {
+            $result = '';
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/Json.php b/app/code/Magento/Ui/ContentType/Json.php
new file mode 100644
index 00000000000..235b327e541
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/Json.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+use Magento\Framework\Object;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\FileSystem;
+use Magento\Framework\View\TemplateEnginePool;
+
+/**
+ * Class Json
+ */
+class Json implements ContentTypeInterface
+{
+    /**
+     * @var \Magento\Framework\View\FileSystem
+     */
+    protected $filesystem;
+
+    /**
+     * @var \Magento\Framework\View\TemplateEnginePool
+     */
+    protected $templateEnginePool;
+
+    /**
+     * Constructor
+     *
+     * @param FileSystem $filesystem
+     * @param TemplateEnginePool $templateEnginePool
+     */
+    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool)
+    {
+        $this->filesystem = $filesystem;
+        $this->templateEnginePool = $templateEnginePool;
+    }
+
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $view
+     * @param string $template
+     * @return string
+     */
+    public function render(UiComponentInterface $view, $template = '')
+    {
+        return $view->getRenderContext()
+            ->getConfigurationBuilder()
+            ->toJson($view->getRenderContext()->getStorage(), $view->getName());
+    }
+}
diff --git a/app/code/Magento/Ui/ContentType/Xml.php b/app/code/Magento/Ui/ContentType/Xml.php
new file mode 100644
index 00000000000..883f3716358
--- /dev/null
+++ b/app/code/Magento/Ui/ContentType/Xml.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\FileSystem;
+use Magento\Framework\View\TemplateEnginePool;
+use Magento\Framework\Xml\Generator;
+
+/**
+ * Class Xml
+ */
+class Xml implements ContentTypeInterface
+{
+    /**
+     * @var \Magento\Framework\View\FileSystem
+     */
+    protected $filesystem;
+
+    /**
+     * @var \Magento\Framework\View\TemplateEnginePool
+     */
+    protected $templateEnginePool;
+
+    /**
+     * @var \Magento\Framework\Xml\Generator
+     */
+    protected $generator;
+
+    /**
+     * @param FileSystem $filesystem
+     * @param TemplateEnginePool $templateEnginePool
+     * @param Generator $generator
+     */
+    public function __construct(FileSystem $filesystem, TemplateEnginePool $templateEnginePool, Generator $generator)
+    {
+        $this->filesystem = $filesystem;
+        $this->templateEnginePool = $templateEnginePool;
+        $this->generator = $generator;
+    }
+
+    /**
+     * Render data
+     *
+     * @param UiComponentInterface $view
+     * @param string $template
+     * @return string
+     */
+    public function render(UiComponentInterface $view, $template = '')
+    {
+        $templateEngine = false;
+        if ($template) {
+            $extension = pathinfo($template, PATHINFO_EXTENSION);
+            $templateEngine = $this->templateEnginePool->get($extension);
+        }
+        if ($templateEngine) {
+            $path = $this->filesystem->getTemplateFileName($template);
+            $result = $templateEngine->render($view, $path);
+        } else {
+            $result = $this->getDataXml($view);
+        }
+        return $result;
+    }
+
+    /**
+     * @param UiComponentInterface $view
+     * @return string
+     */
+    protected function getDataXml(UiComponentInterface $view)
+    {
+        $result = [
+            'configuration' => $view->getRenderContext()->getStorage()->getComponentsData($view->getName())->getData(),
+            'data' => []
+        ];
+        foreach ($view->getRenderContext()->getStorage()->getData($view->getName()) as $key => $value) {
+            if (is_object($value)) {
+                if (method_exists($value, 'toXml')) {
+                    $result['data'][$key] = $value->toXml();
+                } else {
+                    $result['data'][$key] = $this->objectToXml($value);
+                }
+            } else {
+                $result['data'][$key] = $value;
+            }
+        }
+        return $this->generator->arrayToXml($result);
+    }
+
+    /**
+     * Convert object to xml format
+     *
+     * @param \Magento\Framework\Object $object
+     * @return string
+     */
+    protected function objectToXml(\Magento\Framework\Object $object)
+    {
+        return (string)$object;
+    }
+}
diff --git a/app/code/Magento/Ui/Context/DataProvider.php b/app/code/Magento/Ui/Context/DataProvider.php
new file mode 100644
index 00000000000..718f652063e
--- /dev/null
+++ b/app/code/Magento/Ui/Context/DataProvider.php
@@ -0,0 +1,40 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Context;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class DataProvider
+ */
+class DataProvider extends AbstractView
+{
+    /**
+     * @return string
+     */
+    public function getAsJson()
+    {
+        return $this->renderContext->getConfigurationBuilder()->toJson($this->renderContext->getStorage());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php b/app/code/Magento/Ui/Control/Action.php
similarity index 81%
rename from dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php
rename to app/code/Magento/Ui/Control/Action.php
index 59159a54d48..ee9ec3d2801 100644
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php
+++ b/app/code/Magento/Ui/Control/Action.php
@@ -21,10 +21,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-return array(
-    'cataloginventory_stock' => array(
-        'name' => 'cataloginventory_stock',
-        'instance' => 'Magento\CatalogInventory\Model\Indexer\Stock',
-        'depends' => array()
-    ),
-);
+namespace Magento\Ui\Control;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class Action
+ */
+class Action extends AbstractView implements ControlInterface
+{
+
+}
diff --git a/app/code/Magento/Ui/Control/ActionPool.php b/app/code/Magento/Ui/Control/ActionPool.php
new file mode 100644
index 00000000000..6307ffe4250
--- /dev/null
+++ b/app/code/Magento/Ui/Control/ActionPool.php
@@ -0,0 +1,148 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\LayoutInterface;
+use Magento\Framework\View\Element\Template;
+
+/**
+ * Class ActionPool
+ */
+class ActionPool implements ActionPoolInterface
+{
+    /**
+     * Actions toolbar block name
+     */
+    const ACTIONS_PAGE_TOOLBAR = 'page.actions.toolbar';
+
+    /**
+     * Render context
+     *
+     * @var Context
+     */
+    protected $context;
+
+    /**
+     * Actions pool
+     *
+     * @var Item[]
+     */
+    protected $items;
+
+    /**
+     * Button factory
+     *
+     * @var ItemFactory
+     */
+    protected $itemFactory;
+
+    /**
+     * @var \Magento\Framework\View\Element\AbstractBlock
+     */
+    protected $toolbarBlock;
+
+    /**
+     * Construct
+     *
+     * @param Context $context
+     * @param ItemFactory $itemFactory
+     */
+    public function __construct(Context $context, ItemFactory $itemFactory)
+    {
+        $this->context = $context;
+        $this->itemFactory = $itemFactory;
+        $this->toolbarBlock = $this->context->getPageLayout()->getBlock(static::ACTIONS_PAGE_TOOLBAR);
+    }
+
+
+    /**
+     * Create button container
+     *
+     * @param string $key
+     * @param UiComponentInterface $view
+     * @return \Magento\Backend\Block\Widget\Button\Toolbar\Container
+     */
+    protected function createContainer($key, UiComponentInterface $view)
+    {
+        $container = $this->context->getPageLayout()->createBlock(
+            'Magento\Ui\Control\Container',
+            'container-' . $key,
+            [
+                'data' => [
+                    'button_item' => $this->items[$key],
+                    'context' => $view
+                ]
+            ]
+        );
+
+        return $container;
+    }
+
+    /**
+     * Add button
+     *
+     * @param string $key
+     * @param array $data
+     * @param UiComponentInterface $view
+     * @return void
+     */
+    public function add($key, array $data, UiComponentInterface $view)
+    {
+        $data['id'] = isset($data['id']) ? $data['id'] : $key;
+
+        if ($this->toolbarBlock !== false) {
+            $this->items[$key] = $this->itemFactory->create();
+            $this->items[$key]->setData($data);
+            $container = $this->createContainer($key, $view);
+            $this->toolbarBlock->setChild($key, $container);
+        }
+    }
+
+    /**
+     * Remove button
+     *
+     * @param string $key
+     * @return void
+     */
+    public function remove($key)
+    {
+        unset($this->items[$key]);
+    }
+
+    /**
+     * Update button
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function update($key, array $data)
+    {
+        if (isset($this->items[$key])) {
+            $this->items[$key]->setData($data);
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/Control/ActionPoolInterface.php b/app/code/Magento/Ui/Control/ActionPoolInterface.php
new file mode 100644
index 00000000000..9c852845ce8
--- /dev/null
+++ b/app/code/Magento/Ui/Control/ActionPoolInterface.php
@@ -0,0 +1,60 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\LayoutInterface;
+
+/**
+ * Interface ActionPoolInterface
+ */
+interface ActionPoolInterface
+{
+    /**
+     * Add button
+     *
+     * @param string $key
+     * @param array $data
+     * @param UiComponentInterface $context
+     * @return void
+     */
+    public function add($key, array $data, UiComponentInterface $context);
+
+    /**
+     * Remove button
+     *
+     * @param string $key
+     * @return void
+     */
+    public function remove($key);
+
+    /**
+     * Update button
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function update($key, array $data);
+}
diff --git a/app/code/Magento/Ui/Control/Button.php b/app/code/Magento/Ui/Control/Button.php
new file mode 100644
index 00000000000..a56d6aafede
--- /dev/null
+++ b/app/code/Magento/Ui/Control/Button.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\View\Element\Template;
+
+/**
+ * Class Button
+ */
+class Button extends Template
+{
+    /**
+     * Define block template
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->setTemplate('Magento_Ui::control/button/default.phtml');
+        parent::_construct();
+    }
+
+
+    /**
+     * Retrieve button type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        if (in_array($this->getData('type'), ['reset', 'submit'])) {
+            return $this->getData('type');
+        }
+
+        return 'button';
+    }
+
+    /**
+     * Retrieve onclick handler
+     *
+     * @return string
+     */
+    public function getOnClick()
+    {
+        $url = $this->hasData('url') ? $this->getData('url') : $this->getUrl();
+        return sprintf("setLocation('%s');", $url);
+    }
+
+    /**
+     * Retrieve attributes html
+     *
+     * @return string
+     */
+    public function getAttributesHtml()
+    {
+        $disabled = $this->getDisabled() ? 'disabled' : '';
+        $title = $this->getTitle();
+        if (empty($title)) {
+            $title = $this->getLabel();
+        }
+        $classes = ['action-', 'scalable'];
+        if ($this->hasData('class')) {
+            $classes[] = $this->getClass();
+        }
+        if ($disabled) {
+            $classes[] = $disabled;
+        }
+
+        return $this->attributesToHtml($this->prepareAttributes($title, $classes, $disabled));
+    }
+
+    /**
+     * Prepare attributes
+     *
+     * @param string $title
+     * @param array $classes
+     * @param string $disabled
+     * @return array
+     */
+    protected function prepareAttributes($title, $classes, $disabled)
+    {
+        $attributes = [
+            'id' => $this->getId(),
+            'name' => $this->getElementName(),
+            'title' => $title,
+            'type' => $this->getType(),
+            'class' => implode(' ', $classes),
+            'onclick' => $this->getOnClick(),
+            'style' => $this->getStyle(),
+            'value' => $this->getValue(),
+            'disabled' => $disabled
+        ];
+        if ($this->getDataAttribute()) {
+            foreach ($this->getDataAttribute() as $key => $attr) {
+                $attributes['data-' . $key] = is_scalar($attr) ? $attr : json_encode($attr);
+            }
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Attributes list to html
+     *
+     * @param array $attributes
+     * @return string
+     */
+    protected function attributesToHtml($attributes)
+    {
+        $html = '';
+        foreach ($attributes as $attributeKey => $attributeValue) {
+            if ($attributeValue === null || $attributeValue == '') {
+                continue;
+            }
+            $html .= $attributeKey . '="' . $this->escapeHtml($attributeValue) . '" ';
+        }
+
+        return $html;
+    }
+}
diff --git a/app/code/Magento/Ui/Control/Container.php b/app/code/Magento/Ui/Control/Container.php
new file mode 100644
index 00000000000..e792a23ccdd
--- /dev/null
+++ b/app/code/Magento/Ui/Control/Container.php
@@ -0,0 +1,73 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\View\Element\AbstractBlock;
+
+/**
+ * Class Container
+ */
+class Container extends AbstractBlock
+{
+    /**
+     * Default button class
+     */
+    const DEFAULT_BUTTON = 'Magento\Ui\Control\Button';
+
+    /**
+     * Create button renderer
+     *
+     * @param string $blockName
+     * @param string $blockClassName
+     * @return \Magento\Backend\Block\Widget\Button
+     */
+    protected function createButton($blockName, $blockClassName = null)
+    {
+        if (null === $blockClassName) {
+            $blockClassName = static::DEFAULT_BUTTON;
+        }
+
+        return $this->getLayout()->createBlock($blockClassName, $blockName);
+    }
+
+    /**
+     * Render element HTML
+     *
+     * @return string
+     */
+    protected function _toHtml()
+    {
+        /** @var \Magento\Ui\Control\Item $item */
+        $item = $this->getButtonItem();
+        $data = $item->getData();
+
+        $block = $this->createButton(
+            $this->getData('context')->getNameInLayout() . '-' . $item->getId() . '-button',
+            isset($data['class_name']) ? $data['class_name'] : null
+        );
+        $block->setData($data);
+
+        return $block->toHtml();
+    }
+}
diff --git a/app/code/Magento/Ui/Control/ControlInterface.php b/app/code/Magento/Ui/Control/ControlInterface.php
new file mode 100644
index 00000000000..abe034b11c8
--- /dev/null
+++ b/app/code/Magento/Ui/Control/ControlInterface.php
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface ControlInterface
+ */
+interface ControlInterface extends UiComponentInterface
+{
+    //
+}
diff --git a/app/code/Magento/Ui/Control/Item.php b/app/code/Magento/Ui/Control/Item.php
new file mode 100644
index 00000000000..4207af227a8
--- /dev/null
+++ b/app/code/Magento/Ui/Control/Item.php
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Framework\Object;
+
+/**
+ * Class Item
+ */
+class Item extends Object
+{
+    //
+}
diff --git a/app/code/Magento/Ui/Control/Link.php b/app/code/Magento/Ui/Control/Link.php
new file mode 100644
index 00000000000..8853dd30c4d
--- /dev/null
+++ b/app/code/Magento/Ui/Control/Link.php
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Control;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class Link
+ */
+class Link extends AbstractView implements ControlInterface
+{
+    //
+}
diff --git a/app/code/Magento/Rss/Controller/Order/Status.php b/app/code/Magento/Ui/Controller/Adminhtml/Listing/Ajax.php
similarity index 50%
rename from app/code/Magento/Rss/Controller/Order/Status.php
rename to app/code/Magento/Ui/Controller/Adminhtml/Listing/Ajax.php
index 8798ede2110..96039ae733d 100644
--- a/app/code/Magento/Rss/Controller/Order/Status.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/Listing/Ajax.php
@@ -22,50 +22,59 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Order;
+namespace Magento\Ui\Controller\Adminhtml\Listing;
 
-class Status extends \Magento\Framework\App\Action\Action
+use Magento\Backend\App\Action\Context;
+use Magento\Framework\View\Element\UiComponentFactory;
+
+/**
+ * Class Ajax
+ */
+class Ajax extends \Magento\Backend\App\Action
 {
     /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
+     * @var UiComponentFactory
      */
-    protected $_coreRegistry = null;
+    protected $factory;
 
     /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
+     * @param Context $context
+     * @param UiComponentFactory $factory
      */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_coreRegistry = $coreRegistry;
+    public function __construct(Context $context, UiComponentFactory $factory)
+    {
         parent::__construct($context);
+        $this->factory = $factory;
     }
-
     /**
-     * Order status action
+     * Action for AJAX request
      *
      * @return void
      */
     public function execute()
     {
-        $order = $this->_objectManager->get(
-            'Magento\Rss\Helper\Order'
-        )->getOrderByStatusUrlKey(
-            (string)$this->getRequest()->getParam('data')
+        $this->_response->appendBody(
+            $this->factory->createUiComponent($this->getComponent(), $this->getName())->render()
         );
+    }
 
-        if (!is_null($order)) {
-            $this->_coreRegistry->register('current_order', $order);
-            $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
-            $this->_view->loadLayout(false);
-            $this->_view->renderLayout();
-            return;
-        }
+    /**
+     * Getting name
+     *
+     * @return mixed
+     */
+    protected function getName()
+    {
+        return $this->_request->getParam('name');
+    }
 
-        $this->_forward('nofeed', 'index', 'rss');
+    /**
+     * Getting component
+     *
+     * @return mixed
+     */
+    protected function getComponent()
+    {
+        return $this->_request->getParam('component');
     }
 }
diff --git a/app/code/Magento/Ui/DataProvider/Options/Store.php b/app/code/Magento/Ui/DataProvider/Options/Store.php
new file mode 100644
index 00000000000..830993acce3
--- /dev/null
+++ b/app/code/Magento/Ui/DataProvider/Options/Store.php
@@ -0,0 +1,110 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataProvider\Options;
+
+use Magento\Framework\Escaper;
+use Magento\Ui\DataProvider\OptionsInterface;
+use Magento\Store\Model\System\Store as SystemStore;
+
+/**
+ * Class Store
+ */
+class Store implements OptionsInterface
+{
+    /**
+     * Escaper
+     *
+     * @var \Magento\Framework\Escaper
+     */
+    protected $escaper;
+
+    /**
+     * System store
+     *
+     * @var SystemStore
+     */
+    protected $systemStore;
+
+    /**
+     * Constructor
+     *
+     * @param SystemStore $systemStore
+     * @param Escaper $escaper
+     */
+    public function __construct(SystemStore $systemStore, Escaper $escaper)
+    {
+        $this->systemStore = $systemStore;
+        $this->escaper = $escaper;
+    }
+
+    /**
+     * Get options
+     *
+     * @param array $options
+     * @return array
+     */
+    public function getOptions(array $options = [])
+    {
+        $websiteCollection = $this->systemStore->getWebsiteCollection();
+        $groupCollection = $this->systemStore->getGroupCollection();
+        $storeCollection = $this->systemStore->getStoreCollection();
+
+        $currentOptions = [
+            __('All Store Views') => [
+                'label' => __('All Store Views'),
+                'value' => 0
+            ]
+        ];
+        /** @var \Magento\Store\Model\Website $website */
+        foreach ($websiteCollection as $website) {
+            $groups = [];
+            /** @var \Magento\Store\Model\Group $group */
+            foreach ($groupCollection as $group) {
+                if ($group->getWebsiteId() == $website->getId()) {
+                    $stores = [];
+                    /** @var  \Magento\Store\Model\Store $store */
+                    foreach ($storeCollection as $store) {
+                        if ($store->getGroupId() == $group->getId()) {
+                            $name = $this->escaper->escapeHtml($store->getName());
+                            $stores[$name]['label'] = str_repeat(' ', 8) . $name;
+                            $stores[$name]['value'] = $store->getId();
+                        }
+                    }
+                    if (!empty($stores)) {
+                        $name = $this->escaper->escapeHtml($group->getName());
+                        $groups[$name]['label'] = str_repeat(' ', 4) . $name;
+                        $groups[$name]['value'] = $stores;
+                    }
+                }
+            }
+            if (!empty($groups)) {
+                $name = $this->escaper->escapeHtml($website->getName());
+                $currentOptions[$name]['label'] = $name;
+                $currentOptions[$name]['value'] = $groups;
+            }
+        }
+
+        return array_merge_recursive($currentOptions, $options);
+    }
+}
diff --git a/app/code/Magento/UrlRedirect/Model/OptionProvider.php b/app/code/Magento/Ui/DataProvider/OptionsFactory.php
similarity index 52%
rename from app/code/Magento/UrlRedirect/Model/OptionProvider.php
rename to app/code/Magento/Ui/DataProvider/OptionsFactory.php
index 46d9a7357eb..9cde93cacee 100644
--- a/app/code/Magento/UrlRedirect/Model/OptionProvider.php
+++ b/app/code/Magento/Ui/DataProvider/OptionsFactory.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * URL Rewrite Option Provider
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,55 +21,47 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Model;
+namespace Magento\Ui\DataProvider;
 
-use Magento\Framework\Option\ArrayInterface;
+use Magento\Framework\ObjectManager;
 
-class OptionProvider implements ArrayInterface
+/**
+ * Class OptionsFactory
+ */
+class OptionsFactory
 {
-    const TEMPORARY = 'R';
-
-    const PERMANENT = 'RP';
-
     /**
-     * @var array|null
+     * @var ObjectManager
      */
-    protected $_options = null;
+    protected $objectManager;
 
     /**
-     * Get all options
+     * Constructor
      *
-     * @return array
+     * @param ObjectManager $objectManager
      */
-    public function getAllOptions()
+    public function __construct(ObjectManager $objectManager)
     {
-        if (is_null($this->_options)) {
-            $this->_options = array(
-                '' => __('No'),
-                self::TEMPORARY => __('Temporary (302)'),
-                self::PERMANENT => __('Permanent (301)'),
-            );
-        }
-        return $this->_options;
+        $this->objectManager = $objectManager;
     }
 
     /**
-     * Get options list (redirects only)
+     * Getting provider object
      *
-     * @return string[]
+     * @param string $class
+     * @param array $arguments
+     * @return OptionsInterface
+     * @throws \InvalidArgumentException
      */
-    public function getRedirectOptions()
+    public function create($class, array $arguments = [])
     {
-        return array(self::TEMPORARY, self::PERMANENT);
-    }
+        $object = $this->objectManager->create($class, $arguments);
+        if (!($object instanceof OptionsInterface)) {
+            throw new \InvalidArgumentException(
+                sprintf('"%s" must implement the interface \Magento\Ui\DataProvider\OptionsInterface', $class)
+            );
+        }
 
-    /**
-     * Return option array
-     *
-     * @return array
-     */
-    public function toOptionArray()
-    {
-        return $this->getAllOptions();
+        return $object;
     }
 }
diff --git a/app/code/Magento/Theme/Block/Html/Head/AssetBlockInterface.php b/app/code/Magento/Ui/DataProvider/OptionsInterface.php
similarity index 81%
rename from app/code/Magento/Theme/Block/Html/Head/AssetBlockInterface.php
rename to app/code/Magento/Ui/DataProvider/OptionsInterface.php
index e89e67cb5ca..2f1b0037923 100644
--- a/app/code/Magento/Theme/Block/Html/Head/AssetBlockInterface.php
+++ b/app/code/Magento/Ui/DataProvider/OptionsInterface.php
@@ -21,17 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Theme\Block\Html\Head;
+namespace Magento\Ui\DataProvider;
 
 /**
- * Asset block interface
+ * Class OptionsInterface
  */
-interface AssetBlockInterface
+interface OptionsInterface
 {
     /**
-     * Get block asset
+     * Get options
      *
-     * @return \Magento\Framework\View\Asset\AssetInterface
+     * @param array $options
+     * @return array
      */
-    public function getAsset();
+    public function getOptions(array $options = []);
 }
diff --git a/app/code/Magento/Ui/DataProvider/Row/Store.php b/app/code/Magento/Ui/DataProvider/Row/Store.php
new file mode 100644
index 00000000000..e6bb50f9609
--- /dev/null
+++ b/app/code/Magento/Ui/DataProvider/Row/Store.php
@@ -0,0 +1,97 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataProvider\Row;
+
+use Magento\Framework\Escaper;
+use Magento\Framework\UrlInterface;
+use Magento\Ui\DataProvider\RowInterface;
+use Magento\Store\Model\System\Store as SystemStore;
+
+/**
+ * Class Store
+ */
+class Store implements RowInterface
+{
+    /**
+     * Escaper
+     *
+     * @var \Magento\Framework\Escaper
+     */
+    protected $escaper;
+
+    /**
+     * System store
+     *
+     * @var SystemStore
+     */
+    protected $systemStore;
+
+    /**
+     * Constructor
+     *
+     * @param SystemStore $systemStore
+     * @param Escaper $escaper
+     */
+    public function __construct(SystemStore $systemStore, Escaper $escaper)
+    {
+        $this->systemStore = $systemStore;
+        $this->escaper = $escaper;
+    }
+
+    /**
+     * Get data
+     *
+     * @param array $dataRow
+     * @return mixed
+     */
+    public function getData(array $dataRow)
+    {
+        $content = '';
+        $origStores = $dataRow['store_id'];
+
+        if (empty($origStores)) {
+            return '';
+        }
+        if (!is_array($origStores)) {
+            $origStores = [$origStores];
+        }
+        if (in_array(0, $origStores) && count($origStores) == 1) {
+            return __('All Store Views');
+        }
+
+        $data = $this->systemStore->getStoresStructure(false, $origStores);
+
+        foreach ($data as $website) {
+            $content .= $website['label'] . "<br/>";
+            foreach ($website['children'] as $group) {
+                $content .= str_repeat('&nbsp;', 3) . $this->escaper->escapeHtml($group['label']) . "<br/>";
+                foreach ($group['children'] as $store) {
+                    $content .= str_repeat('&nbsp;', 6) . $this->escaper->escapeHtml($store['label']) . "<br/>";
+                }
+            }
+        }
+
+        return $content;
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Catalog/Salesrule.php b/app/code/Magento/Ui/DataProvider/RowInterface.php
similarity index 81%
rename from app/code/Magento/Rss/Controller/Catalog/Salesrule.php
rename to app/code/Magento/Ui/DataProvider/RowInterface.php
index eeba0161f19..3e6f9e6d77c 100644
--- a/app/code/Magento/Rss/Controller/Catalog/Salesrule.php
+++ b/app/code/Magento/Ui/DataProvider/RowInterface.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,15 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Catalog;
+namespace Magento\Ui\DataProvider;
 
-class Salesrule extends \Magento\Rss\Controller\Catalog
+/**
+ * Interface RowInterface
+ */
+interface RowInterface
 {
     /**
-     * @return void
+     * Get data
+     *
+     * @param array $dataRow
+     * @return mixed
      */
-    public function execute()
-    {
-        $this->_genericAction('salesrule');
-    }
+    public function getData(array $dataRow);
 }
diff --git a/app/code/Magento/Ui/DataProvider/RowPool.php b/app/code/Magento/Ui/DataProvider/RowPool.php
new file mode 100644
index 00000000000..44060227cc7
--- /dev/null
+++ b/app/code/Magento/Ui/DataProvider/RowPool.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataProvider;
+
+use Magento\Framework\ObjectManager;
+
+/**
+ * Class RowPool
+ */
+class RowPool
+{
+    /**
+     * @var RowInterface[]
+     */
+    protected $classPool;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ObjectManager $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Getting provider object
+     *
+     * @param string $class
+     * @param array $arguments
+     * @return RowInterface
+     * @throws \InvalidArgumentException
+     */
+    public function get($class, array $arguments = [])
+    {
+        if (!isset($this->classPool[$class])) {
+            $this->classPool[$class] = $this->objectManager->create($class, $arguments);
+            if (!($this->classPool[$class] instanceof RowInterface)) {
+                throw new \InvalidArgumentException(
+                    sprintf('"%s" must implement the interface \Magento\Ui\DataProvider\RowInterface', $class)
+                );
+            }
+        }
+
+        return $this->classPool[$class];
+    }
+}
diff --git a/app/code/Magento/Theme/Block/Html/Head/Link.php b/app/code/Magento/Ui/DataType/AbstractDataType.php
similarity index 68%
rename from app/code/Magento/Theme/Block/Html/Head/Link.php
rename to app/code/Magento/Ui/DataType/AbstractDataType.php
index a2649c5564a..085d38e5bd7 100644
--- a/app/code/Magento/Theme/Block/Html/Head/Link.php
+++ b/app/code/Magento/Ui/DataType/AbstractDataType.php
@@ -21,25 +21,29 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Theme\Block\Html\Head;
+namespace Magento\Ui\DataType;
+
+use Magento\Ui\AbstractView;
+use Magento\Framework\Object as DataObject;
 
 /**
- * Link page block
+ * Class AbstractDataType
  */
-class Link extends \Magento\Framework\View\Element\Template implements AssetBlockInterface
+abstract class AbstractDataType extends AbstractView implements DataTypeInterface
 {
     /**
-     * Virtual content type
+     * @return bool
      */
-    const VIRTUAL_CONTENT_TYPE = 'link';
+    public function validate()
+    {
+        return true;
+    }
 
     /**
-     * Get block asset
-     *
-     * @return \Magento\Framework\View\Asset\AssetInterface
+     * @return string
      */
-    public function getAsset()
+    public function getDataObjectValue()
     {
-        return $this->_assetRepo->createRemoteAsset($this->_getData('url'), self::VIRTUAL_CONTENT_TYPE);
+        return $this->getData('data_object')[$this->getData('name')];
     }
 }
diff --git a/app/code/Magento/Ui/DataType/Boolean.php b/app/code/Magento/Ui/DataType/Boolean.php
new file mode 100644
index 00000000000..514047f7d8c
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Boolean.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Boolean
+ */
+class Boolean extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/Ui/DataType/DataTypeInterface.php b/app/code/Magento/Ui/DataType/DataTypeInterface.php
new file mode 100644
index 00000000000..2f7ea9586cb
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/DataTypeInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+use Magento\Framework\Object;
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface DataTypeInterface
+ */
+interface DataTypeInterface extends UiComponentInterface
+{
+    /**
+     * Validate data
+     *
+     * @return bool
+     */
+    public function validate();
+
+    /**
+     * Get data object value
+     *
+     * @return mixed
+     */
+    public function getDataObjectValue();
+}
diff --git a/app/code/Magento/Ui/DataType/Date.php b/app/code/Magento/Ui/DataType/Date.php
new file mode 100644
index 00000000000..673302cd2a0
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Date.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Date
+ */
+class Date extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/Ui/DataType/Media.php b/app/code/Magento/Ui/DataType/Media.php
new file mode 100644
index 00000000000..bff0ecdc3b6
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Media.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Media
+ */
+class Media extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/Ui/DataType/Number.php b/app/code/Magento/Ui/DataType/Number.php
new file mode 100644
index 00000000000..dc332bbae71
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Number.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Number
+ */
+class Number extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/Ui/DataType/Password.php b/app/code/Magento/Ui/DataType/Password.php
new file mode 100644
index 00000000000..f4193b249dc
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Password.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Password
+ */
+class Password extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/Ui/DataType/Text.php b/app/code/Magento/Ui/DataType/Text.php
new file mode 100644
index 00000000000..917ee8aabe2
--- /dev/null
+++ b/app/code/Magento/Ui/DataType/Text.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\DataType;
+
+/**
+ * Class Text
+ */
+class Text extends AbstractDataType
+{
+    //
+}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php b/app/code/Magento/Ui/Filter/FilterInterface.php
similarity index 77%
rename from app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php
rename to app/code/Magento/Ui/Filter/FilterInterface.php
index c07e3b084d2..47ff4a7889f 100644
--- a/app/code/Magento/UrlRedirect/Service/V1/UrlSaveInterface.php
+++ b/app/code/Magento/Ui/Filter/FilterInterface.php
@@ -21,18 +21,20 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Service\V1;
+namespace Magento\Ui\Filter;
+
+use Magento\Ui\DataType\DataTypeInterface;
 
 /**
- * Url Save Interface
+ * Interface FilterInterface
  */
-interface UrlSaveInterface
+interface FilterInterface
 {
     /**
-     * Save url rewrites. Return number of saved urls
+     * Get condition by data type
      *
-     * @param \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[] $urls
-     * @return void
+     * @param string|array $value
+     * @return array|null
      */
-    public function save(array $urls);
+    public function getCondition($value);
 }
diff --git a/app/code/Magento/Ui/Filter/FilterPool.php b/app/code/Magento/Ui/Filter/FilterPool.php
new file mode 100644
index 00000000000..c134d73a4de
--- /dev/null
+++ b/app/code/Magento/Ui/Filter/FilterPool.php
@@ -0,0 +1,86 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Filter;
+
+use Magento\Framework\ObjectManager;
+
+/**
+ * Class FilterPool
+ */
+class FilterPool
+{
+    /**
+     * Filter types
+     *
+     * @var array
+     */
+    protected $filterTypes = [
+        'filter_input' => 'Magento\Ui\Filter\Type\Input',
+        'filter_select' => 'Magento\Ui\Filter\Type\Select',
+        'filter_range' => 'Magento\Ui\Filter\Type\Range',
+        'filter_date' => 'Magento\Ui\Filter\Type\Date',
+        'filter_store' => 'Magento\Ui\Filter\Type\Store'
+    ];
+
+    /**
+     * Filters poll
+     *
+     * @var FilterInterface[]
+     */
+    protected $filters = [];
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ObjectManager $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Get filter by type
+     *
+     * @param string $dataType
+     * @return FilterInterface
+     * @throws \InvalidArgumentException
+     */
+    public function getFilter($dataType)
+    {
+        if (!isset($this->filters[$dataType])) {
+            if (!isset($this->filterTypes[$dataType])) {
+                throw new \InvalidArgumentException(sprintf('Unknown filter type "%s"', $dataType));
+            }
+            $this->filters[$dataType] = $this->objectManager->create($this->filterTypes[$dataType]);
+        }
+
+        return $this->filters[$dataType];
+    }
+}
diff --git a/app/code/Magento/Ui/Filter/Type/Date.php b/app/code/Magento/Ui/Filter/Type/Date.php
new file mode 100644
index 00000000000..8771dd73373
--- /dev/null
+++ b/app/code/Magento/Ui/Filter/Type/Date.php
@@ -0,0 +1,172 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Filter\Type;
+
+use\Magento\Ui\Filter\View;
+use Magento\Ui\Filter\FilterPool;
+use Magento\Framework\LocaleInterface;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\Locale\ResolverInterface;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class Date
+ */
+class Date extends View
+{
+    /**
+     * Timezone library
+     *
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
+     */
+    protected $localeDate;
+
+    /**
+     * Scope config
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * Locale resolver
+     *
+     * @var \Magento\Framework\Locale\ResolverInterface
+     */
+    protected $localeResolver;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param Context $renderContext
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param ConfigFactory $configFactory
+     * @param ConfigBuilderInterface $configBuilder
+     * @param FilterPool $filterPool
+     * @param ResolverInterface $localeResolver
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        Context $renderContext,
+        ContentTypeFactory $contentTypeFactory,
+        ConfigFactory $configFactory,
+        ConfigBuilderInterface $configBuilder,
+        FilterPool $filterPool,
+        ResolverInterface $localeResolver,
+        array $data = []
+    ) {
+        $this->localeDate = $context->getLocaleDate();
+        $this->scopeConfig = $context->getScopeConfig();
+        $this->localeResolver = $localeResolver;
+        parent::__construct(
+            $context,
+            $renderContext,
+            $contentTypeFactory,
+            $configFactory,
+            $configBuilder,
+            $filterPool,
+            $data
+        );
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @param string|array $value
+     * @return array|null
+     */
+    public function getCondition($value)
+    {
+        return $this->convertValue($value);
+    }
+
+    /**
+     * Convert value
+     *
+     * @param array|string $value
+     * @return array|null
+     */
+    protected function convertValue($value)
+    {
+        if (!empty($value['from']) || !empty($value['to'])) {
+            $locale = $this->localeResolver->getLocale();
+            if (!empty($value['from'])) {
+                $value['orig_from'] = $value['from'];
+                $value['from'] = $this->convertDate(strtotime($value['from']), $locale);
+            }
+            if (!empty($value['to'])) {
+                $value['orig_to'] = $value['to'];
+                $value['to'] = $this->convertDate(strtotime($value['to']), $locale);
+            }
+            $value['datetime'] = true;
+            $value['locale'] = $locale->toString();
+        } else {
+            $value = null;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Convert given date to default (UTC) timezone
+     *
+     * @param int $date
+     * @param LocaleInterface $locale
+     * @return \Magento\Framework\Stdlib\DateTime\Date|null
+     */
+    protected function convertDate($date, LocaleInterface $locale)
+    {
+        try {
+            $dateObj = $this->localeDate->date(null, null, $locale, false);
+
+            //set default timezone for store (admin)
+            $dateObj->setTimezone(
+                $this->scopeConfig->getValue(
+                    $this->localeDate->getDefaultTimezonePath(),
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                )
+            );
+
+            //set beginning of day
+            $dateObj->setHour(00);
+            $dateObj->setMinute(00);
+            $dateObj->setSecond(00);
+
+            //set date with applying timezone of store
+            $dateObj->set($date, null, $locale);
+
+            //convert store date to default date in UTC timezone without DST
+            $dateObj->setTimezone(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::DEFAULT_TIMEZONE);
+
+            return $dateObj;
+        } catch (\Exception $e) {
+            return null;
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Block/Html/Head/Script.php b/app/code/Magento/Ui/Filter/Type/Input.php
similarity index 69%
rename from app/code/Magento/Theme/Block/Html/Head/Script.php
rename to app/code/Magento/Ui/Filter/Type/Input.php
index c2dcea0793f..dfe42086e41 100644
--- a/app/code/Magento/Theme/Block/Html/Head/Script.php
+++ b/app/code/Magento/Ui/Filter/Type/Input.php
@@ -21,20 +21,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Theme\Block\Html\Head;
+namespace Magento\Ui\Filter\Type;
+
+use \Magento\Ui\Filter\View;
 
 /**
- * Script page block
+ * Class Input
  */
-class Script extends \Magento\Framework\View\Element\AbstractBlock implements AssetBlockInterface
+class Input extends View
 {
     /**
-     * Get block asset
+     * Get condition by data type
      *
-     * @return \Magento\Framework\View\Asset\LocalInterface
+     * @param string|array $value
+     * @return array|null
      */
-    public function getAsset()
+    public function getCondition($value)
     {
-        return $this->_assetRepo->createAsset($this->_getData('file'));
+        $condition = null;
+        if (!empty($value) || is_numeric($value)) {
+            $condition = ['like' => sprintf('%%%s%%', $value)];
+        }
+
+        return $condition;
     }
 }
diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Urlkey.php b/app/code/Magento/Ui/Filter/Type/Range.php
similarity index 56%
rename from app/code/Magento/Catalog/Model/Category/Attribute/Backend/Urlkey.php
rename to app/code/Magento/Ui/Filter/Type/Range.php
index 6e9dbfb3343..f8897889a74 100644
--- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Urlkey.php
+++ b/app/code/Magento/Ui/Filter/Type/Range.php
@@ -21,35 +21,36 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Model\Category\Attribute\Backend;
+namespace Magento\Ui\Filter\Type;
+
+use \Magento\Ui\Filter\View;
 
 /**
- * Category url key attribute backend
- *
- * @author      Magento Core Team <core@magentocommerce.com>
+ * Class Range
  */
-class Urlkey extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
+class Range extends View
 {
     /**
-     * TODO: Enter description here...
+     * Get condition by data type
      *
-     * @param \Magento\Framework\Object $object
-     * @return $this
+     * @param array|string $value
+     * @return array|null
      */
-    public function beforeSave($object)
+    public function getCondition($value)
     {
-        $attributeName = $this->getAttribute()->getName();
-
-        $urlKey = $object->getData($attributeName);
-        if ($urlKey === false) {
-            return $this;
+        if (!empty($value['from']) || !empty($value['to'])) {
+            if (isset($value['from']) && empty($value['from']) && $value['from'] !== '0') {
+                $value['orig_from'] = $value['from'];
+                $value['from'] = null;
+            }
+            if (isset($value['to']) && empty($value['to']) && $value['to'] !== '0') {
+                $value['orig_to'] = $value['to'];
+                $value['to'] = null;
+            }
+        } else {
+            $value = null;
         }
-        if ($urlKey == '') {
-            $urlKey = $object->getName();
-        }
-
-        $object->setData($attributeName, $object->formatUrlKey($urlKey));
 
-        return $this;
+        return $value;
     }
 }
diff --git a/app/code/Magento/Theme/Block/Html/Head/Css.php b/app/code/Magento/Ui/Filter/Type/Select.php
similarity index 70%
rename from app/code/Magento/Theme/Block/Html/Head/Css.php
rename to app/code/Magento/Ui/Filter/Type/Select.php
index c0203bb1c38..2fb7a42b1bd 100644
--- a/app/code/Magento/Theme/Block/Html/Head/Css.php
+++ b/app/code/Magento/Ui/Filter/Type/Select.php
@@ -21,20 +21,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Theme\Block\Html\Head;
+namespace Magento\Ui\Filter\Type;
+
+use \Magento\Ui\Filter\View;
 
 /**
- * Css page block
+ * Class Select
  */
-class Css extends \Magento\Framework\View\Element\AbstractBlock implements AssetBlockInterface
+class Select extends View
 {
     /**
-     * Get block asset
+     * Get condition by data type
      *
-     * @return \Magento\Framework\View\Asset\LocalInterface
+     * @param string|array $value
+     * @return array|null
      */
-    public function getAsset()
+    public function getCondition($value)
     {
-        return $this->_assetRepo->createAsset($this->_getData('file'));
+        $condition = null;
+        if (!empty($value) || is_numeric($value)) {
+            $condition = ['eq' => $value];
+        }
+
+        return $condition;
     }
 }
diff --git a/app/code/Magento/Index/App/Shell/ErrorHandler.php b/app/code/Magento/Ui/Filter/Type/Store.php
similarity index 76%
rename from app/code/Magento/Index/App/Shell/ErrorHandler.php
rename to app/code/Magento/Ui/Filter/Type/Store.php
index 2813a8980bf..1c2667d48ec 100644
--- a/app/code/Magento/Index/App/Shell/ErrorHandler.php
+++ b/app/code/Magento/Ui/Filter/Type/Store.php
@@ -21,19 +21,23 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\App\Shell;
+namespace Magento\Ui\Filter\Type;
 
-class ErrorHandler
+use Magento\Ui\Filter\FilterInterface;
+
+/**
+ * Class Store
+ */
+class Store implements FilterInterface
 {
     /**
-     * Terminate execution of the script
+     * Get condition by data type
      *
-     * @param int|string $status
-     * @return void
-     * @SuppressWarnings(PHPMD.ExitExpression)
+     * @param string|array $value
+     * @return array|null
      */
-    public function terminate($status)
+    public function getCondition($value)
     {
-        exit($status);
+        return $value;
     }
 }
diff --git a/app/code/Magento/Ui/Filter/View.php b/app/code/Magento/Ui/Filter/View.php
new file mode 100644
index 00000000000..40c34e9e934
--- /dev/null
+++ b/app/code/Magento/Ui/Filter/View.php
@@ -0,0 +1,122 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Filter;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\AbstractView;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\Template;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Filter variable name
+     */
+    const FILTER_VAR = 'filter';
+
+    /**
+     * Filters pool
+     *
+     * @var FilterPool
+     */
+    protected $filterPool;
+
+    /**
+     * Root view component
+     *
+     * @var UiComponentInterface
+     */
+    protected $rootComponent;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param Context $renderContext
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param ConfigFactory $configFactory
+     * @param ConfigBuilderInterface $configBuilder
+     * @param FilterPool $filterPool
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        Context $renderContext,
+        ContentTypeFactory $contentTypeFactory,
+        ConfigFactory $configFactory,
+        ConfigBuilderInterface $configBuilder,
+        FilterPool $filterPool,
+        array $data = []
+    ) {
+        $this->filterPool = $filterPool;
+        parent::__construct(
+            $context,
+            $renderContext,
+            $contentTypeFactory,
+            $configFactory,
+            $configBuilder,
+            $data
+        );
+    }
+
+    /**
+     * Prepare component data
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_merge($config, $this->getData('config'));
+        }
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(),
+                'parentName' => $this->renderContext->getNamespace(),
+                'configuration' => $config
+            ]
+        );
+        $this->renderContext->getStorage()->addComponentsData($this->configuration);
+    }
+
+    /**
+     * Get condition by data type
+     *
+     * @param string|array $value
+     * @return array|null
+     */
+    public function getCondition($value)
+    {
+        return $this->filterPool->getFilter($this->getData('data_type'))->getCondition($value);
+    }
+}
diff --git a/app/code/Magento/Ui/FilterPool/View.php b/app/code/Magento/Ui/FilterPool/View.php
new file mode 100644
index 00000000000..b43e4651775
--- /dev/null
+++ b/app/code/Magento/Ui/FilterPool/View.php
@@ -0,0 +1,197 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\FilterPool;
+
+use Magento\Ui\AbstractView;
+use Magento\Backend\Helper\Data;
+use Magento\Ui\Filter\FilterPool;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Ui\Filter\View as FilterView;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Data helper
+     *
+     * @var \Magento\Backend\Helper\Data
+     */
+    protected $dataHelper;
+
+    /**
+     * Filters pool
+     *
+     * @var FilterPool
+     */
+    protected $filterPool;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param Context $renderContext
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param ConfigFactory $configFactory
+     * @param ConfigBuilderInterface $configBuilder
+     * @param Data $dataHelper
+     * @param FilterPool $filterPool
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        Context $renderContext,
+        ContentTypeFactory $contentTypeFactory,
+        ConfigFactory $configFactory,
+        ConfigBuilderInterface $configBuilder,
+        Data $dataHelper,
+        FilterPool $filterPool,
+        array $data = []
+    ) {
+        $this->dataHelper = $dataHelper;
+        $this->filterPool = $filterPool;
+        parent::__construct(
+            $context,
+            $renderContext,
+            $contentTypeFactory,
+            $configFactory,
+            $configBuilder,
+            $data
+        );
+    }
+
+    /**
+     * Prepare component data
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_merge($config, $this->getData('config'));
+        }
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(),
+                'parentName' => $this->renderContext->getNamespace(),
+                'configuration' => $config
+            ]
+        );
+
+        $this->updateDataCollection();
+    }
+
+    /**
+     * Update data collection
+     *
+     * @return void
+     */
+    protected function updateDataCollection()
+    {
+        $collection = $this->renderContext->getStorage()->getDataCollection($this->getParentName());
+
+        $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName());
+        $metaData = $metaData['fields'];
+        $filterData = $this->dataHelper->prepareFilterString(
+            $this->renderContext->getRequestParam(FilterView::FILTER_VAR)
+        );
+        foreach ($filterData as $field => $value) {
+            if (!isset($metaData[$field]['filter_type'])) {
+                continue;
+            }
+            $condition = $this->filterPool->getFilter($metaData[$field]['filter_type'])->getCondition($value);
+            if ($condition !== null) {
+                $collection->addFieldToFilter($field, $condition);
+            }
+        }
+    }
+
+    /**
+     * Get list of required filters
+     *
+     * @return array
+     */
+    protected function getListOfRequiredFilters()
+    {
+        $result = [];
+        foreach ($this->getFields() as $field) {
+            $result[] = isset($field['filter_type']) ? $field['filter_type'] : $field['input_type'];
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get fields
+     *
+     * @return array
+     */
+    public function getFields()
+    {
+        $meta = $this->renderContext->getStorage()->getMeta($this->getParentName());
+        $fields = [];
+        if (isset($meta['fields'])) {
+            foreach ($meta['fields'] as $name => $config) {
+                if (isset($config['filterable']) && $config['filterable'] === false) {
+                    continue;
+                }
+                $fields[$name] = $config;
+            }
+        }
+        return $fields;
+    }
+
+    /**
+     * Get active filters
+     *
+     * @return array
+     */
+    public function getActiveFilters()
+    {
+        $metaData = $this->renderContext->getStorage()->getMeta($this->getParentName());
+        $metaData = $metaData['fields'];
+        $filters = [];
+        $filterData = $this->dataHelper->prepareFilterString(
+            $this->renderContext->getRequestParam(FilterView::FILTER_VAR)
+        );
+        foreach ($filterData as $field => $value) {
+            if (isset($metaData[$field]['filter_type'])) {
+                $filters[$field] = [
+                    'title' => $metaData[$field]['title'],
+                    'current_display_value' => $value
+                ];
+            }
+        }
+
+        return $filters;
+    }
+}
diff --git a/app/code/Magento/Customer/Model/Resource/Form/Attribute/CollectionFactory.php b/app/code/Magento/Ui/Form/Field.php
similarity index 62%
rename from app/code/Magento/Customer/Model/Resource/Form/Attribute/CollectionFactory.php
rename to app/code/Magento/Ui/Form/Field.php
index 3bb1220e36f..22ef9883fb9 100644
--- a/app/code/Magento/Customer/Model/Resource/Form/Attribute/CollectionFactory.php
+++ b/app/code/Magento/Ui/Form/Field.php
@@ -21,30 +21,31 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Customer\Model\Resource\Form\Attribute;
+namespace Magento\Ui\Form;
 
-class CollectionFactory
-{
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Ui\AbstractView;
 
+/**
+ * Class AbstractFormElement
+ */
+class Field extends AbstractView implements UiComponentInterface
+{
     /**
-     * @param \Magento\Framework\ObjectManager $objectManager
+     * @return mixed
      */
-    public function __construct(\Magento\Framework\ObjectManager $objectManager)
+    public function renderHeader()
     {
-        $this->_objectManager = $objectManager;
+        return $this->getRenderEngine()->render($this, $this->getHeaderTemplate());
     }
 
     /**
-     * Create Collection
+     * Getting template for field header section
      *
-     * @return Collection
+     * @return string|false
      */
-    public function create()
+    public function getHeaderTemplate()
     {
-        return $this->_objectManager->create('Magento\Customer\Model\Resource\Form\Attribute\Collection');
+        return isset($this->configuration['header_template']) ? $this->configuration['header_template'] : false;
     }
 }
diff --git a/app/code/Magento/Index/Model/Process/FileFactory.php b/app/code/Magento/Ui/FormElement/AbstractFormElement.php
similarity index 58%
rename from app/code/Magento/Index/Model/Process/FileFactory.php
rename to app/code/Magento/Ui/FormElement/AbstractFormElement.php
index ad15eb86864..c81b45dc625 100644
--- a/app/code/Magento/Index/Model/Process/FileFactory.php
+++ b/app/code/Magento/Ui/FormElement/AbstractFormElement.php
@@ -21,37 +21,52 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Model\Process;
+namespace Magento\Ui\FormElement;
+
+use Magento\Ui\AbstractView;
 
 /**
- * Process file entity
+ * Class AbstractFormElement
  */
-class FileFactory
+abstract class AbstractFormElement extends AbstractView implements ElementInterface
 {
     /**
-     * Entity class name
+     * @return string
+     */
+    public function getHtmlId()
+    {
+        return '';
+    }
+
+    /**
+     * @return string|int
      */
-    const CLASS_NAME = 'Magento\Index\Model\Process\File';
+    public function getValue()
+    {
+        return $this->getData('value');
+    }
 
     /**
-     * @var \Magento\Framework\ObjectManager
+     * @return string
      */
-    protected $_objectManager;
+    public function getFormInputName()
+    {
+        return $this->getData('input_name');
+    }
 
     /**
-     * @param \Magento\Framework\ObjectManager $objectManager
+     * @return bool
      */
-    public function __construct(\Magento\Framework\ObjectManager $objectManager)
+    public function getIsReadonly()
     {
-        $this->_objectManager = $objectManager;
+        return (bool) $this->getData('readonly');
     }
 
     /**
-     * @param array $arguments
-     * @return \Magento\Index\Model\Process\File
+     * @return string
      */
-    public function create(array $arguments = array())
+    public function getCssClasses()
     {
-        return $this->_objectManager->create(self::CLASS_NAME, $arguments);
+        return $this->getData('css_classes');
     }
 }
diff --git a/app/code/Magento/Ui/FormElement/Checkbox.php b/app/code/Magento/Ui/FormElement/Checkbox.php
new file mode 100644
index 00000000000..d7756464893
--- /dev/null
+++ b/app/code/Magento/Ui/FormElement/Checkbox.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\FormElement;
+
+/**
+ * Class Checkbox
+ */
+class Checkbox extends AbstractFormElement
+{
+    //
+}
diff --git a/app/code/Magento/Ui/FormElement/ElementInterface.php b/app/code/Magento/Ui/FormElement/ElementInterface.php
new file mode 100644
index 00000000000..89211a68a85
--- /dev/null
+++ b/app/code/Magento/Ui/FormElement/ElementInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\FormElement;
+
+use Magento\Framework\View\Element\UiComponentInterface;
+
+/**
+ * Interface ElementInterface
+ */
+interface ElementInterface extends UiComponentInterface
+{
+    /**
+     * @return string
+     */
+    public function getHtmlId();
+
+    /**
+     * @return string
+     */
+    public function getFormInputName();
+
+    /**
+     * @return bool
+     */
+    public function getIsReadonly();
+
+    /**
+     * @return string
+     */
+    public function getCssClasses();
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php b/app/code/Magento/Ui/FormElement/Input.php
similarity index 79%
rename from app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php
rename to app/code/Magento/Ui/FormElement/Input.php
index f11a90a801d..a35daa0fe3a 100644
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php
+++ b/app/code/Magento/Ui/FormElement/Input.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,16 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Controller\Adminhtml\Process;
+namespace Magento\Ui\FormElement;
 
-class ReindexAll extends \Magento\Index\Controller\Adminhtml\Process
+/**
+ * Class Input
+ */
+class Input extends AbstractFormElement
 {
     /**
-     * Rebiuld all processes index
-     *
-     * @return void
+     * @return mixed|string
      */
-    public function execute()
+    public function getType()
     {
+        return $this->getData('input_type') ? $this->getData('input_type') : 'text';
     }
 }
diff --git a/app/code/Magento/Rss/Controller/Catalog/NewAction.php b/app/code/Magento/Ui/FormElement/Radio.php
similarity index 83%
rename from app/code/Magento/Rss/Controller/Catalog/NewAction.php
rename to app/code/Magento/Ui/FormElement/Radio.php
index ba0fbf471b3..2874e2ace1c 100644
--- a/app/code/Magento/Rss/Controller/Catalog/NewAction.php
+++ b/app/code/Magento/Ui/FormElement/Radio.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,15 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Catalog;
+namespace Magento\Ui\FormElement;
 
-class NewAction extends \Magento\Rss\Controller\Catalog
+/**
+ * Class Radio
+ */
+class Radio extends AbstractFormElement
 {
     /**
-     * @return void
+     * @return bool
      */
-    public function execute()
+    public function getChecked()
     {
-        $this->_genericAction('new');
+        return false;
     }
 }
diff --git a/app/code/Magento/Rss/Controller/Catalog/Special.php b/app/code/Magento/Ui/FormElement/Range.php
similarity index 83%
rename from app/code/Magento/Rss/Controller/Catalog/Special.php
rename to app/code/Magento/Ui/FormElement/Range.php
index a79f18aabd5..b52d6780679 100644
--- a/app/code/Magento/Rss/Controller/Catalog/Special.php
+++ b/app/code/Magento/Ui/FormElement/Range.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,15 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Catalog;
+namespace Magento\Ui\FormElement;
 
-class Special extends \Magento\Rss\Controller\Catalog
+/**
+ * Class Range
+ */
+class Range extends AbstractFormElement
 {
     /**
-     * @return void
+     * @return mixed
      */
-    public function execute()
+    public function getType()
     {
-        $this->_genericAction('special');
+        return $this->getData('input_type');
     }
 }
diff --git a/app/code/Magento/Ui/FormElement/Select.php b/app/code/Magento/Ui/FormElement/Select.php
new file mode 100644
index 00000000000..c8e81f6b64a
--- /dev/null
+++ b/app/code/Magento/Ui/FormElement/Select.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\FormElement;
+
+/**
+ * Class Select
+ */
+class Select extends AbstractFormElement
+{
+    //
+}
diff --git a/app/code/Magento/Ui/FormElement/Textarea.php b/app/code/Magento/Ui/FormElement/Textarea.php
new file mode 100644
index 00000000000..41cd26e4852
--- /dev/null
+++ b/app/code/Magento/Ui/FormElement/Textarea.php
@@ -0,0 +1,32 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\FormElement;
+
+/**
+ * Class Textarea
+ */
+class Textarea extends AbstractFormElement
+{
+    //
+}
diff --git a/app/code/Magento/Ui/Listing/View.php b/app/code/Magento/Ui/Listing/View.php
new file mode 100644
index 00000000000..9d0256f4637
--- /dev/null
+++ b/app/code/Magento/Ui/Listing/View.php
@@ -0,0 +1,271 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Listing;
+
+use Magento\Ui\AbstractView;
+use Magento\Ui\Control\ActionPool;
+use \Magento\Ui\DataProvider\RowPool;
+use Magento\Ui\DataProvider\OptionsFactory;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Options provider key in data array
+     */
+    const OPTIONS_PROVIDER_KEY = 'options_provider';
+
+    /**
+     * Row data provider key in data array
+     */
+    const ROW_DATA_PROVIDER_KEY = 'row_data_provider';
+
+    /**
+     * Data provider row pool
+     *
+     * @var RowPool
+     */
+    protected $dataProviderRowPool;
+
+    /**
+     * Page action pool
+     *
+     * @var ActionPool
+     */
+    protected $actionPool;
+
+    /**
+     * Constructor
+     *
+     * @param TemplateContext $context
+     * @param Context $renderContext
+     * @param ContentTypeFactory $contentTypeFactory
+     * @param OptionsFactory $optionsFactory
+     * @param ActionPool $actionPool
+     * @param RowPool $dataProviderRowPool
+     * @param ConfigFactory $configFactory
+     * @param ConfigBuilderInterface $configBuilder
+     * @param array $data
+     */
+    public function __construct(
+        TemplateContext $context,
+        Context $renderContext,
+        ContentTypeFactory $contentTypeFactory,
+        ConfigFactory $configFactory,
+        ConfigBuilderInterface $configBuilder,
+        OptionsFactory $optionsFactory,
+        ActionPool $actionPool,
+        RowPool $dataProviderRowPool,
+        array $data = []
+    ) {
+        $this->actionPool = $actionPool;
+        $this->optionsFactory = $optionsFactory;
+        $this->dataProviderRowPool = $dataProviderRowPool;
+        parent::__construct(
+            $context,
+            $renderContext,
+            $contentTypeFactory,
+            $configFactory,
+            $configBuilder,
+            $data
+        );
+    }
+
+    /**
+     * Prepare custom data
+     *
+     * @return void
+     */
+    public function prepare()
+    {
+        $meta = $this->getMeta();
+        $config = $this->getDefaultConfiguration();
+
+        if ($this->hasData('configuration')) {
+            $configuration = $this->getData('configuration');
+            if (!empty($configuration['page_actions'])) {
+                foreach ($configuration['page_actions'] as $key => $action) {
+                    $config['page_actions'][$key] = isset($configuration['page_actions'])
+                        ? array_replace($config['page_actions'][$key], $configuration['page_actions'][$key])
+                        : $config['page_actions'][$key];
+                }
+            }
+            unset($configuration['page_actions']);
+            $config = array_merge($config, $configuration);
+        }
+
+        foreach ($config['page_actions'] as $key => $action) {
+            $this->actionPool->add($key, $action, $this);
+        }
+        unset($config['page_actions']);
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->getData('name'),
+                'parentName' => $this->getData('name'),
+                'configuration' => $config
+            ]
+        );
+        $this->renderContext->getStorage()->addComponentsData($this->configuration);
+        $this->renderContext->getStorage()->addMeta($this->getData('name'), $meta);
+        $this->renderContext->getStorage()->addDataCollection($this->getData('name'), $this->getData('dataSource'));
+    }
+
+    /**
+     * Render view
+     *
+     * @return mixed|string
+     */
+    public function render()
+    {
+        $this->initialConfiguration();
+
+        return parent::render();
+    }
+
+    /**
+     * Get meta data
+     *
+     * @return array
+     */
+    public function getMeta()
+    {
+        $meta = $this->getData('meta');
+        foreach ($meta['fields'] as $key => $field) {
+
+            // TODO fixme
+            if ($field['data_type'] === 'date') {
+                $field['date_format'] = $this->_localeDate->getDateTimeFormat(
+                    \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM
+                );
+            }
+
+            if (isset($field[static::OPTIONS_PROVIDER_KEY])) {
+                $field['options'] = $this->optionsFactory->create($field[static::OPTIONS_PROVIDER_KEY])
+                    ->getOptions(empty($field['options']) ? [] : $field['options']);
+            }
+
+            unset($field[static::OPTIONS_PROVIDER_KEY]);
+            $meta['fields'][$key] = $field;
+        }
+
+        return $meta;
+    }
+
+    /**
+     * Apply data provider to row data
+     *
+     * @param array $dataRow
+     * @return array
+     */
+    protected function getDataFromDataProvider(array $dataRow)
+    {
+        if ($this->hasData(static::ROW_DATA_PROVIDER_KEY)) {
+            foreach ($this->getData(static::ROW_DATA_PROVIDER_KEY) as $field => $data) {
+                $dataRow[$field] = $this->dataProviderRowPool->get($data['class'])->getData($dataRow);
+            }
+        }
+
+        return $dataRow;
+    }
+
+    /**
+     * Get collection items
+     *
+     * @return array
+     */
+    public function getCollectionItems()
+    {
+        $items = [];
+        $collection = $this->renderContext->getStorage()->getDataCollection($this->getName());
+        foreach ($collection->getItems() as $item) {
+            $actualFields = [];
+            $itemsData = $this->getDataFromDataProvider($item->getData());
+            foreach (array_keys($this->getData('meta/fields')) as $field) {
+                $actualFields[$field] = $itemsData[$field];
+            }
+            $items[] = $actualFields;
+        }
+
+        return $items;
+    }
+
+    /**
+     * Configuration initialization
+     *
+     * @return void
+     */
+    protected function initialConfiguration()
+    {
+        $this->renderContext->getStorage()->addGlobalData(
+            'client',
+            [
+                'root' => $this->getUrl($this->getData('client_root')),
+                'ajax' => [
+                    'data' => [
+                        'component' => $this->getNameInLayout()
+                    ]
+                ]
+            ]
+        );
+        $this->renderContext->getStorage()->addGlobalData('dump', ['extenders' => []]);
+
+        $countItems = $this->renderContext->getStorage()->getDataCollection($this->getName())->getSize();
+        $this->renderContext->getStorage()->addData(
+            $this->getName(),
+            [
+                'meta_reference' => $this->getName(),
+                'items' => $this->getCollectionItems(),
+                'pages' => ceil($countItems / $this->renderContext->getRequestParam('limit', 20)),
+                'totalCount' => $countItems
+            ]
+        );
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    public function getDefaultConfiguration()
+    {
+        return [
+            'page_actions' => [
+                'add' => [
+                    'name' => 'add',
+                    'label' => __('Add New'),
+                    'class' => 'primary',
+                    'url' => $this->getUrl('*/*/new')
+                ]
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Ui/ListingContainer/Massaction/View.php b/app/code/Magento/Ui/ListingContainer/Massaction/View.php
new file mode 100644
index 00000000000..d8b53c500b5
--- /dev/null
+++ b/app/code/Magento/Ui/ListingContainer/Massaction/View.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ListingContainer\Massaction;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Prepare component data
+     *
+     * @return $this|void
+     */
+    public function prepare()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_merge($config, $this->getData('config'));
+        }
+        array_walk_recursive(
+            $config,
+            function (&$item, $key, $object) {
+                if ($key === 'url') {
+                    $item = $object->getUrl($item);
+                }
+            },
+            $this
+        );
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(),
+                'parentName' => $this->renderContext->getNamespace(),
+                'configuration' => $config
+            ]
+        );
+
+        $this->renderContext->getStorage()->addComponentsData($this->configuration);
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    protected function getDefaultConfiguration()
+    {
+        return  ['actions' => []];
+    }
+}
diff --git a/app/code/Magento/Ui/Paging/View.php b/app/code/Magento/Ui/Paging/View.php
new file mode 100644
index 00000000000..ebee775d875
--- /dev/null
+++ b/app/code/Magento/Ui/Paging/View.php
@@ -0,0 +1,82 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Paging;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Prepare component data
+     *
+     * @return $this|void
+     */
+    public function prepare()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_merge($config, $this->getData('config'));
+        }
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(),
+                'parentName' => $this->renderContext->getNamespace(),
+                'configuration' => $config
+            ]
+        );
+
+        $this->renderContext->getStorage()->addComponentsData($this->configuration);
+        $this->updateDataCollection();
+    }
+
+    /**
+     * Update data collection
+     *
+     * @return void
+     */
+    protected function updateDataCollection()
+    {
+        $this->renderContext->getStorage()->getDataCollection($this->getParentName())
+            ->setCurPage($this->renderContext->getRequestParam('page', $this->configuration->getData('current')))
+            ->setPageSize($this->renderContext->getRequestParam('limit', $this->configuration->getData('pageSize')));
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    protected function getDefaultConfiguration()
+    {
+        return  [
+            'sizes' => [20, 30, 50, 100, 200],
+            'pageSize' => 20,
+            'current' => 1
+        ];
+    }
+}
diff --git a/app/code/Magento/Ui/Search/View.php b/app/code/Magento/Ui/Search/View.php
new file mode 100644
index 00000000000..37e650a6344
--- /dev/null
+++ b/app/code/Magento/Ui/Search/View.php
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Search;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    //
+}
diff --git a/app/code/Magento/Ui/Sorting/View.php b/app/code/Magento/Ui/Sorting/View.php
new file mode 100644
index 00000000000..d218417c58e
--- /dev/null
+++ b/app/code/Magento/Ui/Sorting/View.php
@@ -0,0 +1,84 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Sorting;
+
+use Magento\Ui\AbstractView;
+
+/**
+ * Class View
+ */
+class View extends AbstractView
+{
+    /**
+     * Prepare component data
+     *
+     * @return $this|void
+     */
+    public function prepare()
+    {
+        $config = $this->getDefaultConfiguration();
+        if ($this->hasData('config')) {
+            $config = array_merge($config, $this->getData('config'));
+        }
+
+        $this->configuration = $this->configurationFactory->create(
+            [
+                'name' => $this->renderContext->getNamespace() . '_' . $this->getNameInLayout(),
+                'parentName' => $this->renderContext->getNamespace(),
+                'configuration' => $config
+            ]
+        );
+
+        $this->renderContext->getStorage()->addComponentsData($this->configuration);
+
+        $this->updateDataCollection();
+    }
+
+    /**
+     * Update data collection
+     *
+     * @return void
+     */
+    protected function updateDataCollection()
+    {
+        $field = $this->configuration->getData('field');
+        $direction = $this->configuration->getData('direction');
+        if (!empty($field) && !empty($direction)) {
+            $this->renderContext->getStorage()->getDataCollection($this->getParentName())->setOrder(
+                $this->renderContext->getRequestParam('sort', $field),
+                strtoupper($this->renderContext->getRequestParam('dir', $direction))
+            );
+        }
+    }
+
+    /**
+     * Get default parameters
+     *
+     * @return array
+     */
+    protected function getDefaultConfiguration()
+    {
+        return ['direction' => 'asc'];
+    }
+}
diff --git a/app/code/Magento/Index/composer.json b/app/code/Magento/Ui/composer.json
similarity index 51%
rename from app/code/Magento/Index/composer.json
rename to app/code/Magento/Ui/composer.json
index 5cd219b4584..cc0b3354d6a 100644
--- a/app/code/Magento/Index/composer.json
+++ b/app/code/Magento/Ui/composer.json
@@ -1,20 +1,20 @@
 {
-    "name": "magento/module-index",
+    "name": "magento/module-ui",
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
                 "*",
-                "Magento/Index"
+                "Magento/Ui"
             ]
         ]
     }
diff --git a/app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml b/app/code/Magento/Ui/etc/adminhtml/routes.xml
similarity index 91%
rename from app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml
rename to app/code/Magento/Ui/etc/adminhtml/routes.xml
index 312f40563c2..593c09ef12b 100644
--- a/app/code/Magento/UrlRedirect/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Ui/etc/adminhtml/routes.xml
@@ -25,8 +25,8 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
-        <route id="adminhtml">
-            <module name="Magento_UrlRedirect" before="Magento_Adminhtml" />
+        <route id="mui" frontName="mui">
+            <module name="Magento_Ui" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml
new file mode 100644
index 00000000000..2d27a89f540
--- /dev/null
+++ b/app/code/Magento/Ui/etc/di.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface" type="Magento\Ui\ContentType\Builders\ConfigJson" />
+    <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageBuilderInterface" type="Magento\Ui\ContentType\Builders\ConfigStorageJson" />
+    <preference for="Magento\Framework\View\Element\UiComponent\ConfigInterface" type="Magento\Ui\Configuration" />
+    <preference for="Magento\Framework\View\Element\UiComponent\ConfigStorageInterface" type="Magento\Ui\ConfigurationStorage" />
+    <type name="Magento\Framework\View\Element\UiComponentFactory" shared="true" />
+    <type name="Magento\Ui\Context" shared="true" />
+    <type name="Magento\Ui\ContentType\Builders\ConfigJson" shared="true" />
+    <preference for="Magento\Ui\Control\ActionPoolInterface" type="Magento\Ui\Control\ActionPool" />
+</config>
diff --git a/app/code/Magento/Index/etc/module.xml b/app/code/Magento/Ui/etc/module.xml
similarity index 88%
rename from app/code/Magento/Index/etc/module.xml
rename to app/code/Magento/Ui/etc/module.xml
index 92b3bfd022c..d859f136d0a 100644
--- a/app/code/Magento/Index/etc/module.xml
+++ b/app/code/Magento/Ui/etc/module.xml
@@ -24,14 +24,14 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_Index" schema_version="1.6.0.0" active="true">
+    <module name="Magento_Ui" schema_version="1.6.0.0" active="true">
         <sequence>
-            <module name="Magento_Core"/>
-            <module name="Magento_Store"/>
+            <module name="Magento_Backend"/>
+        	<module name="Magento_Directory"/>
         </sequence>
         <depends>
-            <module name="Magento_Store"/>
             <module name="Magento_Backend"/>
+            <module name="Magento_Store"/>
         </depends>
     </module>
-</config>
+</config>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/layout/default.xml b/app/code/Magento/Ui/view/base/layout/default.xml
new file mode 100644
index 00000000000..a6ecc6b8b68
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/layout/default.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <referenceContainer name="footer">
+        <block class="Magento\Ui\Context\DataProvider" name="ui.global.config" after="-">
+            <arguments>
+                <argument name="content_template" xsi:type="string">Magento_Ui::context/default.phtml</argument>
+            </arguments>
+        </block>
+    </referenceContainer>
+</page>
diff --git a/app/code/Magento/Ui/view/base/layout/ui_components.xml b/app/code/Magento/Ui/view/base/layout/ui_components.xml
new file mode 100644
index 00000000000..86e63e3a94b
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/layout/ui_components.xml
@@ -0,0 +1,134 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
+    <block class="Magento\Ui\Listing\View" name="listing">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::listing/horizontal_grid.phtml</argument>
+            <argument name="save_parameters_in_session" xsi:type="string">1</argument>
+            <argument name="client_root" xsi:type="string">mui/listing/ajax</argument>
+        </arguments>
+        <container label="Listing Head" name="listing_head"/>
+        <container label="Listing Before" name="listing_before">
+            <ui_component name="paging_small_top" component="paging" />
+            <ui_component name="filter_base" component="filter_pool" />
+            <ui_component name="massaction_top" component="control_massaction" />
+            <ui_component name="sorting_base" component="sorting" />
+        </container>
+    </block>
+    <block class="Magento\Ui\Sorting\View" name="sorting">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::sorting/default.phtml</argument>
+            <argument name="config" xsi:type="array">
+                <item name="direction" xsi:type="string">asc</item>
+            </argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\Paging\View" name="paging">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::paging/default.phtml</argument>
+        </arguments>
+    </block>
+
+    <block class="Magento\Ui\Control\Action" name="actions">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::control/action/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\ListingContainer\Massaction\View" name="control_massaction">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::listingcontainer/massaction/default.phtml</argument>
+        </arguments>
+    </block>
+
+    <block class="Magento\Ui\FormElement\Input" name="input">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::form_element/input/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\FormElement\Select" name="select">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::form_element/select/default.phtml</argument>
+        </arguments>
+    </block>
+
+    <block class="Magento\Ui\DataType\Boolean" name="boolean">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/boolean/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\DataType\Date" name="date">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/date/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\DataType\Media" name="media">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/media/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\DataType\Text" name="text">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::data_type/text/default.phtml</argument>
+        </arguments>
+    </block>
+
+    <block class="Magento\Ui\Filter\Type\Select" name="filter_select">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/select/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\Filter\Type\Range" name="filter_range">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/range/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\Filter\Type\Input" name="filter_input">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/input/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\Filter\Type\Date" name="filter_date">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter/type/date/default.phtml</argument>
+        </arguments>
+    </block>
+    <block class="Magento\Ui\FilterPool\View" name="filter_pool">
+        <arguments>
+            <argument name="content_template" xsi:type="string">Magento_Ui::filter_pool/default.phtml</argument>
+            <argument name="config" xsi:type="array">
+                <item name="types" xsi:type="array">
+                    <item name="filter_date" xsi:type="array">
+                        <item name="dateFormat" xsi:type="string">mm/dd/yyyy</item>
+                    </item>
+                    <item name="filter_input" xsi:type="array"/>
+                    <item name="filter_select" xsi:type="array"/>
+                    <item name="filter_range" xsi:type="array"/>
+                </item>
+            </argument>
+        </arguments>
+    </block>
+
+</layout>
diff --git a/app/code/Magento/Ui/view/base/requirejs-config.js b/app/code/Magento/Ui/view/base/requirejs-config.js
new file mode 100644
index 00000000000..e599c608220
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/requirejs-config.js
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+var config = {
+    paths: {
+        'ui/template/filter': 'Magento_Ui/templates/filter',
+        'ui/template/pagination': 'Magento_Ui/templates/pagination',
+        'ui/template/pageactions': 'Magento_Ui/templates/pageactions',
+        'ui/template/massaction': 'Magento_Ui/templates/massaction',
+        'ui/template/listing/grid': 'Magento_Ui/templates/listing/grid'
+    }
+};
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/context/default.phtml b/app/code/Magento/Ui/view/base/templates/context/default.phtml
new file mode 100644
index 00000000000..ade6febbfac
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/context/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Context\DataProvider $this
+ */
+?>
+<script type="application/json">
+    <?php echo $this->getAsJson(); ?>
+</script>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/control/action/default.phtml b/app/code/Magento/Ui/view/base/templates/control/action/default.phtml
new file mode 100644
index 00000000000..c8e8be73c3c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/control/action/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Control\Action $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/control/button/default.phtml b/app/code/Magento/Ui/view/base/templates/control/button/default.phtml
new file mode 100644
index 00000000000..5c6b8c5e788
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/control/button/default.phtml
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var $this \Magento\Ui\Control\Button
+ */
+?>
+<?php echo $this->getBeforeHtml(); ?>
+<button <?php echo $this->getAttributesHtml(), $this->getUiId(); ?>>
+    <span><?php echo $this->getLabel(); ?></span>
+</button>
+<?php echo $this->getAfterHtml(); ?>
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/boolean/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/boolean/default.phtml
new file mode 100644
index 00000000000..17564330aef
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/boolean/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Boolean $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/date/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/date/default.phtml
new file mode 100644
index 00000000000..4ec821a7978
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/date/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Date $this
+ */
+?>
+<span data-bind="datepicker: { storage: from, options: config }, attr: {placeholder: $t('From')}">
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/media/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/media/default.phtml
new file mode 100644
index 00000000000..376ecefa5ef
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/media/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Media $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/number/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/number/default.phtml
new file mode 100644
index 00000000000..ec9992dcd9a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/number/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Number $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/password/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/password/default.phtml
new file mode 100644
index 00000000000..b4abbd190eb
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/password/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Password $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/data_type/text/default.phtml b/app/code/Magento/Ui/view/base/templates/data_type/text/default.phtml
new file mode 100644
index 00000000000..811706cfbe1
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/data_type/text/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\DataType\Text $this
+ */
+?>
+<span>
+    <?php echo $this->getDataObjectValue(); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/content.phtml b/app/code/Magento/Ui/view/base/templates/filter/content.phtml
new file mode 100644
index 00000000000..699560b1a21
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/content.phtml
@@ -0,0 +1,38 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\View $this
+ */
+?>
+<fieldset class="field field-<?php echo $this->getData('data_type') ?>">
+    <legend class="label"><?php echo $this->renderElementLabel($this->getData('data_type'), [
+            'title' => $this->getData('title')
+        ]); ?></legend>
+    <div class="control">
+        <?php echo $this->renderElement($this->getData('filter_type'), [
+            'title' => $this->getData('title'),
+            'options' => $this->getData('options')
+        ]); ?>
+    </div>
+</fieldset>
\ No newline at end of file
diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml b/app/code/Magento/Ui/view/base/templates/filter/default.phtml
similarity index 71%
rename from app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml
rename to app/code/Magento/Ui/view/base/templates/filter/default.phtml
index 74cd2357bdc..04fc20ce0a2 100644
--- a/app/code/Magento/UrlRedirect/view/adminhtml/templates/edit.phtml
+++ b/app/code/Magento/Ui/view/base/templates/filter/default.phtml
@@ -21,18 +21,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
+?>
+<?php
 /**
- * Urlrewrites edit container
- *
- * @var $this \Magento\UrlRedirect\Block\Edit
+ * @var \Magento\Ui\Filter\View $this
  */
 ?>
-<?php echo $this->getChildHtml() ?>
 
-<?php if ($this->getChildBlock('form')): ?>
-<script type="text/javascript">
-    jQuery('#edit_form').mage('form')
-        .mage('validation', {validationUrl: '<?php echo $this->getValidationUrl() ?>'});
+<script data-mage-apply='{"Magento_Ui/js/listing/filter": ""}' type="application/json">
+    <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
 </script>
-<?php endif; ?>
+<div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'">
+    <!-- ko template: 'ui/filter' --><!-- /ko -->
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/date/content.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/date/content.phtml
new file mode 100644
index 00000000000..5a79e044684
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/date/content.phtml
@@ -0,0 +1,52 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Range $this
+ */
+?>
+<fieldset class="field field-range field-<?php echo $this->getData('data_type') ?>">
+    <legend class="label"><?php echo $this->renderElementLabel('input', [
+            'title' => $this->getData('title')
+        ]); ?></legend><br />
+    <div class="control">
+        <div class="fields group group-2">
+            <div class="field field-range-from">
+                <label class="label"><span data-bind-="text: $t('From')">From</span></label>
+                <div class="control">
+                    <?php echo $this->renderElement('input', [
+                            'data-bind' => "datepicker: { storage: from, options: config }, attr: {placeholder: \$t('From')}",
+                        ]); ?>
+                </div>
+            </div>
+            <div class="field field-range-to">
+                <label class="label"><span data-bind-="text: $t('To')">To</span></label>
+                <div class="control">
+                    <?php echo $this->renderElement('input', [
+                            'data-bind' => "datepicker: { storage: to, options: config }, attr: {placeholder: \$t('To')}",
+                        ]); ?>
+                </div>
+            </div>
+        </div>
+    </div>
+</fieldset>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/date/label.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/date/label.phtml
new file mode 100644
index 00000000000..0f8b6965c31
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/date/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Range $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/input/content.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/input/content.phtml
new file mode 100644
index 00000000000..fd864cc142c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/input/content.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Input $this
+ */
+?>
+<fieldset class="field field-<?php echo $this->getData('data_type') ?>">
+    <legend class="label"><?php echo $this->renderElementLabel('input', [
+            'title' => $this->getData('title')
+        ]); ?></legend><br />
+    <div class="control">
+        <?php echo $this->renderElement('input', [
+                'data-bind' => "",
+            ]); ?>
+    </div>
+</fieldset>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/input/label.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/input/label.phtml
new file mode 100644
index 00000000000..65a01307c9e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/input/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Input $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/range/content.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/range/content.phtml
new file mode 100644
index 00000000000..5a79e044684
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/range/content.phtml
@@ -0,0 +1,52 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Range $this
+ */
+?>
+<fieldset class="field field-range field-<?php echo $this->getData('data_type') ?>">
+    <legend class="label"><?php echo $this->renderElementLabel('input', [
+            'title' => $this->getData('title')
+        ]); ?></legend><br />
+    <div class="control">
+        <div class="fields group group-2">
+            <div class="field field-range-from">
+                <label class="label"><span data-bind-="text: $t('From')">From</span></label>
+                <div class="control">
+                    <?php echo $this->renderElement('input', [
+                            'data-bind' => "datepicker: { storage: from, options: config }, attr: {placeholder: \$t('From')}",
+                        ]); ?>
+                </div>
+            </div>
+            <div class="field field-range-to">
+                <label class="label"><span data-bind-="text: $t('To')">To</span></label>
+                <div class="control">
+                    <?php echo $this->renderElement('input', [
+                            'data-bind' => "datepicker: { storage: to, options: config }, attr: {placeholder: \$t('To')}",
+                        ]); ?>
+                </div>
+            </div>
+        </div>
+    </div>
+</fieldset>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/range/label.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/range/label.phtml
new file mode 100644
index 00000000000..0f8b6965c31
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/range/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Range $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/select/content.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/select/content.phtml
new file mode 100644
index 00000000000..aa8ea51cbef
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/select/content.phtml
@@ -0,0 +1,38 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Select $this
+ */
+?>
+<fieldset class="field field-<?php echo $this->getData('data_type') ?>">
+    <legend class="label"><?php echo $this->renderElementLabel('select', [
+            'title' => $this->getData('title')
+        ]); ?></legend><br />
+    <div class="control">
+        <?php echo $this->renderElement('select', [
+                'data-bind' => "",
+                'options' => $this->getData('options')
+            ]); ?>
+    </div>
+</fieldset>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter/type/select/label.phtml b/app/code/Magento/Ui/view/base/templates/filter/type/select/label.phtml
new file mode 100644
index 00000000000..65a01307c9e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter/type/select/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\Type\Input $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml
new file mode 100644
index 00000000000..916cd562401
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter_pool/active.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\Filter\View $this
+ */
+?>
+<strong class="item-label" data-bind-="text: $t(filter.title)"><?php echo $this->getData('title') ?></strong>
+<span class="item-value" data-bind-="text: $t(filter.output)"><?php echo $this->getData('current_display_value') ?></span>
+<button data-bind-="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind-="text: $t('Remove')"></span></button>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml b/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml
new file mode 100644
index 00000000000..9548d891a1e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/filter_pool/default.phtml
@@ -0,0 +1,72 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FilterPool\View $this
+ */
+?>
+<?php if (true): ?>
+    <script data-mage-apply='{"Magento_Ui/js/listing/filter": ""}' type="application/json">
+        <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+    </script>
+    <div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'">
+        <!-- ko template: 'ui/filter' --><!-- /ko -->
+    </div>
+<?php else: ?>
+    <div class="filters" data-mage-apply='{"Magento_Ui/js/listing/filter": ""}'
+         data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'">
+        <button class="action filters-toggle" data-bind="click: toggle"><span
+                data-bind-="text: $t('Filter')">Filter</span></button>
+        <div class="form filters-form" data-bind-="visible: isVisible" data-part-="filter-form">
+            <fieldset class="filters-fieldset fieldset">
+                <legend class="legend filters-legend">
+                    <span data-bind-="text: $t('Advanced filter')"></span>
+                </legend>
+                <br/>
+                <?php foreach ($this->getFields() as $field): ?>
+                    <?php echo $this->renderElement($field['filter_type'], $field); ?>
+                <?php endforeach; ?>
+            </fieldset>
+            <div class="actions filters-actions">
+                <button class="action primary action-apply" data-bind-="click: apply" type="button"><span
+                        data-bind-="text: $t('Apply')"></span></button>
+                <button class="action secondary action-reset" data-bind-="click: reset" type="button"><span
+                        data-bind-="text: $t('Reset')"></span></button>
+                <button class="action secondary action-close" data-bind-="click: close" type="button"><span
+                        data-bind-="text: $t('Close')"></span></button>
+            </div>
+        </div>
+        <div class="filters-current">
+            <ul class="filters-items items">
+                <?php foreach ($this->getActiveFilters() as $filter): ?>
+                    <li class="filters-item item">
+                        <?php echo $this->renderElement('filter', $filter); ?>
+                    </li>
+                <?php endforeach; ?>
+            </ul>
+            <button data-bind-="click: reset" class="action action-clear">
+                <span data-bind-="text: $t('Clear all')"></span>
+            </button>
+        </div>
+    </div>
+<?php endif; ?>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/checkbox/content.phtml b/app/code/Magento/Ui/view/base/templates/form_element/checkbox/content.phtml
new file mode 100644
index 00000000000..bac8c10ba74
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/checkbox/content.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Checkbox $this
+ */
+?>
+<select>
+    <?php echo $this->getValue(); ?>
+</select>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/checkbox/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/checkbox/label.phtml
new file mode 100644
index 00000000000..372b6e56132
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/checkbox/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Checkbox $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/input/content.phtml b/app/code/Magento/Ui/view/base/templates/form_element/input/content.phtml
new file mode 100644
index 00000000000..d524db52374
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/input/content.phtml
@@ -0,0 +1,29 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Input $this
+ */
+?>
+<input data-bind="<?php echo $this->getData('data-bind') ?>" class="input-text no-changes"
+       type="<?php echo $this->getType(); ?>" value="<?php echo $this->getValue(); ?>"/>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/input/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/input/label.phtml
new file mode 100644
index 00000000000..af84af15696
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/input/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Input $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/radio/content.phtml b/app/code/Magento/Ui/view/base/templates/form_element/radio/content.phtml
new file mode 100644
index 00000000000..9b5d25b4785
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/radio/content.phtml
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Radio $this
+ */
+?>
+<input type="radio" value="<?php echo $this->getValue(); ?>" checked="<?php echo $this->getChecked(); ?>" />
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/radio/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/radio/label.phtml
new file mode 100644
index 00000000000..372b6e56132
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/radio/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Checkbox $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/categories.phtml b/app/code/Magento/Ui/view/base/templates/form_element/range/content.phtml
similarity index 54%
rename from app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/categories.phtml
rename to app/code/Magento/Ui/view/base/templates/form_element/range/content.phtml
index bc690fdc810..25e4dc2c7e8 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/categories.phtml
+++ b/app/code/Magento/Ui/view/base/templates/form_element/range/content.phtml
@@ -21,21 +21,25 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/** @var $this \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree */
+/**
+ * @var \Magento\Ui\FormElement\Input $this
+ */
 ?>
-<fieldset class="fieldset" data-ui-id="category-selector">
-    <legend class="legend"><span><?php echo __('Select Category') ?></span></legend>
-    <div class="content" style="clear: both;">
-        <input type="hidden" name="categories" id="product_categories" value="" />
-        <?php if ($this->getRoot()): ?>
-        <div data-mage-init='<?php
-            echo $this->escapeHtml($this->helper('Magento\Core\Helper\Data')->jsonEncode(array(
-                'categoryTree' => array(
-                    'data' => $this->getTreeArray(null),
-                    'url' => $this->getLoadTreeUrl(),
-                )
-            )));
-        ?>' class="jstree-default"></div>
-        <?php endif; ?>
+<div class="fields group group-2">
+    <div class="field field-range-from">
+        <label class="label"><span data-bind-="text: $t('From')">From</span></label>
+
+        <div class="control">
+            <input type="text" class="input-text no-changes"
+                   data-bind-="datepicker: { storage: from, options: config }, attr: {placeholder: $t('From')}">
+        </div>
+    </div>
+    <div class="field field-range-to">
+        <label class="label"><span data-bind-="text: $t('To')">To</span></label>
+
+        <div class="control">
+            <input type="text" class="input-text no-changes"
+                   data-bind-="datepicker: { storage: to, options: config }, attr: {placeholder: $t('To')}">
+        </div>
     </div>
-</fieldset>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/range/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/range/label.phtml
new file mode 100644
index 00000000000..af84af15696
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/range/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Input $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/select/content.phtml b/app/code/Magento/Ui/view/base/templates/form_element/select/content.phtml
new file mode 100644
index 00000000000..6091fd3dcdd
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/select/content.phtml
@@ -0,0 +1,51 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Select $this
+ */
+?>
+<select>
+    <?php foreach ($this->getData('options') as $option): ?>
+        <?php if (is_array($option['value'])): ?>
+            <optgroup label="<?php echo $option['label']; ?>">
+                <?php foreach ($option['value'] as $subOption): ?>
+                    <?php if (is_array($subOption['value'])): ?>
+                        <optgroup label="<?php echo $subOption['label']; ?>">
+                            <?php foreach ($subOption['value'] as $subSubOption): ?>
+                                <?php if (!is_array($subSubOption['value'])): ?>
+                                    <option value="<?php echo
+                                        $subSubOption['value']; ?>"><?php echo $subSubOption['label']; ?></option>
+                                <?php endif; ?>
+                            <?php endforeach; ?>
+                        </optgroup>
+                    <?php else: ?>
+                        <option value="<?php echo $subOption['value']; ?>"><?php echo $subOption['label']; ?></option>
+                    <?php endif; ?>
+                <?php endforeach; ?>
+            </optgroup>
+        <?php else: ?>
+            <option value="<?php echo $option['value']; ?>"><?php echo $option['label']; ?></option>
+        <?php endif; ?>
+    <?php endforeach; ?>
+</select>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/select/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/select/label.phtml
new file mode 100644
index 00000000000..081b11ee06a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/select/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Select $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/textarea/content.phtml b/app/code/Magento/Ui/view/base/templates/form_element/textarea/content.phtml
new file mode 100644
index 00000000000..d28807ea987
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/textarea/content.phtml
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Textarea $this
+ */
+?>
+<textarea><?php echo $this->getValue(); ?></textarea>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/form_element/textarea/label.phtml b/app/code/Magento/Ui/view/base/templates/form_element/textarea/label.phtml
new file mode 100644
index 00000000000..32929ddb30a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/form_element/textarea/label.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\FormElement\Textarea $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/label/default.phtml b/app/code/Magento/Ui/view/base/templates/label/default.phtml
new file mode 100644
index 00000000000..801edf83625
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/label/default.phtml
@@ -0,0 +1,30 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @var \Magento\Ui\AbstractView $this
+ */
+?>
+<span>
+    <?php echo $this->getData('title'); ?>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml b/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml
new file mode 100644
index 00000000000..d1759260ec7
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/listing/horizontal_grid.phtml
@@ -0,0 +1,80 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var \Magento\Ui\Listing\View $this
+ */
+
+?>
+
+<?php if (true): ?>
+    <script>
+        var allowLocalCache = true;
+    </script>
+    <script data-mage-apply='{"Magento_Ui/js/listing/utils/provider": ""}' type="application/json">
+        <?php
+            echo $this->getRenderContext()
+                ->getConfigurationBuilder()
+                    ->toJson($this->getRenderContext()->getStorage(), $this->getName());
+        ?>
+    </script>
+    <script data-mage-apply='{"Magento_Ui/js/listing/grid": ""}' type="application/json">
+        <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+    </script>
+    <?php echo $this->getChildHtml('listing_head'); ?>
+    <div class="grid">
+        <?php echo $this->getChildHtml('listing_before'); ?>
+        <div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'">
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        </div>
+        <?php echo $this->getChildHtml('listing_after'); ?>
+    </div>
+    <div data-role="spinner" class="grid-loading-mask">
+        <div class="grid-loader"></div>
+    </div>
+<?php else: ?>
+    <div class="grid" data-mage-apply='{"Magento_Ui/js/listing/utils/provider": ""}'>
+        <?php echo $this->getChildHtml('listing_before'); ?>
+        <table>
+            <thead>
+            <tr>
+                <?php foreach ($this->getMeta()['fields'] as $name => $field): $field['name'] = $name; ?>
+                    <th><?php echo $this->renderElementLabel($field['data_type'], $field); ?></th>
+                <?php endforeach; ?>
+            </tr>
+            </thead>
+            <tbody>
+            <?php foreach ($this->getCollectionItems() as $item): ?>
+            <tr>
+                <?php foreach ($this->getMeta()['fields'] as $name => $field): $field['name'] = $name; $field['data_object'] = $item; ?>
+                <td><?php echo $this->renderElement($field['data_type'], $field); ?></td>
+                <?php endforeach; ?>
+            </tr>
+        <?php endforeach; ?>
+            </tbody>
+        </table>
+        <?php echo $this->getChildHtml('listing_after'); ?>
+    </div>
+<?php endif; ?>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml
new file mode 100644
index 00000000000..dd0335d9ef3
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/default.phtml
@@ -0,0 +1,36 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var \Magento\Ui\ListingContainer\Massaction\View $this
+ */
+?>
+
+<script data-mage-apply='{ "Magento_Ui/js/listing/massaction": "" }' type="application/json">
+    <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+</script>
+<div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'" class="grid-actions">
+    <!-- ko template: 'ui/massaction' --><!-- /ko -->
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml
new file mode 100644
index 00000000000..d1b3eee36be
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/listingcontainer/massaction/page_actions.phtml
@@ -0,0 +1,35 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var \Magento\Ui\ListingContainer\Massaction\View $this
+ */
+?>
+<script data-mage-apply='{ "Magento_Ui/js/listing/massaction": "" }' type="application/json">
+    <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+</script>
+<div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'">
+    <!-- ko template: 'ui/pageactions' --><!-- /ko -->
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/templates/paging/default.phtml b/app/code/Magento/Ui/view/base/templates/paging/default.phtml
new file mode 100644
index 00000000000..52605b14c1a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/paging/default.phtml
@@ -0,0 +1,65 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var \Magento\Ui\Paging\View $this
+ */
+
+?>
+<?php if (true): ?>
+    <script data-mage-apply='{"Magento_Ui/js/listing/paging" : ""}' type="application/json">
+        <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+    </script>
+    <div data-bind="scope: '<?php echo $this->getParentName(); ?>:<?php echo $this->getName(); ?>'" class="pager">
+        <!-- ko template: 'ui/pagination' --><!-- /ko -->
+    </div>
+<?php else: ?>
+    <div class="pager" data-mage-apply='{"Magento_Ui/js/listing/paging" : ""}'>
+        <span data-part="left">
+            <span class="pages-total-found">Total <strong data-bind-="text: totalCount"><?php echo $this->getTotalCount(); ?></strong> records</span>
+            <label class="view-pages">
+                View
+                <?php echo $this->renderElement('select', (array)$this->getOptions()); ?>
+                per page.
+            </label>
+        </span>
+        <span data-part="right">
+            <span data-bind-="css: { disabled: isFirst() }, click: prev" class="action-previous">
+                <span>Previous page</span>
+            </span>
+            <?php echo $this->renderElement('input', [
+                    'type' => 'text',
+                    'css_classes' => 'input-text page'
+                ]); ?>
+            <span class="pages-total">
+                of
+                <span data-bind-="text: pages" style="vertical-align: top;"><?php echo $this->getTotalPages() ?></span>
+            </span>
+            <span data-bind-="css: { disabled: isLast() }, click: next" class="action-next">
+                <span>Next page</span>
+            </span>
+        </span>
+    </div>
+<?php endif; ?>
diff --git a/app/code/Magento/Ui/view/base/templates/sorting/default.phtml b/app/code/Magento/Ui/view/base/templates/sorting/default.phtml
new file mode 100644
index 00000000000..d62cc68e6c0
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/templates/sorting/default.phtml
@@ -0,0 +1,34 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/**
+ * @var \Magento\Ui\Sorting\View $this
+ */
+
+?>
+
+<script data-mage-apply='{ "Magento_Ui/js/listing/sorting": "" }' type="application/json">
+    <?php echo $this->getConfigurationBuilder()->toJson($this->getConfiguration()); ?>
+</script>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/class.js b/app/code/Magento/Ui/view/base/web/js/lib/class.js
new file mode 100644
index 00000000000..b7d6b8f029b
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/class.js
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore'
+], function(_) {
+    'use strict';
+
+    /**
+     * Analogue of Backbone.extend function.
+     * @param  {Object} protoProps - object, that describes the prototype of
+     * created constructor.
+     * @return {Function} - new constructor
+     */
+    function extend( protoProps ){
+        var parent = this,
+            child,
+            args,
+            hasConstructor;
+
+        protoProps      = protoProps || {};
+        hasConstructor  = protoProps.hasOwnProperty('constructor');
+
+        child = hasConstructor ?
+            protoProps.constructor :
+            function() {
+                return parent.apply(this, arguments);
+            };
+
+        child.prototype = Object.create( parent.prototype );
+        child.prototype.constructor = child;
+
+        args = [child.prototype];
+
+        args.push.apply(args, arguments);
+
+        _.extend.apply(_, args);
+
+        child.extend = extend;
+        child.__super__ = parent.prototype;
+
+        return child;
+    }
+
+    /**
+     * Constructor, which calls initialize with passed arguments.
+     */
+    function Class() {
+        this.initialize.apply(this, arguments);
+    }
+
+    Class.prototype.initialize = function(){};
+
+    Class.extend = extend;
+
+    return Class;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/component.js b/app/code/Magento/Ui/view/base/web/js/lib/component.js
new file mode 100644
index 00000000000..b099f5ebada
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/component.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'Magento_Ui/js/lib/registry/registry'
+], function(registry) {
+    'use strict';
+
+    /**
+     * Extends configuration that will be retrieved from the data provider
+     * with configuration that is stored in a 'baseConfig' object.
+     * @param {Object} provider - DataProvider instance.
+     * @param {Object} baseConfig - Basic configuration.
+     * @returns {Object} Resulting configurational object.
+     */
+    function getConfig(provider, baseConfig) {
+        var configs     = provider.config.get('components'),
+            storeConfig = configs[baseConfig.name] || {};
+
+        return _.extend({
+            provider: provider
+        }, storeConfig, baseConfig);
+    }
+
+    /**
+     * Creates new instance of a grids' component.
+     * @param {Object} data -
+            Data object that was passed while creating component initializer. 
+     * @param {HTMLElement} el -
+            Element upon which compononet is going to be initialized.
+     * @param {Object} base -
+            Basic configuration.
+     */
+    function init(data, el, base) {
+        var providerName    = base.parent_name,
+            component       = providerName + ':' + base.name,
+            mainComponent   = providerName + ':' + providerName,
+            deps            = [providerName];
+
+        if (registry.has(component)) {
+            return;
+        }
+
+        if (component !== mainComponent) {
+            deps.push(mainComponent);
+        }
+
+        registry.get(deps, function(provider) {
+            var config = getConfig(provider, base);
+
+            registry.set(component, new data.constr(config));
+        });
+    }
+
+    return function(data) {
+        return init.bind(this, data);
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/events.js b/app/code/Magento/Ui/view/base/web/js/lib/events.js
new file mode 100644
index 00000000000..a4b9e20d341
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/events.js
@@ -0,0 +1,91 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore'
+], function(_) {
+    'use strict';
+
+    function addHandler(events, callback, name) {
+        (events[name] = events[name] || []).push(callback);
+    }
+
+    function getEvents(obj, name) {
+        var events = obj._events = obj._events || {};
+
+        return name ? events[name] : events;
+    }
+
+    return {
+        /**
+         * Calls callback when name event is triggered.
+         * @param  {String}   name
+         * @param  {Function} callback
+         * @return {Object} reference to this
+         */
+        on: function(name, callback) {
+            var events = getEvents(this);
+
+            typeof name === 'object' ?
+                _.each(name, addHandler.bind(window, events)) :
+                addHandler(events, callback, name);
+
+            return this;
+        },
+
+        /**
+         * Removed callback from listening to target event 
+         * @param  {String} name
+         * @return {Object} reference to this
+         */
+        off: function(name) {
+            var events      = getEvents(this),
+                handlers    = events[name];
+
+            if (Array.isArray(handlers)) {
+                delete events[name];
+            }
+
+            return this;
+        },
+
+        /**
+         * Triggers event and executes all attached callbacks
+         * @param  {String} name
+         * @return {Object} reference to this
+         */
+        trigger: function(name) {
+            var handlers = getEvents(this, name),
+                args;
+
+            if (typeof handlers !== 'undefined') {
+                args = Array.prototype.slice.call(arguments, 1);
+
+                handlers.forEach(function(callback) {
+                    callback.apply(this, args);
+                });
+            }
+
+            return this;
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js
new file mode 100644
index 00000000000..b4568e41e76
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/date.js
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'ko',
+    'moment',
+    'jquery',
+    'date-format-normalizer'
+], function(ko, moment, $, convert) {
+    'use strict';
+
+    ko.bindingHandlers.date = {
+
+        /**
+         * Reads passed date and format from valueAccessor, uses convert function to format it.
+         * Writes date to el.innerText using jQuery
+         * @param {HTMLElement} el - Element, that binding is applied to
+         * @param {Function} valueAccessor - Function that returns value, passed to binding
+         */
+        init: function(element, valueAccessor) {
+            var config = valueAccessor(),
+                format = convert(config.format),
+                date   = moment(config.value).format(format);
+
+            $(element).text(date);
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/datepicker.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/datepicker.js
new file mode 100644
index 00000000000..b45f14d6d26
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/datepicker.js
@@ -0,0 +1,74 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Creates datepicker binding and registers in to ko.bindingHandlers object */
+define([
+    'ko',
+    'jquery',
+    'mage/calendar'
+], function (ko, $) {
+    'use strict';
+    
+    ko.bindingHandlers.datepicker = {
+        /**
+         * Initializes calendar widget on element and stores it's value to observable property.
+         * Datepicker binding takes either observable property or object { storage: {ko.observable}, options: {Object} }.
+         * For more info about options take a look at "mage/calendar" and jquery.ui.datepicker widget.
+         * @param {HTMLElement} el - Element, that binding is applied to
+         * @param {Function} valueAccessor - Function that returns value, passed to binding
+         */
+        init: function (el, valueAccessor) {
+            var config = valueAccessor(),
+                observable,
+                options = {};
+
+            if (typeof config === 'object') {
+                observable = config.storage;
+                options    = config.options;
+            } else {
+                observable = config;
+            }
+
+            $(el).calendar(options);
+
+            ko.utils.registerEventHandler(el, 'change', function (e) {
+                observable(this.value);
+            });
+        },
+
+        /**
+         * Reads target observable from valueAccessor and writes its' value to el.value
+         * @param {HTMLElement} el - Element, that binding is applied to
+         * @param {Function} valueAccessor - Function that returns value, passed to binding
+         */
+        update: function(el, valueAccessor){
+            var config = valueAccessor(),
+                observable;
+
+            observable = typeof config === 'object' ?
+                config.storage :
+                config;
+
+            el.value = observable();
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
new file mode 100644
index 00000000000..0d55e4a3822
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Creates outerClick binding and registers in to ko.bindingHandlers object */
+define([
+    'ko',
+    'jquery'
+], function (ko, $) {
+    'use strict';
+
+    ko.bindingHandlers.outerClick = {
+
+        /**
+         * Attaches click handler to document
+         * @param {HTMLElement} el - Element, that binding is applied to
+         * @param {Function} valueAccessor - Function that returns value, passed to binding
+         * @param  {Object} allBindings - all bindings object
+         * @param  {Object} viewModel - reference to viewmodel
+         */
+        init: function (element, valueAccessor, allBindings, viewModel) {
+            var callback = valueAccessor();
+
+            callback = callback.bind(viewModel);
+
+            $(document).on('click', callback);
+
+            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
+                $(document).off('click', callback);
+            });
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/scope.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/scope.js
new file mode 100644
index 00000000000..a503dbb84f5
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/scope.js
@@ -0,0 +1,103 @@
+/**
+ * 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    storage
+ * @package     test
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Creates scope binding and registers in to ko.bindingHandlers object */
+define([
+    'ko',
+    'Magento_Ui/js/lib/registry/registry',
+    'jquery',
+    'mage/translate'
+], function(ko, registry, $) {
+    'use strict';
+
+    var i18n = $.mage.__;
+
+    /**
+     * Fetches components from registry and stores them to context object, then passes it to callback function.
+     * @param {Object} components - map, representing components to be attached to the new context.
+     * @param {Function} callback - Function to be called when components are fetched.
+     */
+    function getMultiple(components, callback) {
+        var key,
+            paths = [],
+            context = {};
+
+        for (key in components) {
+            paths.push(components[key]);
+        }
+
+        registry.get(paths, function() {
+
+            for (key in components) {
+                context[key] = registry.get(components[key]);
+            }
+
+            callback(context);
+        });
+    }
+
+    /**
+     * Creates child context with passed component param as $data. Extends context with $t helper.
+     * Applies bindings to descendant nodes.
+     * @param {HTMLElement} el - element to apply bindings to.
+     * @param {ko.bindingContext} bindingContext - instance of ko.bindingContext, passed to binding initially.
+     * @param {Object} component - component instance to attach to new context
+     */
+    function applyComponents(el, bindingContext, component) {
+        component = bindingContext.createChildContext(component);
+        
+        ko.utils.extend(component, { $t: i18n });
+
+        ko.applyBindingsToDescendants(component, el);
+    }
+
+    ko.bindingHandlers.scope = {
+
+        /**
+         * Scope binding's init method.
+         * @returns {Object} - Knockout declaration for it to let binding control descendants.
+         */
+        init: function () {
+            return { controlsDescendantBindings: true };
+        },
+
+        /**
+         * Reads params passed to binding, parses component declarations.
+         * Fetches for those found and attaches them to the new context.
+         * @param {HTMLElement} el - Element to apply bindings to.
+         * @param {Function} valueAccessor - Function that returns value, passed to binding.
+         * @param {Object} allBindings - Object, which represents all bindings applied to element.
+         * @param {Object} viewModel - Object, which represents view model binded to el.
+         * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.
+         */
+        update: function(el, valueAccessor, allBindings, viewModel, bindingContext) {
+            var component = valueAccessor(),
+                apply = applyComponents.bind(this, el, bindingContext);
+
+            typeof component === 'object' ?
+                getMultiple(component, apply) :
+                registry.get(component, apply);
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/stop_propagation.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/stop_propagation.js
new file mode 100644
index 00000000000..f6f560a4c50
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/bind/stop_propagation.js
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Creates stopPropagation binding and registers in to ko.bindingHandlers object */
+define(['ko'], function (ko) {
+    'use strict';
+
+    ko.bindingHandlers.stopPropagation = {
+
+        /**
+         * Stops propagation on element
+         * @param  {HTMLElement} element - element to apply binding to
+         */
+        init: function (element) {
+          ko.utils.registerEventHandler(element, 'click', function (event) {
+              event.cancelBubble = true;
+              if (event.stopPropagation) {
+                 event.stopPropagation(); 
+              }
+          });
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
new file mode 100644
index 00000000000..0e653db78e5
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Loads all available knockout bindings, sets custom template engine, initializes knockout on page */
+define([
+    'ko',
+    'jquery',
+    './template/engine',
+    './bind/date',
+    './bind/scope',
+    './bind/datepicker',
+    './bind/stop_propagation',
+    './bind/outer_click'
+], function(ko, $, templateEngine) {
+    'use strict';
+
+    ko.setTemplateEngine(templateEngine);
+    ko.applyBindings();
+
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js
new file mode 100644
index 00000000000..bea785fd56e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/scope.js
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'ko',
+    '../class',
+    './initialize'
+], function(ko, Class) {
+    'use strict';
+
+    /**
+     * Wrapper for ko.observable and ko.observableArray.
+     * Assignes one or another ko property to obj[key]
+     * @param  {Object} obj   - object to store property to
+     * @param  {String} key   - key
+     * @param  {*} value      - initial value of observable
+     */
+    function observe(obj, key, value){
+        var method = Array.isArray(value) ? 'observableArray' : 'observable';
+
+        obj[key] = ko[method](value);
+    }
+
+    return Class.extend({
+
+        /**
+         * If 2 params passed, path is considered as key.
+         * Else, path is considered as object.
+         * Assignes props to this based on incoming params
+         * @param  {Object|String} path
+         * @param  {*} value
+         */
+        observe: function(path, value) {
+            var key;
+
+            if (typeof path === 'string') {
+                observe(this, path, value);
+            } else {
+                for (key in path) {
+                    observe(this, key, path[key]);
+                }
+            }
+        },
+
+        /**
+         * Reads it's params from provider and stores it into its params object
+         * @return {Object} reference to instance
+         */
+        pushParams: function(){
+            var params      = this.params,
+                provider    = this.provider.params,
+                data        = {};
+
+            params.items.forEach(function(name) {
+                data[name] = this[name]();
+            }, this);
+
+            provider.set(params.dir, data);
+
+            return this;
+        },
+
+        /**
+         * Loops over params.items and writes it's corresponding {key: value} 
+         * pairs to this as observables.
+         * @return {Object} reference to instance
+         */
+        pullParams: function(){
+            var params      = this.params,
+                provider    = this.provider.params,
+                data        = provider.get(params.dir);
+
+            params.items.forEach(function(name) {
+                this[name](data[name]);
+            }, this);
+
+            return this;
+        },
+
+        /**
+         * Calls pushParams and calls refresh on this.provider
+         */
+        reload: function() {
+            this.pushParams()
+                .provider.refresh();
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
new file mode 100644
index 00000000000..c6cd52728a7
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'ko',
+    './observable_source',
+    '../../renderer/renderer',
+    'mage/apply/main'
+], function (ko, Source, Renderer, Mage) {
+    'use strict';
+
+    var sources = {};
+
+    /**
+     * Creates unique template identifier based on template name and it's extenders (optional)
+     * @param  {String} templateName
+     * @param  {Object} templateOptions
+     * @return {String} - unique template identifier
+     */
+    function createTemplateIdentifier(templateName, templateOptions) {
+        var extenders = templateOptions.extenders || [];
+
+        return templateName + '|' + extenders.join(' ');
+    }
+
+    /**
+     * Remote template engine class. Is used to be able to load remote templates via knockout template binding.
+     */
+    var RemoteTemplateEngine = function() {};
+    var NativeTemplateEngine = ko.nativeTemplateEngine;
+
+    RemoteTemplateEngine.prototype = new NativeTemplateEngine;
+    RemoteTemplateEngine.prototype.constructor = RemoteTemplateEngine;
+
+    /**
+     * Overrided method of native knockout template engine.
+     * Caches template after it's unique name and renders in once.
+     * If template name is not typeof string, delegates work to knockout.templateSources.anonymousTemplate.
+     * @param  {*} template
+     * @param  {HTMLElement} templateDocument - document
+     * @param  {Object} options - options, passed to template binding
+     * @return {TemplateSource} - object with methods 'nodes' and 'data'.
+     */
+    RemoteTemplateEngine.prototype.makeTemplateSource = function(template, templateDocument, options) {
+        var source,
+            extenders = options.extenders || [],
+            templateId;
+
+        if (typeof template === 'string') {
+            templateId = createTemplateIdentifier(template, options);
+            source = sources[templateId];
+
+            if (!source) {
+                source = new Source(template);
+                sources[templateId] = source;
+
+                Renderer.render(template, extenders).done(function(rendered) {
+                    source.nodes(rendered);
+                    Mage.apply();
+                });
+            }
+
+            return source;
+
+        } else if ((template.nodeType == 1) || (template.nodeType == 8)) {
+            return new ko.templateSources.anonymousTemplate(template);
+        } else {
+            throw new Error("Unknown template type: " + template);
+        }
+    };
+
+    /**
+     * Overrided method of native knockout template engine.
+     * Should return array of html elements.
+     * @param  {TemplateSource} templateSource - object with methods 'nodes' and 'data'.
+     * @param  {ko.bindingContext} bindingContext
+     * @param  {Object} options - options, passed to template binding
+     * @return {Array} - array of html elements
+     */
+    RemoteTemplateEngine.prototype.renderTemplateSource = function (templateSource, bindingContext, options) {
+        var nodes = templateSource.nodes();
+
+        return ko.utils.cloneNodes(nodes);
+    };
+
+    /**
+     * Overrided method of native knockout template engine.
+     * Created in order to invoke makeTemplateSource method with custom set of params.
+     * @param  {*} template - template identifier
+     * @param  {ko.bindingContext} bindingContext
+     * @param  {Object} options - options, passed to template binding
+     * @param  {HTMLElement} templateDocument - document
+     * @return {Array} - array of html elements
+     */
+    RemoteTemplateEngine.prototype.renderTemplate = function (template, bindingContext, options, templateDocument) {
+        var templateSource = this['makeTemplateSource'](template, templateDocument, options);
+        return this['renderTemplateSource'](templateSource, bindingContext, options);
+    };
+
+    return new RemoteTemplateEngine;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/ko/template/observable_source.js b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/observable_source.js
new file mode 100644
index 00000000000..6a98d3b0c7c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/ko/template/observable_source.js
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * Is being used by knockout template engine to store template to.
+ */
+define(['ko', 'Magento_Ui/js/lib/class'], function(ko, Class) {
+    'use strict';
+
+    return Class.extend({
+
+        /**
+         * Initializes templateName, _data, nodes properties.
+         * @param  {template} template - identifier of template
+         */
+        initialize: function(template) {
+            this.templateName = template;
+            this._data = {};
+            this.nodes = ko.observable([]);
+        },
+
+        /**
+         * Data setter. If only one arguments passed, returns corresponding value.
+         * Else, writes into it.
+         * @param  {String} key - key to write to or to read from
+         * @param  {*} value
+         * @return {*} - if 1 arg provided, returnes _data[key] property
+         */
+        data: function(key, value) {
+            if (arguments.length === 1) {
+                return this._data[key];
+            }
+
+            this._data[key] = value;
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/loader.js
new file mode 100644
index 00000000000..dda4160510e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/loader.js
@@ -0,0 +1,101 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define(['jquery'], function($) {
+    'use strict';
+    
+    var storage = window.localStorage;
+
+    function getStoragePathFor(name, entity) {
+        return '__' + entity + 'Cache__' + name;
+    }
+
+    /**
+     * Converts arrayLikeObject to array
+     * @param  {Object|Array} arrayLikeObject - target
+     * @return {Array} - result array
+     */
+    function toArray(arrayLikeObject) {
+        return Array.prototype.slice.call(arrayLikeObject);
+    }
+
+    /**
+     * Formats path of type "path.to.template" to RequireJS compatible
+     * @param  {String} path
+     * @return {String} - formatted template path
+     */
+    function formatTemplatePath(path) {
+        return 'text!' + path.replace(/^([^\/]+)/g, '$1/template') + '.html';
+    }
+
+    /**
+     * Waits for all items in passed array of promises to resolve.
+     * @param  {Array} promises - array of promises
+     * @return {Deferred} - promise of promises to resolve
+     */
+    function waitFor(promises) {
+        return $.when.apply(this, promises);
+    }
+
+    return {
+        /**
+         * Loops over arguments and loads template for each.
+         * @return {Deferred} - promise of templates to be loaded
+         */
+        loadTemplate: function() {
+            var isLoaded  = $.Deferred(),
+                templates = toArray(arguments);
+
+            waitFor(templates.map(this._loadTemplate)).done(function () {
+                templates = toArray(arguments);
+                isLoaded.resolve.apply(isLoaded, templates);
+            });
+
+            return isLoaded.promise();
+        },
+
+        _loadTemplate: function (name) {
+            var isLoaded    = $.Deferred(),
+                storagePath = getStoragePathFor(name, 'template'),
+                path        = formatTemplatePath(name),
+                cached;
+
+            if (allowLocalCache) {
+                cached = storage.getItem(storagePath) || null;
+            }
+
+            if (cached) {
+                setTimeout(function () {
+                    isLoaded.resolve(cached);    
+                }, 0)
+            } else {
+                require([path], function (template) {
+                    storage.setItem(storagePath, template);
+                    isLoaded.resolve(template);
+                });
+            }
+
+            return isLoaded.promise();
+
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js b/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js
new file mode 100644
index 00000000000..090d5705cd4
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/mixins/loader.js
@@ -0,0 +1,49 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'Magento_Ui/js/lib/spinner'
+], function (spinner) {
+    'use strict';
+
+    return {
+        /**
+         * Activates spinner
+         * @return {Object} reference to instance
+         */
+        lock: function() {
+            spinner.show();
+
+            return this;
+        },
+
+        /**
+         * Deactivates spinner
+         * @return {Object} reference to instance
+         */
+        unlock: function() {
+            spinner.hide();
+
+            return this;
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
new file mode 100644
index 00000000000..62ce273967f
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
@@ -0,0 +1,124 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './storage'
+], function(storage) {
+    'use strict';
+
+    var id = 0,
+        requests = {},
+        map = {};
+
+    /**
+     * Clears all of the entries of a specified request.
+     * @param {Number} id - Id of request.
+     */
+    function clear(id) {
+        var ei,
+            elems,
+            index,
+            handlers;
+
+        elems = requests[id].deps;
+
+        for (ei = elems.length; ei--;) {
+            handlers = map[elems[ei]];
+
+            index = handlers.indexOf(id);
+
+            if (~index) {
+                handlers.splice(index, 1);
+            }
+        }
+
+        delete requests[id];
+    }
+
+
+    /**
+     * Tries to resolve pending request.
+     * @param {Number} id - Id of request.
+     * @returns {Boolean} Whether specified request was successfully resolved.
+     */
+    function resolve(id) {
+        var request = requests[id],
+            elems = request.deps,
+            callback = request.callback,
+            isResolved;
+
+        isResolved = storage.has(elems);
+
+        if (isResolved) {
+            callback.apply(window, storage.get(elems));
+        }
+
+        return isResolved;
+    }
+
+    return {
+        /**
+         * Tries to resolve dependencies affected by the scpecified element.
+         * @param {String} elem - Elements' name.
+         * @returns {events} Chainable.
+         */
+        resolve: function(elem) {
+            var pending = map[elem];
+
+            if (typeof pending !== 'undefined') {
+                pending
+                    .filter(resolve)
+                    .forEach(clear);
+            }
+
+            return this;
+        },
+
+
+        /**
+         * Creates a new request for the specified set
+                of elements in case some of them wasn't registered yeat.
+                Otherwise triggers callback immediately.
+         * @param {Array} elems - Requested elements.
+         * @param {Function} callback -
+                Callback that will be triggered as soon as
+                all of the elements will be registered. 
+         * @returns {events} Chainable.
+         */
+        wait: function(elems, callback) {
+            if (storage.has(elems)) {
+                return callback.apply(window, storage.get(elems));
+            }
+
+            elems.forEach(function(elem) {
+                (map[elem] = map[elem] || []).push(id);
+            });
+
+            requests[id++] = {
+                callback: callback,
+                deps: elems
+            };
+
+            return this;
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
new file mode 100644
index 00000000000..57214f40121
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './storage',
+    './events'
+], function( storage, events ){
+    'use strict';
+    
+    /**
+     * Adds element to the storage and tries to resolve
+            pending dependencies for it.   
+     * @param {String} elem - Elements' name.
+     * @param {*} value - Elements' value.
+     */
+    function set(elem, value) {
+        storage.set(elem, value);
+        events.resolve(elem);
+    }
+
+
+    /**
+     * Tries to split the incoming string by spaces.
+     * @params {(String|*)} st - String to split.
+     * @returns {Array|*}
+            The resulting array or the unmodified
+            incoming value if first parameter wasn't a string.
+     */
+    function stringToArray(st) {
+        return typeof st === 'string' ?
+            st.split(' ') :
+            st;
+    }
+
+    return {
+        /**
+         * Retrieves data from registry.
+         * @params {(String|Array)} elems -
+                An array of elements' names or a string of names divided by spaces.
+         * @params {Function} [callback] -
+                Callback function that will be triggered
+                when all of the elements are registered.
+         * @returns {Array|*|Undefined}
+                Returns either an array of elements
+                or an element itself if only is requested.
+                If callback function is specified then returns 'undefined'.
+         */
+        get: function(elems, callback) {
+            var records;
+
+            elems = stringToArray(elems);
+
+            if (typeof callback !== 'undefined') {
+                events.wait(elems, callback);
+            } else {
+                records = storage.get(elems);
+
+                return elems.length === 1 ?
+                    records[0] :
+                    records;
+            }
+        },
+
+
+        /**
+         * Sets data to registry.
+         * @params {(String|Array|Object)} elems -
+                An array of elements' names or a string of names divided by spaces.
+                Also might be an object with element -> value pairs.
+         * @params {*} [value] -
+                Value that will be assigned to elements.
+                This parameter is ignored when the first one
+                represents an object of element -> value pairs.
+         * @returns {registry} Chainable.  
+         */
+        set: function(elems, value) {
+            var i;
+
+            elems = stringToArray(elems);
+
+            if (!Array.isArray(elems)) {
+
+                for (i in elems) {
+                    set(i, elems[i]);
+                }
+            } else {
+
+                for (i = elems.length; i--;) {
+                    set(elems[i], value)
+                }
+            }
+
+            return this;
+        },
+
+        /**
+         * Removes specified elements from a storage.
+         * @params {(String|Array)} elems -
+                An array of elements' names or a string of names divided by spaces.
+         * @returns {registry} Chainable.
+         */
+        remove: function(elems) {
+            storage.remove(stringToArray(elems));
+
+            return this;
+        },
+
+        /**
+         * Checks whether specified elements has been registered.
+         * @params {(String|Array)} elems -
+                An array of elements' names or a string of names divided by spaces.
+         * @returns {Boolean}
+         */
+        has: function(elems) {
+            return storage.has(stringToArray(elems));
+        }
+
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
new file mode 100644
index 00000000000..793579bdccc
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([], function(){
+    'use strict';
+    
+    var data = {};
+
+    return {
+        /**
+         * Retrieves values of the specified elements.
+         * @param {Array} elems - An array of elements.
+         * @returns {Array} Array of values. 
+         */
+        get: function(elems) {
+            var result = [],
+                record;
+
+            elems.forEach(function(elem) {
+                record = data[elem];
+
+                result.push(record ? record.value : undefined);
+            });
+
+            return result;
+        },
+
+
+        /**
+         * Sets key -> value pair.
+         * @param {String} elem - Elements' name.
+         * @param {*} value - Value of the element.
+         * returns {storage} Chainable.
+         */
+        set: function(elem, value) {
+            var record = data[elem] = data[elem] || {};
+
+            record.value = value;
+
+            return this;
+        },
+
+
+        /**
+         * Removes specified elements from storage.
+         * @param {Array} elems - An array of elements to be removed.
+         * returns {storage} Chainable.
+         */
+        remove: function(elems) {
+            elems.forEach(function(elem) {
+                delete data[elem];
+            });
+
+            return this;
+        },
+
+
+        /**
+         * Checks whether all of the specified elements has been registered.
+         * @param {Array} elems - An array of elements.
+         * @returns {Boolean}
+         */
+        has: function(elems) {
+            return elems.every(function(elem) {
+                return typeof data[elem] !== 'undefined';
+            });
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js
new file mode 100644
index 00000000000..728e86df476
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/renderer/overrides.js
@@ -0,0 +1,110 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define(['jquery'], function($) {
+    'use strict';
+
+    return {
+
+        /**
+         * Removes passed html element.
+         * @param  {HTMLElement} oldPart - html element to remove
+         */
+        remove: function(oldPart) {
+            $(oldPart).remove();
+        },
+
+        /**
+         * Picks last node of newParts and replaces oldPart node with it.
+         * @param  {HTMLElement} oldPart  - html element to replace
+         * @param  {Array} newParts - array of html elements 
+         */
+        replace: function(oldPart, newParts) {
+            var newPart = _.last(newParts);
+
+            $(oldPart).replaceWith(newPart);
+        },
+
+        /**
+         * Picks last node of newParts and replaces oldPart node with it's children.
+         * @param  {HTMLElement} oldPart  - html element to replace
+         * @param  {HTMLElement} newParts - array of html elements 
+         */
+        body: function(oldPart, newParts) {
+            var newPart = _.last(newParts);
+
+            $(oldPart).replaceWith(newPart.children);
+        },
+
+        /**
+         * Picks the last item of newParts array and overides oldPart's html attributes with ones of it's own.
+         * @param  {HTMLElement} oldPart - target html element to update
+         * @param  {Array} newParts - array of html elements to get attributes from
+         */
+        update: function(oldPart, newParts) {
+            var newPart = _.last(newParts);
+
+            var attributes = newPart.attributes;
+            var value, name;
+
+            _.each(attributes, function(attr) {
+                value = attr.value;
+                name = attr.name;
+
+                if (attr.name.indexOf('data-part') !== -1) {
+                    return;
+                }
+
+                $(oldPart).attr(name, value);
+            });
+        },
+
+        /**
+         * Prepends oldPart with each html element's children from newParts array.
+         * @param  {HTMLElement} oldPart - html element to prepend to
+         * @param  {Array} newParts - array of html elements to get attributes from
+         */
+        prepend: function(oldPart, newParts) {
+            newParts.forEach(function (node) {
+                $(oldPart).prepend(node.children);
+            });
+        },
+
+        /**
+         * Appends oldPart with each html element's children from newParts array.
+         * @param  {HTMLElement} oldPart - html element to append to
+         * @param  {Array} newParts - array of html elements to get attributes from
+         */
+        append: function(oldPart, newParts) {
+            newParts.forEach(function (node) {
+                $(oldPart).append(node.children);
+            });
+        },
+
+        /**
+         * @return {Array} - array of strings representing available set of actions
+         */
+        getActions: function() {
+            return 'replace remove body update append prepend'.split(' ');
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
new file mode 100644
index 00000000000..c3c7985c559
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
@@ -0,0 +1,290 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    '../loader',
+    './overrides',
+    'jquery',
+    'underscore'
+], function(loader, overrides, $, _) {
+    'use strict';
+
+    return {
+
+        /**
+         * Renders template and it's extenders using this._parse function.
+         * Loads all extenders then merges them and wraps into div[data-template-extend="parent"] where parent is target template.
+         * If no extenders provider, simply loads target template and passes execution to _parse.
+         * @param {String} template - string, representing path to core template and it's extenders.
+         * @param {Array} extenders - array of strings
+         * @return {Deferred} - Promise of template to be rendered. Is being resolved with array of HTML elements.
+         */
+        render: function (template, extenders) {
+            var isRendered = $.Deferred(),
+                parent = template,
+
+                extenders = extenders || [],
+                extendersToLoad = [],
+                extendersHtml = '',
+
+                resolve       = isRendered.resolve.bind(isRendered),
+                loadTemplate  = this._load.bind(this),
+                parseTemplate = this._parse.bind(this);
+
+            if (extenders.length) {
+
+                loadTemplate.apply(this, extenders).done(function () {
+
+                    toArray(arguments).forEach(function (chunk) {
+                        extendersHtml += chunk;
+                    });
+
+                    extendersHtml = '<div data-template-extend="' + parent+ '">' + extendersHtml + '</div>';
+
+                    parseTemplate(extendersHtml).done(resolve);
+
+                }); 
+            } else {
+
+                loadTemplate(parent)
+                    .then(parseTemplate)
+                    .done(resolve);
+            }
+
+            return isRendered.promise();
+        },
+
+        /**
+         * Loads templates via loader module.
+         * @return {Deferred} - Promise of templates to be loaded
+         */
+        _load: function () {
+            return loader.loadTemplate.apply(loader, arguments);
+        },
+
+        /**
+         * Takes raw text (html), parses it, puts it to docuemntFragment container.
+         * Looks up for all [data-template-exted] attributes, creates array of extend nodes.
+         * Maps this array to extractTemplatePath to have all extend points pathes gathered.
+         * Maps pathes to this.render method (which returns promise) and waits for this array to resolve.
+         * Then looks up for [data-part-*] attributes and creates map of new parts.
+         * Then overrides parent template's corresponding parts with new parts.
+         * @param  {String} rawHtml - loaded raw text (html)
+         * @return {Deferred} - Promise of template to be parsed. Is being resolved with array of HTML elements.
+         */
+        _parse: function(rawHtml) {
+            var templatePath,
+                templateContainer,
+                extendNodes,
+                templatesToRender = [],
+                extendPointsToRender = [];
+
+            templateContainer = document.createDocumentFragment();
+
+            wrap(toArray($(rawHtml)), templateContainer);
+
+            extendNodes          = getExtendNodesFrom(templateContainer);
+            templatesToRender    = extendNodes.map(extractTemplatePath, this)
+            extendPointsToRender = templatesToRender.map(this.render, this);
+
+            return waitFor(extendPointsToRender).then(function() {
+                var correspondingExtendNode,
+                    container,
+                    newParts = [],
+                    args = toArray(arguments);
+
+                args.forEach(function(renderedNodes, idx) {
+                    container = document.createDocumentFragment();
+                    wrap(renderedNodes, container);
+
+                    correspondingExtendNode = extendNodes[idx];
+                    newParts = this._buildPartsMapFrom(correspondingExtendNode);
+
+                    $(correspondingExtendNode).empty();
+
+                    this._overridePartsOf(container)
+                        .by(newParts)
+                        .appendTo(correspondingExtendNode);
+
+                }, this);
+
+                return toArray(templateContainer.childNodes);
+            }.bind(this));
+        },
+
+        /**
+         * Builds parst map from HTML element by looking for all available override actions selectors.
+         * @param  {HTMLElement} container - container to look up for new parts declarations
+         * @return {Object} - Map of parts to apply. E.g. { toolbar: { replace: [HTMLElement1, HTMLElement2], append: [HTMLElement3] } }
+         */
+        _buildPartsMapFrom: function(container) {
+            var partsMap = {},
+                actionNodes,
+                partSelector,
+                targetPart,
+                actions = overrides.getActions();
+
+            actions.forEach(function(action) {
+                partSelector = createActionSelectorFor(action);
+                actionNodes  = toArray(container.querySelectorAll(partSelector));
+
+                actionNodes.forEach(function(node) {
+                    targetPart = node.getAttribute('data-part-' + action);
+
+                    if (!partsMap[targetPart]) {
+                        partsMap[targetPart] = {};
+                    }
+
+                    targetPart = partsMap[targetPart];
+
+                    if (!targetPart[action]) {
+                        targetPart[action] = [];
+                    }
+
+                    targetPart[action].push(node);
+                });
+            });
+
+            return partsMap;
+        },
+
+        /**
+         * Caches template and returns object for the sake of chaining
+         * @param  {HTMLElement} template - container to look for parts to be overrided by new ones.
+         * @return {Object}
+         */
+        _overridePartsOf: function(template) {
+            return {
+
+                /**
+                 * Loops over newParts map and invokes override actions for each found.
+                 * @param  {Object} newParts - the result of _buildPartsMapFrom method.
+                 * @return {Object} - Returns object for the sake of chaining
+                 */
+                by: function(newParts) {
+                    var oldElement;
+
+                    _.each(newParts, function(actions, partName) {
+                        _.each(actions, function(newElements, action) {
+
+                            oldElement = template.querySelector(createPartSelectorFor(partName));
+                            overrides[action](
+                                oldElement,
+                                newElements
+                            );
+
+                        });
+                    });
+
+                    return {
+
+                        /**
+                         * Appends template's (overrided already) children to extendNode.
+                         * @param  {HTMLElement} extendNode - initial container of new parts declarations
+                         */
+                        appendTo: function(extendNode) {
+                            if (template.hasChildNodes()) {
+                                toArray(template.childNodes).forEach(function (child) {
+                                    extendNode.appendChild(child);
+                                });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * Extracts template path from node by [data-part-extend] attribute
+     * @param  {HTMLElement} node - node to look up for [data-part-extend] attr
+     * @return {String} - value of [data-part-extend] attribute
+     */
+    function extractTemplatePath(node) {
+        return node.getAttribute('data-template-extend');
+    }
+
+    /**
+     * Looks up for [data-template-extend] selector in container.
+     * @param  {HTMLElement} container - node to lookup
+     * @return {Array} - array of found HTML elements
+     */
+    function getExtendNodesFrom(container) {
+        return toArray(container.querySelectorAll('[data-template-extend]'))
+    }
+
+    /**
+     * Checks if passed object has keys.
+     * @param  {Object}  object - target object
+     * @return {Boolean} - true, if object has no keys
+     */
+    function isEmpty(object) {
+        return !Object.keys(object).length;
+    }
+
+    /**
+     * Wraps nodes into container
+     * @param  {Array} nodes - array of nodes
+     * @param  {HTMLElement} container - target container
+     */
+    function wrap(nodes, container) {
+        nodes.forEach(function (node) {
+            container.appendChild(node);
+        });
+    }
+
+    /**
+     * Creates action selector.
+     * @param  {String} action
+     * @return {String} - Action selector
+     */
+    function createActionSelectorFor(action) {
+        return '[data-part-' + action + ']';
+    }
+
+    /**
+     * Creates data-part selector.
+     * @param  {String} part
+     * @return {String} - Part selector
+     */
+    function createPartSelectorFor(part) {
+        return '[data-part="' + part + '"]';
+    }
+
+    /**
+     * Converts arrayLikeObject to array
+     * @param  {Object|Array} arrayLikeObject - target
+     * @return {Array} - result array
+     */
+    function toArray(arrayLikeObject) {
+        return Array.prototype.slice.call(arrayLikeObject);
+    }
+
+    /**
+     * Waits for all items in passed array of promises to resolve.
+     * @param  {Array} promises - array of promises
+     * @return {Deferred} - promise of promises to resolve
+     */
+    function waitFor(promises) {
+        return $.when.apply(this, promises);
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/spinner.js b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js
new file mode 100644
index 00000000000..92e83b9860b
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/spinner.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'jquery'
+], function ($) {
+    'use strict';
+
+    var spinner = $('[data-role="spinner"]');
+
+    return {
+        show: function () {
+            spinner.show();
+        },
+
+        hide: function () {
+            spinner.hide();
+        }
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js
new file mode 100644
index 00000000000..5ad17b60482
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/storage/index.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * Assembles storages returning storage mapping
+ */
+define([
+    './storage',
+    './meta'
+], function(Storage, MetaStorage){
+    'use strict';
+
+    return {
+        meta:   MetaStorage,
+        params: Storage,
+        config: Storage,
+        data:   Storage,
+        dump:   Storage
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js
new file mode 100644
index 00000000000..74bfdea7e00
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/storage/meta.js
@@ -0,0 +1,204 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    './storage'
+], function(_, Storage) {
+    'use strict';
+
+    /**
+     * Loops over first level of object looking for valueKey of typeof object values
+     * to be typeof object as well. Breaks loop on first entry on one.
+     * @param  {Object}  target
+     * @param  {String}  valueKey - complex to look for
+     * @return {Boolean}
+     */
+    function hasComplexValue(target, valueKey) {
+        var result = false,
+            key,
+            object;
+
+
+        for (key in target) {
+            object = target[key];
+
+            if (typeof object === 'object' && typeof object[valueKey] === 'object') {
+                result = true;
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Recursively loops over object's properties and converts it to array ignoring keys.
+     * If typeof 'value' properties is 'object', creates 'items' property and assigns
+     * execution of nestedObjectToArray on 'value' to it.
+     * If typeof 'value' key is not an 'object', is simply writes an object itself to result array. 
+     * @param  {Object} obj
+     * @return {Array} result array
+     */
+    function nestedObjectToArray(obj, valueKey) {
+        var target,
+            items = [];
+
+        for (var prop in obj) {
+
+            target = obj[prop];
+            if (typeof target[valueKey] === 'object') {
+
+                target.items = nestedObjectToArray(target[valueKey], valueKey);
+                delete target[valueKey];
+            }
+            items.push(target);
+        }
+
+        return items;
+    }
+
+    return Storage.extend({
+
+        /**
+         * Initializes data prop based on data argument.
+         * Calls initFields and initColspan methods 
+         * @param  {Object} config
+         */
+        initialize: function(data) {
+            this.data = data || {};
+
+            this.initFields()
+                .initColspan();
+        },
+
+        /**
+         * Formats fields property to compatible format.
+         * Processes those. Assignes fiedls to data.fields.
+         * @return {Object} - reference to instance
+         */
+        initFields: function(){
+            var data    = this.data,
+                fields  = data.fields;
+
+            fields = this._fieldsToArray(fields);
+
+            fields.forEach(this._processField, this);
+
+            data.fields = fields;
+
+            return this;
+        },
+
+        /**
+         * Assigns data.colspan to this.getVisible().length
+         * @return {Object} - reference to instance
+         */
+        initColspan: function(){
+            var visible = this.getVisible();
+
+            this.data.colspan = visible.length;
+
+            return this;
+        },
+
+        /**
+         * Assignes default params to field
+         * @param  {Object} field
+         * @return {Object} reference to instance
+         */
+        applyDefaults: function(field) {
+            var defaults = this.data.defaults;
+
+            if (defaults) {
+                _.defaults(field, defaults);
+            }
+
+            return this;
+        },
+
+        /**
+         * Format options based on those being nested
+         * @param  {Object} field
+         * @return {Object} reference to instance
+         */
+        formatOptions: function(field) {
+            var result,
+                options,
+                isNested;
+
+            options = field.options;
+
+            if (options) {
+                result      = {};
+                isNested    = hasComplexValue(options, 'value');
+
+                if(isNested){
+                    result = nestedObjectToArray(options, 'value');
+                }
+                else{
+                    _.each(options, function(option){
+                        result[option.value] = option.label;
+                    }); 
+                }   
+                                
+                field.options = result;
+            }
+
+            return this;
+        },
+
+        /**
+         * Returns filted by visible property fields array.
+         * @return {Array} filted by visible property fields array
+         */
+        getVisible: function(){
+            var fields  = this.data.fields;
+            
+            return fields.filter(function(field){
+                return field.visible;
+            });
+        },
+
+        /**
+         * Convertes fields object to array, assigning key to index property.
+         * @param  {Object} fields
+         * @return {Array} array of fields
+         */
+        _fieldsToArray: function(fields){
+            return _.map(fields, function(field, id){
+                field.index = id;
+                
+                return field;
+            });
+        },
+
+        /**
+         * Calls applyDefaults and formatOptions on field
+         * @param  {Object} field
+         */
+        _processField: function(field){
+            this.applyDefaults(field)
+                .formatOptions(field);
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js b/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js
new file mode 100644
index 00000000000..753ed45692a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/storage/storage.js
@@ -0,0 +1,92 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    '../class',
+    '../events'
+], function(_, Class, EventsBus) {
+    'use strict';
+
+    return Class.extend({
+
+        /**
+         * Inits this.data to incoming data
+         * @param  {Object} data
+         */
+        initialize: function(data) {
+            this.data = data || {};
+        },
+
+        /**
+         * If path specified, returnes this.data[path], else returns this.data
+         * @param  {String} path
+         * @return {*} this.data[path] or simply this.data
+         */
+        get: function(path) {
+            return !path ? this.data : this.data[path];
+        },
+
+        /**
+         * Sets value property to path and triggers update by path, passing result
+         * @param {String|*} path
+         * @param {Object} reference to instance
+         */
+        set: function(path, value){
+            var result = this._override.apply(this, arguments);
+
+            value   = result.value;
+            path    = result.path;
+
+            this.trigger('update', value);
+
+            if (path) {
+                this.trigger('update:' + path, value);
+            }
+
+            return this;
+        },
+        
+        /**
+         * Assignes props to this.data based on incoming params
+         * @param  {String|*} path
+         * @param  {*} value
+         * @return {Object}
+         */
+        _override: function(path, value) {
+            if (arguments.length > 1) {
+                this.data[path] = value;
+            } else {
+                value = path;
+                path = false;
+
+                this.data = value;
+            }
+
+            return {
+                path: path,
+                value: value
+            };
+        }
+
+    }, EventsBus);
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/utils.js b/app/code/Magento/Ui/view/base/web/js/lib/utils.js
new file mode 100644
index 00000000000..d3fafe226b1
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/lib/utils.js
@@ -0,0 +1,96 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore'
+], function(_) {
+    'use strict';
+
+    var utils = {},
+        atobSupport,
+        btoaSupport;
+    
+    atobSupport = typeof atob === 'function';
+    btoaSupport = typeof btoa === 'function';
+
+    /** 
+     * Base64 encoding/decoding methods.
+     * First check for native support.
+     */
+    if( btoaSupport && atobSupport ){
+         _.extend(utils, {
+            atob: function(input){
+                return window.atob(input);
+            },
+
+            btoa: function(input){
+                return window.btoa(input);
+            }
+        });
+    }
+    else{
+        _.extend(utils, {
+            atob: function(input){
+                return Base64.decode(input)
+            },
+
+            btoa: function(input){
+                return Base64.encode(input);
+            }
+        });
+    }    
+
+    /**
+     * Submits specified data as a form object.
+     * @param {Object} params - Parameters of form.
+     */
+    utils.submitAsForm = function(params){  
+        var form,
+            field;
+
+        form = document.createElement('form');
+
+        form.setAttribute('method', params.method);
+        form.setAttribute('action', params.action);
+
+        _.each(params.data, function(value, name){
+            field = document.createElement('input');
+
+            if(typeof value === 'object'){
+                value = JSON.stringify(value);
+            }
+
+            field.setAttribute('name', name);
+            field.setAttribute('type', 'hidden');
+            
+            field.value = value;
+
+            form.appendChild(field);
+        });
+
+        document.body.appendChild(form);
+
+        form.submit();
+    };
+
+    return utils;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter.js b/app/code/Magento/Ui/view/base/web/js/listing/filter.js
new file mode 100644
index 00000000000..4d0802e0ab7
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter.js
@@ -0,0 +1,297 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/ko/scope',
+    'Magento_Ui/js/lib/component'
+], function(_, Scope, Component) {
+    'use strict';
+
+    var BASE_PATH = 'Magento_Ui/js/listing/filter';
+
+    var defaults = {
+        types: {
+            filter_input:  BASE_PATH + '/input',
+            filter_select: BASE_PATH + '/select',
+            filter_range:  BASE_PATH + '/range',
+            filter_date:   BASE_PATH + '/date'
+        }
+    };
+
+    var Filter = Scope.extend({
+        /**
+         * Initializes instance properties 
+         * @param {Object} config - Filter component configuration
+         */
+        initialize: function(config) {
+            _.extend(this, config);
+
+            this.initObservable()
+                .loadControls();
+        },
+
+        /**
+         * Callback method that proceeds initialization of filter component.
+         */
+        proceed: function () {
+            this.extractFields()
+                .initFilters();
+        },
+
+        /**
+         * Initiates loading of filters constructors.
+         */
+        loadControls: function () {
+            var coreTypes = defaults.types,
+                paths,
+                types;
+
+            types = _.map(this.types, function (config, type) {
+                config.name = type;
+
+                if(!config.control){
+                   config.control = coreTypes[type];
+                }
+
+                return config;
+            });
+
+            paths = _.pluck(types, 'control');
+
+            require(paths, this.onControlsLoaded.bind(this, types));
+        },
+
+        /**
+         * Initializes observable properties of instance.
+         * @returns {Filter} Chainbale.
+         */
+        initObservable: function(){
+            this.observe({
+                isVisible:  false,
+                active:     [],
+                filters:    []
+            });
+
+            return this; 
+        },
+
+        /**
+         * Filters filterable fields and stores them to this.fields 
+         * @returns {Filter} Chainbale.
+         */
+        extractFields: function () {
+            var provider    = this.provider.meta,
+                fields      = provider.getVisible();
+
+            this.fields = fields.filter(function (field) {
+                return field.filterable;
+            });
+
+            return this;
+        },
+
+        /**
+         * Initializes filters by creating instances of
+         * corresponding classes found in controls by filter type.
+         * @returns {Filter} Chainbale.
+         */
+        initFilters: function () {
+            var controls = this.types,
+                config,
+                type,
+                filters,
+                control;
+
+            filters = this.fields.map(function (field) {
+                type    = (field.filter_type || field.input_type);
+                config  = controls && controls[type];
+                control = config.constr;
+
+                field.type = type;
+
+                return new control(field, config);
+            }, this);
+
+            this.filters(filters);
+
+            return this;
+        },
+
+        /**
+         * Extracts an array of non-empty filters.
+         * @returns {Array} Array of non-empty filters
+         */
+        getNotEmpty: function(){
+            return this.filters().filter(function(filter){
+                return !filter.isEmpty();
+            });
+        },
+
+        /**
+         * Writes the result of getNotEmpty to active observable.
+         * @returns {Filter} Chainbale.
+         */
+        findActive: function(){
+            this.active(this.getNotEmpty());
+
+            return this;
+        },
+
+        /**
+         * Returns an array filters' data.
+         * @param {Boolean} [all=false] -
+                Whether to extract data from all of the filters
+                or from only the active ones.
+         * @returns {Array} Array of filters' data.
+         */
+        getData: function(all){
+            var filters;
+
+            filters = all ? this.filters() : this.active();
+
+            return filters.map(function(filter){
+                return filter.dump();
+            });
+        },
+
+        /**
+         * Clears data of all filters or of specified one.
+         * @param {Object} [filter] - If specified, clears data only of this filter.
+         * @returns {Filter} Chainbale.
+         */
+        clearData: function(filter){
+            var active = this.active;
+
+            if(filter){
+                filter.reset();
+
+                active.remove(filter);
+            }
+            else{
+                this.filters().forEach(function (filter) {
+                    filter.reset();
+                });
+
+                active.removeAll();
+            }
+
+            return this;
+        },
+
+        /**
+         * Updates an array of active filters
+         * and reloads data provider with new filtering parameters.
+         * @returns {Filter} Chainbale.
+         */
+        apply: function () {
+            this.findActive()
+                .reload();
+
+            return this;
+        },
+
+        /**
+         * Clears filters and updates data provider with new filtering parameters.
+         * @param {Object} [filter] - If specified then clears only this filter. 
+         * @returns {Filter} Chainbale.
+         */
+        reset: function(filter){
+            this.clearData(filter)           
+                .reload();
+
+            return this;
+        },
+
+        /**
+         * Sets set of params to storage.
+         * @param {*} action - data to set to storage params
+         * @returns {Filter} Chainbale.
+         */
+        pushParams: function() {
+            var params = this.provider.params;
+
+            params.set('filter', this.getData());
+
+            return this;
+        },
+
+        /**
+         * @description Toggles isVisible observable property
+         */
+        toggle: function () {
+            this.isVisible(!this.isVisible());
+        },
+
+        /**
+         * @description Sets isVisible observable property to false
+         */
+        close: function () {
+            this.isVisible(false);
+        },
+
+        /**
+         * Returns path to filter's template splited by dots.
+         * @param {Object} - instance of one of controls classes
+         * @returns {String} - path to template based on type of filter
+         */
+        getTemplateFor: function (filter) {
+            return 'ui/filter/' + filter.type;
+        },
+
+        /**
+         * Resets specified filter using reset method
+         * @param  {Object} filter - filter to reset
+         */
+        onClear: function(filter) {
+            return this.reset.bind(this, filter);
+        },
+
+        /**
+         * Callback that fires when all of the filters constructors has been loaded.
+         * @param {Array} controlsMap - An array of availbale filter types and theirs configuration.       
+         */
+        onControlsLoaded: function (controlsMap) {
+            var controls = Array.prototype.slice.call(arguments, 1),
+                types = {},
+                control;
+
+            controls.forEach(function (constr, idx) {
+                control = controlsMap[idx];
+
+                delete control.control;
+                
+                control.constr = constr;
+
+                types[control.name] = control;
+            });
+
+            this.types = types;
+
+            this.proceed();
+        }
+    });
+
+    return Component({
+        constr: Filter
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js
new file mode 100644
index 00000000000..c794561d512
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/abstract.js
@@ -0,0 +1,45 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'Magento_Ui/js/lib/ko/scope',
+    'underscore'
+], function (Scope, _) {
+    'use strict';
+    
+    return Scope.extend({
+
+        /**
+         * Extends instance with data passed.
+         * @param {Object} data - Item of "fields" array from grid configuration
+         * @param {Object} config - Filter configuration
+         */
+        initialize: function (data, config) {
+            _.extend(this, data);
+            this.config = config;
+
+            this.observe('output', '');
+        },
+
+        isEmpty: function(){}
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js
new file mode 100644
index 00000000000..8cdf0a6b518
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/date.js
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './range'
+], function (Range) {
+    'use strict';
+    
+    return Range;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js
new file mode 100644
index 00000000000..2ffebf37507
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/filters.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** Assembles available filter controls and returns it's mapping. */
+define([
+    './item/input',
+    './item/select',
+    './item/range',
+    './item/store'
+], function (InputControl, SelectControl, RangeControl, StoreControl) {
+    'use strict';
+
+    return {
+        input:      InputControl,
+        select:     SelectControl,
+        date:       RangeControl,
+        range:      RangeControl,
+        store:      StoreControl
+    }
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js
new file mode 100644
index 00000000000..adce344c6db
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/input.js
@@ -0,0 +1,81 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './abstract',
+    'underscore'
+], function (AbstractControl, _) {
+    'use strict';
+    
+    return AbstractControl.extend({
+
+        /**
+         * Invokes initialize method of parent class and initializes observable properties of instance.
+         * @param {Object} data - Item of "fields" array from grid configuration
+         * @param {Object} config - Filter configuration
+         */
+        initialize: function (data) {
+            this.constructor.__super__.initialize.apply(this, arguments);
+
+            this.observe('value', '');
+        },
+
+        /**
+         * Returnes true if this.value is falsy
+         * @return {Boolean} true if this.value is falsy, false otherwise
+         */
+        isEmpty: function(){
+            return !this.value();
+        },
+
+        /**
+         * Returns this.value(). Is used for displaying on UI.
+         * @return {[type]} [description]
+         */
+        display: function(){
+            return this.value();
+        },
+
+        /**
+         * Returns dump of instance's current state
+         * @returns {Object} - object which represents current state of instance
+         */
+        dump: function () {
+            this.output( this.display() );
+            
+            return {
+                field: this.index,
+                value: this.value()
+            };
+        },
+
+        /**
+         * Resets state properties of instance and calls dump method.
+         * @returns {Object} - object which represents current state of instance
+         */
+        reset: function () {
+            this.value(null);
+
+            return this.dump();
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js
new file mode 100644
index 00000000000..d062e087f07
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/range.js
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './abstract',
+    'underscore'
+], function (AbstractControl, _) {
+    'use strict';
+    
+    return AbstractControl.extend({
+
+        /**
+         * Invokes initialize method of parent class and initializes observable properties of instance.
+         * @param {Object} data - Item of "fields" array from grid configuration
+         * @param {Object} config - Filter configuration
+         */
+        initialize: function (data, config) {
+            this.constructor.__super__.initialize.apply(this, arguments);
+
+            this.observe({
+                from: '',
+                to:   ''
+            });
+        },
+        
+        /**
+         * Creates dump copy of current state.
+         * @return {Object} dumped value object
+         */
+        getValues: function(){
+            var value   = {},
+                from    = this.from(),
+                to      = this.to();
+
+            if (from) {
+                value.from = from;
+            }
+
+            if (to) {
+                value.to = to;
+            }
+
+            return value;
+        },
+
+        /**
+         * Returns string value of current state for UI
+         * @return {String}
+         */
+        display: function(){
+            var values = this.getValues();
+
+            return _.map(values, function(value, name){
+                return name + ': ' + value;
+            }).join(' ');
+        },
+
+        /**
+         * Checkes if current state is empty.
+         * @return {Boolean}
+         */
+        isEmpty: function(){
+            return ( !this.to() && !this.from() );
+        },
+
+        /**
+         * Returns dump of instance's current state
+         * @returns {Object} - object which represents current state of instance
+         */
+        dump: function () {
+            this.output( this.display() );
+
+            return {
+                field: this.index,
+                value: this.getValues()
+            };
+        },
+
+        /**
+         * Resets state properties of instance and calls dump method.
+         * @returns {Object} - object which represents current state of instance
+         */
+        reset: function () {
+            this.to('');
+            this.from('');
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js b/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js
new file mode 100644
index 00000000000..bf13a70b394
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/filter/select.js
@@ -0,0 +1,100 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './abstract',
+    'underscore'
+], function (AbstractControl, _) {
+    'use strict';
+
+    return AbstractControl.extend({
+
+        /**
+         * Invokes initialize method of parent class and initializes properties of instance.
+         * @param {Object} data - Item of "fields" array from grid configuration
+         * @param {Object} config - Filter configuration
+         */
+        initialize: function (data) {
+            this.constructor.__super__.initialize.apply(this, arguments);
+
+            this.caption = 'Select...';
+
+            this.observe('selected', '');
+
+            this.options = this.options ? this.formatOptions(this.options) : [];
+        },
+
+        /**
+         * Checkes if current state is empty.
+         * @return {Boolean}
+         */
+        isEmpty: function(){
+            var selected = this.selected();
+
+            return !(selected && selected.value);
+        },
+
+        /**
+         * Formats options property of instance.
+         * @param {Object} options - object representing options
+         * @returns {Array} - Options, converted to array
+         */
+        formatOptions: function (options) {
+            return _.map(options, function (value, key) {
+                return { value: key, label: value  };
+            });
+        },
+
+        /**
+         * Returns string value of current state for UI
+         * @return {String}
+         */
+        display: function(){
+            var selected = this.selected();
+
+            return selected && selected.label;
+        },
+
+        /**
+         * Returns dump of instance's current state
+         * @returns {Object} - object which represents current state of instance
+         */
+        dump: function () {
+            var selected = this.selected();
+
+            this.output( this.display() );
+
+            return {
+                field: this.index,
+                value: selected && selected.value
+            }
+        },
+
+        /**
+         * Resets state properties of instance and calls dump method.
+         * @returns {Object} - object which represents current state of instance
+         */
+        reset: function () {
+            this.selected(null);
+        }
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/grid.js b/app/code/Magento/Ui/view/base/web/js/listing/grid.js
new file mode 100644
index 00000000000..26c49228a9f
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/grid.js
@@ -0,0 +1,240 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/component',
+    'Magento_Ui/js/lib/ko/scope',
+    'Magento_Ui/js/lib/mixins/loader',
+], function(_, Component, Scope, Loader) {
+    'use strict';
+
+    var Listing =  Scope.extend({
+
+        /**
+         * Extends instance with defaults and config, initializes observable properties.
+         * Updates provider with current state of instance. 
+         * @param  {Object} settings
+         */
+        initialize: function(settings) {
+            _.extend(this, settings);
+
+            this.initFields()
+                .initObservable()
+                .initListeners()
+                .updateItems();
+
+            this.unlock();
+        },
+
+        /**
+         * Initializes raw properties
+         * @return {Object} reference to instance
+         */
+        initFields: function(){
+            this.meta          = this.provider.meta;
+            this.fields        = this.meta.getVisible();
+            this.itemActionKey = this.meta.get('item_action');
+
+            return this;
+        },
+
+        /**
+         * Initializes observable properties of instance.
+         * @return {Object} - reference to instance
+         */
+        initObservable: function() {
+            this.observe({
+                rows:               [],
+                isLocked:           false,
+                colspan:            this.meta.get('colspan'),
+                extenders:          null,
+                templateExtenders:  []
+            });
+
+            return this;
+        },
+
+        /**
+         * Init instance's subscribtions
+         * @return {Object} - reference to instance
+         */
+        initListeners: function() {
+            var provider    = this.provider,
+                meta        = provider.meta,
+                dump        = provider.dump;
+
+            _.bindAll(this, 'lock', 'onRefresh', 'updateExtenders', 'updateColspan');
+
+            provider.on({
+                'beforeRefresh':    this.lock,
+                'refresh':          this.onRefresh
+            });
+
+            dump.on('update:extenders', this.updateExtenders);
+            meta.on('update:colspan', this.updateColspan);
+
+            return this;
+        },
+
+        /**
+         * Is being called when some component pushed it's extender to global storage.
+         * Preprocesses incoming array of extenders and sets the results into extenders
+         * and templateExtenders observable arrays
+         * @param  {Array} extenders
+         */
+        updateExtenders: function (extenders) {
+            var adjusted = extenders.reduce(function (adjusted, extender) {
+
+                adjusted[extender.as] = extender.name;
+                return adjusted;
+
+            }, {});
+            
+            this.extenders(adjusted);
+
+            this.templateExtenders(extenders.map(this.adjustTemplateExtender, this));
+        },
+
+        /**
+         * Fetches items from storage and stores it into rows observable array
+         * @return {Object} - reference to instance
+         */
+        updateItems: function() {
+            var items = this.provider.data.get('items');
+
+            this.rows(items.map(this.formatItem, this));
+
+            return this;
+        },
+
+        formatItem: function (item) {
+            var actions       = item.actions,
+                itemActionKey = this.itemActionKey,
+                itemAction;
+
+            if (actions) {
+                itemAction = actions[itemActionKey];
+                item.action_url = itemAction.href;
+
+                if (itemAction.hidden) {
+                    delete item.actions[itemActionKey];
+                }
+                
+                item.actions = _.map(item.actions, function (action) { return action });
+            }
+
+            return item;
+        },
+
+        applyItemActionFor: function (item) {
+            return this.redirectTo.bind(this, item.action_url);
+        },
+
+        /**
+         * Returns extender by name of component which set it.
+         * @param  {String} name
+         * @return {String} - Namespace string by which target component is registered in storage.
+         */
+        getExtender: function(name) {
+            var extenders = this.extenders();
+
+            return extenders ? (this.parent_name + ':' + extenders[name]) : null;
+        },
+
+        /**
+         * Returns path to template for arbitrary field
+         * @param  {String} field
+         * @return {String} - path to template
+         */
+        getCellTemplateFor: function(field) {
+            return this.getRootTemplatePath() + '/cell/' + field.data_type;
+        },
+
+        /**
+         * Returns object which represents template bindings params
+         * @return {Object} - template binding params
+         */
+        getTemplate: function() {
+            return {
+                name:      this.getRootTemplatePath(),
+                extenders: this.templateExtenders()
+            };
+        },
+
+        /**
+         * Generates template path for extender.
+         * @param  {Object} extender
+         * @return {String} - extender's template path
+         */
+        adjustTemplateExtender: function (extender) {
+            return this.getRootTemplatePath() + '/extender/' + extender.path;
+        },
+
+        /**
+         * Returns root template path for grid
+         * @return {String} - root template path
+         */
+        getRootTemplatePath: function() {
+            return 'ui/listing/grid';
+        },
+
+        /**
+         * Provider's refresh event's handler.
+         * Locks grid and updates items.
+         */
+        onRefresh: function() {
+            this.unlock()
+                .updateItems();
+        },
+
+        /**
+         * Updates colspan observable property
+         * @param  {String} colspan
+         */
+        updateColspan: function(colspan){
+            this.colspan(colspan);
+        },
+
+        /**
+         * Sets location.href to target url
+         * @param  {String} url
+         */
+        redirectTo: function (url) {
+            if (url) {
+                window.location.href = url;    
+            }
+        },
+
+        /**
+         * Indicates if rows observable array is empty
+         * @return {Boolean} [description]
+         */
+        hasData: function(){
+            return this.rows().length;
+        }
+    }, Loader);
+
+    return Component({
+        constr: Listing
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/massaction.js b/app/code/Magento/Ui/view/base/web/js/listing/massaction.js
new file mode 100644
index 00000000000..9bbd49e0b8a
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/massaction.js
@@ -0,0 +1,422 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/ko/scope',
+    'Magento_Ui/js/lib/component'
+], function (_, Scope, Component) {
+    'use strict';
+
+    function capitaliseFirstLetter(string) {
+        return string.charAt(0).toUpperCase() + string.slice(1);
+    }
+
+    var defaults = {
+        actions: [],
+        selects: [
+            { value: 'selectAll',    label: 'Select all'                },
+            { value: 'deselectAll',  label: 'Deselect all'              },
+            { value: 'selectPage',   label: 'Select all on this page'   },
+            { value: 'deselectPage', label: 'Deselect all on this page' }
+        ],
+        selectableTemplate: 'selectable'
+    };
+
+    var MassActions = Scope.extend({
+
+        /**
+         * Extends instance with defaults and config, initializes observable properties.
+         * Updates storage with current state of instance.
+         * @param {Object} config
+         */
+        initialize: function (config) {
+            _.extend(this, defaults, config);
+
+            this.initObservable()
+                .initProperties()
+                .formatActions()
+                .attachTemplateExtender()
+                .initListeners()
+                .countPages();
+        },
+
+        /**
+         * Initializes observable properties of instance.
+         * @returns {MassActions} Chainable.
+         */
+        initObservable: function () {
+            this.observe({
+                selected:           this.selected || [],
+                excluded:           [],
+                allSelected:        this.allSelected || false,
+                actionsVisible:     false,
+                menuVisible:        false,
+                hasMultiplePages:      ''
+            });
+
+            this.selected.subscribe(this.onSelectionsChange.bind(this));
+
+            return this;
+        },
+
+        /**
+         * Initializes instance properties
+         * @returns {MassActions} Chainable.
+         */
+        initProperties: function () {
+            var provider = this.provider.meta;
+
+            this.indexField = provider.get('index_field');
+
+            return this;
+        },
+
+        /**
+         * Convertes incoming optins to compatible format
+         * @returns {MassActions} Chainable.
+         */
+        formatActions: function(){
+            var actions = this.actions;
+
+            if(!Array.isArray(actions)){
+
+                this.actions = _.map(actions, function(action, name){
+                    action.value = name;
+
+                    return action;
+                });
+            }
+
+            return this;
+        },
+
+        /**
+         * Attaches it's template to provider.dump's extenders
+         * @returns {MassActions} Chainable.
+         */
+        attachTemplateExtender: function () {
+            var provider    = this.provider,
+                dump        = provider.dump,
+                meta        = provider.meta,
+                colspan     = meta.get('colspan'),
+                extenders   = dump.get('extenders');
+
+            if(!this.selectableTemplate) {
+                return this;
+            }
+
+            extenders.push({
+                path:   this.selectableTemplate,
+                name:   this.name,
+                as:     'massaction'
+            });
+
+            dump.trigger('update:extenders', extenders);
+            meta.set('colspan', colspan + 1);
+
+            return this;
+        },
+
+        /**
+         * Init instance's subscribtions
+         * @returns {MassActions} Chainable.
+         */
+        initListeners: function(){
+            this.provider.on('refresh', this.onRefresh.bind(this));
+
+            return this;
+        },
+
+        /**
+         * Prepares params object, which represents the current state of instance.
+         * @returns {Object} - params object
+         */
+        buildParams: function () {           
+            if (this.allSelected()) {
+
+                return {
+                    all_selected: true,
+                    excluded: this.excluded()
+                };
+            }
+
+            return {
+                selected: this.selected()
+            };
+        },
+        
+        /**
+         * Toggles observable property based on area argument.
+         * @param {String} area - Name of the area to be toggled.
+         */
+        toggle: function(area){
+            var visible = this[area];
+
+            visible(!visible());
+        },
+
+        /**
+         * Sets actionsVisible to false
+         */
+        hideActions: function () {
+            this.actionsVisible(false);
+        },
+
+        /**
+         * Sets menuVisible to false
+         */
+        hideMenu: function () {
+            this.menuVisible(false);
+        },
+
+        /**
+         * Updates storage's params by the current state of instance
+         * and hides dropdowns.
+         * @param {String} action
+         */
+        setAction: function (action) {
+            return function(){
+                this.submit(action)
+                    .hideActions();
+            }.bind(this);
+        },
+
+        /**
+         * Sends actions's data to server.
+         * @param {Object} action - An action object.
+         * @returns {MassActions} Chainable.
+         */
+        submit: function(action) {
+            var client = this.provider.client;
+
+            if (this.count) {
+
+                client.submit({
+                    method: 'post',
+                    action: action.url,
+                    data: {
+                        massaction: this.buildParams()
+                    }
+                });
+            } else {
+                
+                alert("You haven't selected any items!");
+            }
+
+            return this;
+        },
+
+        /**
+         * Retrieve all id's from available records.
+         * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result.
+         * @returns {Array} An array of ids'.
+         */
+        getIds: function(exclude){
+            var items   = this.provider.data.get('items'),
+                ids     = _.pluck(items, this.indexField);
+
+            return exclude ?
+                _.difference(ids, this.excluded()) :
+                ids;    
+        },
+
+        /**
+         * Sets isAllSelected observable to true and selects all items on current page.
+         */
+        selectAll: function () {
+            this.allSelected(true);
+            
+            this.clearExcluded()
+                .selectPage();
+        },
+
+        /**
+         * Sets isAllSelected observable to false and deselects all items on current page.
+         */
+        deselectAll: function () {
+            this.allSelected(false);
+            this.deselectPage();
+        },
+
+        /**
+         * Selects all items on current page, adding their ids to selected observable array
+         */
+        selectPage: function () {
+            this.selected(this.getIds());
+        },
+
+        /**
+         * Deselects all items on current page, emptying selected observable array
+         */
+        deselectPage: function () {
+            this.selected.removeAll();
+        },
+        
+        updateExcluded: function(selected) {
+            var excluded    = this.excluded(),
+                fromPage    = _.difference(this.getIds(), selected);
+
+            excluded = _.union(excluded, fromPage);
+
+            excluded = _.difference(excluded, selected);
+
+            this.excluded(excluded);
+
+            return this;
+        },
+
+        /**
+         * Clears the array of not selected records.
+         * @returns {MassActions} Chainable.
+         */
+        clearExcluded: function(){
+            this.excluded.removeAll();
+
+            return this;
+        },
+
+        /**
+         * Returns handler for row click
+         * @param  {String} url
+         * @return {Function} click handler
+         */
+        redirectTo: function (url) {
+
+            /**
+             * Sets location.href to target url
+             */
+            return function () {
+                window.location.href = url;
+            }
+        },
+
+        /**
+         * Gets current pages count and assignes it's being more than one to
+         *     hasMultiplePages observable.
+         * @returns {MassActions} Chainable.
+         */
+        countPages: function() {
+            var provider = this.provider.data;
+
+            this.pages = provider.get('pages');
+
+            this.hasMultiplePages(this.pages > 1);
+
+            return this;
+        },
+
+        /**
+         * Counts number of 'selected' items. 
+         * @returns {MassActions} Chainable.
+         */
+        countSelect: function() {
+            var provider    = this.provider,
+                total       = provider.data.get('totalCount'),
+                excluded    = this.excluded().length,
+                count       = this.selected().length;
+
+            if (this.allSelected()) {
+                count = total - excluded;
+            }
+
+            provider.meta.set('selected', count);
+
+            this.count = count;
+
+            return this;
+        },
+
+        /**
+         * If isAllSelected is true, deselects all, else selects all
+         */
+        toggleSelectAll: function () {
+            var isAllSelected = this.allSelected();
+
+            isAllSelected ? this.deselectAll() : this.selectAll();
+        },
+
+        /**
+         * Looks up for corresponding to passed action checker method,
+         * and returnes it's result. If method not found, returnes true;
+         * @param {String} action - e.g. selectAll, deselectAll
+         * @returns {Boolean} should action be visible
+         */
+        shouldBeVisible: function (action) {
+            var checker = this['should' + capitaliseFirstLetter(action) + 'BeVisible'];
+
+            return checker ? checker.call(this) : true;
+        },
+
+        /**
+         * Checkes if selectAll action supposed to be visible
+         * @returns {Boolean}
+         */
+        shouldSelectAllBeVisible: function () {
+            return !this.allSelected() && this.hasMultiplePages();
+        },
+
+        /**
+         * Checkes if deselectAll action supposed to be visible
+         * @returns {Boolean}
+         */
+        shouldDeselectAllBeVisible: function () {
+            return this.allSelected() && this.hasMultiplePages();
+        },
+
+        onToggle: function(area){
+            return this.toggle.bind(this, area);
+        },
+
+        /**
+         * Creates handler for applying action (e.g. selectAll)
+         * @param {String} action
+         * @returns {Function} - click handler
+         */
+        onApplySelect: function (action) {
+            return function(){
+                this.menuVisible(false);
+                this[action]();
+            }.bind(this);
+        },
+
+        /**
+         * Updates state according to changes of provider.
+         */
+        onRefresh: function () {
+            if( this.allSelected() ){
+                this.selected(this.getIds(true));
+            }
+
+            this.countPages();
+        },
+
+        onSelectionsChange: function(selected){
+            this.updateExcluded(selected)
+                .countSelect();
+        }
+    });
+
+    return Component({
+        constr: MassActions
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/paging.js b/app/code/Magento/Ui/view/base/web/js/listing/paging.js
new file mode 100644
index 00000000000..2b38b195c1c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/paging.js
@@ -0,0 +1,209 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    '../lib/ko/scope',
+    '../lib/component'
+], function(_, Scope, Component) {
+    'use strict';
+
+    var defaults = {
+        sizes: [5, 10, 20, 30, 50, 100, 200],
+        params: {
+            dir: 'paging',
+            items: ['pageSize', 'current']
+        }
+    };
+
+    var Paging = Scope.extend({
+
+        /**
+         * Extends instance with defaults and config, initializes observable properties.
+         * Updates storage with current state of instance. 
+         * @param  {Object} config
+         */
+        initialize: function(config) {
+            _.extend(this, defaults, config);
+
+            this.initObservable(config)
+                .initProvider()
+                .pushParams();
+        },
+
+        /**
+         * Initializes observable properties of instance.
+         * @return {Object} - reference to instance
+         */
+        initObservable: function(config) {
+            var data = this.provider.data.get();
+
+            this.observe({
+                'pages':        data.pages || 1,
+                'totalCount':   data.totalCount,
+                'current':      this.current,
+                'pageSize':     this.pageSize,
+                'selected':     0
+            });
+
+            return this;
+        },
+
+        /**
+         * Subscribes on provider's events
+         * @returns {Paging} Chainable.
+         */
+        initProvider: function(){
+            var provider    = this.provider,
+                params      = provider.params,
+                meta        = provider.meta;
+
+            _.bindAll(this, 'drop', 'onRefresh', 'pullParams', 'updateSelected');
+
+            provider.on('refresh', this.onRefresh);
+            
+            meta.on('update:selected', this.updateSelected);
+
+            params.on({
+                'update:filter':    this.drop,
+                'update:sorting':   this.drop,
+                'update:paging':    this.pullParams
+            });
+
+            return this;
+        },
+
+        /**
+         * Increments current observable prop by val and call reload method 
+         * @param {String} val
+         */
+        go: function(val) {
+            var current = this.current;
+
+            current(current() + val);
+
+            this.reload();
+        },
+
+        /**
+         * Calls go method with 1 as agrument
+         */
+        next: function() {
+            this.go(1);
+        },
+
+        /**
+         * Calls go method with -1 as agrument
+         */
+        prev: function() {
+            this.go(-1);
+        },
+
+        /**
+         * Compares current and pages observables and returns boolean result
+         * @return {Boolean} is current equal to pages property
+         */
+        isLast: function() {
+            return this.current() === this.pages();
+        },
+
+        /**
+         * Compares current observable to 1
+         * @return {Boolean} is current page first
+         */
+        isFirst: function() {
+            return this.current() === 1;
+        },
+
+        /**
+         * Returns closest existing page number to page argument
+         * @param  {Number} page
+         * @return {Number} closest existing page number
+         */
+        getInRange: function(page) {
+            return Math.min(Math.max(1, page), this.pages());
+        },
+        
+        /**
+         * Sets current observable to 1 and calls pushParams method
+         */
+        drop: function() {
+            this.current(1);
+
+            this.pushParams();
+        },
+
+        /**
+         * Updates number of selected items.
+         * @param {Number} count - New number of selected items.
+         */
+        updateSelected: function(count){
+            this.selected(count);
+        },
+
+        /**
+         * Is being called on provider's refresh event.
+         * Updates totalCount and pages observables
+         */
+        onRefresh: function() {
+            var data = this.provider.data.get();
+
+            this.totalCount(data.totalCount);
+            this.pages(data.pages || 1);
+        },
+
+        /**
+         * Is being triggered on user interaction with page size select.
+         * Resets current page to first if needed.
+         */
+        onSizeChange: function() {
+            var size = this.pageSize();
+
+            if (size * this.current() > this.totalCount()) {
+                this.current(1);
+            }
+
+            this.reload();
+        },
+
+        /**
+         * Validates page change according to user's input.
+         * Sets current observable to result of validation.
+         * Calls reload method then.
+         */
+        onPageChange: function() {
+            var current,
+                valid;
+
+            current = +this.current();
+            valid = !isNaN(current) ? this.getInRange(current) : 1;
+
+            this.current(valid);
+
+            this.reload();
+        }
+    });
+
+    return Component({
+        constr: Paging
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/sorting.js b/app/code/Magento/Ui/view/base/web/js/listing/sorting.js
new file mode 100644
index 00000000000..741458ecab4
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/sorting.js
@@ -0,0 +1,154 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/lib/ko/scope',
+    'Magento_Ui/js/lib/component'
+], function(_, Scope, Component) {
+    'use strict';
+    
+    var defaults = {
+        dirs: {
+            asc: 'sort-arrow-asc',
+            desc: 'sort-arrow-desc'
+        },
+        params: {
+            dir: 'sorting',
+            items: ['field', 'direction']
+        },
+        initialDir: 'asc',
+        noSort: 'not-sort',
+        templateExtender: 'sortable'
+    };
+
+    var Sorting = Scope.extend({
+
+        /**
+         * Extends instance with defaults and config, initializes observable properties.
+         * Updates storage with current state of instance. 
+         * @param  {Object} config
+         */
+        initialize: function(config) {
+            _.extend(this, defaults, config);
+            
+            this.initObservable()
+                .attachTemplateExtender()
+                .pushParams();
+        },
+
+        /**
+         * Initializes observable properties of instance.
+         * @returns {Sorting} Chainable.
+         */
+        initObservable: function(){
+            this.observe({
+                field:      this.field,
+                direction:  this.direction
+            });
+
+            return this;
+        },
+
+        /**
+         * Attaches it's template to provider.dump's extenders
+         * @returns {Sorting} Chainable.
+         */
+        attachTemplateExtender: function () {
+            var provider    = this.provider.dump,
+                extenders   = provider.get('extenders');
+                
+            extenders.push({
+                path: this.templateExtender,
+                name: this.name,
+                as:   'sorting'
+            });
+
+            provider.trigger('update:extenders', extenders);
+
+            return this;
+        },
+
+        /**
+         * Generates css class for indicating sorting state for field. 
+         * @param {String} id - identifier of field to be sorted
+         * @returns {String} - css class.
+         */
+        setClass: function(id) {
+            return this.isSorted(id) ?
+                this.dirs[this.direction()] :
+                this.noSort;
+        },
+
+        /**
+         * Toggles observable dir property betweeen 'asc' and 'desc' values.
+         */
+        toggleDirection: function() {
+            var dir = this.direction;
+
+            dir(dir() === 'asc' ? 'desc' : 'asc');
+        },
+
+        /**
+         * Sets currently sorted field and initial sorting type for it.
+         * @param {String} id - identifier of field to be sorted
+         */
+        setSort: function(id) {
+            this.field(id);
+            this.direction(this.initialDir);
+        },
+
+        /**
+         * Sorts by field and reloads storage.
+         * @param {(String|Number)} id - Identifier of field to be sorted.
+         */
+        sortBy: function(id) {
+            this.isSorted(id) ?
+                this.toggleDirection() :
+                this.setSort(id);
+
+            this.reload();
+        },
+
+        /**
+         * Checks if the field is currently sorted.
+         * @param {String} id - identifier of field to be sorted
+         * @returns {Boolean} true, if target field is sorted already, false otherwise
+         */
+        isSorted: function(id) {
+            return id === this.field();
+        },
+
+        /**
+         * Returns function to handle user's click (workaround for knockout.js).
+         * @param {Object} field
+         * @returns {Function} - click handler
+         */
+        onClick: function(field) {
+            return this.sortBy.bind(this, field.index);
+        }
+    });
+
+    return Component({
+        constr: Sorting
+    });
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/utils/data_provider.js b/app/code/Magento/Ui/view/base/web/js/listing/utils/data_provider.js
new file mode 100644
index 00000000000..02a5df17fa2
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/utils/data_provider.js
@@ -0,0 +1,131 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    './rest',
+    'Magento_Ui/js/lib/storage/index',
+    'Magento_Ui/js/lib/class',
+    'Magento_Ui/js/lib/events'
+], function(_, Rest, storages, Class, EventsBus) {
+    'use strict';
+    
+    var defaults = {
+        stores: ['config', 'meta', 'data', 'params', 'dump']
+    };
+
+    var DataProvider = Class.extend({
+        /**
+         * Initializes DataProvider instance.
+         * @param {Object} settings - Settings to initialize object with.
+         */
+        initialize: function(settings) {
+            _.extend(this, defaults, settings);
+
+            this.initStorages()
+                .initClient();
+        },
+
+        /**
+         * Creates instances of storage objects.
+         * @returns {DataProvider} Chainable.
+         */
+        initStorages: function() {
+            var storage,
+                config;
+
+            this.stores.forEach(function(store) {
+                storage = storages[store];
+                config  = this[store];
+
+                this[store] = new storage(config);
+            }, this);
+
+            return this;
+        },
+
+        /**
+         * Creates instances of a REST client.
+         * @returns {DataProvider} Chainable.
+         */
+        initClient: function() {
+            var config = this.config.get('client');
+
+            this.client = new Rest(config);
+
+            this.client.on('read', this.onRead.bind(this));
+
+            return this;
+        },
+
+        /**
+         * Tries to retrieve data from server using REST client.
+         * Allways attaches cached parameters to request.
+         * @param {Object} [options] - Additional paramters to be attached. 
+         * @returns {DataProvider} Chainable.
+         */
+        refresh: function(options) {
+            var stored = this.params.get(),
+                params = _.extend({}, stored, options || {});
+
+            this.trigger('beforeRefresh')
+                .client.read(params);
+
+            return this;
+        },
+
+        /**
+         * Updates list of storages with a specified data.
+         * @param {Object} data - Data to update storages with.
+         * @returns {DataProvider} Chainable.
+         */
+        updateStorages: function(data) {
+            var value;
+
+            this.stores.forEach(function(store) {
+                value = data[store];
+
+                if(value){
+                    this[store].set(value);
+                }
+            }, this);
+
+            return this;
+        },
+
+        /**
+         * Callback method that fires when REST client
+         * will resolve requets to the server.
+         * @param {Object} result - Server response.
+         */
+        onRead: function(result) {
+            result = {
+                data: result.data
+            };
+
+            this.updateStorages(result)
+                .trigger('refresh', result);
+        }
+    }, EventsBus);
+    
+    return DataProvider;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/utils/provider.js b/app/code/Magento/Ui/view/base/web/js/listing/utils/provider.js
new file mode 100644
index 00000000000..2ac588271e8
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/utils/provider.js
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'jquery',
+    './data_provider',
+    'Magento_Ui/js/lib/registry/registry'
+], function($, DataProvider, registry) {
+    'use strict';
+
+    /**
+     * Merges passed settings with preset ajax properties
+     * @param  {Object} settings
+     * @returns {Object} - mutated settings
+     */
+    function getConfig(settings) {
+        var config = settings.config,
+            client = config.client = config.client || {};
+
+        $.extend(true, client, {
+            ajax: {
+                data: {
+                    name: settings.name,
+                    form_key: FORM_KEY
+                }
+            }
+        });
+
+        return settings;
+    }
+
+    /**
+     * Creates new data provider and register it by settings.name 
+     * @param {HTMLElement} el - Element upon which this module was called.
+     * @param {Object} settings
+     */
+    function init(el, settings) {
+        var name    = settings.name,
+            config  = getConfig(settings);
+
+        registry.set(name, new DataProvider(config));
+    }
+
+    return init;
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/utils/request_builder.js b/app/code/Magento/Ui/view/base/web/js/listing/utils/request_builder.js
new file mode 100644
index 00000000000..6085c9d2481
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/utils/request_builder.js
@@ -0,0 +1,159 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/**
+ * @returns {Function} Request builder function.
+ */
+define([
+    'Magento_Ui/js/lib/utils'
+], function(utils) {
+    'use strict';
+
+    /**
+     * @param {String} - name of params set
+     * @param {Object} - params to convert
+     * @returns {String} - concatenated name/params pairs by custom logic and separator
+     * @private
+     */
+    function parseObject(name, value) {
+        var key,
+            result = [];
+
+        for (key in value) {
+            result.push(name + '[' + key + ']' + '=' + value[key])
+        }
+
+        return result.join('&');
+    }
+
+    /**
+     * @param {String} - name of property
+     * @param {String} - corresponding value
+     * @returns {String} - concatenated params by separator "="
+     * @private
+     */
+    function parseValue(name, value) {
+        return name + '=' + value;
+    }
+
+    /**
+     * Extracts sorting parameters from object and returns string representation of it.
+     * @param {Object} param - Sorting parameters object, e.g. { field: 'field_to_sort', dir: 'asc' }.
+     * @returns {String} - Chunk of url string that represents sorting params
+     * @private
+     */
+    function extractSortParams(params) {
+        var result,
+            sorting = params.sorting;
+
+        if (typeof sorting === 'undefined') {
+            return '';
+        }
+
+        result = '/sort/' + sorting.field + '/dir/' + sorting.direction;
+
+        delete params.sorting;
+
+        return result;
+    }
+
+    /**
+     * Extracts pager parameters from an object and returns it's string representation.
+     * @param {Object} params which contains "paging" params object.
+     * @returns {String} - Chunk of url string that represents pager params
+     * @private
+     */
+    function extractPagerParams(params) {
+        var result,
+            paging = params.paging;
+
+        if (typeof paging === 'undefined') {
+            return '';
+        }
+
+        result = '/limit/' + paging.pageSize + '/page/' + paging.current;
+
+        delete params.paging;
+
+        return result;
+    }
+
+    /**
+     * Formats filter data according to the type of it's value.
+     * @param {Object} filter - filter object to format.
+     * @returns {String} - Chunk of url string that represents filter's params
+     * @private
+     */
+    function formatFilter(filter) {
+        var name = filter.field,
+            value = filter.value;
+
+        return typeof value !== 'object' ?
+            parseValue(name, value) :
+            parseObject(name, value);
+    }
+
+    /**
+     * Formats and assembles filter data.
+     * @param {Object} params - object containing "filter" array.
+     * @returns {String} - Chunk of url string that represents filters
+     * @private
+     */
+    function extractFilterParams(params) {
+        var filters,
+            result;
+
+        filters = params.filter;
+
+        if (typeof filters === 'undefined' || !filters.length) {
+            return '';
+        }
+
+        result = filters.map(formatFilter).join('&');
+
+        result = '/filter/' + utils.btoa(encodeURI(result));
+
+        delete params.filter;
+
+        return result;
+    }
+
+    return function(root, params) {
+        var url,
+            lastChar;
+
+        lastChar = root.charAt(root.length - 1);
+
+        if (lastChar === '/') {
+            root = root.substr(0, root.length - 1);
+        }
+
+        url =
+            root +
+            extractSortParams(params) +
+            extractPagerParams(params) +
+            extractFilterParams(params);
+
+        return url;
+    };
+
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/js/listing/utils/rest.js b/app/code/Magento/Ui/view/base/web/js/listing/utils/rest.js
new file mode 100644
index 00000000000..1a9d42038cb
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/listing/utils/rest.js
@@ -0,0 +1,103 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    'underscore',
+    'jquery',
+    'Magento_Ui/js/lib/utils',
+    'Magento_Ui/js/lib/class',
+    'Magento_Ui/js/lib/events',
+    './request_builder'
+], function(_, $, utils, Class, EventsBus, requestBuilder) {
+    'use strict';
+
+    var defaults = {
+        ajax: {
+            dataType: 'json'
+        }
+    };
+
+    return Class.extend({
+        initialize: function(config) {
+            $.extend(true, this.config = {}, defaults, config);
+        },
+
+        /**
+         * Sends ajax request using params and config passed to it and calls this.config.onRead when done.
+         * @param {Object} params - request body params
+         * @param {Object} config - config to build url from
+         */
+        read: function(params, config) {
+            config = this.createConfig(params, config);
+
+            $.ajax(config)
+                .done(this.onRead.bind(this));
+        },
+
+        /**
+         * Creates config for ajax call.
+         * @param {Object} params - request body params
+         * @param {Object} config - config to build url from
+         * @returns {Object} - merged config for ajax call
+         */
+        createConfig: function(params, config) {
+            var baseConf;
+
+            config = config || {};
+            params = params || {};
+
+            baseConf = {
+                url: requestBuilder(this.config.root, params),
+                data: params
+            };
+
+            return $.extend(true, baseConf, this.config.ajax, config);
+        },
+
+        /**
+         * Callback of ajax call.
+         * Parses results and triggers read event;
+         * @param  {Object|*} result - Result of ajax call.
+         */
+        onRead: function(result){
+            result = typeof result === 'string' ?
+                JSON.parse(result) :
+                result;
+
+            this.trigger('read', result);
+        },
+
+        /**
+         * Submits data using utils.submitAsForm
+         * @param {Object} config - object containing ajax options
+         */
+        submit: function(config){
+            var ajax = this.config.ajax,
+                data = ajax.data || {};
+
+            _.extend(config.data, data);
+
+            utils.submitAsForm(config);
+        }
+    }, EventsBus);
+
+});
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter.html b/app/code/Magento/Ui/view/base/web/templates/filter.html
new file mode 100644
index 00000000000..2fca9c73cd3
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/filter.html
@@ -0,0 +1,60 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<div class="filters">
+    <button class="action filters-toggle" data-bind="click: toggle, css: { active: isVisible }">
+        <span data-bind="text: $t('Filter')"></span>
+    </button>
+    <div class="form filters-form" data-bind="visible: isVisible" data-part="filter-form">
+        <fieldset class="filters-fieldset fieldset">
+            <legend class="legend filters-legend">
+                <span data-bind="text: $t('Advanced filter')"></span>
+            </legend><br />
+            <!-- ko foreach: { data: filters, as: 'item' } -->
+            <!-- ko template: $parent.getTemplateFor(item) --><!-- /ko -->
+            <!-- /ko -->
+        </fieldset>
+        <div class="actions filters-actions">
+            <button class="action secondary action-reset" data-bind="click: reset" type="button"><span data-bind="text: $t('Reset')"></span></button>
+            <button class="action primary action-apply" data-bind="click: apply" type="button"><span data-bind="text: $t('Apply')"></span></button>
+            <button class="action secondary action-close" data-bind="click: close" type="button"><span data-bind="text: $t('Close')"></span></button>
+        </div>
+    </div>
+    <div class="filters-current" data-bind="css: {active: active().length}">
+        <ul class="filters-items items">
+            <!-- ko foreach: { data: active, as: 'filter' } -->
+
+            <li class="filters-item item">
+                <strong class="item-label" data-bind="text: $t(filter.title)"></strong>
+                <span class="item-value" data-bind="text: $t(filter.output)"></span>
+                <button data-bind="click: $parent.onClear(filter)" type="button" class="action action-remove"><span data-bind="text: $t('Remove')"></span></button>
+            </li>
+
+            <!-- /ko -->
+        </ul>
+        <button data-bind="click: reset" class="action action-clear">
+            <span data-bind="text: $t('Clear all')"></span>
+        </button>
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html
new file mode 100644
index 00000000000..5e2f1625ffd
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/filter/filter_date.html
@@ -0,0 +1,45 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fieldset class="field field-range field-date">
+    <legend class="label">
+        <span data-bind="text: title"></span>
+    </legend><br />
+    <div class="control">
+        <div class="fields group group-2">
+            <div class="field field-range-from">
+                <label class="label"><span data-bind="text: $t('From')"></span></label>
+                <div class="control">
+                    <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: from, options: config }, attr: {placeholder: $t('From')}">
+                </div>
+            </div>
+            <div class="field field-range-to">
+                <label class="label"><span data-bind="text: $t('To')"></span></label>
+                <div class="control">
+                    <input type="text" class="input-text no-changes" data-bind="datepicker: { storage: to, options: config }, attr: {placeholder: $t('To')}">
+                </div>
+            </div>
+        </div>
+    </div>
+</fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html
new file mode 100644
index 00000000000..7df60c829d7
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/filter/filter_input.html
@@ -0,0 +1,32 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<div class="field">
+    <label class="label" data-bind="attr: {for: index}">
+        <span data-bind="text: title"></span>
+    </label>
+    <div class="control">
+        <input data-bind="value: value, attr: {id: index}" class="input-text" type="text">
+    </div>
+</div>
diff --git a/app/code/Magento/Reports/view/frontend/templates/product_compared.phtml b/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html
similarity index 50%
rename from app/code/Magento/Reports/view/frontend/templates/product_compared.phtml
rename to app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html
index 581715f5640..62d2078c2c2 100644
--- a/app/code/Magento/Reports/view/frontend/templates/product_compared.phtml
+++ b/app/code/Magento/Ui/view/base/web/templates/filter/filter_range.html
@@ -1,4 +1,4 @@
-<?php
+<!--
 /**
  * Magento
  *
@@ -21,23 +21,25 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/* @var $this \Magento\Reports\Block\Product\Compared */
-?>
-<?php if ($_products = $this->getRecentlyComparedProducts()): ?>
-    <div class="block compared links">
-        <div class="title">
-            <strong><?php echo __('Recently Compared Products') ?></strong>
-        </div>
-        <div class="content">
-            <ol id="recently-compared-items" class="items compared">
-                <?php foreach ($_products as $_item): ?>
-                    <li class="item">
-                        <strong class="product name">
-                            <a href="<?php echo $this->getProductUrl($_item) ?>"><?php echo $this->helper('Magento\Catalog\Helper\Output')->productAttribute($_item, $_item->getName() , 'name') ?></a>
-                        </strong>
-                    </li>
-                <?php endforeach; ?>
-            </ol>
+-->
+<fieldset class="field field-range">
+    <legend class="label">
+        <span data-bind="text: title"></span>
+    </legend><br />
+    <div class="control">
+        <div class="fields group group-2">
+            <div class="field field-range-from">
+                <label class="label"><span data-bind="text: $t('From')"></span></label>
+                <div class="control hide-picker">
+                    <input type="text" class="input-text no-changes" data-bind="value: from, attr: {placeholder: $t('From')}">
+                </div>
+            </div>
+            <div class="field field-range-to">
+                <label class="label"><span data-bind="text: $t('To')"></span></label>
+                <div class="control hide-picker">
+                    <input type="text" class="input-text no-changes" data-bind="value: to, attr: {placeholder: $t('To')}">
+                </div>
+            </div>
         </div>
     </div>
-<?php endif; ?>
+</fieldset>
diff --git a/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html b/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html
new file mode 100644
index 00000000000..c214ebf8e1e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/filter/filter_select.html
@@ -0,0 +1,32 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<div class="field">
+    <label class="label" data-bind="attr: {for: index}">
+        <span data-bind="text: title"></span>
+    </label>
+    <div class="control">
+        <select data-bind="attr: {id: index}, options: options, value: selected, optionsText: 'label', optionsCaption: caption" class="select"></select>
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid.html
new file mode 100644
index 00000000000..408ac291f82
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid.html
@@ -0,0 +1,54 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<div class="hor-scroll">
+    <table class="data">
+        <thead data-part="head">
+            <tr class="headings" data-part="head.row">
+                <!-- ko foreach: { data: fields, as: 'field' } -->
+                <th>
+                    <span data-bind="text: field.title"></span>
+                </th>
+                <!-- /ko -->
+            </tr>
+        </thead>
+        <tbody data-part="body">
+            <!-- ko if: hasData() -->
+                <!-- ko foreach: { data: rows, as: 'row' } -->
+                    <tr data-part="body.row" class="even pointer" data-bind="click: $parent.applyItemActionFor(row)">
+                        <!-- ko foreach: { data: $parent.fields, as: 'field' }  -->
+                            <!-- ko template: $parents[1].getCellTemplateFor(field) --><!-- /ko -->
+                        <!-- /ko -->
+                    </tr>
+                <!-- /ko -->
+            <!-- /ko -->
+
+             <!-- ko ifnot: hasData() -->
+                <tr class="even">
+                    <td class="empty-text" data-bind="attr: { colspan: colspan }, text: $t('We couldn\'t find any records.')"></td>
+                </tr>
+             <!-- /ko -->
+        </tbody>
+    </table>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html
new file mode 100644
index 00000000000..c909952f33f
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/actions.html
@@ -0,0 +1,34 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<td data-part="body.row.cell" data-bind="stopPropagation: true">
+    <div data-bind="if: window.Array.isArray(row[field.index])">
+        <div data-bind="foreach: { data: row[field.index], as: 'action' }">
+            <a target="_blank" data-bind="attr: { href: action.href }, text: action.title"></a>
+        </div>
+    </div>
+    <div data-bind="ifnot: window.Array.isArray(row[field.index])">
+        <a target="_blank" data-bind="attr: { href: row[field.index].href }, text: row[field.index].title"></a>
+    </div>
+</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html
new file mode 100644
index 00000000000..a353121b4c5
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/date.html
@@ -0,0 +1,27 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<td data-part="body.row.cell">
+    <span data-bind="date: { value: row[field.index], format: field.date_format }"></span>
+</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html
new file mode 100644
index 00000000000..b5d79a06bfa
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/store.html
@@ -0,0 +1,27 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<td data-part="body.row.cell">
+    <span data-bind="html: row[field.index]"></span>
+</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html
new file mode 100644
index 00000000000..5278612f556
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/cell/text.html
@@ -0,0 +1,32 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<td data-part="body.row.cell">
+    <span data-bind="'if': 'options' in $data">
+        <span data-bind="text: options[row[index]]"></span>
+    </span>
+    <span data-bind="ifnot: 'options' in $data">
+        <span data-bind="text: row[field.index]"></span>
+    </span>
+</td>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html
new file mode 100644
index 00000000000..35235f6db5c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/selectable.html
@@ -0,0 +1,56 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<table>
+    <thead>
+        <tr data-part-prepend="head.row">
+            <th class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction')">
+                <div class="mass-select" data-bind="outerClick: hideMenu, stopPropagation: true">
+                    <label class="field choice mass-select-field">
+                        <input type="checkbox" id="mass-select-checkbox" data-bind="checked: allSelected, event: { 'change': toggleSelectAll }">
+                    </label>
+                    <button class="mass-select-toggle" data-toggle="dropdown" data-bind="css: { 'active': menuVisible }, click: onToggle('menuVisible')">
+                        <span data-bind="text: $t('Options')"></span>
+                    </button>
+                    <ul class="mass-select-menu" data-bind="css: { 'active': menuVisible } ">
+                        <!-- ko foreach: { data: selects , as: 'action' } -->
+                        <li data-bind="click: $parent.onApplySelect(action.value), visible: $parent.shouldBeVisible(action.value)">
+                            <span data-bind="text: $t(action.label)"></span>
+                        </li>
+                        <!-- /ko -->
+                    </ul>
+                </div>
+            </th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr data-part-prepend="body.row">
+            <td class="col-select col-massaction" data-bind="scope: $parent.getExtender('massaction'), stopPropagation: true">
+                <label class="select-box">
+                    <input type="checkbox" class="massaction-checkbox" data-bind="checked: selected, value: row[indexField]">
+                </label>
+            </td>
+        </tr>
+    </tbody>
+</table>
diff --git a/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html
new file mode 100644
index 00000000000..0e60cf3e83c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/listing/grid/extender/sortable.html
@@ -0,0 +1,43 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<table>
+    <thead data-part-replace="head" data-bind="scope: getExtender('sorting')">
+        <tr class="headings" data-part="head.row">
+            <!-- ko foreach: { data: $parent.fields, as: 'field' } -->
+            <th>
+                <!-- ko if: field.sortable -->
+                <span>
+                    <a href="#" data-bind="text: field.title, css: $parent.setClass(field.index), click: $parent.onClick(field)"></a>
+                </span>
+                <!-- /ko -->
+                
+                <!-- ko ifnot: field.sortable -->
+                <span data-bind="text: field.title"></span>
+                <!-- /ko -->
+            </th>
+            <!-- /ko -->
+        </tr>
+    </thead>
+</table>
diff --git a/app/code/Magento/Ui/view/base/web/templates/massaction.html b/app/code/Magento/Ui/view/base/web/templates/massaction.html
new file mode 100644
index 00000000000..a3714a62728
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/massaction.html
@@ -0,0 +1,36 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<div title="Select Items" class="actions-split" data-bind="css: {'active': actionsVisible}, stopPropagation: true, outerClick: hideActions">
+    <button title="Actions" class="action-default scalable add" data-bind="click: onToggle('actionsVisible')">
+        <span data-bind="text: $t('Actions')"></span>
+    </button>
+    <button title="" class="action-toggle scalable  add" data-toggle="dropdown" data-bind="click: onToggle('actionsVisible'), css: {active: actionsVisible}">
+        <span>|</span>
+    </button>
+
+    <ul class="dropdown-menu" data-bind="css: {'active': actionsVisible}, foreach: {data: actions, as: 'action'}">
+        <li data-bind="click: $parent.setAction(action)"><span class="item" data-bind="text: label"></span></li>
+    </ul>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Reports/view/frontend/templates/product_viewed.phtml b/app/code/Magento/Ui/view/base/web/templates/pageactions.html
similarity index 52%
rename from app/code/Magento/Reports/view/frontend/templates/product_viewed.phtml
rename to app/code/Magento/Ui/view/base/web/templates/pageactions.html
index b6a5016b5db..4f4b1a046dd 100644
--- a/app/code/Magento/Reports/view/frontend/templates/product_viewed.phtml
+++ b/app/code/Magento/Ui/view/base/web/templates/pageactions.html
@@ -1,4 +1,4 @@
-<?php
+<!--
 /**
  * Magento
  *
@@ -21,23 +21,24 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/* @var $this \Magento\Reports\Block\Product\Viewed */
-?>
-<?php if ($_products = $this->getRecentlyViewedProducts()): ?>
-    <div class="block viewed links">
-        <div class="title">
-            <strong><?php echo __('Recently Viewed Products') ?></strong>
-        </div>
-        <div class="content">
-            <ol id="recently-viewed-items" class="items viewed">
-                <?php foreach ($_products as $_item): ?>
-                    <li class="item">
-                        <strong class="product name">
-                            <a href="<?php echo $this->getProductUrl($_item) ?>"><?php echo $this->helper('Magento\Catalog\Helper\Output')->productAttribute($_item, $_item->getName(), 'name') ?></a>
-                        </strong>
-                    </li>
-                <?php endforeach; ?>
-            </ol>
+-->
+<div class="page-main-actions">
+    <div class="page-actions-placeholder"></div>
+    <div class="page-actions" data-ui-id="page-actions-toolbar-content-header">
+        <div class="page-actions-inner" data-title="Pages">
+            <div class="page-actions-buttons">
+                <!-- ko foreach: actions -->
+                <button data-bind="
+                            attr: {title: $t(label)},
+                            css: {primary: type === 'primary'},
+                            click: $parent.redirectTo(url)"
+                        type="button"
+                        class="action- scalable add"
+                        data-ui-id="cms-page-add-button">
+                    <span data-bind="text: $t(label)"></span>
+                </button>
+                <!-- /ko -->
+            </div>
         </div>
     </div>
-<?php endif; ?>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/pagination.html b/app/code/Magento/Ui/view/base/web/templates/pagination.html
new file mode 100644
index 00000000000..31db568e603
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/pagination.html
@@ -0,0 +1,50 @@
+<!--
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<span data-part="left">
+    <span class="pages-total-found">
+        <strong data-bind="text: totalCount"></strong> records found
+         <!-- ko if: selected -->
+        (<strong data-bind="text: selected"></strong> selected)
+        <!-- /ko -->
+    </span>
+    <label class="view-pages">
+        View
+        <select data-bind="options: sizes, value: pageSize, event: { change: onSizeChange}"></select>
+        per page.
+    </label>
+</span>
+<span data-part="right">
+    <span data-bind="css: { disabled: isFirst() }, click: prev" class="action-previous">
+        <span>Previous page</span>
+    </span>
+    <input data-bind="value: current, event: {change: onPageChange}" type="text" class="input-text page" />
+    <span class="pages-total">
+        of
+        <span data-bind="text: pages" style="vertical-align: top;"></span>
+    </span>
+    <span data-bind="css: { disabled: isLast() }, click: next" class="action-next">
+        <span>Next page</span>
+    </span>
+</span>
\ No newline at end of file
diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json
index feba73b5d7f..ea4a5bd145d 100644
--- a/app/code/Magento/Ups/composer.json
+++ b/app/code/Magento/Ups/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php b/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php
deleted file mode 100644
index d840d589a38..00000000000
--- a/app/code/Magento/UrlRedirect/Controller/Adminhtml/UrlRedirect.php
+++ /dev/null
@@ -1,468 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Controller\Adminhtml;
-
-use Magento\Backend\App\Action;
-use Magento\Catalog\Model\Category;
-use Magento\Catalog\Model\Product;
-use Magento\Framework\Model\Exception;
-
-class UrlRedirect extends Action
-{
-    /**#@+
-     * Entity types
-     */
-    const ENTITY_TYPE_CUSTOM = 'custom';
-    const ENTITY_TYPE_PRODUCT = 'product';
-    const ENTITY_TYPE_CATEGORY = 'category';
-    const ENTITY_TYPE_CMS_PAGE = 'cms-page';
-    /**#@-*/
-
-    const ID_MODE = 'id';
-
-    const PRODUCT_MODE = 'product';
-
-    const CATEGORY_MODE = 'category';
-
-    const CMS_PAGE_MODE = 'cms_page';
-
-    /**
-     * @var Product
-     */
-    private $_product;
-
-    /**
-     * @var Category
-     */
-    private $_category;
-
-    /**
-     * @var \Magento\Cms\Model\Page
-     */
-    private $_cmsPage;
-
-    /**
-     * @var \Magento\UrlRedirect\Model\UrlRedirect
-     */
-    private $_urlRewrite;
-
-    /**
-     * Show URL rewrites index page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('URL Rewrites'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_UrlRedirect::urlrewrite');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Show urlrewrite edit/create page
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('URL Rewrites'));
-        $this->_title->add(__('[New/Edit] URL Rewrite'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_UrlRedirect::urlrewrite');
-
-        $mode = $this->_getMode();
-        switch ($mode) {
-            case self::PRODUCT_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\UrlRedirect\Block\Catalog\Product\Edit',
-                    '',
-                    array(
-                        'data' => array(
-                            'category' => $this->_getCategory(),
-                            'product' => $this->_getProduct(),
-                            'is_category_mode' => $this->getRequest()->has('category'),
-                            'url_rewrite' => $this->_getUrlRewrite()
-                        )
-                    )
-                );
-                break;
-            case self::CATEGORY_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\UrlRedirect\Block\Catalog\Category\Edit',
-                    '',
-                    array(
-                        'data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite())
-                    )
-                );
-                break;
-            case self::CMS_PAGE_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\UrlRedirect\Block\Cms\Page\Edit',
-                    '',
-                    array(
-                        'data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite())
-                    )
-                );
-                break;
-            case self::ID_MODE:
-            default:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\UrlRedirect\Block\Edit',
-                    '',
-                    array('data' => array('url_rewrite' => $this->_getUrlRewrite()))
-                );
-                break;
-        }
-
-        $this->_addContent($editBlock);
-        if (in_array($mode, array(self::PRODUCT_MODE, self::CATEGORY_MODE))) {
-            $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get current mode
-     *
-     * @return string
-     */
-    private function _getMode()
-    {
-        if ($this->_getProduct()->getId() || $this->getRequest()->has('product')) {
-            $mode = self::PRODUCT_MODE;
-        } elseif ($this->_getCategory()->getId() || $this->getRequest()->has('category')) {
-            $mode = self::CATEGORY_MODE;
-        } elseif ($this->_getCmsPage()->getId() || $this->getRequest()->has('cms_page')) {
-            $mode = self::CMS_PAGE_MODE;
-        } elseif ($this->getRequest()->has('id')) {
-            $mode = self::ID_MODE;
-        } else {
-            $mode = $this->_objectManager->get('Magento\UrlRedirect\Block\Selector')->getDefaultMode();
-        }
-        return $mode;
-    }
-
-    /**
-     * Ajax products grid action
-     *
-     * @return void
-     */
-    public function productGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\UrlRedirect\Block\Catalog\Product\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * Ajax categories tree loader action
-     *
-     * @return void
-     */
-    public function categoriesJsonAction()
-    {
-        $categoryId = $this->getRequest()->getParam('id', null);
-        $this->getResponse()->setBody(
-            $this->_objectManager->get(
-                'Magento\UrlRedirect\Block\Catalog\Category\Tree'
-            )->getTreeArray(
-                $categoryId,
-                true,
-                1
-            )
-        );
-    }
-
-    /**
-     * Ajax CMS pages grid action
-     *
-     * @return void
-     */
-    public function cmsPageGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\UrlRedirect\Block\Cms\Page\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * Urlrewrite save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        if ($data = $this->getRequest()->getPost()) {
-            /** @var $session \Magento\Backend\Model\Session */
-            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-            try {
-                /** @var $model \Magento\UrlRedirect\Model\UrlRedirect */
-                $model = $this->_getUrlRewrite();
-
-                $requestPath = $this->getRequest()->getParam('request_path');
-                $this->_objectManager->get('Magento\UrlRedirect\Helper\UrlRewrite')->validateRequestPath($requestPath);
-
-                $model->setEntityType($this->getRequest()->getParam('entity_type', self::ENTITY_TYPE_CUSTOM))
-                    ->setStoreId($this->getRequest()->getParam('store_id', 0))
-                    ->setTargetPath($this->getRequest()->getParam('target_path'))
-                    ->setRedirectType($this->getRequest()->getParam('redirect_type'))
-                    ->setDescription($this->getRequest()->getParam('description'))
-                    ->setRequestPath($requestPath);
-
-                $this->_onUrlRewriteSaveBefore($model);
-
-                $model->save();
-
-                $this->messageManager->addSuccess(__('The URL Rewrite has been saved.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $session->setUrlrewriteData($data);
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.'));
-                $session->setUrlrewriteData($data);
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
-    /**
-     * Call before save urlrewrite handlers
-     *
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $model
-     * @return void
-     */
-    protected function _onUrlRewriteSaveBefore($model)
-    {
-        $this->_handleCatalogUrlRewrite($model);
-        $this->_handleCmsPageUrlRewrite($model);
-    }
-
-    /**
-     * Override urlrewrite data, basing on current category and product
-     *
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $model
-     * @return void
-     * @throws Exception
-     */
-    protected function _handleCatalogUrlRewrite($model)
-    {
-        $product = $this->_getInitializedProduct($model);
-        $category = $this->_getInitializedCategory($model);
-
-        if ($product || $category) {
-            /** @var $catalogUrlModel \Magento\Catalog\Model\Url */
-            $catalogUrlModel = $this->_objectManager->get('Magento\Catalog\Model\Url');
-            $model->setTargetPath($catalogUrlModel->generatePath('target', $product, $category));
-            $model->setEntityType(
-                $product && $product->getId() ? self::ENTITY_TYPE_PRODUCT : self::ENTITY_TYPE_CATEGORY
-            );
-            $model->setEntityId($product && $product->getId() ? $product->getId() : $category->getId());
-        }
-    }
-
-    /**
-     * Get product instance applicable for generatePath
-     *
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $model
-     * @return Product|null
-     */
-    private function _getInitializedProduct($model)
-    {
-        /** @var $product Product */
-        $product = $this->_getProduct();
-        if ($product->getId()) {
-            $model->setProductId($product->getId());
-        } else {
-            $product = null;
-        }
-
-        return $product;
-    }
-
-    /**
-     * Get category instance applicable for generatePath
-     *
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $model
-     * @return Category|null
-     */
-    private function _getInitializedCategory($model)
-    {
-        /** @var $category Category */
-        $category = $this->_getCategory();
-        if ($category->getId()) {
-            $model->setCategoryId($category->getId());
-        } else {
-            $category = null;
-        }
-        return $category;
-    }
-
-    /**
-     * Override URL rewrite data, basing on current CMS page
-     *
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $model
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    private function _handleCmsPageUrlRewrite($model)
-    {
-        /** @var $cmsPage \Magento\Cms\Model\Page */
-        $cmsPage = $this->_getCmsPage();
-        if (!$cmsPage->getId()) {
-            return;
-        }
-
-        /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsPageUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
-
-        $model->setTargetPath($cmsPageUrlRewrite->generateTargetPath($cmsPage));
-        $model->setEntityType(self::ENTITY_TYPE_CMS_PAGE);
-        $model->setEntityId($cmsPage->getId());
-    }
-
-    /**
-     * URL rewrite delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        if ($this->_getUrlRewrite()->getId()) {
-            try {
-                $this->_getUrlRewrite()->delete();
-                $this->messageManager->addSuccess(__('The URL Rewrite has been deleted.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while deleting URL Rewrite.'));
-                $this->_redirect('adminhtml/*/edit/', array('id' => $this->_getUrlRewrite()->getId()));
-                return;
-            }
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Check whether this contoller is allowed in admin permissions
-     *
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_UrlRedirect::urlrewrite');
-    }
-
-    /**
-     * Get Category from request
-     *
-     * @return Category
-     */
-    private function _getCategory()
-    {
-        if (!$this->_category) {
-            $this->_category = $this->_objectManager->create('Magento\Catalog\Model\Category');
-            $categoryId = (int)$this->getRequest()->getParam('category', 0);
-
-            if (!$categoryId && $this->_getUrlRewrite()->getId()
-                && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_CATEGORY
-            ) {
-                $categoryId = $this->_getUrlRewrite()->getEntityId();
-            }
-
-            if ($categoryId) {
-                $this->_category->load($categoryId);
-            }
-        }
-        return $this->_category;
-    }
-
-    /**
-     * Get Product from request
-     *
-     * @return Product
-     */
-    private function _getProduct()
-    {
-        if (!$this->_product) {
-            $this->_product = $this->_objectManager->create('Magento\Catalog\Model\Product');
-            $productId = (int)$this->getRequest()->getParam('product', 0);
-
-            if (!$productId && $this->_getUrlRewrite()->getId()
-                && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_PRODUCT
-            ) {
-                $productId = $this->_getUrlRewrite()->getEntityId();
-            }
-
-            if ($productId) {
-                $this->_product->load($productId);
-            }
-        }
-        return $this->_product;
-    }
-
-    /**
-     * Get CMS page from request
-     *
-     * @return \Magento\Cms\Model\Page
-     */
-    private function _getCmsPage()
-    {
-        if (!$this->_cmsPage) {
-            $this->_cmsPage = $this->_objectManager->create('Magento\Cms\Model\Page');
-            $cmsPageId = (int)$this->getRequest()->getParam('cms_page', 0);
-
-            if (!$cmsPageId && $this->_getUrlRewrite()->getId()
-                && $this->_getUrlRewrite()->getEntityType() === self::ENTITY_TYPE_CMS_PAGE
-            ) {
-                $cmsPageId = $this->_getUrlRewrite()->getEntityId();
-            }
-
-            if ($cmsPageId) {
-                $this->_cmsPage->load($cmsPageId);
-            }
-        }
-        return $this->_cmsPage;
-    }
-
-    /**
-     * Get URL rewrite from request
-     *
-     * @return \Magento\UrlRedirect\Model\UrlRedirect
-     */
-    private function _getUrlRewrite()
-    {
-        if (!$this->_urlRewrite) {
-            $this->_urlRewrite = $this->_objectManager->create('Magento\UrlRedirect\Model\UrlRedirect');
-
-            $urlRewriteId = (int)$this->getRequest()->getParam('id', 0);
-            if ($urlRewriteId) {
-                $this->_urlRewrite->load((int)$this->getRequest()->getParam('id', 0));
-            }
-        }
-        return $this->_urlRewrite;
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Controller/Router.php b/app/code/Magento/UrlRedirect/Controller/Router.php
deleted file mode 100644
index 2407898978e..00000000000
--- a/app/code/Magento/UrlRedirect/Controller/Router.php
+++ /dev/null
@@ -1,94 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Controller;
-
-/**
- * UrlRedirect Controller Router
- */
-class Router implements \Magento\Framework\App\RouterInterface
-{
-    /** @var \Magento\Framework\StoreManagerInterface */
-    protected $storeManager;
-
-    /** @var \Magento\Framework\App\ResponseInterface */
-    protected $response;
-
-    /** @var \Magento\UrlRedirect\Service\V1\UrlMatcherInterface */
-    protected $urlMatcher;
-
-    /**
-     * @var \Magento\Framework\App\ActionFactory
-     */
-    protected $actionFactory;
-
-    /**
-     * @param \Magento\Framework\App\ActionFactory $actionFactory
-     * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\App\ResponseInterface $response
-     * @param \Magento\UrlRedirect\Service\V1\UrlMatcherInterface $urlMatcher
-     */
-    public function __construct(
-        \Magento\Framework\App\ActionFactory $actionFactory,
-        \Magento\Framework\StoreManagerInterface $storeManager,
-        \Magento\Framework\App\ResponseInterface $response,
-        \Magento\UrlRedirect\Service\V1\UrlMatcherInterface $urlMatcher
-    ) {
-        $this->actionFactory = $actionFactory;
-        $this->storeManager = $storeManager;
-        $this->response = $response;
-        $this->urlMatcher = $urlMatcher;
-    }
-
-    /**
-     * Validate and Match Cms Page and modify request
-     *
-     * @param \Magento\Framework\App\RequestInterface $request
-     * @return mixed
-     */
-    public function match(\Magento\Framework\App\RequestInterface $request)
-    {
-        $identifier = trim($request->getPathInfo(), '/');
-        $urlRewrite = $this->urlMatcher->match($identifier, $this->storeManager->getStore()->getId());
-        if ($urlRewrite === null) {
-            return null;
-        }
-
-        $redirectType = $urlRewrite->getRedirectType();
-        if ($redirectType) {
-            $redirectCode = $redirectType == \Magento\UrlRedirect\Model\OptionProvider::PERMANENT ? 301 : 302;
-            $this->response->setRedirect($urlRewrite->getTargetPath(), $redirectCode);
-            $request->setDispatched(true);
-            return $this->actionFactory->createController(
-                'Magento\Framework\App\Action\Redirect',
-                array('request' => $request)
-            );
-        }
-
-        $request->setPathInfo('/' . $urlRewrite->getTargetPath());
-        return $this->actionFactory->createController(
-            'Magento\Framework\App\Action\Forward',
-            array('request' => $request)
-        );
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php b/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php
deleted file mode 100644
index 806219890e7..00000000000
--- a/app/code/Magento/UrlRedirect/Helper/UrlRewrite.php
+++ /dev/null
@@ -1,95 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Helper;
-
-class UrlRewrite extends \Magento\Framework\App\Helper\AbstractHelper
-{
-    /**
-     * Validation error constants
-     */
-    const VERR_MANYSLASHES = 1;
-
-    // Too many slashes in a row of request path, e.g. '///foo//'
-    const VERR_ANCHOR = 2;
-
-    // Anchor is not supported in request path, e.g. 'foo#bar'
-
-    /**
-     * @var \Magento\UrlRedirect\Model\OptionProvider
-     */
-    protected $_urlrewrite;
-
-    /**
-     * @param \Magento\Framework\App\Helper\Context $context
-     * @param \Magento\UrlRedirect\Model\OptionProvider $urlrewrite
-     */
-    public function __construct(
-        \Magento\Framework\App\Helper\Context $context,
-        \Magento\UrlRedirect\Model\OptionProvider $urlrewrite
-    ) {
-        parent::__construct($context);
-        $this->_urlrewrite = $urlrewrite;
-    }
-
-    /**
-     * Core func to validate request path
-     * If something is wrong with a path it throws localized error message and error code,
-     * that can be checked to by wrapper func to alternate error message
-     *
-     * @param string $requestPath
-     * @return bool
-     * @throws \Exception
-     */
-    protected function _validateRequestPath($requestPath)
-    {
-        if (strpos($requestPath, '//') !== false) {
-            throw new \Exception(
-                __('Two and more slashes together are not permitted in request path'),
-                self::VERR_MANYSLASHES
-            );
-        }
-        if (strpos($requestPath, '#') !== false) {
-            throw new \Exception(__('Anchor symbol (#) is not supported in request path'), self::VERR_ANCHOR);
-        }
-        return true;
-    }
-
-    /**
-     * Validates request path
-     * Either returns TRUE (success) or throws error (validation failed)
-     *
-     * @param string $requestPath
-     * @throws \Magento\Framework\Model\Exception
-     * @return bool
-     */
-    public function validateRequestPath($requestPath)
-    {
-        try {
-            $this->_validateRequestPath($requestPath);
-        } catch (\Exception $e) {
-            throw new \Magento\Framework\Model\Exception($e->getMessage());
-        }
-        return true;
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php b/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php
deleted file mode 100644
index f19d49ef955..00000000000
--- a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
- * URL rewrite resource model
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Model\Resource;
-
-class UrlRedirect extends \Magento\Framework\Model\Resource\Db\AbstractDb
-{
-    /**
-     * Define main table
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('url_rewrite', 'url_rewrite_id');
-    }
-
-    /**
-     * Initialize array fields
-     *
-     * @return $this
-     */
-    protected function _initUniqueFields()
-    {
-        $this->_uniqueFields = array(
-            array('field' => array('request_path', 'store_id'), 'title' => __('Request Path for Specified Store'))
-        );
-        return $this;
-    }
-
-    /**
-     * Retrieve select object for load object data
-     *
-     * @param string $field
-     * @param mixed $value
-     * @param \Magento\UrlRedirect\Model\UrlRedirect $object
-     * @return \Zend_Db_Select
-     */
-    protected function _getLoadSelect($field, $value, $object)
-    {
-        /** @var $select \Magento\Framework\DB\Select */
-        $select = parent::_getLoadSelect($field, $value, $object);
-
-        if (!is_null($object->getStoreId())) {
-            $select->where(
-                'store_id IN(?)',
-                array(\Magento\Store\Model\Store::DEFAULT_STORE_ID, $object->getStoreId())
-            );
-            $select->order('store_id ' . \Magento\Framework\DB\Select::SQL_DESC);
-            $select->limit(1);
-        }
-
-        return $select;
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Model/Storage/Db.php b/app/code/Magento/UrlRedirect/Model/Storage/Db.php
deleted file mode 100644
index 0a477302d77..00000000000
--- a/app/code/Magento/UrlRedirect/Model/Storage/Db.php
+++ /dev/null
@@ -1,104 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Model\Storage;
-
-use Magento\Framework\App\Resource;
-use Magento\UrlRedirect\Service\V1\Data\Converter;
-use Magento\UrlRedirect\Service\V1\Data\Filter;
-
-/**
- * Db storage
- */
-class Db extends AbstractStorage
-{
-    /**
-     * DB Storage table name
-     */
-    const TABLE_NAME = 'url_rewrite';
-
-    /**
-     * @var \Magento\Framework\DB\Adapter\AdapterInterface
-     */
-    protected $connection;
-
-    /**
-     * @param Converter $converter
-     * @param Resource $resource
-     */
-    public function __construct(Converter $converter, Resource $resource)
-    {
-        $this->connection = $resource->getConnection(Resource::DEFAULT_WRITE_RESOURCE);
-
-        parent::__construct($converter);
-    }
-
-    /**
-     * Prepare select statement for specific filter
-     *
-     * @param Filter $filter
-     * @return \Magento\Framework\DB\Select
-     */
-    protected function prepareSelect($filter)
-    {
-        $select = $this->connection->select();
-        $select->from(self::TABLE_NAME);
-
-        foreach ($filter->getFilter() as $column => $value) {
-            $select->where($this->connection->quoteIdentifier($column) . ' IN (?)', $value);
-        }
-        return $select;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function doFindAllByFilter($filter)
-    {
-        return $this->connection->fetchAll($this->prepareSelect($filter));
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function doFindByFilter($filter)
-    {
-        return $this->connection->fetchRow($this->prepareSelect($filter));
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function doAddMultiple($data)
-    {
-        $this->connection->insertMultiple(self::TABLE_NAME, $data);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function deleteByFilter(Filter $filter)
-    {
-        $this->connection->query($this->prepareSelect($filter)->deleteFromSelect(self::TABLE_NAME));
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php b/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php
deleted file mode 100644
index f2fc91a18a3..00000000000
--- a/app/code/Magento/UrlRedirect/Service/V1/Data/Filter.php
+++ /dev/null
@@ -1,138 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Service\V1\Data;
-
-/**
- * Url rewrite search filter
- */
-class Filter
-{
-    /**
-     * Data with filter values
-     *
-     * @var array
-     */
-    protected $data = [];
-
-    /**
-     * Possible fields for filter
-     *
-     * @var array
-     */
-    protected $possibleFields = [
-        UrlRewrite::ENTITY_ID,
-        UrlRewrite::ENTITY_TYPE,
-        UrlRewrite::STORE_ID,
-        UrlRewrite::REQUEST_PATH,
-        UrlRewrite::REDIRECT_TYPE,
-    ];
-
-    /**
-     * Filter constructor
-     *
-     * @param array $filterData
-     * @throws \InvalidArgumentException
-     */
-    public function __construct(array $filterData = [])
-    {
-        if ($filterData) {
-            if ($wrongFields = array_diff(array_keys($filterData), $this->possibleFields)) {
-                throw new \InvalidArgumentException(
-                    sprintf('There is wrong fields passed to filter: "%s"', implode(', ', $wrongFields))
-                );
-            }
-            $this->data = $filterData;
-        }
-        return $this;
-    }
-
-    /**
-     * @param string $key
-     * @param mixed $value
-     * @return $this
-     */
-    protected function _set($key, $value)
-    {
-        $this->data[$key] = $value;
-        return $this;
-    }
-
-    /**
-     * @return array
-     */
-    public function getFilter()
-    {
-        return $this->data;
-    }
-
-    /**
-     * @param int $entityId
-     *
-     * @return $this
-     */
-    public function setEntityId($entityId)
-    {
-        return $this->_set(UrlRewrite::ENTITY_ID, $entityId);
-    }
-
-    /**
-     * @param int|array $entityType
-     *
-     * @return $this
-     */
-    public function setEntityType($entityType)
-    {
-        return $this->_set(UrlRewrite::ENTITY_TYPE, $entityType);
-    }
-
-    /**
-     * @param string $requestPath
-     *
-     * @return $this
-     */
-    public function setRequestPath($requestPath)
-    {
-        return $this->_set(UrlRewrite::REQUEST_PATH, $requestPath);
-    }
-
-    /**
-     * @param int $storeId
-     *
-     * @return $this
-     */
-    public function setStoreId($storeId)
-    {
-        return $this->_set(UrlRewrite::STORE_ID, $storeId);
-    }
-
-    /**
-     * @param string|array $redirectType
-     *
-     * @return $this
-     */
-    public function setRedirectType($redirectType)
-    {
-        return $this->_set(UrlRewrite::REDIRECT_TYPE, $redirectType);
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php b/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php
deleted file mode 100644
index 0e29a14db25..00000000000
--- a/app/code/Magento/UrlRedirect/Service/V1/UrlManager.php
+++ /dev/null
@@ -1,127 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Service\V1;
-
-use Magento\UrlRedirect\Service\V1\Data\Filter;
-use Magento\UrlRedirect\Service\V1\Data\FilterFactory;
-use Magento\UrlRedirect\Service\V1\Data\UrlRewrite;
-use Magento\UrlRedirect\Model\StorageInterface;
-
-/**
- * Url Manager
- */
-class UrlManager implements UrlMatcherInterface, UrlSaveInterface
-{
-    /**
-     * @var StorageInterface
-     */
-    protected $storage;
-
-    /**
-     * @var FilterFactory
-     */
-    protected $filterFactory;
-
-    /**
-     * @param StorageInterface $storage
-     * @param FilterFactory $filterFactory
-     */
-    public function __construct(StorageInterface $storage, FilterFactory $filterFactory)
-    {
-        $this->storage = $storage;
-        $this->filterFactory = $filterFactory;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function save(array $urls)
-    {
-        $this->storage->deleteByFilter($this->createFilter($urls));
-
-        $this->storage->addMultiple($urls);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function match($requestPath, $storeId)
-    {
-        /** @var Filter $filter */
-        $filter = $this->filterFactory->create();
-        $filter->setRequestPath($requestPath)->setStoreId($storeId);
-
-        return $this->findByFilter($filter);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function findByEntity($entityId, $entityType, $storeId = 0)
-    {
-        /** @var Filter $filter */
-        $filter = $this->filterFactory->create();
-        $filter->setEntityId($entityId)->setEntityType($entityType)->setStoreId($storeId);
-
-        return $this->findByFilter($filter);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function findByFilter(Filter $filter)
-    {
-        return $this->storage->findByFilter($filter);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function findAllByFilter(Filter $filter)
-    {
-        return $this->storage->findAllByFilter($filter);
-    }
-
-    /**
-     * Get filter for url rows deletion due to provided urls
-     *
-     * @param UrlRewrite[] $urls
-     * @return Filter
-     */
-    protected function createFilter($urls)
-    {
-        $filterData = [];
-        $uniqueKeys = [UrlRewrite::ENTITY_ID, UrlRewrite::ENTITY_TYPE, UrlRewrite::STORE_ID];
-        foreach ($urls as $url) {
-            foreach ($uniqueKeys as $key) {
-                $fieldValue = $url->getByKey($key);
-
-                if (!isset($filterData[$key]) || !in_array($fieldValue, $filterData[$key])) {
-                    $filterData[$key][] = $fieldValue;
-                }
-            }
-        }
-        return $this->filterFactory->create(['filterData' => $filterData]);
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php b/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php
deleted file mode 100644
index 2ebc555c694..00000000000
--- a/app/code/Magento/UrlRedirect/Service/V1/UrlMatcherInterface.php
+++ /dev/null
@@ -1,67 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRedirect\Service\V1;
-
-use Magento\UrlRedirect\Service\V1\Data\Filter;
-
-/**
- * Url Matcher Interface
- */
-interface UrlMatcherInterface
-{
-    /**
-     * Match provided request path for store and if matched - return corresponding Data Object
-     *
-     * @param string $requestPath
-     * @param int $storeId
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null
-     */
-    public function match($requestPath, $storeId);
-
-    /**
-     * Match provided entity for store and if matched - return corresponding Data Object
-     *
-     * @param int $entityId
-     * @param int $entityType
-     * @param int $storeId
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null
-     */
-    public function findByEntity($entityId, $entityType, $storeId);
-
-    /**
-     * Find row by specific filter
-     *
-     * @param Filter $filter
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite|null
-     */
-    public function findByFilter(Filter $filter);
-
-    /**
-     * Find rows by specific filter
-     *
-     * @param Filter $filter
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
-     */
-    public function findAllByFilter(Filter $filter);
-}
diff --git a/app/code/Magento/UrlRedirect/composer.json b/app/code/Magento/UrlRedirect/composer.json
deleted file mode 100644
index 97c616314a1..00000000000
--- a/app/code/Magento/UrlRedirect/composer.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "name": "magento/module-url-redirect",
-    "description": "N/A",
-    "require": {
-        "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
-        "magento/magento-composer-installer": "*"
-    },
-    "type": "magento2-module",
-    "version": "0.1.0-alpha96",
-    "extra": {
-        "map": [
-            [
-                "*",
-                "Magento/UrlRedirect"
-            ]
-        ]
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/i18n/de_DE.csv b/app/code/Magento/UrlRedirect/i18n/de_DE.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/de_DE.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/en_US.csv b/app/code/Magento/UrlRedirect/i18n/en_US.csv
deleted file mode 100644
index 2d0c4e9330a..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/en_US.csv
+++ /dev/null
@@ -1,62 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/es_ES.csv b/app/code/Magento/UrlRedirect/i18n/es_ES.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/es_ES.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/fr_FR.csv b/app/code/Magento/UrlRedirect/i18n/fr_FR.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/fr_FR.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/nl_NL.csv b/app/code/Magento/UrlRedirect/i18n/nl_NL.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/nl_NL.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/pt_BR.csv b/app/code/Magento/UrlRedirect/i18n/pt_BR.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/pt_BR.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/i18n/zh_CN.csv b/app/code/Magento/UrlRedirect/i18n/zh_CN.csv
deleted file mode 100644
index 8b6c4909ac3..00000000000
--- a/app/code/Magento/UrlRedirect/i18n/zh_CN.csv
+++ /dev/null
@@ -1,57 +0,0 @@
-Custom,Custom
-Back,Back
-ID,ID
-SKU,SKU
-No,No
-Action,Action
-Reset,Reset
-Edit,Edit
-"Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
-"Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Request Path for Specified Store","Request Path for Specified Store"
-"Temporary (302)","Temporary (302)"
-"Permanent (301)","Permanent (301)"
-"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
-"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
-"Category:","Category:"
-"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
-"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
-"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
-"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
-"Product:","Product:"
-"Skip Category Selection","Skip Category Selection"
-"Name","Name"
-"Status","Status"
-"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
-"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
-"CMS page:","CMS page:"
-"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
-"Title","Title"
-"URL Key","URL Key"
-"Store View","Store View"
-"Edit URL Rewrite","Edit URL Rewrite"
-"Add New URL Rewrite","Add New URL Rewrite"
-"Delete","Delete"
-"Are you sure you want to do this?","Are you sure you want to do this?"
-"Save","Save"
-"Block Information","Block Information"
-"URL Rewrite Information","URL Rewrite Information"
-"Request Path","Request Path"
-"Target Path","Target Path"
-"Redirect","Redirect"
-"Description","Description"
-"Store","Store"
-"URL Rewrite Management","URL Rewrite Management"
-"Add URL Rewrite","Add URL Rewrite"
-"For category","For category"
-"For product","For product"
-"For CMS page","For CMS page"
-"Create URL Rewrite:","Create URL Rewrite:"
-"URL Rewrites","URL Rewrites"
-"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
-"The URL Rewrite has been saved.","The URL Rewrite has been saved."
-"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
-"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
-"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
-"Select Category","Select Category"
-"Options","Options"
diff --git a/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php b/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php
deleted file mode 100644
index 26f675220af..00000000000
--- a/app/code/Magento/UrlRedirect/sql/urlredirect_setup/install-1.0.0.0.php
+++ /dev/null
@@ -1,109 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/* @var $installer \Magento\Core\Model\Resource\Setup */
-$installer = $this;
-
-$installer->startSetup();
-
-/**
- * Create table 'url_rewrite'
- */
-$table = $installer->getConnection()->newTable(
-    $installer->getTable('url_rewrite')
-)->addColumn(
-    'url_rewrite_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-    null,
-    array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
-    'Redirect Id'
-)->addColumn(
-    'entity_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
-    null,
-    array('unsigned' => true, 'nullable' => false),
-    'Entity ID'
-)->addColumn(
-    'entity_type',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    32,
-    array('nullable' => false),
-    'Entity type code'
-)->addColumn(
-    'request_path',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    255,
-    array(),
-    'Request Path'
-)->addColumn(
-    'target_path',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    255,
-    array(),
-    'Target Path'
-)->addColumn(
-    'redirect_type',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    2,
-    array('nullable' => true),
-    'Redirect Type'
-)->addColumn(
-    'store_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
-    null,
-    array('unsigned' => true, 'nullable' => false, 'default' => '0'),
-    'Store Id'
-)->addColumn(
-    'description',
-    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    255,
-    array(),
-    'Description'
-)->addIndex(
-    $installer->getIdxName(
-        'url_rewrite',
-        array('request_path', 'store_id'),
-        \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
-    ),
-    array('request_path', 'store_id'),
-    array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE)
-)->addIndex(
-    $installer->getIdxName('url_rewrite', array('target_path', 'store_id')),
-    array('target_path', 'store_id')
-)->addIndex(
-    $installer->getIdxName('url_rewrite', array('store_id')),
-    array('store_id')
-)->addForeignKey(
-    $installer->getFkName('url_rewrite', 'store_id', 'store', 'store_id'),
-    'store_id',
-    $installer->getTable('store'),
-    'store_id',
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
-)->setComment(
-    'Url Rewrites'
-);
-$installer->getConnection()->createTable($table);
-
-$installer->endSetup();
diff --git a/app/code/Magento/UrlRewrite/App/Request/RewriteService.php b/app/code/Magento/UrlRewrite/App/Request/RewriteService.php
deleted file mode 100644
index 71ddf252f43..00000000000
--- a/app/code/Magento/UrlRewrite/App/Request/RewriteService.php
+++ /dev/null
@@ -1,75 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\App\Request;
-
-class RewriteService
-{
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
-     */
-    protected $_rewriteFactory;
-
-    /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $_config;
-
-    /**
-     * @var \Magento\Framework\App\RouterList
-     */
-    protected $_routerList;
-
-    /**
-     * @param \Magento\Framework\App\RouterList $routerList
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
-     */
-    public function __construct(
-        \Magento\Framework\App\RouterList $routerList,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
-        \Magento\Framework\App\Config\ScopeConfigInterface $config
-    ) {
-        $this->_rewriteFactory = $rewriteFactory;
-        $this->_config = $config;
-        $this->_routerList = $routerList;
-    }
-
-    /**
-     * Apply rewrites to current request
-     *
-     * @param \Magento\Framework\App\RequestInterface $request
-     * @return void
-     */
-    public function applyRewrites(\Magento\Framework\App\RequestInterface $request)
-    {
-        // URL rewrite
-        if (!$request->isStraight()) {
-            \Magento\Framework\Profiler::start('db_url_rewrite');
-            /** @var $urlRewrite \Magento\UrlRewrite\Model\UrlRewrite */
-            $urlRewrite = $this->_rewriteFactory->create();
-            $urlRewrite->rewrite($request);
-            \Magento\Framework\Profiler::stop('db_url_rewrite');
-        }
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php b/app/code/Magento/UrlRewrite/Block/Catalog/Category/Edit.php
similarity index 83%
rename from app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php
rename to app/code/Magento/UrlRewrite/Block/Catalog/Category/Edit.php
index a0316d07eaf..7f77459dec3 100644
--- a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Edit.php
+++ b/app/code/Magento/UrlRewrite/Block/Catalog/Category/Edit.php
@@ -21,12 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Catalog\Category;
+namespace Magento\UrlRewrite\Block\Catalog\Category;
 
 /**
  * Block for Catalog Category URL rewrites
  */
-class Edit extends \Magento\UrlRedirect\Block\Edit
+class Edit extends \Magento\UrlRewrite\Block\Edit
 {
     /**
      * @var \Magento\Catalog\Model\CategoryFactory
@@ -35,14 +35,14 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
         array $data = array()
@@ -67,7 +67,9 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
         if ($this->_getCategory()->getId()) {
             $this->_addCategoryLinkBlock();
             $this->_addEditFormBlock();
-            $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'category');
+            if ($this->_getUrlRewrite()->getId() === null) {
+                $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'category');
+            }
         } else {
             $this->_addUrlRewriteSelectorBlock();
             $this->_addCategoryTreeBlock();
@@ -96,7 +98,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
     {
         $this->addChild(
             'category_link',
-            'Magento\UrlRedirect\Block\Link',
+            'Magento\UrlRewrite\Block\Link',
             array(
                 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'category',
                 'item_name' => $this->_getCategory()->getName(),
@@ -112,18 +114,18 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
      */
     private function _addCategoryTreeBlock()
     {
-        $this->addChild('categories_tree', 'Magento\UrlRedirect\Block\Catalog\Category\Tree');
+        $this->addChild('categories_tree', 'Magento\UrlRewrite\Block\Catalog\Category\Tree');
     }
 
     /**
      * Creates edit form block
      *
-     * @return \Magento\UrlRedirect\Block\Catalog\Edit\Form
+     * @return \Magento\UrlRewrite\Block\Catalog\Edit\Form
      */
     protected function _createEditFormBlock()
     {
         return $this->getLayout()->createBlock(
-            'Magento\UrlRedirect\Block\Catalog\Edit\Form',
+            'Magento\UrlRewrite\Block\Catalog\Edit\Form',
             '',
             array('data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite()))
         );
diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php b/app/code/Magento/UrlRewrite/Block/Catalog/Category/Tree.php
similarity index 95%
rename from app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php
rename to app/code/Magento/UrlRewrite/Block/Catalog/Category/Tree.php
index 40328487999..a0eb8b4fd22 100644
--- a/app/code/Magento/UrlRedirect/Block/Catalog/Category/Tree.php
+++ b/app/code/Magento/UrlRewrite/Block/Catalog/Category/Tree.php
@@ -21,7 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Catalog\Category;
+namespace Magento\UrlRewrite\Block\Catalog\Category;
+
+use Magento\Catalog\Model\Category;
 
 /**
  * Categories tree block for URL rewrites editing process
@@ -33,9 +35,9 @@ class Tree extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
     /**
      * List of allowed category ids
      *
-     * @var int[]|null
+     * @var []
      */
-    protected $_allowedCategoryIds = null;
+    protected $_allowedCategoryIds = [];
 
     /**
      * @var string
@@ -125,7 +127,7 @@ class Tree extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
             return $this->_jsonEncoder->encode($result);
         }
 
-        $this->_allowedCategoryIds = null;
+        $this->_allowedCategoryIds = [];
 
         return $result;
     }
@@ -168,7 +170,7 @@ class Tree extends \Magento\Catalog\Block\Adminhtml\Category\AbstractCategory
             'product_count' => (int)$node->getProductCount()
         );
 
-        if (is_array($this->_allowedCategoryIds) && !in_array($result['id'], $this->_allowedCategoryIds)) {
+        if ($node->getParentId() == Category::TREE_ROOT_ID && !in_array($result['id'], $this->_allowedCategoryIds)) {
             $result['disabled'] = true;
         }
 
diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php b/app/code/Magento/UrlRewrite/Block/Catalog/Edit/Form.php
similarity index 72%
rename from app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php
rename to app/code/Magento/UrlRewrite/Block/Catalog/Edit/Form.php
index 450beaea8d4..dc3c71545c3 100644
--- a/app/code/Magento/UrlRedirect/Block/Catalog/Edit/Form.php
+++ b/app/code/Magento/UrlRewrite/Block/Catalog/Edit/Form.php
@@ -25,21 +25,16 @@
 /**
  * Edit form for Catalog product and category URL rewrites
  */
-namespace Magento\UrlRedirect\Block\Catalog\Edit;
+namespace Magento\UrlRewrite\Block\Catalog\Edit;
 
-use Magento\UrlRedirect\Controller\Adminhtml\UrlRedirect;
+use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
 /**
  * @SuppressWarnings(PHPMD.DepthOfInheritance)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Form extends \Magento\UrlRedirect\Block\Edit\Form
+class Form extends \Magento\UrlRewrite\Block\Edit\Form
 {
-    /**
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_catalogUrl;
-
     /**
      * @var \Magento\Catalog\Model\ProductFactory
      */
@@ -50,17 +45,24 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
      */
     protected $_categoryFactory;
 
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\OptionProvider $optionProvider
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Store\Model\System\Store $systemStore
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\Catalog\Model\Url $catalogUrl
+     * @param \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -69,23 +71,25 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
         \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\OptionProvider $optionProvider,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Store\Model\System\Store $systemStore,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\Catalog\Model\Url $catalogUrl,
+        \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
         array $data = array()
     ) {
         $this->_productFactory = $productFactory;
         $this->_categoryFactory = $categoryFactory;
-        $this->_catalogUrl = $catalogUrl;
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
         parent::__construct(
             $context,
             $registry,
             $formFactory,
-            $optionFactory,
+            $optionProvider,
             $rewriteFactory,
             $systemStore,
             $adminhtmlData,
@@ -124,23 +128,23 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
             $category = null;
             if ($this->_getProduct()->getId()) {
                 $product = $this->_getProduct();
-                $category = $this->_getCategory();
-            } elseif ($this->_getCategory()->getId()) {
+            }
+            if ($this->_getCategory()->getId()) {
                 $category = $this->_getCategory();
             }
 
             if ($product || $category) {
                 $sessionData = $this->_getSessionData();
                 if (!isset($sessionData['request_path'])) {
-                    $requestPath->setValue($this->_catalogUrl->generatePath('request', $product, $category, ''));
+                    $requestPath->setValue($this->getRequestPath($product, $category));
                 }
-                $targetPath->setValue($this->_catalogUrl->generatePath('target', $product, $category));
+                $targetPath->setValue($this->getTargetPath($product, $category));
                 $disablePaths = true;
             }
         } else {
             $disablePaths = in_array(
                 $model->getEntityType(),
-                [UrlRedirect::ENTITY_TYPE_PRODUCT, UrlRedirect::ENTITY_TYPE_CATEGORY, UrlRedirect::ENTITY_TYPE_CMS_PAGE]
+                [Rewrite::ENTITY_TYPE_PRODUCT, Rewrite::ENTITY_TYPE_CATEGORY, Rewrite::ENTITY_TYPE_CMS_PAGE]
             );
         }
 
@@ -151,6 +155,30 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
         return $this;
     }
 
+    /**
+     * @param \Magento\Catalog\Model\Product|null $product
+     * @param \Magento\Catalog\Model\Category|null $category
+     * @return string
+     */
+    protected function getRequestPath($product = null, $category = null)
+    {
+        return $product
+            ? $this->productUrlPathGenerator->getUrlPathWithSuffix($product, $product->getStoreId(), $category)
+            : $this->categoryUrlPathGenerator->getUrlPathWithSuffix($category);
+    }
+
+    /**
+     * @param \Magento\Catalog\Model\Product|null $product
+     * @param \Magento\Catalog\Model\Category|null $category
+     * @return string
+     */
+    protected function getTargetPath($product = null, $category = null)
+    {
+        return $product
+            ? $this->productUrlPathGenerator->getCanonicalUrlPath($product, $category)
+            : $this->categoryUrlPathGenerator->getCanonicalUrlPath($category);
+    }
+
     /**
      * Get catalog entity associated stores
      *
diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php b/app/code/Magento/UrlRewrite/Block/Catalog/Product/Edit.php
similarity index 83%
rename from app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php
rename to app/code/Magento/UrlRewrite/Block/Catalog/Product/Edit.php
index 895f0a45433..5746fea489e 100644
--- a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Edit.php
+++ b/app/code/Magento/UrlRewrite/Block/Catalog/Product/Edit.php
@@ -21,12 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Catalog\Product;
+namespace Magento\UrlRewrite\Block\Catalog\Product;
 
 /**
  * Block for Catalog Category URL rewrites editing
  */
-class Edit extends \Magento\UrlRedirect\Block\Edit
+class Edit extends \Magento\UrlRewrite\Block\Edit
 {
     /**
      * @var \Magento\Catalog\Model\ProductFactory
@@ -40,7 +40,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
@@ -48,7 +48,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
      */
     public function __construct(
         \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
@@ -83,17 +83,19 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
         if ($this->_getProduct()->getId()) {
             if ($this->_getCategory()->getId() || !$this->getIsCategoryMode()) {
                 $this->_addEditFormBlock();
-                $this->_updateBackButtonLink(
-                    $this->_adminhtmlData->getUrl(
-                        'adminhtml/*/edit',
-                        array('product' => $this->_getProduct()->getId())
-                    ) . 'category'
-                );
+                if ($this->_getUrlRewrite()->getId() === null) {
+                    $productId = $this->_getProduct()->getId();
+                    $this->_updateBackButtonLink(
+                        $this->_adminhtmlData->getUrl('adminhtml/*/edit', array('product' => $productId)) . 'category'
+                    );
+                }
             } else {
                 // categories selector & skip categories button
                 $this->_addCategoriesTreeBlock();
                 $this->_addSkipCategoriesBlock();
-                $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'product');
+                if ($this->_getUrlRewrite()->getId() === null) {
+                    $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'product');
+                }
             }
         } else {
             $this->_addUrlRewriteSelectorBlock();
@@ -136,7 +138,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
     {
         $this->addChild(
             'product_link',
-            'Magento\UrlRedirect\Block\Link',
+            'Magento\UrlRewrite\Block\Link',
             array(
                 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'product',
                 'item_name' => $this->_getProduct()->getName(),
@@ -154,7 +156,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
     {
         $this->addChild(
             'category_link',
-            'Magento\UrlRedirect\Block\Link',
+            'Magento\UrlRewrite\Block\Link',
             array(
                 'item_url' => $this->_adminhtmlData->getUrl(
                     'adminhtml/*/*',
@@ -173,7 +175,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
      */
     private function _addProductsGridBlock()
     {
-        $this->addChild('products_grid', 'Magento\UrlRedirect\Block\Catalog\Product\Grid');
+        $this->addChild('products_grid', 'Magento\UrlRewrite\Block\Catalog\Product\Grid');
     }
 
     /**
@@ -183,7 +185,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
      */
     private function _addCategoriesTreeBlock()
     {
-        $this->addChild('categories_tree', 'Magento\UrlRedirect\Block\Catalog\Category\Tree');
+        $this->addChild('categories_tree', 'Magento\UrlRewrite\Block\Catalog\Category\Tree');
     }
 
     /**
@@ -211,12 +213,12 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
     /**
      * Creates edit form block
      *
-     * @return \Magento\UrlRedirect\Block\Catalog\Edit\Form
+     * @return \Magento\UrlRewrite\Block\Catalog\Edit\Form
      */
     protected function _createEditFormBlock()
     {
         return $this->getLayout()->createBlock(
-            'Magento\UrlRedirect\Block\Catalog\Edit\Form',
+            'Magento\UrlRewrite\Block\Catalog\Edit\Form',
             '',
             array(
                 'data' => array(
diff --git a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php b/app/code/Magento/UrlRewrite/Block/Catalog/Product/Grid.php
similarity index 88%
rename from app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php
rename to app/code/Magento/UrlRewrite/Block/Catalog/Product/Grid.php
index ae56598e355..cb7d7daad23 100644
--- a/app/code/Magento/UrlRedirect/Block/Catalog/Product/Grid.php
+++ b/app/code/Magento/UrlRewrite/Block/Catalog/Product/Grid.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Catalog\Product;
+namespace Magento\UrlRewrite\Block\Catalog\Product;
 
 /**
  * Products grid for URL rewrites editing
@@ -47,7 +47,15 @@ class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid
      */
     protected function _prepareColumns()
     {
-        $this->addColumn('entity_id', array('header' => __('ID'), 'width' => 50, 'index' => 'entity_id'));
+        $this->addColumn(
+            'entity_id',
+            array(
+                'header' => __('ID'),
+                'index' => 'entity_id',
+                'header_css_class' => 'col-id',
+                'column_css_class' => 'col-id'
+            )
+        );
 
         $this->addColumn('name', array('header' => __('Name'), 'index' => 'name'));
 
diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php b/app/code/Magento/UrlRewrite/Block/Cms/Page/Edit.php
similarity index 83%
rename from app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php
rename to app/code/Magento/UrlRewrite/Block/Cms/Page/Edit.php
index fe4960b43a9..7616f711c95 100644
--- a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit.php
+++ b/app/code/Magento/UrlRewrite/Block/Cms/Page/Edit.php
@@ -21,12 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Cms\Page;
+namespace Magento\UrlRewrite\Block\Cms\Page;
 
 /**
  * Block for CMS pages URL rewrites
  */
-class Edit extends \Magento\UrlRedirect\Block\Edit
+class Edit extends \Magento\UrlRewrite\Block\Edit
 {
     /**
      * @var \Magento\Cms\Model\PageFactory
@@ -35,14 +35,14 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Cms\Model\PageFactory $pageFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Cms\Model\PageFactory $pageFactory,
         array $data = array()
@@ -67,7 +67,9 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
         if ($this->_getCmsPage()->getId()) {
             $this->_addCmsPageLinkBlock();
             $this->_addEditFormBlock();
-            $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'cms_page');
+            if ($this->_getUrlRewrite()->getId() === null) {
+                $this->_updateBackButtonLink($this->_adminhtmlData->getUrl('adminhtml/*/edit') . 'cms_page');
+            }
         } else {
             $this->_addUrlRewriteSelectorBlock();
             $this->_addCmsPageGridBlock();
@@ -96,7 +98,7 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
     {
         $this->addChild(
             'cms_page_link',
-            'Magento\UrlRedirect\Block\Link',
+            'Magento\UrlRewrite\Block\Link',
             array(
                 'item_url' => $this->_adminhtmlData->getUrl('adminhtml/*/*') . 'cms_page',
                 'item_name' => $this->getCmsPage()->getTitle(),
@@ -112,18 +114,18 @@ class Edit extends \Magento\UrlRedirect\Block\Edit
      */
     private function _addCmsPageGridBlock()
     {
-        $this->addChild('cms_pages_grid', 'Magento\UrlRedirect\Block\Cms\Page\Grid');
+        $this->addChild('cms_pages_grid', 'Magento\UrlRewrite\Block\Cms\Page\Grid');
     }
 
     /**
      * Creates edit form block
      *
-     * @return \Magento\UrlRedirect\Block\Cms\Page\Edit\Form
+     * @return \Magento\UrlRewrite\Block\Cms\Page\Edit\Form
      */
     protected function _createEditFormBlock()
     {
         return $this->getLayout()->createBlock(
-            'Magento\UrlRedirect\Block\Cms\Page\Edit\Form',
+            'Magento\UrlRewrite\Block\Cms\Page\Edit\Form',
             '',
             array('data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite()))
         );
diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php b/app/code/Magento/UrlRewrite/Block/Cms/Page/Edit/Form.php
similarity index 75%
rename from app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php
rename to app/code/Magento/UrlRewrite/Block/Cms/Page/Edit/Form.php
index 6cdc0a33bfc..712408dbae9 100644
--- a/app/code/Magento/UrlRedirect/Block/Cms/Page/Edit/Form.php
+++ b/app/code/Magento/UrlRewrite/Block/Cms/Page/Edit/Form.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Cms\Page\Edit;
+namespace Magento\UrlRewrite\Block\Cms\Page\Edit;
 
 /**
  * Edit form for CMS page URL rewrites
@@ -29,28 +29,26 @@ namespace Magento\UrlRedirect\Block\Cms\Page\Edit;
  * @SuppressWarnings(PHPMD.DepthOfInheritance)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Form extends \Magento\UrlRedirect\Block\Edit\Form
+class Form extends \Magento\UrlRewrite\Block\Edit\Form
 {
     /**
      * @var \Magento\Cms\Model\PageFactory
      */
     protected $_pageFactory;
 
-    /**
-     * @var \Magento\Cms\Model\Page\UrlrewriteFactory
-     */
-    protected $_urlRewriteFactory;
+    /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator */
+    protected $cmsPageUrlPathGenerator;
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\OptionProvider $optionProvider
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Store\Model\System\Store $systemStore
      * @param \Magento\Backend\Helper\Data $adminhtmlData
-     * @param \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory
      * @param \Magento\Cms\Model\PageFactory $pageFactory
+     * @param \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -59,33 +57,33 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
         \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\OptionProvider $optionProvider,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Store\Model\System\Store $systemStore,
         \Magento\Backend\Helper\Data $adminhtmlData,
-        \Magento\Cms\Model\Page\UrlrewriteFactory $urlRewriteFactory,
         \Magento\Cms\Model\PageFactory $pageFactory,
+        \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator,
         array $data = array()
     ) {
-        $this->_urlRewriteFactory = $urlRewriteFactory;
         $this->_pageFactory = $pageFactory;
         parent::__construct(
             $context,
             $registry,
             $formFactory,
-            $optionFactory,
+            $optionProvider,
             $rewriteFactory,
             $systemStore,
             $adminhtmlData,
             $data
         );
+        $this->cmsPageUrlPathGenerator = $cmsPageUrlPathGenerator;
     }
 
     /**
      * Form post init
      *
      * @param \Magento\Framework\Data\Form $form
-     * @return \Magento\UrlRedirect\Block\Cms\Page\Edit\Form
+     * @return \Magento\UrlRewrite\Block\Cms\Page\Edit\Form
      */
     protected function _formPostInit($form)
     {
@@ -104,23 +102,14 @@ class Form extends \Magento\UrlRedirect\Block\Edit\Form
         $targetPath = $this->getForm()->getElement('target_path');
 
         $model = $this->_getModel();
-        /** @var $cmsPageUrlrewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsPageUrlrewrite = $this->_urlRewriteFactory->create();
         if (!$model->getId()) {
             $sessionData = $this->_getSessionData();
             if (!isset($sessionData['request_path'])) {
-                $requestPath->setValue($cmsPageUrlrewrite->generateRequestPath($cmsPage));
+                $requestPath->setValue($this->cmsPageUrlPathGenerator->getUrlPath($cmsPage));
             }
-            $targetPath->setValue($cmsPageUrlrewrite->generateTargetPath($cmsPage));
-            $disablePaths = true;
-        } else {
-            $cmsPageUrlrewrite->load($this->_getModel()->getId(), 'url_rewrite_id');
-            $disablePaths = $cmsPageUrlrewrite->getId() > 0;
+            $targetPath->setValue($this->cmsPageUrlPathGenerator->getCanonicalUrlPath($cmsPage));
         }
-        if ($disablePaths) {
-            $targetPath->setData('disabled', true);
-        }
-
+        $targetPath->setData('disabled', true);
         return $this;
     }
 
diff --git a/app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php b/app/code/Magento/UrlRewrite/Block/Cms/Page/Grid.php
similarity index 98%
rename from app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php
rename to app/code/Magento/UrlRewrite/Block/Cms/Page/Grid.php
index 8cb6ca507ab..07736045c80 100644
--- a/app/code/Magento/UrlRedirect/Block/Cms/Page/Grid.php
+++ b/app/code/Magento/UrlRewrite/Block/Cms/Page/Grid.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Cms\Page;
+namespace Magento\UrlRewrite\Block\Cms\Page;
 
 /**
  * CMS pages grid for URL rewrites
diff --git a/app/code/Magento/UrlRedirect/Block/Edit.php b/app/code/Magento/UrlRewrite/Block/Edit.php
similarity index 87%
rename from app/code/Magento/UrlRedirect/Block/Edit.php
rename to app/code/Magento/UrlRewrite/Block/Edit.php
index deb100ce6ff..24b4d3bdfe3 100644
--- a/app/code/Magento/UrlRedirect/Block/Edit.php
+++ b/app/code/Magento/UrlRewrite/Block/Edit.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block;
+namespace Magento\UrlRewrite\Block;
 
 /**
  * Block for URL rewrites edit page
@@ -29,7 +29,7 @@ namespace Magento\UrlRedirect\Block;
 class Edit extends \Magento\Backend\Block\Widget\Container
 {
     /**
-     * @var \Magento\UrlRedirect\Block\Selector
+     * @var \Magento\UrlRewrite\Block\Selector
      */
     private $_selectorBlock;
 
@@ -38,7 +38,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      *
      * @var string
      */
-    protected $_controller = 'urlredirect';
+    protected $_controller = 'url_rewrite';
 
     /**
      * Generated buttons html cache
@@ -55,19 +55,19 @@ class Edit extends \Magento\Backend\Block\Widget\Container
     protected $_adminhtmlData = null;
 
     /**
-     * @var \Magento\UrlRedirect\Model\UrlRedirectFactory
+     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
      */
     protected $_rewriteFactory;
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         array $data = array()
     ) {
@@ -104,9 +104,6 @@ class Edit extends \Magento\Backend\Block\Widget\Container
             $this->_headerText = __('Add New URL Rewrite');
         }
 
-        $this->_updateBackButtonLink(
-            $this->_adminhtmlData->getUrl('adminhtml/*/edit') . $this->_getSelectorBlock()->getDefaultMode()
-        );
         $this->_addUrlRewriteSelectorBlock();
         $this->_addEditFormBlock();
     }
@@ -135,7 +132,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addResetButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'reset',
             array(
                 'label' => __('Reset'),
@@ -153,7 +150,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addBackButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'back',
             array(
                 'label' => __('Back'),
@@ -172,7 +169,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _updateBackButtonLink($link)
     {
-        $this->_updateButton('back', 'onclick', 'setLocation(\'' . $link . '\')');
+        $this->updateButton('back', 'onclick', 'setLocation(\'' . $link . '\')');
     }
 
     /**
@@ -182,7 +179,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addDeleteButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'delete',
             array(
                 'label' => __('Delete'),
@@ -208,11 +205,11 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addSaveButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'save',
             array(
                 'label' => __('Save'),
-                'class' => 'save primary save-url-redirect',
+                'class' => 'save primary save-url-rewrite',
                 'level' => -1,
                 'data_attribute' => array(
                     'mage-init' => array('button' => array('event' => 'save', 'target' => '#edit_form'))
@@ -224,12 +221,12 @@ class Edit extends \Magento\Backend\Block\Widget\Container
     /**
      * Creates edit form block
      *
-     * @return \Magento\UrlRedirect\Block\Edit\Form
+     * @return \Magento\UrlRewrite\Block\Edit\Form
      */
     protected function _createEditFormBlock()
     {
         return $this->getLayout()->createBlock(
-            'Magento\UrlRedirect\Block\Edit\Form',
+            'Magento\UrlRewrite\Block\Edit\Form',
             '',
             array('data' => array('url_rewrite' => $this->_getUrlRewrite()))
         );
@@ -248,12 +245,12 @@ class Edit extends \Magento\Backend\Block\Widget\Container
     /**
      * Get selector block
      *
-     * @return \Magento\UrlRedirect\Block\Selector
+     * @return \Magento\UrlRewrite\Block\Selector
      */
     private function _getSelectorBlock()
     {
         if (!$this->_selectorBlock) {
-            $this->_selectorBlock = $this->getLayout()->createBlock('Magento\UrlRedirect\Block\Selector');
+            $this->_selectorBlock = $this->getLayout()->createBlock('Magento\UrlRewrite\Block\Selector');
         }
         return $this->_selectorBlock;
     }
@@ -286,7 +283,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
     /**
      * Get or create new instance of URL rewrite
      *
-     * @return \Magento\UrlRedirect\Model\UrlRedirect
+     * @return \Magento\UrlRewrite\Model\UrlRewrite
      */
     protected function _getUrlRewrite()
     {
diff --git a/app/code/Magento/UrlRedirect/Block/Edit/Form.php b/app/code/Magento/UrlRewrite/Block/Edit/Form.php
similarity index 91%
rename from app/code/Magento/UrlRedirect/Block/Edit/Form.php
rename to app/code/Magento/UrlRewrite/Block/Edit/Form.php
index 82bc37e8b82..3de22757e0b 100644
--- a/app/code/Magento/UrlRedirect/Block/Edit/Form.php
+++ b/app/code/Magento/UrlRewrite/Block/Edit/Form.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block\Edit;
+namespace Magento\UrlRewrite\Block\Edit;
 
 /**
  * URL rewrites edit form
@@ -63,21 +63,21 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     protected $_systemStore;
 
     /**
-     * @var \Magento\UrlRedirect\Model\UrlRedirectFactory
+     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
      */
     protected $_rewriteFactory;
 
     /**
-     * @var \Magento\UrlRedirect\Model\OptionProviderFactory
+     * @var \Magento\UrlRewrite\Model\OptionProvider
      */
-    protected $_optionFactory;
+    protected $optionProvider;
 
     /**
      * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory
-     * @param \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory
+     * @param \Magento\UrlRewrite\Model\OptionProvider $optionProvider
+     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Store\Model\System\Store $systemStore
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param array $data
@@ -86,13 +86,13 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\UrlRedirect\Model\OptionProviderFactory $optionFactory,
-        \Magento\UrlRedirect\Model\UrlRedirectFactory $rewriteFactory,
+        \Magento\UrlRewrite\Model\OptionProvider $optionProvider,
+        \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Store\Model\System\Store $systemStore,
         \Magento\Backend\Helper\Data $adminhtmlData,
         array $data = array()
     ) {
-        $this->_optionFactory = $optionFactory;
+        $this->optionProvider = $optionProvider;
         $this->_rewriteFactory = $rewriteFactory;
         $this->_systemStore = $systemStore;
         $this->_adminhtmlData = $adminhtmlData;
@@ -205,16 +205,14 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
             )
         );
 
-        /** @var $optionsModel \Magento\UrlRedirect\Model\OptionProvider */
-        $optionsModel = $this->_optionFactory->create();
         $fieldset->addField(
             'redirect_type',
             'select',
             array(
-                'label' => __('Redirect'),
-                'title' => __('Redirect'),
+                'label' => __('Redirect Type'),
+                'title' => __('Redirect Type'),
                 'name' => 'redirect_type',
-                'options' => $optionsModel->getAllOptions(),
+                'options' => $this->optionProvider->toOptionArray(),
                 'value' => $this->_formValues['redirect_type']
             )
         );
@@ -271,6 +269,9 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                     'value' => $this->_formValues['store_id']
                 )
             );
+            if ($this->_getModel()->getIsAutogenerated()) {
+                $storeElement->setReadonly(true);
+            }
             $storeElement->setRenderer($renderer);
         }
     }
@@ -297,7 +298,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     protected function _getSessionData()
     {
         if (is_null($this->_sessionData)) {
-            $this->_sessionData = $this->_backendSession->getData('urlrewrite_data', true);
+            $this->_sessionData = $this->_backendSession->getData('url_rewrite_data', true);
         }
         return $this->_sessionData;
     }
@@ -305,7 +306,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     /**
      * Get URL rewrite model instance
      *
-     * @return \Magento\UrlRedirect\Model\UrlRedirect
+     * @return \Magento\UrlRewrite\Model\UrlRewrite
      */
     protected function _getModel()
     {
diff --git a/app/code/Magento/UrlRedirect/Block/GridContainer.php b/app/code/Magento/UrlRewrite/Block/GridContainer.php
similarity index 88%
rename from app/code/Magento/UrlRedirect/Block/GridContainer.php
rename to app/code/Magento/UrlRewrite/Block/GridContainer.php
index b949f48d40f..8eb1e1f7bf1 100644
--- a/app/code/Magento/UrlRedirect/Block/GridContainer.php
+++ b/app/code/Magento/UrlRewrite/Block/GridContainer.php
@@ -21,22 +21,19 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block;
+namespace Magento\UrlRewrite\Block;
 
-/**
- * Block for Urlrewrites grid container
- */
 class GridContainer extends \Magento\Backend\Block\Widget\Grid\Container
 {
     /**
-     * Part for generating apropriate grid block name
+     * Part for generating appropriate grid block name
      *
      * @var string
      */
-    protected $_controller = 'urlredirect';
+    protected $_controller = 'url_rewrite';
 
     /**
-     * @var \Magento\UrlRedirect\Block\Selector
+     * @var \Magento\UrlRewrite\Block\Selector
      */
     protected $_urlrewriteSelector;
 
@@ -47,7 +44,7 @@ class GridContainer extends \Magento\Backend\Block\Widget\Grid\Container
      */
     public function __construct(
         \Magento\Backend\Block\Widget\Context $context,
-        \Magento\UrlRedirect\Block\Selector $urlrewriteSelector,
+        \Magento\UrlRewrite\Block\Selector $urlrewriteSelector,
         array $data = array()
     ) {
         $this->_urlrewriteSelector = $urlrewriteSelector;
diff --git a/app/code/Magento/UrlRedirect/Block/Link.php b/app/code/Magento/UrlRewrite/Block/Link.php
similarity index 97%
rename from app/code/Magento/UrlRedirect/Block/Link.php
rename to app/code/Magento/UrlRewrite/Block/Link.php
index 942f4db971a..b60edfc1512 100644
--- a/app/code/Magento/UrlRedirect/Block/Link.php
+++ b/app/code/Magento/UrlRewrite/Block/Link.php
@@ -29,7 +29,7 @@
  * @method string getItemUrl()
  * @method string getItemName()
  */
-namespace Magento\UrlRedirect\Block;
+namespace Magento\UrlRewrite\Block;
 
 class Link extends \Magento\Framework\View\Element\AbstractBlock
 {
diff --git a/app/code/Magento/UrlRedirect/Block/Selector.php b/app/code/Magento/UrlRewrite/Block/Selector.php
similarity index 94%
rename from app/code/Magento/UrlRedirect/Block/Selector.php
rename to app/code/Magento/UrlRewrite/Block/Selector.php
index 643c3f84d65..e7154a89059 100644
--- a/app/code/Magento/UrlRedirect/Block/Selector.php
+++ b/app/code/Magento/UrlRewrite/Block/Selector.php
@@ -21,9 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Block;
+namespace Magento\UrlRewrite\Block;
 
-class Selector extends \Magento\Framework\View\Element\Template
+class Selector extends \Magento\Backend\Block\Template
 {
     /**
      * List of available modes from source model
@@ -46,10 +46,10 @@ class Selector extends \Magento\Framework\View\Element\Template
     protected function _construct()
     {
         $this->_modes = array(
+            'id' => __('Custom'),
             'category' => __('For category'),
             'product' => __('For product'),
             'cms_page' => __('For CMS page'),
-            'id' => __('Custom')
         );
     }
 
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite.php
similarity index 71%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite.php
index f6a4c537e37..23259b13a6f 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url;
 
 use Magento\Backend\App\Action;
 use Magento\Catalog\Model\Category;
@@ -29,11 +29,18 @@ use Magento\Catalog\Model\Product;
 
 /**
  * URL rewrite adminhtml controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Urlrewrite extends Action
+class Rewrite extends Action
 {
+    /**#@+
+     * Entity types
+     */
+    const ENTITY_TYPE_CUSTOM = 'custom';
+    const ENTITY_TYPE_PRODUCT = 'product';
+    const ENTITY_TYPE_CATEGORY = 'category';
+    const ENTITY_TYPE_CMS_PAGE = 'cms-page';
+    /**#@-*/
+
     /**
      * @var Product
      */
@@ -61,7 +68,7 @@ class Urlrewrite extends Action
      */
     protected function _isAllowed()
     {
-        return $this->_authorization->isAllowed('Magento_Catalog::urlrewrite');
+        return $this->_authorization->isAllowed('Magento_UrlRewrite::urlrewrite');
     }
 
     /**
@@ -74,11 +81,15 @@ class Urlrewrite extends Action
         if (!$this->_category) {
             $this->_category = $this->_objectManager->create('Magento\Catalog\Model\Category');
             $categoryId = (int)$this->getRequest()->getParam('category', 0);
-
-            if (!$categoryId && $this->_getUrlRewrite()->getId()) {
-                $categoryId = $this->_getUrlRewrite()->getCategoryId();
+            $urlRewrite = $this->_getUrlRewrite();
+            if (!$categoryId && $urlRewrite->getId()) {
+                $metaData = $urlRewrite->getMetadata();
+                if ($urlRewrite->getEntityType() === self::ENTITY_TYPE_CATEGORY) {
+                    $categoryId = $urlRewrite->getEntityId();
+                } elseif (!empty($metaData['category_id'])) {
+                    $categoryId = $metaData['category_id'];
+                }
             }
-
             if ($categoryId) {
                 $this->_category->load($categoryId);
             }
@@ -96,11 +107,10 @@ class Urlrewrite extends Action
         if (!$this->_product) {
             $this->_product = $this->_objectManager->create('Magento\Catalog\Model\Product');
             $productId = (int)$this->getRequest()->getParam('product', 0);
-
-            if (!$productId && $this->_getUrlRewrite()->getId()) {
-                $productId = $this->_getUrlRewrite()->getProductId();
+            $urlRewrite = $this->_getUrlRewrite();
+            if (!$productId && $urlRewrite->getId() && $urlRewrite->getEntityType() === self::ENTITY_TYPE_PRODUCT) {
+                $productId = $this->_getUrlRewrite()->getEntityId();
             }
-
             if ($productId) {
                 $this->_product->load($productId);
             }
@@ -118,15 +128,10 @@ class Urlrewrite extends Action
         if (!$this->_cmsPage) {
             $this->_cmsPage = $this->_objectManager->create('Magento\Cms\Model\Page');
             $cmsPageId = (int)$this->getRequest()->getParam('cms_page', 0);
-
-            if (!$cmsPageId && $this->_getUrlRewrite()->getId()) {
-                $urlRewriteId = $this->_getUrlRewrite()->getId();
-                /** @var $cmsUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-                $cmsUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
-                $cmsUrlRewrite->load($urlRewriteId, 'url_rewrite_id');
-                $cmsPageId = $cmsUrlRewrite->getCmsPageId();
+            $urlRewrite = $this->_getUrlRewrite();
+            if (!$cmsPageId && $urlRewrite->getId() && $urlRewrite->getEntityType() === self::ENTITY_TYPE_CMS_PAGE) {
+                $cmsPageId = $this->_getUrlRewrite()->getEntityId();
             }
-
             if ($cmsPageId) {
                 $this->_cmsPage->load($cmsPageId);
             }
@@ -143,10 +148,9 @@ class Urlrewrite extends Action
     {
         if (!$this->_urlRewrite) {
             $this->_urlRewrite = $this->_objectManager->create('Magento\UrlRewrite\Model\UrlRewrite');
-
             $urlRewriteId = (int)$this->getRequest()->getParam('id', 0);
             if ($urlRewriteId) {
-                $this->_urlRewrite->load((int)$this->getRequest()->getParam('id', 0));
+                $this->_urlRewrite->load($urlRewriteId);
             }
         }
         return $this->_urlRewrite;
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CategoriesJson.php
similarity index 83%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CategoriesJson.php
index d1531fba2ff..eae4699aefd 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CategoriesJson.php
@@ -22,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class CategoriesJson extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class CategoriesJson extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
     /**
      * Ajax categories tree loader action
@@ -34,9 +34,9 @@ class CategoriesJson extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
     public function execute()
     {
         $categoryId = $this->getRequest()->getParam('id', null);
-        $this->getResponse()->representJson(
+        $this->getResponse()->setBody(
             $this->_objectManager->get(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree'
+                'Magento\UrlRewrite\Block\Catalog\Category\Tree'
             )->getTreeArray(
                 $categoryId,
                 true,
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
similarity index 81%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
index 445db1ab97e..5777dda4bd7 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
@@ -22,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class CmsPageGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class CmsPageGrid extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
     /**
      * Ajax CMS pages grid action
@@ -34,7 +34,7 @@ class CmsPageGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
     public function execute()
     {
         $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Cms\Page\Grid')->toHtml()
+            $this->_view->getLayout()->createBlock('Magento\UrlRewrite\Block\Cms\Page\Grid')->toHtml()
         );
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
similarity index 92%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
index 612cd4f40b8..197d9443c9e 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
@@ -22,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class Delete extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class Delete extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
     /**
      * URL rewrite delete action
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
similarity index 80%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
index b9feb97f13e..06cdc0c323b 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
@@ -22,17 +22,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class Edit extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
+    /**#@+
+     * Modes
+     */
     const ID_MODE = 'id';
-
     const PRODUCT_MODE = 'product';
-
     const CATEGORY_MODE = 'category';
-
     const CMS_PAGE_MODE = 'cms_page';
+    /**#@-*/
 
     /**
      * Get current mode
@@ -50,7 +51,7 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
         } elseif ($this->getRequest()->has('id')) {
             $mode = self::ID_MODE;
         } else {
-            $mode = $this->_objectManager->get('Magento\Backend\Block\Urlrewrite\Selector')->getDefaultMode();
+            $mode = $this->_objectManager->get('Magento\UrlRewrite\Block\Selector')->getDefaultMode();
         }
         return $mode;
     }
@@ -62,18 +63,14 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
      */
     public function execute()
     {
-        $this->_title->add(__('URL Redirects'));
-        $this->_title->add(__('[New/Edit] URL Redirect'));
-
         $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
+        $this->_setActiveMenu('Magento_UrlRewrite::urlrewrite');
 
         $mode = $this->_getMode();
-
         switch ($mode) {
             case self::PRODUCT_MODE:
                 $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit',
+                    'Magento\UrlRewrite\Block\Catalog\Product\Edit',
                     '',
                     array(
                         'data' => array(
@@ -87,7 +84,7 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
                 break;
             case self::CATEGORY_MODE:
                 $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit',
+                    'Magento\UrlRewrite\Block\Catalog\Category\Edit',
                     '',
                     array(
                         'data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite())
@@ -96,7 +93,7 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
                 break;
             case self::CMS_PAGE_MODE:
                 $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit',
+                    'Magento\UrlRewrite\Block\Cms\Page\Edit',
                     '',
                     array(
                         'data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite())
@@ -106,17 +103,14 @@ class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
             case self::ID_MODE:
             default:
                 $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Edit',
+                    'Magento\UrlRewrite\Block\Edit',
                     '',
                     array('data' => array('url_rewrite' => $this->_getUrlRewrite()))
                 );
                 break;
         }
-
+        $this->_title->add($editBlock->getHeaderText());
         $this->_addContent($editBlock);
-        if (in_array($mode, array(self::PRODUCT_MODE, self::CATEGORY_MODE))) {
-            $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-        }
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
similarity index 81%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
index 76de37ae37a..222804a3664 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
@@ -22,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class Index extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class Index extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
     /**
      * Show URL rewrites index page
@@ -33,10 +33,10 @@ class Index extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
      */
     public function execute()
     {
-        $this->_title->add(__('URL Redirects'));
+        $this->_title->add(__('URL Rewrites'));
 
         $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
+        $this->_setActiveMenu('Magento_UrlRewrite::urlrewrite');
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/ProductGrid.php
similarity index 81%
rename from app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php
rename to app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/ProductGrid.php
index a5e0f8579c5..993393a6961 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/ProductGrid.php
@@ -22,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
 
-class ProductGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+class ProductGrid extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
 {
     /**
      * Ajax products grid action
@@ -34,7 +34,7 @@ class ProductGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
     public function execute()
     {
         $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid')->toHtml()
+            $this->_view->getLayout()->createBlock('Magento\UrlRewrite\Block\Catalog\Product\Grid')->toHtml()
         );
     }
 }
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
new file mode 100644
index 00000000000..e6f5bd53a66
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
@@ -0,0 +1,193 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\Framework\Model\Exception;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+
+class Save extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator */
+    protected $cmsPageUrlPathGenerator;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator
+     * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
+     * @param \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator
+     * @param UrlFinderInterface $urlFinder
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator $productUrlPathGenerator,
+        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
+        \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $cmsPageUrlPathGenerator,
+        UrlFinderInterface $urlFinder
+    ) {
+        parent::__construct($context);
+        $this->productUrlPathGenerator = $productUrlPathGenerator;
+        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
+        $this->cmsPageUrlPathGenerator = $cmsPageUrlPathGenerator;
+        $this->urlFinder = $urlFinder;
+    }
+
+    /**
+     * Override urlrewrite data, basing on current category and product
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     * @throws Exception
+     */
+    protected function _handleCatalogUrlRewrite($model)
+    {
+        $productId = $this->_getProduct()->getId();
+        $categoryId = $this->_getCategory()->getId();
+        if ($productId || $categoryId) {
+            if ($model->isObjectNew()) {
+                $model->setEntityType($productId ? self::ENTITY_TYPE_PRODUCT : self::ENTITY_TYPE_CATEGORY)
+                    ->setEntityId($productId ? : $categoryId);
+                if ($productId && $categoryId) {
+                    $model->setMetadata(serialize(['category_id' => $categoryId]));
+                }
+            }
+            $model->setTargetPath($this->getTargetPath($model));
+        }
+    }
+
+    /**
+     * Get Target Path
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return string
+     * @throws Exception
+     */
+    protected function getTargetPath($model)
+    {
+        $targetPath = $this->getCanonicalTargetPath();
+        if ($model->getRedirectType() && !$model->getIsAutogenerated()) {
+            $data = [
+                UrlRewrite::ENTITY_ID => $model->getEntityId(),
+                UrlRewrite::TARGET_PATH => $targetPath,
+                UrlRewrite::ENTITY_TYPE => $model->getEntityType(),
+                UrlRewrite::STORE_ID => $model->getStoreId(),
+            ];
+            $rewrite = $this->urlFinder->findOneByData($data);
+            if (!$rewrite) {
+                $message = $model->getEntityType() === self::ENTITY_TYPE_PRODUCT
+                    ? __('Chosen product does not associated with the chosen store or category.')
+                    : __('Chosen category does not associated with the chosen store.');
+                throw new Exception($message);
+            }
+            $targetPath = $rewrite->getRequestPath();
+        }
+        return $targetPath;
+    }
+
+    /**
+     * @return string
+     */
+    protected function getCanonicalTargetPath()
+    {
+        $product = $this->_getProduct()->getId() ? $this->_getProduct() : null;
+        $category = $this->_getCategory()->getId() ? $this->_getCategory() : null;
+        return $product
+            ? $this->productUrlPathGenerator->getCanonicalUrlPath($product, $category)
+            : $this->categoryUrlPathGenerator->getCanonicalUrlPath($category);
+    }
+
+    /**
+     * Override URL rewrite data, basing on current CMS page
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     */
+    private function _handleCmsPageUrlRewrite($model)
+    {
+        $cmsPage = $this->_getCmsPage();
+        if ($cmsPage->getId()) {
+            if ($model->isObjectNew()) {
+                $model->setEntityType(self::ENTITY_TYPE_CMS_PAGE)->setEntityId($cmsPage->getId());
+            }
+            if ($model->getRedirectType() && !$model->getIsAutogenerated()) {
+                $targetPath = $this->cmsPageUrlPathGenerator->getUrlPath($cmsPage);
+            } else {
+                $targetPath = $this->cmsPageUrlPathGenerator->getCanonicalUrlPath($cmsPage);
+            }
+            $model->setTargetPath($targetPath);
+        }
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            /** @var $session \Magento\Backend\Model\Session */
+            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+            try {
+                $model = $this->_getUrlRewrite();
+
+                $requestPath = $this->getRequest()->getParam('request_path');
+                $this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->validateRequestPath($requestPath);
+
+                $model->setEntityType($this->getRequest()->getParam('entity_type', self::ENTITY_TYPE_CUSTOM))
+                    ->setRequestPath($requestPath)
+                    ->setTargetPath($this->getRequest()->getParam('target_path', $model->getTargetPath()))
+                    ->setRedirectType($this->getRequest()->getParam('redirect_type'))
+                    ->setStoreId($this->getRequest()->getParam('store_id', 0))
+                    ->setDescription($this->getRequest()->getParam('description'));
+
+                $this->_handleCatalogUrlRewrite($model);
+                $this->_handleCmsPageUrlRewrite($model);
+                $model->save();
+
+                $this->messageManager->addSuccess(__('The URL Rewrite has been saved.'));
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $session->setUrlRewriteData($data);
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.'));
+                $session->setUrlRewriteData($data);
+            }
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/UrlRewrite/Controller/Router.php b/app/code/Magento/UrlRewrite/Controller/Router.php
new file mode 100644
index 00000000000..255904c15c1
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Controller/Router.php
@@ -0,0 +1,137 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Controller;
+
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\UrlFinderInterface;
+use Magento\UrlRewrite\Model\OptionProvider;
+
+/**
+ * UrlRewrite Controller Router
+ */
+class Router implements \Magento\Framework\App\RouterInterface
+{
+    /** var \Magento\Framework\App\ActionFactory */
+    protected $actionFactory;
+
+    /** @var \Magento\Framework\UrlInterface */
+    protected $url;
+
+    /** @var \Magento\Framework\StoreManagerInterface */
+    protected $storeManager;
+
+    /** @var \Magento\Framework\App\ResponseInterface */
+    protected $response;
+
+    /** @var UrlFinderInterface */
+    protected $urlFinder;
+
+    /**
+     * @param \Magento\Framework\App\ActionFactory $actionFactory
+     * @param \Magento\Framework\UrlInterface $url
+     * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\ResponseInterface $response
+     * @param UrlFinderInterface $urlFinder
+     */
+    public function __construct(
+        \Magento\Framework\App\ActionFactory $actionFactory,
+        \Magento\Framework\UrlInterface $url,
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\ResponseInterface $response,
+        UrlFinderInterface $urlFinder
+    ) {
+        $this->actionFactory = $actionFactory;
+        $this->url = $url;
+        $this->storeManager = $storeManager;
+        $this->response = $response;
+        $this->urlFinder = $urlFinder;
+    }
+
+    /**
+     * Match corresponding URL Rewrite and modify request
+     *
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @return \Magento\Framework\App\ActionInterface|null
+     */
+    public function match(\Magento\Framework\App\RequestInterface $request)
+    {
+        if ($fromStore = $request->getParam('___from_store')) {
+            $oldStoreId = $this->storeManager->getStore($fromStore)->getId();
+            $oldRewrite = $this->getRewrite($request->getPathInfo(), $oldStoreId);
+            if ($oldRewrite) {
+                $rewrite = $this->urlFinder->findOneByData(
+                    [
+                        UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(),
+                        UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(),
+                        UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(),
+                        UrlRewrite::IS_AUTOGENERATED => 1,
+                    ]
+                );
+                if ($rewrite && $rewrite->getRequestPath() !== $oldRewrite->getRequestPath()) {
+                    return $this->redirect($request, $rewrite->getRequestPath(), OptionProvider::TEMPORARY);
+                }
+            }
+        }
+        $rewrite = $this->getRewrite($request->getPathInfo(), $this->storeManager->getStore()->getId());
+        if ($rewrite === null) {
+            return null;
+        }
+
+        $redirectType = $rewrite->getRedirectType();
+        if ($redirectType) {
+            return $this->redirect($request, $rewrite->getTargetPath(), $redirectType);
+        }
+
+        $request->setPathInfo('/' . $rewrite->getTargetPath());
+        return $this->actionFactory->create('Magento\Framework\App\Action\Forward', array('request' => $request));
+    }
+
+    /**
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @param string $url
+     * @param int $code
+     * @return \Magento\Framework\App\ActionInterface
+     */
+    protected function redirect($request, $url, $code)
+    {
+        $this->response->setRedirect($this->url->getUrl('', array('_direct' => $url)), $code);
+        $request->setDispatched(true);
+        return $this->actionFactory->create('Magento\Framework\App\Action\Redirect', array('request' => $request));
+    }
+
+    /**
+     * @param string $requestPath
+     * @param int $storeId
+     * @return UrlRewrite|null
+     */
+    protected function getRewrite($requestPath, $storeId)
+    {
+        return $this->urlFinder->findOneByData(
+            [
+                UrlRewrite::REQUEST_PATH => trim($requestPath, '/'),
+                UrlRewrite::STORE_ID => $storeId,
+            ]
+        );
+    }
+}
diff --git a/app/code/Magento/UrlRewrite/Helper/UrlRewrite.php b/app/code/Magento/UrlRewrite/Helper/UrlRewrite.php
index 7e4f8b6775d..70a3b58bb87 100644
--- a/app/code/Magento/UrlRewrite/Helper/UrlRewrite.php
+++ b/app/code/Magento/UrlRewrite/Helper/UrlRewrite.php
@@ -35,23 +35,6 @@ class UrlRewrite extends \Magento\Framework\App\Helper\AbstractHelper
 
     // Anchor is not supported in request path, e.g. 'foo#bar'
 
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider
-     */
-    protected $_urlrewrite;
-
-    /**
-     * @param \Magento\Framework\App\Helper\Context $context
-     * @param \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider $urlrewrite
-     */
-    public function __construct(
-        \Magento\Framework\App\Helper\Context $context,
-        \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider $urlrewrite
-    ) {
-        parent::__construct($context);
-        $this->_urlrewrite = $urlrewrite;
-    }
-
     /**
      * Core func to validate request path
      * If something is wrong with a path it throws localized error message and error code,
@@ -114,20 +97,11 @@ class UrlRewrite extends \Magento\Framework\App\Helper\AbstractHelper
                         __('Two and more slashes together are not permitted in url rewrite suffix')
                     );
                 case self::VERR_ANCHOR:
-                    throw new \Magento\Framework\Model\Exception(__('Anchor symbol (#) is not supported in url rewrite suffix'));
+                    throw new \Magento\Framework\Model\Exception(
+                        __('Anchor symbol (#) is not supported in url rewrite suffix')
+                    );
             }
         }
         return true;
     }
-
-    /**
-     * Has redirect options set
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $urlRewrite
-     * @return bool
-     */
-    public function hasRedirectOptions($urlRewrite)
-    {
-        return in_array($urlRewrite->getOptions(), $this->_urlrewrite->getRedirectOptions());
-    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Backend/AdminConfigTest.php b/app/code/Magento/UrlRewrite/Model/OptionProvider.php
similarity index 64%
rename from dev/tests/integration/testsuite/Magento/Backend/AdminConfigTest.php
rename to app/code/Magento/UrlRewrite/Model/OptionProvider.php
index eabab85f95f..2842ab8fcee 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/AdminConfigTest.php
+++ b/app/code/Magento/UrlRewrite/Model/OptionProvider.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * URL Rewrite Option Provider
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,28 +23,34 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\UrlRewrite\Model;
 
-namespace Magento\Backend;
-
-use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\Option\ArrayInterface;
 
 /**
- * Test class for \Magento\Backend\AdminConfig
- *
+ * @codeCoverageIgnore
  */
-class AdminConfigTest extends \PHPUnit_Framework_TestCase
+class OptionProvider implements ArrayInterface
 {
     /**
-     * Test for setting session name for admin
-     *
+     * Permanent redirect code
+     */
+    const PERMANENT = 301;
+
+    /**
+     * Redirect code
+     */
+    const TEMPORARY = 302;
+
+    /**
+     * {@inheritdoc}
      */
-    public function testSetSessionNameByConstructor()
+    public function toOptionArray()
     {
-        $sessionName = 'adminHtmlSession';
-        $adminConfig = Bootstrap::getObjectManager()->create(
-            'Magento\Backend\AdminConfig',
-            ['sessionName' => $sessionName]
+        return array(
+            0 => __('No'),
+            self::TEMPORARY => __('Temporary (302)'),
+            self::PERMANENT => __('Permanent (301)'),
         );
-        $this->assertSame($sessionName, $adminConfig->getName());
     }
 }
diff --git a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite.php
index 7b93f1822d2..fada0a0fbba 100644
--- a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite.php
+++ b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite.php
@@ -34,7 +34,7 @@ class UrlRewrite extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     protected function _construct()
     {
-        $this->_init('core_url_rewrite', 'url_rewrite_id');
+        $this->_init('url_rewrite', 'url_rewrite_id');
     }
 
     /**
@@ -45,7 +45,6 @@ class UrlRewrite extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected function _initUniqueFields()
     {
         $this->_uniqueFields = array(
-            array('field' => array('id_path', 'store_id', 'is_system'), 'title' => __('ID Path for Specified Store')),
             array('field' => array('request_path', 'store_id'), 'title' => __('Request Path for Specified Store'))
         );
         return $this;
@@ -75,100 +74,4 @@ class UrlRewrite extends \Magento\Framework\Model\Resource\Db\AbstractDb
 
         return $select;
     }
-
-    /**
-     * Retrieve request_path using id_path and current store's id.
-     *
-     * @param string $idPath
-     * @param int|\Magento\Store\Model\Store $store
-     * @return string
-     */
-    public function getRequestPathByIdPath($idPath, $store)
-    {
-        if ($store instanceof \Magento\Store\Model\Store) {
-            $storeId = (int)$store->getId();
-        } else {
-            $storeId = (int)$store;
-        }
-
-        $select = $this->_getReadAdapter()->select();
-        /** @var $select \Magento\Framework\DB\Select */
-        $select->from(
-            array('main_table' => $this->getMainTable()),
-            'request_path'
-        )->where(
-            'main_table.store_id = :store_id'
-        )->where(
-            'main_table.id_path = :id_path'
-        )->limit(
-            1
-        );
-
-        $bind = array('store_id' => $storeId, 'id_path' => $idPath);
-
-        return $this->_getReadAdapter()->fetchOne($select, $bind);
-    }
-
-    /**
-     * Load rewrite information for request
-     * If $path is array - we must load all possible records and choose one matching earlier record in array
-     *
-     * @param   \Magento\UrlRewrite\Model\UrlRewrite $object
-     * @param   array|string $path
-     * @return  $this
-     */
-    public function loadByRequestPath(\Magento\UrlRewrite\Model\UrlRewrite $object, $path)
-    {
-        if (!is_array($path)) {
-            $path = array($path);
-        }
-
-        $pathBind = array();
-        foreach ($path as $key => $url) {
-            $pathBind['path' . $key] = $url;
-        }
-        // Form select
-        $adapter = $this->_getReadAdapter();
-        $select = $adapter->select()->from(
-            $this->getMainTable()
-        )->where(
-            'request_path IN (:' . implode(', :', array_flip($pathBind)) . ')'
-        )->where(
-            'store_id IN(?)',
-            array(\Magento\Store\Model\Store::DEFAULT_STORE_ID, (int)$object->getStoreId())
-        );
-
-        $items = $adapter->fetchAll($select, $pathBind);
-
-        // Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
-        $mapPenalty = array_flip(array_values($path));
-        // we got mapping array(path => index), lower index - better
-        $currentPenalty = null;
-        $foundItem = null;
-        foreach ($items as $item) {
-            if (!array_key_exists($item['request_path'], $mapPenalty)) {
-                continue;
-            }
-            $penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
-            if (!$foundItem || $currentPenalty > $penalty) {
-                $foundItem = $item;
-                $currentPenalty = $penalty;
-                if (!$currentPenalty) {
-                    // Found best matching item with zero penalty, no reason to continue
-                    break;
-                }
-            }
-        }
-
-        // Set data and finish loading
-        if ($foundItem) {
-            $object->setData($foundItem);
-        }
-
-        // Finish
-        $this->unserializeFields($object);
-        $this->_afterLoad($object);
-
-        return $this;
-    }
 }
diff --git a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite/Collection.php b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite/Collection.php
deleted file mode 100644
index 8724cf077d2..00000000000
--- a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewrite/Collection.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-/**
- * URL rewrite collection
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\Model\Resource\UrlRewrite;
-
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
-{
-    /**
-     * Store Manager Model
-     *
-     * @var \Magento\Framework\StoreManagerInterface
-     */
-    protected $_storeManager;
-
-    /**
-     * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
-     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
-     * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param mixed $connection
-     * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
-     */
-    public function __construct(
-        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
-        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
-        \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\StoreManagerInterface $storeManager,
-        $connection = null,
-        \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
-    ) {
-        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
-        $this->_storeManager = $storeManager;
-    }
-
-    /**
-     * Define resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\UrlRewrite\Model\UrlRewrite', 'Magento\UrlRewrite\Model\Resource\UrlRewrite');
-    }
-
-    /**
-     * Filter collections by stores
-     *
-     * @param mixed $store
-     * @param bool $withAdmin
-     * @return $this
-     */
-    public function addStoreFilter($store, $withAdmin = true)
-    {
-        if (!is_array($store)) {
-            $store = array($this->_storeManager->getStore($store)->getId());
-        }
-        if ($withAdmin) {
-            $store[] = 0;
-        }
-
-        $this->addFieldToFilter('store_id', array('in' => $store));
-
-        return $this;
-    }
-
-    /**
-     *  Add filter by catalog product Id
-     *
-     * @param int $productId
-     * @return $this
-     */
-    public function filterAllByProductId($productId)
-    {
-        $this->getSelect()->where(
-            'id_path = ?',
-            "product/{$productId}"
-        )->orWhere(
-            'id_path LIKE ?',
-            "product/{$productId}/%"
-        );
-
-        return $this;
-    }
-
-    /**
-     * Add filter by all catalog category
-     *
-     * @return $this
-     */
-    public function filterAllByCategory()
-    {
-        $this->getSelect()->where('id_path LIKE ?', "category/%");
-        return $this;
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
similarity index 86%
rename from app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php
rename to app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
index edfa1551655..77a93c7ad3a 100644
--- a/app/code/Magento/UrlRedirect/Model/Resource/UrlRedirect/Collection.php
+++ b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
@@ -23,16 +23,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Model\Resource\UrlRedirect;
+namespace Magento\UrlRewrite\Model\Resource;
 
-class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
+class UrlRewriteCollection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
     /**
      * Store Manager Model
      *
      * @var \Magento\Framework\StoreManagerInterface
      */
-    protected $_storeManager;
+    protected $storeManager;
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
@@ -53,7 +53,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
         parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
-        $this->_storeManager = $storeManager;
+        $this->storeManager = $storeManager;
     }
 
     /**
@@ -63,7 +63,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     protected function _construct()
     {
-        $this->_init('Magento\UrlRedirect\Model\UrlRedirect', 'Magento\UrlRedirect\Model\Resource\UrlRedirect');
+        $this->_init('Magento\UrlRewrite\Model\UrlRewrite', 'Magento\UrlRewrite\Model\Resource\UrlRewrite');
     }
 
     /**
@@ -76,7 +76,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     public function addStoreFilter($store, $withAdmin = true)
     {
         if (!is_array($store)) {
-            $store = array($this->_storeManager->getStore($store)->getId());
+            $store = array($this->storeManager->getStore($store)->getId());
         }
         if ($withAdmin) {
             $store[] = 0;
diff --git a/app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
similarity index 57%
rename from app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php
rename to app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 6d8dca8b501..56d3322a796 100644
--- a/app/code/Magento/UrlRedirect/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -21,37 +21,34 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Model\Storage;
+namespace Magento\UrlRewrite\Model\Storage;
 
 use Magento\Framework\App\Resource;
-use Magento\UrlRedirect\Model\StorageInterface;
-use Magento\UrlRedirect\Service\V1\Data\Converter;
-use Magento\UrlRedirect\Service\V1\Data\Filter;
+use Magento\UrlRewrite\Model\StorageInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
 
 /**
  * Abstract db storage
  */
 abstract class AbstractStorage implements StorageInterface
 {
-    /**
-     * @var Converter
-     */
-    protected $converter;
+    /** @var UrlRewriteBuilder */
+    protected $urlRewriteBuilder;
 
     /**
-     * @param Converter $converter
+     * @param UrlRewriteBuilder $urlRewriteBuilder
      */
-    public function __construct(Converter $converter)
+    public function __construct(UrlRewriteBuilder $urlRewriteBuilder)
     {
-        $this->converter = $converter;
+        $this->urlRewriteBuilder = $urlRewriteBuilder;
     }
 
     /**
      * {@inheritdoc}
      */
-    public function findAllByFilter(Filter $filter)
+    public function findAllByData(array $data)
     {
-        $rows = $this->doFindAllByFilter($filter);
+        $rows = $this->doFindAllByData($data);
 
         $urlRewrites = [];
         foreach ($rows as $row) {
@@ -63,17 +60,17 @@ abstract class AbstractStorage implements StorageInterface
     /**
      * Find all rows by specific filter. Template method
      *
-     * @param Filter $filter
+     * @param array $data
      * @return array
      */
-    abstract protected function doFindAllByFilter($filter);
+    abstract protected function doFindAllByData($data);
 
     /**
      * {@inheritdoc}
      */
-    public function findByFilter(Filter $filter)
+    public function findOneByData(array $data)
     {
-        $row = $this->doFindByFilter($filter);
+        $row = $this->doFindOneByData($data);
 
         return $row ? $this->createUrlRewrite($row) : null;
     }
@@ -81,39 +78,44 @@ abstract class AbstractStorage implements StorageInterface
     /**
      * Find row by specific filter. Template method
      *
-     * @param Filter $filter
+     * @param array $data
      * @return array
      */
-    abstract protected function doFindByFilter($filter);
+    abstract protected function doFindOneByData($data);
 
     /**
      * {@inheritdoc}
      */
-    public function addMultiple(array $urls)
+    public function replace(array $urls)
     {
-        $flatData = [];
-        foreach ($urls as $url) {
-            $flatData[] = $this->converter->convertObjectToArray($url);
+        if (!$urls) {
+            return;
+        }
+
+        try {
+            $this->doReplace($urls);
+        } catch (DuplicateEntryException $e) {
+            throw new DuplicateEntryException(__('URL key for specified store already exists.'));
         }
-        $this->doAddMultiple($flatData);
     }
 
     /**
-     * Add multiple data to storage. Template method
+     * Save new url rewrites and remove old if exist. Template method
      *
-     * @param array $data
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
      * @return int
+     * @throws DuplicateEntryException
      */
-    abstract protected function doAddMultiple($data);
+    abstract protected function doReplace($urls);
 
     /**
      * Create url rewrite object
      *
      * @param array $data
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite
      */
     protected function createUrlRewrite($data)
     {
-        return $this->converter->convertArrayToObject($data);
+        return $this->urlRewriteBuilder->populateWithArray($data)->create();
     }
 }
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
new file mode 100644
index 00000000000..ffa43d8503f
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -0,0 +1,165 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model\Storage;
+
+use Magento\Framework\App\Resource;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+
+class DbStorage extends AbstractStorage
+{
+    /**
+     * DB Storage table name
+     */
+    const TABLE_NAME = 'url_rewrite';
+
+    /**
+     * Code of "Integrity constraint violation: 1062 Duplicate entry" error
+     */
+    const ERROR_CODE_DUPLICATE_ENTRY = 23000;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface
+     */
+    protected $connection;
+
+    /**
+     * @var Resource
+     */
+    protected $resource;
+
+    /**
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder $urlRewriteBuilder
+     * @param \Magento\Framework\App\Resource $resource
+     */
+    public function __construct(UrlRewriteBuilder $urlRewriteBuilder, Resource $resource)
+    {
+        $this->connection = $resource->getConnection(Resource::DEFAULT_WRITE_RESOURCE);
+        $this->resource = $resource;
+
+        parent::__construct($urlRewriteBuilder);
+    }
+
+    /**
+     * Prepare select statement for specific filter
+     *
+     * @param array $data
+     * @return \Magento\Framework\DB\Select
+     */
+    protected function prepareSelect($data)
+    {
+        $select = $this->connection->select();
+        $select->from($this->resource->getTableName(self::TABLE_NAME));
+
+        foreach ($data as $column => $value) {
+            $select->where($this->connection->quoteIdentifier($column) . ' IN (?)', $value);
+        }
+        return $select;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFindAllByData($data)
+    {
+        return $this->connection->fetchAll($this->prepareSelect($data));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFindOneByData($data)
+    {
+        return $this->connection->fetchRow($this->prepareSelect($data));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doReplace($urls)
+    {
+        foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
+            $urlData[UrlRewrite::ENTITY_TYPE] = $type;
+            $this->deleteByData($urlData);
+        }
+        $data = [];
+        foreach ($urls as $url) {
+            $data[] = $url->toArray();
+        }
+        $this->insertMultiple($data);
+    }
+
+    /**
+     * Insert multiple
+     *
+     * @param array $data
+     * @return void
+     * @throws DuplicateEntryException
+     * @throws \Exception
+     */
+    protected function insertMultiple($data)
+    {
+        try {
+            $this->connection->insertMultiple($this->resource->getTableName(self::TABLE_NAME), $data);
+        } catch (\Exception $e) {
+            if ($e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
+                && preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
+            ) {
+                throw new DuplicateEntryException();
+            }
+            throw $e;
+        }
+    }
+
+    /**
+     * Get filter for url rows deletion due to provided urls
+     *
+     * @param UrlRewrite[] $urls
+     * @return array
+     */
+    protected function createFilterDataBasedOnUrls($urls)
+    {
+        $data = [];
+        foreach ($urls as $url) {
+            $entityType = $url->getEntityType();
+            foreach ([UrlRewrite::ENTITY_ID, UrlRewrite::STORE_ID] as $key) {
+                $fieldValue = $url->getByKey($key);
+                if (!isset($data[$entityType][$key]) || !in_array($fieldValue, $data[$entityType][$key])) {
+                    $data[$entityType][$key][] = $fieldValue;
+                }
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteByData(array $data)
+    {
+        $this->connection->query(
+            $this->prepareSelect($data)->deleteFromSelect($this->resource->getTableName(self::TABLE_NAME))
+        );
+    }
+}
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DuplicateEntryException.php b/app/code/Magento/UrlRewrite/Model/Storage/DuplicateEntryException.php
new file mode 100644
index 00000000000..261bd21c551
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DuplicateEntryException.php
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model\Storage;
+
+class DuplicateEntryException extends \RuntimeException
+{
+}
diff --git a/app/code/Magento/UrlRewrite/Model/StorageInterface.php b/app/code/Magento/UrlRewrite/Model/StorageInterface.php
new file mode 100644
index 00000000000..543e8d14918
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Model/StorageInterface.php
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model;
+
+interface StorageInterface extends UrlFinderInterface, UrlPersistInterface
+{
+}
diff --git a/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
new file mode 100644
index 00000000000..39e2e867ab1
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
@@ -0,0 +1,46 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model;
+
+/**
+ * Url Finder Interface
+ */
+interface UrlFinderInterface
+{
+    /**
+     * Find rewrite by specific data
+     *
+     * @param array $data
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+     */
+    public function findOneByData(array $data);
+
+    /**
+     * Find rewrites by specific data
+     *
+     * @param array $data
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function findAllByData(array $data);
+}
diff --git a/app/code/Magento/UrlRedirect/Model/UrlRedirect.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
similarity index 66%
rename from app/code/Magento/UrlRedirect/Model/UrlRedirect.php
rename to app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index 4935d63bc80..d0ad77a2b55 100644
--- a/app/code/Magento/UrlRedirect/Model/UrlRedirect.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * URL Rewrite Model
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,23 +21,27 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Model;
+namespace Magento\UrlRewrite\Model;
 
 /**
- * @method string getEntityType()
- * @method UrlRedirect setEntityType(string $value)
- * @method int getEntityId()
- * @method UrlRedirect setEntityId(int $value)
+ * Url Persist Interface
  */
-class UrlRedirect extends \Magento\Framework\Model\AbstractModel
+interface UrlPersistInterface
 {
     /**
-     * Initialize corresponding resource model
+     * Save new url rewrites and remove old if exist
+     *
+     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
+     * @return void
+     * @throws \Magento\UrlRewrite\Model\Storage\DuplicateEntryException
+     */
+    public function replace(array $urls);
+
+    /**
+     * Remove rewrites that contains some rewrites data
      *
+     * @param array $data
      * @return void
      */
-    protected function _construct()
-    {
-        $this->_init('Magento\UrlRedirect\Model\Resource\UrlRedirect');
-    }
+    public function deleteByData(array $data);
 }
diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php
index e8837ea865d..3f10ce56522 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php
@@ -24,98 +24,23 @@
 namespace Magento\UrlRewrite\Model;
 
 /**
- * URL Rewrite Model
- *
- * @method \Magento\UrlRewrite\Model\UrlRewrite setStoreId(int $value)
- * @method int getCategoryId()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setCategoryId(int $value)
- * @method int getProductId()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setProductId(int $value)
- * @method string getIdPath()
- * @method \Magento\UrlRewrite\Model\UrlRewritesetIdPath(string $value)
- * @method string getRequestPath()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setRequestPath(string $value)
+ * @method int getEntityId()
+ * @method string getEntityType()
+ * @method int getRedirectType()
+ * @method int getStoreId()
+ * @method int getIsAutogenerated()
  * @method string getTargetPath()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setTargetPath(string $value)
- * @method int getIsSystem()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setIsSystem(int $value)
- * @method string getOptions()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setOptions(string $value)
- * @method string getDescription()
- * @method \Magento\UrlRewrite\Model\UrlRewrite setDescription(string $value)
+ * @method UrlRewrite setEntityId(int $value)
+ * @method UrlRewrite setEntityType(string $value)
+ * @method UrlRewrite setMetadata($value)
+ * @method UrlRewrite setRequestPath($value)
+ * @method UrlRewrite setTargetPath($value)
+ * @method UrlRewrite setRedirectType($value)
+ * @method UrlRewrite setStoreId($value)
+ * @method UrlRewrite setDescription($value)
  */
 class UrlRewrite extends \Magento\Framework\Model\AbstractModel
 {
-    /**
-     * Rewrite type category
-     */
-    const TYPE_CATEGORY = 1;
-
-    /**
-     * Rewrite type product
-     */
-    const TYPE_PRODUCT = 2;
-
-    /**
-     * Custom rewrite type
-     */
-    const TYPE_CUSTOM = 3;
-
-    /**
-     * Field name for loading path
-     */
-    const PATH_FIELD = 'id_path';
-
-    /**
-     * Cache tag for clear cache in after save and after delete
-     *
-     * @var array|string|boolean
-     */
-    protected $_cacheTag = false;
-
-    /**
-     * Core store config
-     *
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $_scopeConfig;
-
-    /**
-     * @var \Magento\Framework\StoreManagerInterface
-     */
-    protected $_storeManager;
-
-    /**
-     * @var \Magento\Framework\App\Http\Context
-     */
-    protected $_httpContext;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\StoreManagerInterface $storeManager,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        $this->_scopeConfig = $scopeConfig;
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-        $this->_storeManager = $storeManager;
-        $this->_httpContext = $httpContext;
-    }
-
     /**
      * Initialize corresponding resource model
      *
@@ -124,218 +49,15 @@ class UrlRewrite extends \Magento\Framework\Model\AbstractModel
     protected function _construct()
     {
         $this->_init('Magento\UrlRewrite\Model\Resource\UrlRewrite');
+        $this->_collectionName = 'Magento\UrlRewrite\Model\Resource\UrlRewriteCollection';
     }
 
     /**
-     * Clean cache for front-end menu
-     *
-     * @return  $this
+     * @return array
      */
-    protected function _afterSave()
+    public function getMetadata()
     {
-        if ($this->hasCategoryId()) {
-            $this->_cacheTag = array(
-                \Magento\Catalog\Model\Category::CACHE_TAG,
-                \Magento\Store\Model\Group::CACHE_TAG
-            );
-        }
-
-        parent::_afterSave();
-
-        return $this;
-    }
-
-    /**
-     * Load rewrite information for request
-     * If $path is array - we must load possible records and choose one matching earlier record in array
-     *
-     * @param   mixed $path
-     * @return  $this
-     */
-    public function loadByRequestPath($path)
-    {
-        $this->setId(null);
-        $this->_getResource()->loadByRequestPath($this, $path);
-        $this->_afterLoad();
-        $this->setOrigData();
-        $this->_hasDataChanges = false;
-        return $this;
-    }
-
-    /**
-     * @param int $path
-     * @return $this
-     */
-    public function loadByIdPath($path)
-    {
-        $this->setId(null)->load($path, self::PATH_FIELD);
-        return $this;
-    }
-
-    /**
-     * @param mixed $key
-     * @return bool
-     */
-    public function hasOption($key)
-    {
-        $optArr = explode(',', $this->getOptions());
-
-        return array_search($key, $optArr) !== false;
-    }
-
-    /**
-     * Perform custom url rewrites
-     *
-     * @param \Magento\Framework\App\RequestInterface $request
-     * @return bool
-     */
-    public function rewrite(\Magento\Framework\App\RequestInterface $request = null)
-    {
-        if (is_null($this->getStoreId()) || false === $this->getStoreId()) {
-            $this->setStoreId($this->_storeManager->getStore()->getId());
-        }
-
-        /**
-         * We have two cases of incoming paths - with and without slashes at the end ("/somepath/" and "/somepath").
-         * Each of them matches two url rewrite request paths - with and without slashes at the end
-         * ("/somepath/" and "/somepath").
-         * Choose any matched rewrite, but in priority order that depends on same presence of slash and query params.
-         */
-        $requestCases = array();
-        $pathInfo = $request->getPathInfo();
-        $origSlash = substr($pathInfo, -1) == '/' ? '/' : '';
-        $requestPath = trim($pathInfo, '/');
-
-        // If there were final slash - add nothing to less priority paths. And vice versa.
-        $altSlash = $origSlash ? '' : '/';
-
-        $queryString = $this->_getQueryString();
-        // Query params in request, matching "path + query" has more priority
-        if ($queryString) {
-            $requestCases[] = $requestPath . $origSlash . '?' . $queryString;
-            $requestCases[] = $requestPath . $altSlash . '?' . $queryString;
-        }
-        $requestCases[] = $requestPath . $origSlash;
-        $requestCases[] = $requestPath . $altSlash;
-
-        $this->loadByRequestPath($requestCases);
-
-        $targetUrl = $request->getBaseUrl();
-        /**
-         * Try to find rewrite by request path at first, if no luck - try to find by id_path
-         */
-        if (!$this->getId() && isset($_GET['___from_store'])) {
-            try {
-                $fromStoreId = $this->_storeManager->getStore($_GET['___from_store'])->getId();
-            } catch (\Exception $e) {
-                return false;
-            }
-
-            $this->setStoreId($fromStoreId)->loadByRequestPath($requestCases);
-            if (!$this->getId()) {
-                return false;
-            }
-            $currentStore = $this->_storeManager->getStore();
-            $this->setStoreId($currentStore->getId())->loadByIdPath($this->getIdPath());
-            $currentStore->setCookie();
-            $targetUrl .= '/' . $this->getRequestPath();
-
-            $this->_sendRedirectHeaders($targetUrl, true);
-        }
-
-        if (!$this->getId()) {
-            return false;
-        }
-
-
-        $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $this->getRequestPath());
-        $external = substr($this->getTargetPath(), 0, 6);
-        $isPermanentRedirectOption = $this->hasOption('RP');
-        if ($external === 'http:/' || $external === 'https:') {
-            $this->_storeManager->getStore($this->getStoreId())->setCookie();
-            $this->_sendRedirectHeaders($this->getTargetPath(), $isPermanentRedirectOption);
-        } else {
-            $targetUrl .= '/' . $this->getTargetPath();
-        }
-        $isRedirectOption = $this->hasOption('R');
-        $isStoreInUrl = $this->_scopeConfig->getValue(
-            \Magento\Store\Model\Store::XML_PATH_STORE_IN_URL,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        if ($isRedirectOption || $isPermanentRedirectOption) {
-            if ($isStoreInUrl && ($storeCode = $this->_storeManager->getStore()->getCode())) {
-                $targetUrl .= '/' . $storeCode . '/' . $this->getTargetPath();
-            }
-
-            $this->_sendRedirectHeaders($targetUrl, $isPermanentRedirectOption);
-        }
-
-        if ($isStoreInUrl && ($storeCode = $this->_storeManager->getStore()->getCode())) {
-            $targetUrl .= '/' . $storeCode . '/' . $this->getTargetPath();
-        }
-
-        $queryString = $this->_getQueryString();
-        if ($queryString) {
-
-
-            $targetUrl .= '?' . $queryString;
-        }
-
-
-        $request->setRequestUri($targetUrl);
-        $request->setPathInfo($this->getTargetPath());
-
-        return true;
-    }
-
-    /**
-     * @return bool|string
-     */
-    protected function _getQueryString()
-    {
-        if (!empty($_SERVER['QUERY_STRING'])) {
-            $queryParams = array();
-            parse_str($_SERVER['QUERY_STRING'], $queryParams);
-            $hasChanges = false;
-            foreach (array_keys($queryParams) as $key) {
-                if (substr($key, 0, 3) === '___') {
-                    unset($queryParams[$key]);
-                    $hasChanges = true;
-                }
-            }
-            if ($hasChanges) {
-                return http_build_query($queryParams);
-            } else {
-                return $_SERVER['QUERY_STRING'];
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return mixed
-     */
-    public function getStoreId()
-    {
-        return $this->_getData('store_id');
-    }
-
-    /**
-     * Add location header and disable browser page caching
-     *
-     * @param string $url
-     * @param bool $isPermanent
-     * @return void
-     */
-    protected function _sendRedirectHeaders($url, $isPermanent = false)
-    {
-        if ($isPermanent) {
-            header('HTTP/1.1 301 Moved Permanently');
-        }
-
-        header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
-        header('Pragma: no-cache');
-        header('Location: ' . $url);
-        exit;
+        $metadata = $this->getData(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::METADATA);
+        return !empty($metadata) ? unserialize($metadata) : [];
     }
 }
diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite/OptionProvider.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite/OptionProvider.php
deleted file mode 100644
index c9b08f41c6e..00000000000
--- a/app/code/Magento/UrlRewrite/Model/UrlRewrite/OptionProvider.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
- * URL Rewrite Option Provider
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\Model\UrlRewrite;
-
-use Magento\Framework\Option\ArrayInterface;
-
-class OptionProvider implements ArrayInterface
-{
-    const TEMPORARY = 'R';
-
-    const PERMANENT = 'RP';
-
-    /**
-     * @var array|null
-     */
-    protected $_options = null;
-
-    /**
-     * Get all options
-     *
-     * @return array
-     */
-    public function getAllOptions()
-    {
-        if (is_null($this->_options)) {
-            $this->_options = array(
-                '' => __('No'),
-                self::TEMPORARY => __('Temporary (302)'),
-                self::PERMANENT => __('Permanent (301)'),
-            );
-        }
-        return $this->_options;
-    }
-
-    /**
-     * Get options list (redirects only)
-     *
-     * @return string[]
-     */
-    public function getRedirectOptions()
-    {
-        return array(self::TEMPORARY, self::PERMANENT);
-    }
-
-    /**
-     * Return option array
-     *
-     * @return array
-     */
-    public function toOptionArray()
-    {
-        return $this->getAllOptions();
-    }
-}
diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
similarity index 74%
rename from app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php
rename to app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
index eb5bc4eaf7b..3367b44794d 100644
--- a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewrite.php
+++ b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Service\V1\Data;
+namespace Magento\UrlRewrite\Service\V1\Data;
 
 use Magento\Framework\Service\Data\AbstractExtensibleObject;
 
@@ -33,13 +33,16 @@ class UrlRewrite extends AbstractExtensibleObject
     /**#@+
      * Value object attribute names
      */
+    const URL_REWRITE_ID = 'url_rewrite_id';
     const ENTITY_ID = 'entity_id';
     const ENTITY_TYPE = 'entity_type';
+    const IS_AUTOGENERATED = 'is_autogenerated';
     const REQUEST_PATH = 'request_path';
     const TARGET_PATH = 'target_path';
     const STORE_ID = 'store_id';
     const REDIRECT_TYPE = 'redirect_type';
     const DESCRIPTION = 'description';
+    const METADATA = 'metadata';
     /**#@-*/
 
     /**
@@ -53,6 +56,14 @@ class UrlRewrite extends AbstractExtensibleObject
         return $this->_get($key);
     }
 
+    /**
+     * @return int
+     */
+    public function getUrlRewriteId()
+    {
+        return $this->_get(self::URL_REWRITE_ID);
+    }
+
     /**
      * @return int
      */
@@ -62,13 +73,21 @@ class UrlRewrite extends AbstractExtensibleObject
     }
 
     /**
-     * @return int
+     * @return string
      */
     public function getEntityType()
     {
         return $this->_get(self::ENTITY_TYPE);
     }
 
+    /**
+     * @return int
+     */
+    public function getIsAutogenerated()
+    {
+        return $this->_get(self::IS_AUTOGENERATED);
+    }
+
     /**
      * @return string
      */
@@ -94,11 +113,11 @@ class UrlRewrite extends AbstractExtensibleObject
     }
 
     /**
-     * @return string
+     * @return int
      */
     public function getRedirectType()
     {
-        return $this->_get(self::REDIRECT_TYPE);
+        return (int)$this->_get(self::REDIRECT_TYPE);
     }
 
     /**
@@ -108,4 +127,23 @@ class UrlRewrite extends AbstractExtensibleObject
     {
         return $this->_get(self::DESCRIPTION);
     }
+
+    /**
+     * @return array
+     */
+    public function getMetadata()
+    {
+        $metadata = $this->_get(self::METADATA);
+        return !empty($metadata) ? unserialize($metadata) : [];
+    }
+
+    /**
+     * Convert UrlRewrite to array
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return $this->_data;
+    }
 }
diff --git a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewriteBuilder.php
similarity index 70%
rename from app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php
rename to app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewriteBuilder.php
index 0d9a441daf1..54bd4a3185d 100644
--- a/app/code/Magento/UrlRedirect/Service/V1/Data/UrlRewriteBuilder.php
+++ b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewriteBuilder.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\UrlRedirect\Service\V1\Data;
+namespace Magento\UrlRewrite\Service\V1\Data;
 
 use Magento\Framework\Service\Data\AbstractExtensibleObjectBuilder;
 
@@ -30,6 +30,24 @@ use Magento\Framework\Service\Data\AbstractExtensibleObjectBuilder;
  */
 class UrlRewriteBuilder extends AbstractExtensibleObjectBuilder
 {
+    /**
+     * @var array
+     */
+    protected $defaultValues = [
+        UrlRewrite::REDIRECT_TYPE => 0,
+        UrlRewrite::IS_AUTOGENERATED => 1,
+        UrlRewrite::METADATA => null,
+        UrlRewrite::DESCRIPTION => null,
+    ];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getData()
+    {
+        return array_merge($this->defaultValues, $this->_data);
+    }
+
     /**
      * @param int $entityId
      *
@@ -41,7 +59,7 @@ class UrlRewriteBuilder extends AbstractExtensibleObjectBuilder
     }
 
     /**
-     * @param int $entityType
+     * @param string $entityType
      *
      * @return $this
      */
@@ -50,6 +68,16 @@ class UrlRewriteBuilder extends AbstractExtensibleObjectBuilder
         return $this->_set(UrlRewrite::ENTITY_TYPE, $entityType);
     }
 
+    /**
+     * @param int $isAutogenerated
+     *
+     * @return $this
+     */
+    public function setIsAutogenerated($isAutogenerated)
+    {
+        return $this->_set(UrlRewrite::IS_AUTOGENERATED, $isAutogenerated);
+    }
+
     /**
      * @param string $requestPath
      *
@@ -85,7 +113,7 @@ class UrlRewriteBuilder extends AbstractExtensibleObjectBuilder
      *
      * @return $this
      */
-    public function setRedirectCode($redirectCode)
+    public function setRedirectType($redirectCode)
     {
         return $this->_set(UrlRewrite::REDIRECT_TYPE, $redirectCode);
     }
@@ -99,4 +127,15 @@ class UrlRewriteBuilder extends AbstractExtensibleObjectBuilder
     {
         return $this->_set(UrlRewrite::DESCRIPTION, $description);
     }
+
+    /**
+     * @param array $metadata
+     *
+     * @return $this
+     */
+    public function setMetadata(array $metadata)
+    {
+        $metadata = $metadata ? serialize($metadata) : null;
+        return $this->_set(UrlRewrite::METADATA, $metadata);
+    }
 }
diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json
index 37851b26362..2faad085665 100644
--- a/app/code/Magento/UrlRewrite/composer.json
+++ b/app/code/Magento/UrlRewrite/composer.json
@@ -3,14 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog-url-rewrite": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-cms-url-rewrite": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/UrlRedirect/etc/acl.xml b/app/code/Magento/UrlRewrite/etc/adminhtml/acl.xml
similarity index 86%
rename from app/code/Magento/UrlRedirect/etc/acl.xml
rename to app/code/Magento/UrlRewrite/etc/adminhtml/acl.xml
index ae933a12f82..4035016591e 100644
--- a/app/code/Magento/UrlRedirect/etc/acl.xml
+++ b/app/code/Magento/UrlRewrite/etc/adminhtml/acl.xml
@@ -23,13 +23,13 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
     <acl>
         <resources>
             <resource id="Magento_Adminhtml::admin">
                 <resource id="Magento_Adminhtml::marketing">
                     <resource id="Magento_Adminhtml::marketing_seo">
-                        <resource id="Magento_UrlRedirect::urlrewrite" title="URL Rewrites" sortOrder="20" />
+                        <resource id="Magento_UrlRewrite::urlrewrite" title="URL Rewrites" sortOrder="20" />
                     </resource>
                 </resource>
             </resource>
diff --git a/app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml b/app/code/Magento/UrlRewrite/etc/adminhtml/menu.xml
similarity index 85%
rename from app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml
rename to app/code/Magento/UrlRewrite/etc/adminhtml/menu.xml
index 5ae310d19f7..2ae113868f6 100644
--- a/app/code/Magento/UrlRedirect/etc/adminhtml/menu.xml
+++ b/app/code/Magento/UrlRewrite/etc/adminhtml/menu.xml
@@ -25,8 +25,8 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/menu.xsd">
     <menu>
-        <add id="Magento_UrlRedirect::catalog_urlrewrite" title="URL Rewrites" module="Magento_UrlRedirect"
+        <add id="Magento_UrlRewrite::urlrewrite" title="URL Rewrites" module="Magento_UrlRewrite"
              sortOrder="20" parent="Magento_Backend::marketing_seo"
-             action="adminhtml/urlRedirect/index" resource="Magento_UrlRedirect::urlrewrite"/>
+             action="adminhtml/url_rewrite/index" resource="Magento_UrlRewrite::urlrewrite"/>
     </menu>
 </config>
diff --git a/app/code/Magento/Index/etc/adminhtml/routes.xml b/app/code/Magento/UrlRewrite/etc/adminhtml/routes.xml
similarity index 94%
rename from app/code/Magento/Index/etc/adminhtml/routes.xml
rename to app/code/Magento/UrlRewrite/etc/adminhtml/routes.xml
index 643858ca001..86857d544e8 100644
--- a/app/code/Magento/Index/etc/adminhtml/routes.xml
+++ b/app/code/Magento/UrlRewrite/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="adminhtml">
-            <module name="Magento_Index" before="Magento_Adminhtml" />
+            <module name="Magento_UrlRewrite" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/UrlRedirect/etc/config.xml b/app/code/Magento/UrlRewrite/etc/config.xml
similarity index 100%
rename from app/code/Magento/UrlRedirect/etc/config.xml
rename to app/code/Magento/UrlRewrite/etc/config.xml
diff --git a/app/code/Magento/UrlRedirect/etc/di.xml b/app/code/Magento/UrlRewrite/etc/di.xml
similarity index 75%
rename from app/code/Magento/UrlRedirect/etc/di.xml
rename to app/code/Magento/UrlRewrite/etc/di.xml
index 888bf6a467b..b5d8c336e84 100644
--- a/app/code/Magento/UrlRedirect/etc/di.xml
+++ b/app/code/Magento/UrlRewrite/etc/di.xml
@@ -24,7 +24,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Magento\UrlRedirect\Model\StorageInterface" type="Magento\UrlRedirect\Model\Storage\Db"/>
-    <preference for="Magento\UrlRedirect\Service\V1\UrlMatcherInterface" type="Magento\UrlRedirect\Service\V1\UrlManager"/>
-    <preference for="Magento\UrlRedirect\Service\V1\UrlSaveInterface" type="Magento\UrlRedirect\Service\V1\UrlManager"/>
+    <preference for="Magento\UrlRewrite\Model\StorageInterface" type="Magento\UrlRewrite\Model\Storage\DbStorage"/>
+    <preference for="Magento\UrlRewrite\Model\UrlFinderInterface" type="Magento\UrlRewrite\Model\Storage\DbStorage"/>
+    <preference for="Magento\UrlRewrite\Model\UrlPersistInterface" type="Magento\UrlRewrite\Model\Storage\DbStorage"/>
 </config>
diff --git a/app/code/Magento/UrlRewrite/etc/frontend/di.xml b/app/code/Magento/UrlRewrite/etc/frontend/di.xml
index 92fe1f4f05d..f2ea6c215b0 100644
--- a/app/code/Magento/UrlRewrite/etc/frontend/di.xml
+++ b/app/code/Magento/UrlRewrite/etc/frontend/di.xml
@@ -24,7 +24,15 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <type name="Magento\Framework\App\FrontController">
-        <plugin name="urlRewrite" type="Magento\UrlRewrite\App\FrontController\Plugin\UrlRewrite" sortOrder="60"/>
+    <type name="Magento\Framework\App\RouterList">
+        <arguments>
+            <argument name="routerList" xsi:type="array">
+                <item name="urlrewrite" xsi:type="array">
+                    <item name="class" xsi:type="string">Magento\UrlRewrite\Controller\Router</item>
+                    <item name="disable" xsi:type="boolean">false</item>
+                    <item name="sortOrder" xsi:type="string">40</item>
+                </item>
+            </argument>
+        </arguments>
     </type>
 </config>
diff --git a/app/code/Magento/UrlRewrite/etc/module.xml b/app/code/Magento/UrlRewrite/etc/module.xml
index cfc1b944e80..55bad3745a4 100644
--- a/app/code/Magento/UrlRewrite/etc/module.xml
+++ b/app/code/Magento/UrlRewrite/etc/module.xml
@@ -26,9 +26,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
     <module name="Magento_UrlRewrite" schema_version="1.0.0.0" active="true">
         <depends>
-            <module name="Magento_Store" />
-            <module name="Magento_Core" />
-            <module name="Magento_Catalog" />
+            <module name="Magento_Backend"/>
+            <module name="Magento_Catalog"/>
+            <module name="Magento_CatalogUrlRewrite"/>
+            <module name="Magento_Cms"/>
+            <module name="Magento_CmsUrlRewrite"/>
+            <module name="Magento_Core"/>
+            <module name="Magento_Store"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/UrlRewrite/i18n/de_DE.csv b/app/code/Magento/UrlRewrite/i18n/de_DE.csv
index f15cd8d3e28..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/de_DE.csv
+++ b/app/code/Magento/UrlRewrite/i18n/de_DE.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","Zwei und mehr zusammenhängende Schrägstriche sind im URL-Rewrite-Suffix nicht zulässig"
-"Anchor symbol (#) is not supported in url rewrite suffix","Das Doppelkreuz (#) wird beim URL-Überschreiben-Suffix nicht unterstützt"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/en_US.csv b/app/code/Magento/UrlRewrite/i18n/en_US.csv
index 7cf00c7c20b..2d0c4e9330a 100644
--- a/app/code/Magento/UrlRewrite/i18n/en_US.csv
+++ b/app/code/Magento/UrlRewrite/i18n/en_US.csv
@@ -1,11 +1,62 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
+No,No
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","Two and more slashes together are not permitted in url rewrite suffix"
-"Anchor symbol (#) is not supported in url rewrite suffix","Anchor symbol (#) is not supported in url rewrite suffix"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/es_ES.csv b/app/code/Magento/UrlRewrite/i18n/es_ES.csv
index 748a57814ae..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/es_ES.csv
+++ b/app/code/Magento/UrlRewrite/i18n/es_ES.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","No se permiten dos o más barras juntas en el sufijo de la url"
-"Anchor symbol (#) is not supported in url rewrite suffix","El símbolo ancla (#) no está soportado en el sufijo de reescritura de url"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/fr_FR.csv b/app/code/Magento/UrlRewrite/i18n/fr_FR.csv
index 23a4c9da125..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/fr_FR.csv
+++ b/app/code/Magento/UrlRewrite/i18n/fr_FR.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","Deux slashs ou plus ne sont pas autorisés dans le suffixe de réécriture de l'URL"
-"Anchor symbol (#) is not supported in url rewrite suffix","Le symbole d'ancrage (#) n'est pas pris en charge dans le suffixe de réécriture de l'url"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/nl_NL.csv b/app/code/Magento/UrlRewrite/i18n/nl_NL.csv
index c036c1f3411..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/nl_NL.csv
+++ b/app/code/Magento/UrlRewrite/i18n/nl_NL.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","Twee of meer schuine strepen zijn niet toegestaan in URL herschrijvings navoeging"
-"Anchor symbol (#) is not supported in url rewrite suffix","Anker symbool (#) is niet ondersteund in URL herschrijvings toevoeging"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/pt_BR.csv b/app/code/Magento/UrlRewrite/i18n/pt_BR.csv
index e84682fb78a..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/pt_BR.csv
+++ b/app/code/Magento/UrlRewrite/i18n/pt_BR.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","Duas ou mais barras juntas não são permitidas em sufixo url reescrito"
-"Anchor symbol (#) is not supported in url rewrite suffix","Símbolo âncora (#) não é suportado no sufixo url reescrito"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/i18n/zh_CN.csv b/app/code/Magento/UrlRewrite/i18n/zh_CN.csv
index 901a6b7b9e3..8b6c4909ac3 100644
--- a/app/code/Magento/UrlRewrite/i18n/zh_CN.csv
+++ b/app/code/Magento/UrlRewrite/i18n/zh_CN.csv
@@ -1,11 +1,57 @@
 Custom,Custom
+Back,Back
+ID,ID
+SKU,SKU
 No,No
-System,System
+Action,Action
+Reset,Reset
+Edit,Edit
 "Two and more slashes together are not permitted in request path","Two and more slashes together are not permitted in request path"
 "Anchor symbol (#) is not supported in request path","Anchor symbol (#) is not supported in request path"
-"Two and more slashes together are not permitted in url rewrite suffix","两个或更多斜杠在 URL 重写后缀中不被允许"
-"Anchor symbol (#) is not supported in url rewrite suffix","URL 重写后缀不支持固定标志 (#)"
-"ID Path for Specified Store","ID Path for Specified Store"
 "Request Path for Specified Store","Request Path for Specified Store"
 "Temporary (302)","Temporary (302)"
 "Permanent (301)","Permanent (301)"
+"Edit URL Rewrite for a Category","Edit URL Rewrite for a Category"
+"Add URL Rewrite for a Category","Add URL Rewrite for a Category"
+"Category:","Category:"
+"We can't set up a URL rewrite because the product you chose is not associated with a website.","We can't set up a URL rewrite because the product you chose is not associated with a website."
+"We can't set up a URL rewrite because the category your chose is not associated with a website.","We can't set up a URL rewrite because the category your chose is not associated with a website."
+"Edit URL Rewrite for a Product","Edit URL Rewrite for a Product"
+"Add URL Rewrite for a Product","Add URL Rewrite for a Product"
+"Product:","Product:"
+"Skip Category Selection","Skip Category Selection"
+"Name","Name"
+"Status","Status"
+"Edit URL Rewrite for CMS page","Edit URL Rewrite for CMS page"
+"Add URL Rewrite for CMS page","Add URL Rewrite for CMS page"
+"CMS page:","CMS page:"
+"Chosen cms page does not associated with any website.","Chosen cms page does not associated with any website."
+"Title","Title"
+"URL Key","URL Key"
+"Store View","Store View"
+"Edit URL Rewrite","Edit URL Rewrite"
+"Add New URL Rewrite","Add New URL Rewrite"
+"Delete","Delete"
+"Are you sure you want to do this?","Are you sure you want to do this?"
+"Save","Save"
+"Block Information","Block Information"
+"URL Rewrite Information","URL Rewrite Information"
+"Request Path","Request Path"
+"Target Path","Target Path"
+"Redirect","Redirect"
+"Description","Description"
+"Store","Store"
+"URL Rewrite Management","URL Rewrite Management"
+"Add URL Rewrite","Add URL Rewrite"
+"For category","For category"
+"For product","For product"
+"For CMS page","For CMS page"
+"Create URL Rewrite:","Create URL Rewrite:"
+"URL Rewrites","URL Rewrites"
+"[New/Edit] URL Rewrite","[New/Edit] URL Rewrite"
+"The URL Rewrite has been saved.","The URL Rewrite has been saved."
+"An error occurred while saving URL Rewrite.","An error occurred while saving URL Rewrite."
+"The URL Rewrite has been deleted.","The URL Rewrite has been deleted."
+"An error occurred while deleting URL Rewrite.","An error occurred while deleting URL Rewrite."
+"Select Category","Select Category"
+"Options","Options"
diff --git a/app/code/Magento/UrlRewrite/sql/urlrewrite_setup/install-1.0.0.0.php b/app/code/Magento/UrlRewrite/sql/urlrewrite_setup/install-1.0.0.0.php
index a443f9e819c..ff6c4a26e0f 100644
--- a/app/code/Magento/UrlRewrite/sql/urlrewrite_setup/install-1.0.0.0.php
+++ b/app/code/Magento/UrlRewrite/sql/urlrewrite_setup/install-1.0.0.0.php
@@ -28,10 +28,10 @@ $installer = $this;
 $installer->startSetup();
 
 /**
- * Create table 'core_url_rewrite'
+ * Create table 'url_rewrite'
  */
 $table = $installer->getConnection()->newTable(
-    $installer->getTable('core_url_rewrite')
+    $installer->getTable('url_rewrite')
 )->addColumn(
     'url_rewrite_id',
     \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
@@ -39,17 +39,17 @@ $table = $installer->getConnection()->newTable(
     array('identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true),
     'Rewrite Id'
 )->addColumn(
-    'store_id',
-    \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
-    null,
-    array('unsigned' => true, 'nullable' => false, 'default' => '0'),
-    'Store Id'
-)->addColumn(
-    'id_path',
+    'entity_type',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-    255,
-    array(),
-    'Id Path'
+    32,
+    array('nullable' => false),
+    'Entity type code'
+)->addColumn(
+    'entity_id',
+    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+    null,
+    array('unsigned' => true, 'nullable' => false),
+    'Entity ID'
 )->addColumn(
     'request_path',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
@@ -63,52 +63,49 @@ $table = $installer->getConnection()->newTable(
     array(),
     'Target Path'
 )->addColumn(
-    'is_system',
+    'redirect_type',
+    \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
+    null,
+    array('unsigned' => true, 'nullable' => false, 'default' => '0'),
+    'Redirect Type'
+)->addColumn(
+    'store_id',
     \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
     null,
-    array('unsigned' => true, 'default' => '1'),
-    'Defines is Rewrite System'
+    array('unsigned' => true, 'nullable' => false),
+    'Store Id'
 )->addColumn(
-    'options',
+    'description',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
     255,
-    array('nullable' => true),
-    'Options'
+    array(),
+    'Description'
 )->addColumn(
-    'description',
+    'is_autogenerated',
+    \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
+    null,
+    array('unsigned' => true, 'nullable' => false, 'default' => 0),
+    'Is rewrite generated automatically flag'
+)->addColumn(
+    'metadata',
     \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
     255,
     array(),
-    'Deascription'
+    'Meta data for url rewrite'
 )->addIndex(
     $installer->getIdxName(
-        'core_url_rewrite',
+        'url_rewrite',
         array('request_path', 'store_id'),
         \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
     ),
     array('request_path', 'store_id'),
     array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE)
 )->addIndex(
-    $installer->getIdxName(
-        'core_url_rewrite',
-        array('id_path', 'is_system', 'store_id'),
-        \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
-    ),
-    array('id_path', 'is_system', 'store_id'),
-    array('type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE)
+    $installer->getIdxName('url_rewrite', array('target_path')),
+    array('target_path')
 )->addIndex(
-    $installer->getIdxName('core_url_rewrite', array('target_path', 'store_id')),
-    array('target_path', 'store_id')
-)->addIndex(
-    $installer->getIdxName('core_url_rewrite', array('store_id')),
-    array('store_id')
-)->addForeignKey(
-    $installer->getFkName('core_url_rewrite', 'store_id', 'store', 'store_id'),
-    'store_id',
-    $installer->getTable('store'),
-    'store_id',
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+    $installer->getIdxName('url_rewrite', array('store_id', 'entity_id')),
+    array('store_id', 'entity_id')
 )->setComment(
     'Url Rewrites'
 );
diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml b/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml
similarity index 90%
rename from app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml
rename to app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml
index 166d657a924..430ee813e38 100644
--- a/app/code/Magento/UrlRedirect/view/adminhtml/layout/adminhtml_urlredirect_index.xml
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/layout/adminhtml_url_rewrite_index.xml
@@ -25,14 +25,14 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
     <referenceContainer name="content">
-        <block class="Magento\UrlRedirect\Block\GridContainer" name="adminhtml.block.urlredirect.grid.container">
-            <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.urlredirect.grid" as="grid">
+        <block class="Magento\UrlRewrite\Block\GridContainer" name="adminhtml.block.url_rewrite.grid.container">
+            <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.url_rewrite.grid" as="grid">
                 <arguments>
-                    <argument name="id" xsi:type="string">urlredirectGrid</argument>
-                    <argument name="dataSource" xsi:type="object">Magento\UrlRedirect\Model\Resource\UrlRedirect\Collection</argument>
+                    <argument name="id" xsi:type="string">urlrewriteGrid</argument>
+                    <argument name="dataSource" xsi:type="object">Magento\UrlRewrite\Model\Resource\UrlRewriteCollection</argument>
                     <argument name="default_sort" xsi:type="string">url_rewrite_id</argument>
                 </arguments>
-                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="adminhtml.urlredirect.grid.columnSet">
+                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="adminhtml.url_rewrite.grid.columnSet">
                     <arguments>
                         <argument name="rowUrl" xsi:type="array">
                             <item name="path" xsi:type="string">adminhtml/*/edit</item>
@@ -76,12 +76,13 @@
                             <argument name="index" xsi:type="string">target_path</argument>
                         </arguments>
                     </block>
-                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="options">
+                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="redirect_type">
                         <arguments>
-                            <argument name="header" xsi:type="string" translate="true">Options</argument>
-                            <argument name="type" xsi:type="string">text</argument>
-                            <argument name="id" xsi:type="string">options</argument>
-                            <argument name="index" xsi:type="string">options</argument>
+                            <argument name="header" xsi:type="string" translate="true">Redirect Type</argument>
+                            <argument name="type" xsi:type="string">options</argument>
+                            <argument name="id" xsi:type="string">redirect_type</argument>
+                            <argument name="index" xsi:type="string">redirect_type</argument>
+                            <argument name="options" xsi:type="options" model="Magento\UrlRewrite\Model\OptionProvider"/>
                         </arguments>
                     </block>
                     <block class="Magento\Backend\Block\Widget\Grid\Column" as="actions">
diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
similarity index 96%
rename from app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml
rename to app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
index c5888579d54..40f36819c34 100644
--- a/app/code/Magento/UrlRedirect/view/adminhtml/templates/categories.phtml
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/** @var $this \Magento\UrlRedirect\Block\Catalog\Category\Tree */
+/** @var $this \Magento\UrlRewrite\Block\Catalog\Category\Tree */
 ?>
 <fieldset class="fieldset" data-ui-id="category-selector">
     <legend class="legend"><span><?php echo __('Select Category') ?></span></legend>
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/edit.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml
similarity index 94%
rename from app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/edit.phtml
rename to app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml
index 4ae6d3fe83b..1d77a8fc846 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/urlrewrite/edit.phtml
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml
@@ -21,11 +21,8 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
 /**
- * Urlrewrites edit container
- *
- * @see \Magento\Backend\Block\Urlrewrite\Edit
+ * @var $this \Magento\UrlRewrite\Block\Edit
  */
 ?>
 <?php echo $this->getChildHtml() ?>
diff --git a/app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml
similarity index 76%
rename from app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml
rename to app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml
index c6db4f73ad9..4f7945adfa5 100644
--- a/app/code/Magento/UrlRedirect/view/adminhtml/templates/selector.phtml
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml
@@ -21,15 +21,15 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/** @var $this \Magento\UrlRedirect\Block\Selector */
+/** @var $this \Magento\UrlRewrite\Block\Selector */
 ?>
 <div class="form-inline">
-    <fieldset class="fieldset" data-ui-id="entity-type-selector">
-        <div class="field field-url-rewrite-option-select">
-            <label for="url-rewrite-option-select" class="label"><?php echo $this->getSelectorLabel() ?></label>
+    <fieldset class="fieldset" data-container-for="entity-type-selector">
+        <div class="field field-entity-type-selector">
+            <label for="entity-type-selector" class="label"><?php echo $this->getSelectorLabel() ?></label>
             <div class="control">
                 <?php $url = $this->helper('Magento\Backend\Helper\Data')->getUrl('adminhtml/*/*')?>
-                <select id="url-rewrite-option-select" class="select" onchange="window.location = this.value;">
+                <select data-role="entity-type-selector" class="select" onchange="window.location = this.value;" id="entity-type-selector">
                 <?php foreach ($this->getModes() as $mode => $label): ?>
                     <option <?php echo ($this->isMode($mode) ? 'selected="selected" ' :'' ) ?>value="<?php echo $url . $mode ?>"><?php echo $label ?></option>
                 <?php endforeach; ?>
diff --git a/app/code/Magento/User/Block/User/Edit/Tab/Main.php b/app/code/Magento/User/Block/User/Edit/Tab/Main.php
index b4431dffa24..b6e570b0599 100644
--- a/app/code/Magento/User/Block/User/Edit/Tab/Main.php
+++ b/app/code/Magento/User/Block/User/Edit/Tab/Main.php
@@ -30,6 +30,8 @@ namespace Magento\User\Block\User\Edit\Tab;
  */
 class Main extends \Magento\Backend\Block\Widget\Form\Generic
 {
+    const CURRENT_USER_PASSWORD_FIELD = 'current_password';
+
     /**
      * @var \Magento\Backend\Model\Auth\Session
      */
@@ -76,17 +78,17 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
         $form = $this->_formFactory->create();
         $form->setHtmlIdPrefix('user_');
 
-        $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('Account Information')));
+        $baseFieldset = $form->addFieldset('base_fieldset', array('legend' => __('Account Information')));
 
         if ($model->getUserId()) {
-            $fieldset->addField('user_id', 'hidden', array('name' => 'user_id'));
+            $baseFieldset->addField('user_id', 'hidden', array('name' => 'user_id'));
         } else {
             if (!$model->hasData('is_active')) {
                 $model->setIsActive(1);
             }
         }
 
-        $fieldset->addField(
+        $baseFieldset->addField(
             'username',
             'text',
             array(
@@ -98,7 +100,7 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
             )
         );
 
-        $fieldset->addField(
+        $baseFieldset->addField(
             'firstname',
             'text',
             array(
@@ -110,7 +112,7 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
             )
         );
 
-        $fieldset->addField(
+        $baseFieldset->addField(
             'lastname',
             'text',
             array(
@@ -122,7 +124,7 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
             )
         );
 
-        $fieldset->addField(
+        $baseFieldset->addField(
             'email',
             'text',
             array(
@@ -142,9 +144,9 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
             $passwordLabel = __('New Password');
         }
         $confirmationLabel = __('Password Confirmation');
-        $this->_addPasswordFields($fieldset, $passwordLabel, $confirmationLabel, $isNewObject);
+        $this->_addPasswordFields($baseFieldset, $passwordLabel, $confirmationLabel, $isNewObject);
 
-        $fieldset->addField(
+        $baseFieldset->addField(
             'interface_locale',
             'select',
             array(
@@ -157,7 +159,7 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
         );
 
         if ($this->_authSession->getUser()->getId() != $model->getUserId()) {
-            $fieldset->addField(
+            $baseFieldset->addField(
                 'is_active',
                 'select',
                 array(
@@ -172,12 +174,30 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic
             );
         }
 
-        $fieldset->addField('user_roles', 'hidden', array('name' => 'user_roles', 'id' => '_user_roles'));
+        $baseFieldset->addField('user_roles', 'hidden', array('name' => 'user_roles', 'id' => '_user_roles'));
 
-        $data = $model->getData();
 
-        unset($data['password']);
 
+        $currentUserVerificationFieldset = $form->addFieldset(
+            'current_user_verification_fieldset',
+            ['legend' => __('Current User Identity Verification')]
+        );
+        $currentUserVerificationFieldset->addField(
+            self::CURRENT_USER_PASSWORD_FIELD,
+            'password',
+            array(
+                'name' => self::CURRENT_USER_PASSWORD_FIELD,
+                'label' => __('Your Password'),
+                'id' => self::CURRENT_USER_PASSWORD_FIELD,
+                'title' => __('Your Password'),
+                'class' => 'input-text validate-current-password required-entry',
+                'required' => true
+            )
+        );
+
+        $data = $model->getData();
+        unset($data['password']);
+        unset($data[self::CURRENT_USER_PASSWORD_FIELD]);
         $form->setValues($data);
 
         $this->setForm($form);
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php
index 851cdc706ef..6e76fa780d0 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php
@@ -48,7 +48,6 @@ class EditRole extends \Magento\User\Controller\Adminhtml\User\Role
 
         $this->_addBreadcrumb($breadCrumb, $breadCrumbTitle);
 
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
         $this->_view->getLayout()->getBlock(
             'adminhtml.user.role.buttons'
         )->setRoleId(
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
index 5103bf66175..ec73d1a22e3 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
@@ -50,6 +50,7 @@ class Save extends \Magento\User\Controller\Adminhtml\User
             $model->setRoleId($uRoles[0]);
         }
 
+        /** @var $currentUser \Magento\User\Model\User */
         $currentUser = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser();
         if ($userId == $currentUser->getId() && $this->_objectManager->get(
             'Magento\Framework\Locale\Validator'
@@ -64,15 +65,29 @@ class Save extends \Magento\User\Controller\Adminhtml\User
             );
         }
 
+        /** Before updating admin user data, ensure that password of current admin user is entered and is correct */
+        $currentUserPasswordField = \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD;
+        $isCurrentUserPasswordValid = isset($data[$currentUserPasswordField])
+            && !empty($data[$currentUserPasswordField]) && is_string($data[$currentUserPasswordField]);
         try {
+            if (!($isCurrentUserPasswordValid && $currentUser->verifyIdentity($data[$currentUserPasswordField]))) {
+                throw new \Magento\Backend\Model\Auth\Exception(
+                    __('You have entered an invalid password for current user.')
+                );
+            }
             $model->save();
             $this->messageManager->addSuccess(__('You saved the user.'));
             $this->_getSession()->setUserData(false);
             $this->_redirect('adminhtml/*/');
         } catch (\Magento\Framework\Model\Exception $e) {
             $this->messageManager->addMessages($e->getMessages());
+            if ($e->getMessage()) {
+                $this->messageManager->addError($e->getMessage());
+            }
             $this->_getSession()->setUserData($data);
-            $this->_redirect('adminhtml/*/edit', array('_current' => true));
+            $arguments = $model->getId() ? ['user_id' => $model->getId()] : [];
+            $arguments = array_merge($arguments, ['_current' => true]);
+            $this->_redirect('adminhtml/*/edit', $arguments);
         }
     }
 }
diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php
index 400c0330ef7..1b9260fb773 100644
--- a/app/code/Magento/User/Model/User.php
+++ b/app/code/Magento/User/Model/User.php
@@ -571,15 +571,8 @@ class User extends AbstractModel implements StorageInterface
             );
             $this->loadByUsername($username);
             $sensitive = $config ? $username == $this->getUsername() : true;
-
-            if ($sensitive && $this->getId() && $this->_encryptor->validateHash($password, $this->getPassword())) {
-                if ($this->getIsActive() != '1') {
-                    throw new \Magento\Backend\Model\Auth\Exception(__('This account is inactive.'));
-                }
-                if (!$this->hasAssigned2Role($this->getId())) {
-                    throw new \Magento\Backend\Model\Auth\Exception(__('Access denied.'));
-                }
-                $result = true;
+            if ($sensitive && $this->getId()) {
+                $result = $this->verifyIdentity($password);
             }
 
             $this->_eventManager->dispatch(
@@ -597,6 +590,28 @@ class User extends AbstractModel implements StorageInterface
         return $result;
     }
 
+    /**
+     * Ensure that provided password matches the current user password. Check if the current user account is active.
+     *
+     * @param string $password
+     * @return bool
+     * @throws \Magento\Backend\Model\Auth\Exception
+     */
+    public function verifyIdentity($password)
+    {
+        $result = false;
+        if ($this->_encryptor->validateHash($password, $this->getPassword())) {
+            if ($this->getIsActive() != '1') {
+                throw new \Magento\Backend\Model\Auth\Exception(__('This account is inactive.'));
+            }
+            if (!$this->hasAssigned2Role($this->getId())) {
+                throw new \Magento\Backend\Model\Auth\Exception(__('Access denied.'));
+            }
+            $result = true;
+        }
+        return $result;
+    }
+
     /**
      * Login user
      *
diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json
index bac3f0ebb18..6db87fb5083 100644
--- a/app/code/Magento/User/composer.json
+++ b/app/code/Magento/User/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-authorization": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-integration": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-authorization": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-integration": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json
index 995cb00ac7a..ebab020361b 100644
--- a/app/code/Magento/Usps/composer.json
+++ b/app/code/Magento/Usps/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-shipping": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-shipping": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Webapi/Controller/ServiceArgsSerializer.php b/app/code/Magento/Webapi/Controller/ServiceArgsSerializer.php
index 1b40db6cbf4..49e55065c93 100644
--- a/app/code/Magento/Webapi/Controller/ServiceArgsSerializer.php
+++ b/app/code/Magento/Webapi/Controller/ServiceArgsSerializer.php
@@ -150,6 +150,7 @@ class ServiceArgsSerializer
     protected function _createFromArray($class, $data)
     {
         $className = is_string($class) ? $class : $class->getName();
+        $data = is_array($data) ? $data : [];
         $builder = $this->_objectManager->create($className . "Builder");
         $class = new ClassReflection($className);
         foreach ($data as $propertyName => $value) {
diff --git a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
index d6a84c81e96..89bb7ea0686 100644
--- a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
+++ b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
@@ -110,9 +110,6 @@ class Handler
         }
 
         $isAllowed = false;
-        $serviceMethodInfo[SoapConfig::KEY_ACL_RESOURCES] = array_values(
-            $serviceMethodInfo[SoapConfig::KEY_ACL_RESOURCES][0]
-        );
         foreach ($serviceMethodInfo[SoapConfig::KEY_ACL_RESOURCES] as $resource) {
             if ($this->_authorization->isAllowed($resource)) {
                 $isAllowed = true;
diff --git a/app/code/Magento/Webapi/Model/Config/ClassReflector/TypeProcessor.php b/app/code/Magento/Webapi/Model/Config/ClassReflector/TypeProcessor.php
index d88613edaa3..84c029afdab 100644
--- a/app/code/Magento/Webapi/Model/Config/ClassReflector/TypeProcessor.php
+++ b/app/code/Magento/Webapi/Model/Config/ClassReflector/TypeProcessor.php
@@ -24,6 +24,7 @@
 namespace Magento\Webapi\Model\Config\ClassReflector;
 
 use Zend\Code\Reflection\ClassReflection;
+use Magento\Webapi\Exception as WebapiException;
 
 /**
  * Type processor of config reader properties
@@ -444,19 +445,22 @@ class TypeProcessor
     public function processSimpleAndAnyType($value, $type)
     {
         $invalidTypeMsg = 'Invalid type for value :"%s". Expected Type: "%s".';
-        if ($this->isArrayType($type) && is_array($value)) {
+        $isArrayType = $this->isArrayType($type);
+        if ($isArrayType && is_array($value)) {
             $arrayItemType = $this->getArrayItemType($type);
             foreach (array_keys($value) as $key) {
                 if ($value !== null && !settype($value[$key], $arrayItemType)) {
-                    throw new \Magento\Webapi\Exception(sprintf($invalidTypeMsg, $value, $type));
+                    throw new WebapiException(sprintf($invalidTypeMsg, $value, $type));
                 }
             }
-        } elseif (!$this->isArrayType($type) && !is_array($value)) {
+        } elseif ($isArrayType && is_null($value)) {
+            return null;
+        } elseif (!$isArrayType && !is_array($value)) {
             if ($value !== null && $type !== self::ANY_TYPE && !settype($value, $type)) {
-                throw new \Magento\Webapi\Exception(sprintf($invalidTypeMsg, $value, $type));
+                throw new WebapiException(sprintf($invalidTypeMsg, $value, $type));
             }
         } else {
-            throw new \Magento\Webapi\Exception(sprintf($invalidTypeMsg, $value, $type));
+            throw new WebapiException(sprintf($invalidTypeMsg, $value, $type));
         }
         return $value;
     }
diff --git a/app/code/Magento/Webapi/Model/Config/Converter.php b/app/code/Magento/Webapi/Model/Config/Converter.php
index d3769681b93..8c6bc7fa3e7 100644
--- a/app/code/Magento/Webapi/Model/Config/Converter.php
+++ b/app/code/Magento/Webapi/Model/Config/Converter.php
@@ -80,8 +80,18 @@ class Converter implements \Magento\Framework\Config\ConverterInterface
                 // For SOAP
                 $resourcePermissionSet[] = $ref;
             }
-            $result[self::KEY_SERVICES][$serviceClass][$serviceMethod][self::KEY_ACL_RESOURCES][]
-                = $resourcePermissionSet;
+            if (!isset($result[self::KEY_SERVICES][$serviceClass][$serviceMethod][self::KEY_ACL_RESOURCES])) {
+                $result[self::KEY_SERVICES][$serviceClass][$serviceMethod][self::KEY_ACL_RESOURCES]
+                    = $resourcePermissionSet;
+            } else {
+                $result[self::KEY_SERVICES][$serviceClass][$serviceMethod][self::KEY_ACL_RESOURCES] =
+                    array_unique(
+                        array_merge(
+                            $result[self::KEY_SERVICES][$serviceClass][$serviceMethod][self::KEY_ACL_RESOURCES],
+                            $resourcePermissionSet
+                        )
+                    );
+            }
 
             $parameters = $route->getElementsByTagName('parameter');
             $data = [];
diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json
index b0b40a27d9e..5774dfbea9d 100644
--- a/app/code/Magento/Webapi/composer.json
+++ b/app/code/Magento/Webapi/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-authorization": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-integration": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-user": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-authorization": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-integration": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-user": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Weee/Pricing/Render/Adjustment.php b/app/code/Magento/Weee/Pricing/Render/Adjustment.php
index 3e491a8e931..82c5b8772c6 100644
--- a/app/code/Magento/Weee/Pricing/Render/Adjustment.php
+++ b/app/code/Magento/Weee/Pricing/Render/Adjustment.php
@@ -139,14 +139,25 @@ class Adjustment extends AbstractAdjustment
     }
 
     /**
-     * Render Weee tax attributes
+     * Render Weee tax attributes name
+     *
+     * @param \Magento\Framework\Object $attribute
+     * @return string
+     */
+    public function renderWeeeTaxAttributeName(\Magento\Framework\Object $attribute)
+    {
+        return $attribute->getData('name');
+    }
+
+    /**
+     * Render Weee tax attributes value
      *
      * @param \Magento\Framework\Object $attribute
      * @return string
      */
     public function renderWeeeTaxAttribute(\Magento\Framework\Object $attribute)
     {
-        return $attribute->getData('name') . ': ' . $this->convertAndFormatCurrency($attribute->getData('amount'));
+        return $this->convertAndFormatCurrency($attribute->getData('amount'));
     }
 
     /**
diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json
index 22f3c292be7..4579e60f538 100644
--- a/app/code/Magento/Weee/composer.json
+++ b/app/code/Magento/Weee/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-tax": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-directory": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-eav": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-bundle": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-tax": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-directory": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-eav": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-bundle": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml b/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
index 6a9f52ecb4c..366c50e1c29 100644
--- a/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
+++ b/app/code/Magento/Weee/view/base/templates/pricing/adjustment.phtml
@@ -30,21 +30,14 @@ $weeeSeparator = $openBrace = $closeBrace = '';
 $openBrace = '(';
 $closeBrace = ')';
 ?>
-
 <?php if ($this->showInclDescr()): // incl. + weee ?>
-    <span class="weee"><?php echo $openBrace ?>
-        <?php foreach ($this->getWeeeTaxAttributes() as $weeeTaxAttribute): ?>
-            <?php echo $weeeSeparator; ?>
-            <?php echo $this->renderWeeeTaxAttribute($weeeTaxAttribute); ?>
-            <?php $weeeSeparator = ' + '; ?>
-        <?php endforeach; ?>
-        <?php echo $closeBrace ?></span>
+    <?php foreach ($this->getWeeeTaxAttributes() as $weeeTaxAttribute): ?>
+        <span class="weee"
+              data-label="<?php echo $this->renderWeeeTaxAttributeName($weeeTaxAttribute); ?>"><?php echo $this->renderWeeeTaxAttribute($weeeTaxAttribute); ?></span>
+    <?php endforeach; ?>
 <?php elseif ($this->showExclDescrIncl()): // excl. + weee + final ?>
-    <?php echo $openBrace ?>
     <?php foreach ($this->getWeeeTaxAttributes() as $weeeTaxAttribute): ?>
-        <span class="weee">
-            <?php echo $this->renderWeeeTaxAttribute($weeeTaxAttribute); ?>
-        </span>
+        <span class="weee"
+              data-label="<?php echo $this->renderWeeeTaxAttributeName($weeeTaxAttribute); ?>"><?php echo $this->renderWeeeTaxAttribute($weeeTaxAttribute); ?></span>
     <?php endforeach; ?>
-    <?php echo $closeBrace ?>
 <?php endif; ?>
diff --git a/app/code/Magento/Weee/view/frontend/layout/default.xml b/app/code/Magento/Weee/view/frontend/layout/default.xml
index c0883d3b2bc..28642f37db4 100644
--- a/app/code/Magento/Weee/view/frontend/layout/default.xml
+++ b/app/code/Magento/Weee/view/frontend/layout/default.xml
@@ -23,6 +23,4 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head"></referenceBlock>
-</page>
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd"/>
diff --git a/app/code/Magento/Weee/view/frontend/templates/checkout/cart/item/price/sidebar.phtml b/app/code/Magento/Weee/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
index 8b8c19ddaf2..1d650545f4d 100644
--- a/app/code/Magento/Weee/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/checkout/cart/item/price/sidebar.phtml
@@ -25,63 +25,64 @@
 /** @var $this \Magento\Weee\Block\Item\Price\Renderer */
 ?>
 <?php $_item = $this->getItem() ?>
-<div class="pricing details<?php echo $this->displayBothPrices() ? ' complex' : ''; ?>">
-    <?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
-        <div class="rate">
-            <?php if ($this->displayBothPrices()): ?>
-                <span class="label excl tax"><?php echo __('Excl. Tax'); ?></span>
-            <?php else: ?>
-                <span class="label display"><?php echo __('Price'); ?></span>
-            <?php endif; ?>
-            <span class="value display">
-                <?php echo $this->formatPrice($this->getUnitDisplayPriceExclTax()) ?>
+<?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
+    <?php $_incl = $this->getPriceInclTax($_item); ?>
+    <?php if ($this->displayBothPrices()): ?>
+        <div class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax'));?>">
+    <?php else: ?>
+        <div class="price-minicart" data-label="<?php echo $this->escapeHtml(__('Price'));?>">
+            <span class="label">
+                <?php echo $this->escapeHtml(__('Price'));?>
             </span>
+    <?php endif; ?>
+            <?php echo $this->formatPrice($this->getUnitDisplayPriceInclTax()) ?>
         </div>
+    <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
+        <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
+            <div class="weee" data-label="<?php echo $tax['title']; ?>">
+                <span class="label">
+                    <?php echo $tax['title']; ?>
+                </span>
+                <?php echo $this->formatPrice($tax['amount_incl_tax'],true,true); ?>
+            </div>
+        <?php endforeach; ?>
 
-        <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
-            <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-                <div class="rate weee">
-                    <span class="label weee"><?php echo $tax['title']; ?></span>
-                    <span class="value weee"><?php echo $this->formatPrice($tax['amount'],true,true); ?></span>
-                </div>
-            <?php endforeach; ?>
-
-            <?php if ($this->displayFinalPrice()): ?>
-                <div class="rate weee total">
-                    <span class="label weee"><?php echo __('Total:'); ?></span>
-                    <span class="value weee"><?php echo $this->formatPrice($this->getFinalUnitDisplayPriceExclTax()); ?></span>
-                </div>
-            <?php endif; ?>
+        <?php if ($this->displayFinalPrice()): ?>
+            <div class="rate weee total">
+                <span class="label"><?php echo __('Total'); ?></span>
+                <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceInclTax()); ?>
+            </div>
         <?php endif; ?>
     <?php endif; ?>
+<?php endif; ?>
 
-<?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
-<?php $_incl = $this->getPriceInclTax($_item); ?>
-    <div class="rate">
-        <?php if ($this->displayBothPrices()): ?>
-            <span class="label tax incl"><?php echo __('Incl. Tax'); ?></span>
-        <?php else: ?>
-            <span class="label display"><?php echo __('Price'); ?></span>
-        <?php endif; ?>
+<?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
+    <?php if ($this->displayBothPrices()): ?>
+        <div class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax'));?>">
+    <?php else: ?>
+        <div class="price-minicart" data-label="<?php echo $this->escapeHtml(__('Price'));?>">
+            <span class="label">
+                <?php echo $this->escapeHtml(__('Price'));?>
+            </span>
+    <?php endif; ?>
+            <?php echo $this->formatPrice($this->getUnitDisplayPriceExclTax()) ?>
+        </div>
 
-        <span class="value display">
-                <?php echo $this->formatPrice($this->getUnitDisplayPriceInclTax()) ?>
-        </span>
-    </div>
     <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
         <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-            <div class="rate weee">
-                <span class="label weee"><?php echo $tax['title']; ?></span>
-                <span class="value weee"><?php echo $this->formatPrice($tax['amount_incl_tax'],true,true); ?></span>
+            <div class="weee" data-label="<?php echo $tax['title']; ?>">
+                <span class="label">
+                    <?php echo $tax['title']; ?>
+                </span>
+                <?php echo $this->formatPrice($tax['amount'],true,true); ?>
             </div>
         <?php endforeach; ?>
 
         <?php if ($this->displayFinalPrice()): ?>
             <div class="rate weee total">
-                <span class="label weee"><?php echo __('Total:'); ?></span>
-                <span class="value weee"><?php echo $this->formatPrice($this->getFinalUnitDisplayPriceInclTax()); ?></span>
+                <span class="label"><?php echo __('Total'); ?></span>
+                <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceExclTax()); ?>
             </div>
         <?php endif; ?>
     <?php endif; ?>
 <?php endif; ?>
-</div>
diff --git a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_excl_tax.phtml b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_excl_tax.phtml
index c0229fe426c..7409194edf5 100644
--- a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_excl_tax.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_excl_tax.phtml
@@ -27,29 +27,27 @@
 $_item = $this->getItem();
 ?>
 <?php if ($this->displayPriceWithWeeeDetails()): ?>
-    <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
+    <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
 <?php else: ?>
-    <span class="cart price">
+    <span class="cart-price">
 <?php endif; ?>
-
 <?php echo $this->formatPrice($this->getRowDisplayPriceExclTax()); ?>
     </span>
 
 <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
-    <div class="cart tax info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;">
+    <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display: none;">
     <?php if ($this->displayPriceWithWeeeDetails()): ?>
         <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-            <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->formatPrice($tax['row_amount'],true,true); ?></span>
+            <span class="weee" data-label="<?php echo $tax['title']; ?>"><?php echo $this->formatPrice($tax['row_amount'],true,true); ?></span>
         <?php endforeach; ?>
     <?php endif; ?>
-    </div>
+    </span>
 
     <?php if ($this->displayFinalPrice()): ?>
-        <div class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
-            <span class="weee"><?php echo __('Total'); ?>:<br />
+        <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
+            <span class="weee" data-label="<?php echo __('Total'); ?>">
                 <?php echo $this->formatPrice($this->getFinalRowDisplayPriceExclTax()); ?>
             </span>
-        </div>
+        </span>
     <?php endif; ?>
 <?php endif; ?>
-
diff --git a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_incl_tax.phtml b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_incl_tax.phtml
index dab120b2152..1d5d0b34024 100644
--- a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_incl_tax.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/row_incl_tax.phtml
@@ -30,27 +30,27 @@ $_weeeHelper = $this->helper('Magento\Weee\Helper\Data');
 ?>
 <?php $_incl = $_item->getRowTotalInclTax(); ?>
 <?php if ($this->displayPriceWithWeeeDetails()): ?>
-    <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
+    <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
 <?php else: ?>
-    <span class="cart price">
+    <span class="cart-price">
 <?php endif; ?>
 <?php echo $this->formatPrice($this->getRowDisplayPriceInclTax()); ?>
     </span>
 
 <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
-    <div class="cart tax info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;">
+    <span class="cart-tax-info" id="subtotal-item-tax-details<?php echo $_item->getId(); ?>" style="display: none;">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-                <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span>
+                <span class="weee" data-label="<?php echo $tax['title']; ?>"><?php echo $this->formatPrice($tax['row_amount_incl_tax'],true,true); ?></span>
             <?php endforeach; ?>
         <?php endif; ?>
-    </div>
+    </span>
 
     <?php if ($this->displayFinalPrice()): ?>
-        <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
-            <span class="weee"><?php echo __('Total incl. tax'); ?>:<br />
+        <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $_item->getId(); ?>"}'>
+            <span class="weee" data-label="<?php echo __('Total incl. tax'); ?>">
                 <?php echo $this->formatPrice($this->getFinalRowDisplayPriceInclTax()); ?>
             </span>
-        </div>
+        </span>
     <?php endif; ?>
 <?php endif; ?>
diff --git a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_excl_tax.phtml b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_excl_tax.phtml
index d0699e03a57..a83eacc60f6 100644
--- a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_excl_tax.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_excl_tax.phtml
@@ -27,28 +27,28 @@
 $_item = $this->getItem();
 ?>
 <?php if ($this->displayPriceWithWeeeDetails()): ?>
-    <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'>
+    <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'>
 <?php else: ?>
-    <span class="cart price">
+    <span class="cart-price">
 <?php endif; ?>
 
 <?php echo $this->formatPrice($this->getUnitDisplayPriceExclTax()); ?>
     </span>
 
 <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
-    <div class="cart tax info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;">
+    <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;">
     <?php if ($this->displayPriceWithWeeeDetails()): ?>
         <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-            <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->formatPrice($tax['amount'],true,true); ?></span>
+            <span class="weee" data-label="<?php echo $tax['title']; ?>"><?php echo $this->formatPrice($tax['amount'],true,true); ?></span>
         <?php endforeach; ?>
     <?php endif; ?>
-    </div>
+    </span>
 
     <?php if ($this->displayFinalPrice()): ?>
-        <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'>
-            <span class="weee"><?php echo __('Total'); ?><br />
+        <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $_item->getId(); ?>"}'>
+            <span class="weee" data-label="<?php echo __('Total'); ?>">
                 <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceExclTax()); ?>
             </span>
-        </div>
+        </span>
     <?php endif; ?>
 <?php endif; ?>
diff --git a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_incl_tax.phtml b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_incl_tax.phtml
index a3dfa7bbb0f..058bf378f15 100644
--- a/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_incl_tax.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/checkout/onepage/review/item/price/unit_incl_tax.phtml
@@ -30,28 +30,28 @@ $_weeeHelper = $this->helper('Magento\Weee\Helper\Data');
 ?>
 <?php $_incl = $_item->getPriceInclTax(); ?>
 <?php if ($this->displayPriceWithWeeeDetails()): ?>
-    <span class="cart tax total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'>
+    <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'>
 <?php else: ?>
-    <span class="cart price">
+    <span class="cart-price">
 <?php endif; ?>
 
 <?php echo $this->formatPrice($this->getUnitDisplayPriceInclTax()); ?>
     </span>
 
 <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item)): ?>
-    <div class="cart-tax-info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display:none;">
+    <span class="cart-tax-info" id="unit-item-tax-details<?php echo $_item->getId(); ?>" style="display: none;">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($_item) as $tax): ?>
-                <span class="weee"><?php echo $tax['title']; ?>: <?php echo $this->formatPrice($tax['amount_incl_tax'],true,true); ?></span>
+                <span class="weee" data-label="<?php echo $tax['title']; ?>"><?php echo $this->formatPrice($tax['amount_incl_tax'],true,true); ?></span>
             <?php endforeach; ?>
         <?php endif; ?>
-    </div>
+    </span>
 
     <?php if ($this->displayFinalPrice()): ?>
-        <div class="cart tax total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'>
-            <span class="weee"><?php echo __('Total incl. tax'); ?>:<br />
+        <span class="cart-tax-total" data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $_item->getId(); ?>"}'>
+            <span class="weee" data-label="<?php echo __('Total incl. tax'); ?>">
                 <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceInclTax()); ?>
             </span>
-        </div>
+        </span>
     <?php endif; ?>
-<?php endif; ?>
\ No newline at end of file
+<?php endif; ?>
diff --git a/app/code/Magento/Weee/view/frontend/templates/item/price/row.phtml b/app/code/Magento/Weee/view/frontend/templates/item/price/row.phtml
index b56723ae6ab..1baed7527d7 100644
--- a/app/code/Magento/Weee/view/frontend/templates/item/price/row.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/item/price/row.phtml
@@ -27,12 +27,12 @@
 $item = $this->getItem();
 ?>
 <?php if (($this->displayPriceInclTax() || $this->displayBothPrices()) && !$item->getNoSubtotal()): ?>
-    <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
+    <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <span class="cart-tax-total"
                 data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $item->getId(); ?>"}'>
         <?php else: ?>
-            <span class="cart price">
+            <span class="cart-price">
         <?php endif; ?>
                 <?php echo $this->formatPrice($this->getRowDisplayPriceInclTax()); ?>
             </span>
@@ -40,52 +40,52 @@ $item = $this->getItem();
         <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($item)): ?>
             <div class="cart-tax-info" id="subtotal-item-tax-details<?php echo $item->getId(); ?>" style="display: none;">
                 <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($item) as $tax): ?>
-                    <span class="weee" data-th="<?php echo $tax['title']; ?>">
+                    <span class="weee" data-label="<?php echo $tax['title']; ?>">
                         <?php echo $this->formatPrice($tax['row_amount_incl_tax'], true, true); ?>
                     </span>
                 <?php endforeach; ?>
             </div>
 
             <?php if ($this->displayFinalPrice()): ?>
-                <div class="cart-tax-total"
+                <span class="cart-tax-total"
                     data-tax-toggle='{"itemTaxId" : "#subtotal-item-tax-details<?php echo $item->getId(); ?>"}'>
-                    <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>">
+                    <span class="weee" data-label="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>">
                         <?php echo $this->formatPrice($this->getFinalRowDisplayPriceInclTax()); ?>
                     </span>
-                </div>
+                </span>
             <?php endif; ?>
         <?php endif; ?>
     </span>
 <?php endif; ?>
 
 <?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
-    <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+    <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <span class="cart-tax-total"
                 data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $item->getId(); ?>"}'>
         <?php else: ?>
-            <span class="cart price">
+            <span class="cart-price">
         <?php endif; ?>
                 <?php echo $this->formatPrice($this->getRowDisplayPriceExclTax()); ?>
             </span>
 
         <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($item)): ?>
-            <div class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $item->getId(); ?>"
-                style="display:none;">
+            <span class="cart-tax-info" id="esubtotal-item-tax-details<?php echo $item->getId(); ?>"
+                style="display: none;">
                 <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($item) as $tax): ?>
-                    <span class="weee" data-th="<?php echo $tax['title']; ?>">
+                    <span class="weee" data-label="<?php echo $tax['title']; ?>">
                         <?php echo $this->formatPrice($tax['row_amount'], true, true); ?>
                     </span>
                 <?php endforeach; ?>
-            </div>
+            </span>
 
             <?php if ($this->displayFinalPrice()): ?>
-                <div class="cart-tax-total"
+                <span class="cart-tax-total"
                     data-tax-toggle='{"itemTaxId" : "#esubtotal-item-tax-details<?php echo $item->getId(); ?>"}'>
-                    <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>">
+                    <span class="weee" data-label="<?php echo $this->escapeHtml(__('Total')); ?>">
                         <?php echo $this->formatPrice($this->getFinalRowDisplayPriceExclTax()); ?>
                     </span>
-                </div>
+                </span>
             <?php endif; ?>
         <?php endif; ?>
     </span>
diff --git a/app/code/Magento/Weee/view/frontend/templates/item/price/unit.phtml b/app/code/Magento/Weee/view/frontend/templates/item/price/unit.phtml
index b5190c715df..1c9ede757f5 100644
--- a/app/code/Magento/Weee/view/frontend/templates/item/price/unit.phtml
+++ b/app/code/Magento/Weee/view/frontend/templates/item/price/unit.phtml
@@ -26,67 +26,66 @@
 
 $item = $this->getItem();
 ?>
-
 <?php if ($this->displayPriceInclTax() || $this->displayBothPrices()): ?>
-    <span class="incl tax" data-th="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
+    <span class="price-including-tax" data-label="<?php echo $this->escapeHtml(__('Incl. Tax')); ?>">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <span class="cart-tax-total"
                 data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $item->getId(); ?>"}'>
         <?php else: ?>
-            <span class="cart price">
+            <span class="cart-price">
         <?php endif; ?>
             <?php echo $this->formatPrice($this->getUnitDisplayPriceInclTax()); ?>
             </span>
 
         <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($item)): ?>
-            <div class="cart-tax-info" id="unit-item-tax-details<?php echo $item->getId(); ?>" style="display: none;">
+            <span class="cart-tax-info" id="unit-item-tax-details<?php echo $item->getId(); ?>" style="display: none;">
                 <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($item) as $tax): ?>
-                    <span class="weee" data-th="<?php echo $tax['title']; ?>">
+                    <span class="weee" data-label="<?php echo $tax['title']; ?>">
                         <?php echo $this->formatPrice($tax['amount_incl_tax'], true, true); ?>
                     </span>
                 <?php endforeach; ?>
-            </div>
+            </span>
 
             <?php if ($this->displayFinalPrice()): ?>
-                <div class="cart-tax-total"
+                <span class="cart-tax-total"
                     data-tax-toggle='{"itemTaxId" : "#unit-item-tax-details<?php echo $item->getId(); ?>"}'>
-                    <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>">
+                    <span class="weee" data-label="<?php echo $this->escapeHtml(__('Total incl. tax')); ?>">
                         <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceInclTax()); ?>
                     </span>
-                </div>
+                </span>
             <?php endif; ?>
         <?php endif; ?>
     </span>
 <?php endif; ?>
 
 <?php if ($this->displayPriceExclTax() || $this->displayBothPrices()): ?>
-    <span class="excl tax" data-th="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
+    <span class="price-excluding-tax" data-label="<?php echo $this->escapeHtml(__('Excl. Tax')); ?>">
         <?php if ($this->displayPriceWithWeeeDetails()): ?>
             <span class="cart-tax-total"
                 data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $item->getId(); ?>"}'>
         <?php else: ?>
-            <span class="cart price">
+            <span class="cart-price">
         <?php endif; ?>
                 <?php echo $this->formatPrice($this->getUnitDisplayPriceExclTax()); ?>
             </span>
 
         <?php if ($this->helper('Magento\Weee\Helper\Data')->getApplied($item)): ?>
-            <div class="cart-tax-info" id="eunit-item-tax-details<?php echo $item->getId(); ?>"
-                style="display:none;">
+            <span class="cart-tax-info" id="eunit-item-tax-details<?php echo $item->getId(); ?>"
+                style="display: none;">
                 <?php foreach ($this->helper('Magento\Weee\Helper\Data')->getApplied($item) as $tax): ?>
-                    <span class="weee" data-th="<?php echo $tax['title']; ?>">
+                    <span class="weee" data-label="<?php echo $tax['title']; ?>">
                         <?php echo $this->formatPrice($tax['amount'], true, true); ?>
                     </span>
                 <?php endforeach; ?>
-            </div>
+            </span>
 
             <?php if ($this->displayFinalPrice()): ?>
-                <div class="cart-tax-total"
+                <span class="cart-tax-total"
                     data-tax-toggle='{"itemTaxId" : "#eunit-item-tax-details<?php echo $item->getId(); ?>"}'>
-                    <span class="weee" data-th="<?php echo $this->escapeHtml(__('Total')); ?>">
+                    <span class="weee" data-label="<?php echo $this->escapeHtml(__('Total')); ?>">
                         <?php echo $this->formatPrice($this->getFinalUnitDisplayPriceExclTax()); ?>
                     </span>
-                </div>
+                </span>
             <?php endif; ?>
         <?php endif; ?>
     </span>
diff --git a/app/code/Magento/Widget/Model/Widget/Instance.php b/app/code/Magento/Widget/Model/Widget/Instance.php
index 8539b6fa4cd..5887285b1b9 100644
--- a/app/code/Magento/Widget/Model/Widget/Instance.php
+++ b/app/code/Magento/Widget/Model/Widget/Instance.php
@@ -53,7 +53,7 @@ class Instance extends \Magento\Framework\Model\AbstractModel
 
     const NOTANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_type_default';
 
-    const SINGLE_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_{{ID}}';
+    const SINGLE_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_id_{{ID}}';
 
     /**
      * @var array
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index 722dfd41368..be96f2855b6 100644
--- a/app/code/Magento/Widget/composer.json
+++ b/app/code/Magento/Widget/composer.json
@@ -3,17 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-cms": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-cms": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Widget/etc/module.xml b/app/code/Magento/Widget/etc/module.xml
index ddbc1e300fa..dd24f23057b 100644
--- a/app/code/Magento/Widget/etc/module.xml
+++ b/app/code/Magento/Widget/etc/module.xml
@@ -34,7 +34,6 @@
             <module name="Magento_Core"/>
             <module name="Magento_Backend"/>
             <module name="Magento_Catalog"/>
-            <module name="Magento_Theme"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_edit.xml b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_edit.xml
index ccc6739ceee..db95f3e7c95 100644
--- a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_edit.xml
+++ b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_edit.xml
@@ -24,26 +24,11 @@
  */
 -->
 <page layout="admin-2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <action method="setCanLoadExtJs">
-            <argument name="flag" xsi:type="string">1</argument>
-        </action>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-window-js">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/window.js</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="prototype-windows-themes-default-css">
-            <arguments>
-                <argument name="file" xsi:type="string">prototype/windows/themes/default.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <link src="prototype/window.js"/>
+        <css src="prototype/windows/themes/default.css"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+    </head>
     <referenceContainer name="content">
         <block class="Magento\Widget\Block\Adminhtml\Widget\Instance\Edit" name="widget_instance_edit"/>
     </referenceContainer>
diff --git a/app/code/Magento/Wishlist/Block/Customer/Sharing.php b/app/code/Magento/Wishlist/Block/Customer/Sharing.php
index 8fefed599ea..cded8c9f7f1 100644
--- a/app/code/Magento/Wishlist/Block/Customer/Sharing.php
+++ b/app/code/Magento/Wishlist/Block/Customer/Sharing.php
@@ -76,10 +76,7 @@ class Sharing extends \Magento\Framework\View\Element\Template
      */
     protected function _prepareLayout()
     {
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('Wish List Sharing'));
-        }
+        $this->pageConfig->setTitle(__('Wish List Sharing'));
     }
 
     /**
diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php
index fba7bcfc71b..512e20cfa76 100644
--- a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php
+++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php
@@ -95,10 +95,7 @@ class Wishlist extends \Magento\Wishlist\Block\AbstractBlock
     protected function _prepareLayout()
     {
         parent::_prepareLayout();
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle(__('My Wish List'));
-        }
+        $this->pageConfig->setTitle(__('My Wish List'));
     }
 
     /**
diff --git a/app/code/Magento/Wishlist/Block/Rss.php b/app/code/Magento/Wishlist/Block/Rss.php
deleted file mode 100644
index 5b6ecaa490c..00000000000
--- a/app/code/Magento/Wishlist/Block/Rss.php
+++ /dev/null
@@ -1,231 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Wishlist\Block;
-
-/**
- * Customer Shared Wishlist Rss Block
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Rss extends \Magento\Wishlist\Block\AbstractBlock
-{
-    /**
-     * Default MAP renderer type
-     *
-     * @var string
-     */
-    protected $_mapRenderer = 'msrp_rss';
-
-    /**
-     * @var \Magento\Wishlist\Model\WishlistFactory
-     */
-    protected $_wishlistFactory;
-
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $_rssFactory;
-
-    /**
-     * @var \Magento\Core\Helper\Data
-     */
-    protected $_coreData;
-
-    /**
-     * @var \Magento\Catalog\Helper\Output
-     */
-    protected $_outputHelper;
-
-    /**
-     * @param \Magento\Catalog\Block\Product\Context $context
-     * @param \Magento\Framework\App\Http\Context $httpContext
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Core\Helper\Data $coreData
-     * @param \Magento\Wishlist\Model\WishlistFactory $wishlistFactory
-     * @param \Magento\Rss\Model\RssFactory $rssFactory
-     * @param \Magento\Catalog\Helper\Output $outputHelper
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Catalog\Block\Product\Context $context,
-        \Magento\Framework\App\Http\Context $httpContext,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Core\Helper\Data $coreData,
-        \Magento\Wishlist\Model\WishlistFactory $wishlistFactory,
-        \Magento\Rss\Model\RssFactory $rssFactory,
-        \Magento\Catalog\Helper\Output $outputHelper,
-        array $data = array()
-    ) {
-        $this->_outputHelper = $outputHelper;
-        $this->_coreData = $coreData;
-        $this->_wishlistFactory = $wishlistFactory;
-        $this->_rssFactory = $rssFactory;
-        parent::__construct(
-            $context,
-            $httpContext,
-            $productFactory,
-            $data
-        );
-    }
-
-    /**
-     * Retrieve Wishlist model
-     *
-     * @return \Magento\Wishlist\Model\Wishlist
-     */
-    protected function _getWishlist()
-    {
-        if (is_null($this->_wishlist)) {
-            $this->_wishlist = parent::_getWishlist();
-            $currentCustomerId = $this->_getHelper()->getCustomer()->getId();
-            if (!$this->_wishlist->getVisibility() && ($this->_wishlist->getCustomerId() != $currentCustomerId)) {
-                $this->_wishlist->unsetData();
-            }
-        }
-
-        return $this->_wishlist;
-    }
-
-    /**
-     * Build wishlist rss feed title
-     *
-     * @return string
-     */
-    protected function _getTitle()
-    {
-        return __('%1\'s Wishlist', $this->_getHelper()->getCustomerName());
-    }
-
-    /**
-     * Render block HTML
-     *
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        /* @var $rssObj \Magento\Rss\Model\Rss */
-        $rssObj = $this->_rssFactory->create();
-        if ($this->_getWishlist()->getId()) {
-            $newUrl = $this->_urlBuilder->getUrl(
-                'wishlist/shared/index',
-                array('code' => $this->_getWishlist()->getSharingCode())
-            );
-            $title = $this->_getTitle();
-            $lang = $this->_scopeConfig->getValue(
-                'general/locale/code',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            );
-            $rssObj->_addHeader(
-                array(
-                    'title' => $title,
-                    'description' => $title,
-                    'link' => $newUrl,
-                    'charset' => 'UTF-8',
-                    'language' => $lang
-                )
-            );
-
-            /** @var $wishlistItem \Magento\Wishlist\Model\Item */
-            foreach ($this->getWishlistItems() as $wishlistItem) {
-                /* @var $product \Magento\Catalog\Model\Product */
-                $product = $wishlistItem->getProduct();
-                $productUrl = $this->getProductUrl($product);
-                $product->setAllowedInRss(true);
-                $product->setAllowedPriceInRss(true);
-                $product->setProductUrl($productUrl);
-                $args = array('product' => $product);
-
-                $this->_eventManager->dispatch('rss_wishlist_xml_callback', $args);
-
-                if (!$product->getAllowedInRss()) {
-                    continue;
-                }
-
-                /** @var $outputHelper \Magento\Catalog\Helper\Output */
-                $outputHelper = $this->_outputHelper;
-                $description = '<table><tr><td><a href="' . $productUrl . '"><img src="' . $this->_imageHelper->init(
-                    $product,
-                    'thumbnail'
-                )->resize(
-                    75,
-                    75
-                ) .
-                    '" border="0" align="left" height="75" width="75"></a></td>' .
-                    '<td style="text-decoration:none;">' .
-                    $outputHelper->productAttribute(
-                        $product,
-                        $product->getShortDescription(),
-                        'short_description'
-                    ) . '<p>';
-
-                if ($product->getAllowedPriceInRss()) {
-                    $description .= $this->getProductPrice($product);
-                }
-                $description .= '</p>';
-
-                if ($this->hasDescription($product)) {
-                    $description .= '<p>' . __(
-                        'Comment:'
-                    ) . ' ' . $outputHelper->productAttribute(
-                        $product,
-                        $product->getDescription(),
-                        'description'
-                    ) . '<p>';
-                }
-                $description .= '</td></tr></table>';
-                $rssObj->_addEntry(
-                    array(
-                        'title' => $outputHelper->productAttribute($product, $product->getName(), 'name'),
-                        'link' => $productUrl,
-                        'description' => $description
-                    )
-                );
-            }
-        } else {
-            $rssObj->_addHeader(
-                array(
-                    'title' => __('We cannot retrieve the wish list.'),
-                    'description' => __('We cannot retrieve the wish list.'),
-                    'link' => $this->_urlBuilder->getUrl(),
-                    'charset' => 'UTF-8'
-                )
-            );
-        }
-
-        return $rssObj->createRssXml();
-    }
-
-    /**
-     * Retrieve Product View URL
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param array $additional
-     * @return string
-     */
-    public function getProductUrl($product, $additional = array())
-    {
-        $additional['_rss'] = true;
-        return parent::getProductUrl($product, $additional);
-    }
-}
diff --git a/app/code/Magento/Wishlist/Block/Share/Email/Rss.php b/app/code/Magento/Wishlist/Block/Rss/EmailLink.php
similarity index 82%
rename from app/code/Magento/Wishlist/Block/Share/Email/Rss.php
rename to app/code/Magento/Wishlist/Block/Rss/EmailLink.php
index a9743ef9981..0b9ef0a96aa 100644
--- a/app/code/Magento/Wishlist/Block/Share/Email/Rss.php
+++ b/app/code/Magento/Wishlist/Block/Rss/EmailLink.php
@@ -25,15 +25,13 @@
 
 /**
  * Wishlist RSS URL to Email Block
- *
- * @author     Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Wishlist\Block\Share\Email;
+namespace Magento\Wishlist\Block\Rss;
 
-class Rss extends \Magento\Framework\View\Element\Template
+class EmailLink extends Link
 {
     /**
      * @var string
      */
-    protected $_template = 'email/rss.phtml';
+    protected $_template = 'rss/email.phtml';
 }
diff --git a/app/code/Magento/Wishlist/Block/Rss/Link.php b/app/code/Magento/Wishlist/Block/Rss/Link.php
new file mode 100644
index 00000000000..d0bd7efde90
--- /dev/null
+++ b/app/code/Magento/Wishlist/Block/Rss/Link.php
@@ -0,0 +1,102 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Wishlist block customer items
+ */
+namespace Magento\Wishlist\Block\Rss;
+
+class Link extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var \Magento\Wishlist\Helper\Data
+     */
+    protected $wishlistHelper;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Wishlist\Helper\Data $wishlistHelper
+     * @param \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Wishlist\Helper\Data $wishlistHelper,
+        \Magento\Framework\App\Rss\UrlBuilderInterface $rssUrlBuilder,
+        array $data = array()
+    ) {
+        parent::__construct($context, $data);
+        $this->wishlistHelper = $wishlistHelper;
+        $this->rssUrlBuilder = $rssUrlBuilder;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLink()
+    {
+        return $this->rssUrlBuilder->getUrl($this->getLinkParams());
+    }
+
+    /**
+     * Check whether status notification is allowed
+     *
+     * @return bool
+     */
+    public function isRssAllowed()
+    {
+        return $this->_scopeConfig->isSetFlag(
+            'rss/wishlist/active',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    /**
+     * @return string
+     */
+    protected function getLinkParams()
+    {
+        $params = array();
+        $wishlistId = $this->wishlistHelper->getWishlist()->getId();
+        $customer = $this->wishlistHelper->getCustomer();
+        if ($customer) {
+            $key = $customer->getId() . ',' . $customer->getEmail();
+            $params = array(
+                'type' => 'wishlist',
+                'data' => $this->wishlistHelper->urlEncode($key),
+                '_secure' => false
+            );
+        }
+        if ($wishlistId) {
+            $params['wishlist_id'] = $wishlistId;
+        }
+        return $params;
+    }
+}
diff --git a/app/code/Magento/Wishlist/Block/Share/Wishlist.php b/app/code/Magento/Wishlist/Block/Share/Wishlist.php
index 8a0ceecf0ae..254487049ab 100644
--- a/app/code/Magento/Wishlist/Block/Share/Wishlist.php
+++ b/app/code/Magento/Wishlist/Block/Share/Wishlist.php
@@ -76,11 +76,7 @@ class Wishlist extends \Magento\Wishlist\Block\AbstractBlock
     protected function _prepareLayout()
     {
         parent::_prepareLayout();
-
-        $headBlock = $this->getLayout()->getBlock('head');
-        if ($headBlock) {
-            $headBlock->setTitle($this->getHeader());
-        }
+        $this->pageConfig->setTitle($this->getHeader());
         return $this;
     }
 
diff --git a/app/code/Magento/Wishlist/Controller/Index/Rss.php b/app/code/Magento/Wishlist/Controller/Index/Rss.php
deleted file mode 100644
index 4cac8d716a8..00000000000
--- a/app/code/Magento/Wishlist/Controller/Index/Rss.php
+++ /dev/null
@@ -1,108 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Wishlist\Controller\Index;
-
-use Magento\Wishlist\Controller\IndexInterface;
-use Magento\Framework\App\Action;
-
-class Rss extends Action\Action implements IndexInterface
-{
-    /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
-     */
-    protected $scopeConfig;
-
-    /**
-     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
-     */
-    protected $wishlistProvider;
-
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $customerSession;
-
-    /**
-     * @var \Magento\Wishlist\Helper\Rss
-     */
-    protected $rssWishlistHelper;
-
-    /**
-     * @var \Magento\Rss\Helper\DataFactory
-     */
-    protected $rssHelperFactory;
-
-    /**
-     * @param Action\Context $context
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Wishlist\Helper\Rss $rssWishlitHelper
-     * @param \Magento\Rss\Helper\DataFactory $rssHelperFactory
-     */
-    public function __construct(
-        Action\Context $context,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Wishlist\Helper\Rss $rssWishlitHelper,
-        \Magento\Rss\Helper\DataFactory $rssHelperFactory
-    ) {
-        $this->customerSession = $customerSession;
-        $this->wishlistProvider = $wishlistProvider;
-        $this->scopeConfig = $scopeConfig;
-        $this->rssWishlistHelper = $rssWishlitHelper;
-        $this->rssHelperFactory = $rssHelperFactory;
-        parent::__construct($context);
-    }
-
-    /**
-     * Wishlist rss feed action
-     * Show all public wishlists and private wishlists that belong to current user
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        if (!$this->rssWishlistHelper->isRssAllow()) {
-            $this->_forward('noroute');
-            return;
-        }
-        /** @var \Magento\Wishlist\Model\Wishlist $wishlist */
-        $wishlist = $this->wishlistProvider->getWishlist();
-        if ($wishlist && ($wishlist->getVisibility()
-            || $this->customerSession->authenticate($this)
-            && $wishlist->getCustomerId() == $this->rssWishlistHelper->getCustomer()->getId())
-        ) {
-            $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=UTF-8');
-            $this->_view->loadLayout(false);
-            $this->_view->renderLayout();
-            return;
-        }
-        /** @var \Magento\Rss\Helper\Data $rssHelper */
-        $rssHelper = $this->rssHelperFactory->create();
-        $rssHelper->sendEmptyRssFeed($this->getResponse());
-    }
-}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Send.php b/app/code/Magento/Wishlist/Controller/Index/Send.php
index 591cae51aa3..5ef37f6a789 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Send.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Send.php
@@ -162,7 +162,7 @@ class Send extends Action\Action implements IndexInterface
             /*if share rss added rss feed to email template*/
             if ($this->getRequest()->getParam('rss_url')) {
                 $rss_url = $this->_view->getLayout()->createBlock(
-                    'Magento\Wishlist\Block\Share\Email\Rss'
+                    'Magento\Wishlist\Block\Rss\EmailLink'
                 )->setWishlistId(
                     $wishlist->getId()
                 )->toHtml();
diff --git a/app/code/Magento/Wishlist/Controller/WishlistProvider.php b/app/code/Magento/Wishlist/Controller/WishlistProvider.php
index 5af58dd44f3..2a1a21211f5 100644
--- a/app/code/Magento/Wishlist/Controller/WishlistProvider.php
+++ b/app/code/Magento/Wishlist/Controller/WishlistProvider.php
@@ -85,14 +85,18 @@ class WishlistProvider implements WishlistProviderInterface
             }
             $customerId = $this->customerSession->getCustomerId();
             $wishlist = $this->wishlistFactory->create();
+
+            if (!$wishlistId && !$customerId) {
+                return $wishlist;
+            }
+
             if ($wishlistId) {
                 $wishlist->load($wishlistId);
-            } else {
+            } elseif ($customerId) {
                 $wishlist->loadByCustomerId($customerId, true);
             }
 
             if (!$wishlist->getId() || $wishlist->getCustomerId() != $customerId) {
-                $wishlist = null;
                 throw new \Magento\Framework\Exception\NoSuchEntityException(
                     __("The requested wish list doesn't exist.")
                 );
diff --git a/app/code/Magento/Wishlist/Helper/Data.php b/app/code/Magento/Wishlist/Helper/Data.php
index 796882bfbb0..6122fdcc759 100644
--- a/app/code/Magento/Wishlist/Helper/Data.php
+++ b/app/code/Magento/Wishlist/Helper/Data.php
@@ -213,12 +213,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
                 $this->_wishlist = $this->_coreRegistry->registry('shared_wishlist');
             } else {
                 $this->_wishlist = $this->wishlistProvider->getWishlist();
-                if (!$this->_wishlist) {
-                    $this->_wishlist = $this->_wishlistFactory->create();
-                    if ($this->getCustomer()) {
-                        $this->_wishlist->loadByCustomerId($this->getCustomer()->getId());
-                    }
-                }
             }
         }
         return $this->_wishlist;
diff --git a/app/code/Magento/Wishlist/Model/Observer.php b/app/code/Magento/Wishlist/Model/Observer.php
index 8c07bb5488a..048b41374aa 100644
--- a/app/code/Magento/Wishlist/Model/Observer.php
+++ b/app/code/Magento/Wishlist/Model/Observer.php
@@ -102,7 +102,7 @@ class Observer
     public function processCartUpdateBefore($observer)
     {
         $cart = $observer->getEvent()->getCart();
-        $data = $observer->getEvent()->getInfo();
+        $data = $observer->getEvent()->getInfo()->toArray();
         $productIds = array();
 
         $wishlist = $this->_getWishlist($cart->getQuote()->getCustomerId());
diff --git a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php
new file mode 100644
index 00000000000..7d9632b68c2
--- /dev/null
+++ b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php
@@ -0,0 +1,277 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Wishlist\Model\Rss;
+
+use \Magento\Framework\App\Rss\DataProviderInterface;
+
+/**
+ * Wishlist RSS model
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class Wishlist implements DataProviderInterface
+{
+    /**
+     * Url Builder
+     *
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * System event manager
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * Parent layout of the block
+     *
+     * @var \Magento\Framework\View\LayoutInterface
+     */
+    protected $layout;
+
+    /**
+     * @var \Magento\Wishlist\Helper\Data
+     */
+    protected $wishlistHelper;
+
+    /**
+     * @var \Magento\Catalog\Helper\Output
+     */
+    protected $outputHelper;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Wishlist\Block\Customer\Wishlist
+     */
+    protected $wishlistBlock;
+
+    /**
+     * @param \Magento\Wishlist\Helper\Rss $wishlistHelper
+     * @param \Magento\Wishlist\Block\Customer\Wishlist $wishlistBlock
+     * @param \Magento\Catalog\Helper\Output $outputHelper
+     * @param \Magento\Catalog\Helper\Image $imageHelper
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param \Magento\Framework\View\LayoutInterface $layout
+     */
+    public function __construct(
+        \Magento\Wishlist\Helper\Rss $wishlistHelper,
+        \Magento\Wishlist\Block\Customer\Wishlist $wishlistBlock,
+        \Magento\Catalog\Helper\Output $outputHelper,
+        \Magento\Catalog\Helper\Image $imageHelper,
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Framework\View\LayoutInterface $layout
+    ) {
+        $this->wishlistHelper = $wishlistHelper;
+        $this->wishlistBlock = $wishlistBlock;
+        $this->outputHelper = $outputHelper;
+        $this->imageHelper = $imageHelper;
+        $this->urlBuilder = $urlBuilder;
+        $this->scopeConfig = $scopeConfig;
+        $this->eventManager = $eventManager;
+        $this->layout = $layout;
+    }
+
+    /**
+     * Check if RSS feed allowed
+     *
+     * @return mixed
+     */
+    public function isAllowed()
+    {
+        return (bool)$this->scopeConfig->getValue(
+            'rss/wishlist/active',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    /**
+     * Get RSS feed items
+     *
+     * @return array
+     */
+    public function getRssData()
+    {
+        $wishlist = $this->getWishlist();
+        if ($wishlist->getId()) {
+            $data = $this->getHeader();
+
+            /** @var $wishlistItem \Magento\Wishlist\Model\Item */
+            foreach ($wishlist->getItemCollection() as $wishlistItem) {
+                /* @var $product \Magento\Catalog\Model\Product */
+                $product = $wishlistItem->getProduct();
+                $productUrl = $this->wishlistBlock->getProductUrl($product, ['_rss' => true]);
+                $product->setAllowedInRss(true);
+                $product->setAllowedPriceInRss(true);
+                $product->setProductUrl($productUrl);
+                $args = array('product' => $product);
+
+                $this->eventManager->dispatch('rss_wishlist_xml_callback', $args);
+
+                if (!$product->getAllowedInRss()) {
+                    continue;
+                }
+
+                $description = '<table><tr><td><a href="' . $productUrl . '"><img src="'
+                    . $this->imageHelper->init($product, 'thumbnail')->resize(75, 75)
+                    . '" border="0" align="left" height="75" width="75"></a></td>'
+                    . '<td style="text-decoration:none;">'
+                    . $this->outputHelper->productAttribute(
+                        $product,
+                        $product->getShortDescription(),
+                        'short_description'
+                    ) . '<p>';
+
+                if ($product->getAllowedPriceInRss()) {
+                    $description .= $this->getProductPriceHtml($product);
+                }
+                $description .= '</p>';
+
+                if (trim($product->getDescription()) != '') {
+                    $description .= '<p>' . __('Comment:') . ' '
+                        . $this->outputHelper->productAttribute(
+                            $product,
+                            $product->getDescription(),
+                            'description'
+                        ) . '<p>';
+                }
+                $description .= '</td></tr></table>';
+
+                $data['entries'][] = (array(
+                    'title' => $this->outputHelper->productAttribute($product, $product->getName(), 'name'),
+                    'link' => $productUrl,
+                    'description' => $description
+                ));
+            }
+        } else {
+            $data = array(
+                'title' => __('We cannot retrieve the wish list.'),
+                'description' => __('We cannot retrieve the wish list.'),
+                'link' => $this->urlBuilder->getUrl(),
+                'charset' => 'UTF-8'
+            );
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        return 'rss_wishlist_data';
+    }
+
+    /**
+     * @return int
+     */
+    public function getCacheLifetime()
+    {
+        return 60;
+    }
+
+    /**
+     * Get data for Header section of RSS feed
+     *
+     * @return array
+     */
+    public function getHeader()
+    {
+        $title = __('%1\'s Wishlist', $this->wishlistHelper->getCustomerName());
+        $newUrl = $this->urlBuilder->getUrl(
+            'wishlist/shared/index',
+            array('code' => $this->getWishlist()->getSharingCode())
+        );
+
+        return array('title' => $title, 'description' => $title, 'link' => $newUrl, 'charset' => 'UTF-8');
+    }
+
+    /**
+     * Retrieve Wishlist model
+     *
+     * @return \Magento\Wishlist\Model\Wishlist
+     */
+    protected function getWishlist()
+    {
+        $wishlist = $this->wishlistHelper->getWishlist();
+        $currentCustomer = $this->wishlistHelper->getCustomer();
+        if (!$wishlist->getVisibility() && $currentCustomer
+            && ($wishlist->getCustomerId() != $currentCustomer->getId())
+        ) {
+            $wishlist->unsetData();
+        }
+        return $wishlist;
+    }
+
+    /**
+     * Return HTML block with product price
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return string
+     */
+    public function getProductPriceHtml(\Magento\Catalog\Model\Product $product)
+    {
+        $price = '';
+        /** @var \Magento\Framework\Pricing\Render $priceRender */
+        $priceRender = $this->layout->getBlock('product.price.render.default');
+        if (!$priceRender) {
+            $priceRender = $this->layout->createBlock(
+                'Magento\Framework\Pricing\Render',
+                'product.price.render.default',
+                array('data' => array('price_render_handle' => 'catalog_product_prices'))
+            );
+        }
+        if ($priceRender) {
+            $price = $priceRender->render(
+                \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
+                $product,
+                ['zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST]
+            );
+        }
+        return $price;
+    }
+
+    /**
+     * @return array
+     */
+    public function getFeeds()
+    {
+        return array();
+    }
+}
diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json
index 0b81bceb49b..b4547a75dd3 100644
--- a/app/code/Magento/Wishlist/composer.json
+++ b/app/code/Magento/Wishlist/composer.json
@@ -3,25 +3,25 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.1.0-alpha96",
-        "magento/module-customer": "0.1.0-alpha96",
-        "magento/module-catalog": "0.1.0-alpha96",
-        "magento/module-core": "0.1.0-alpha96",
-        "magento/module-checkout": "0.1.0-alpha96",
-        "magento/module-theme": "0.1.0-alpha96",
-        "magento/module-catalog-inventory": "0.1.0-alpha96",
-        "magento/module-rss": "0.1.0-alpha96",
-        "magento/module-backend": "0.1.0-alpha96",
-        "magento/module-bundle": "0.1.0-alpha96",
-        "magento/module-sales": "0.1.0-alpha96",
-        "magento/module-grouped-product": "0.1.0-alpha96",
-        "magento/module-configurable-product": "0.1.0-alpha96",
-        "magento/module-downloadable": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/module-store": "0.1.0-alpha97",
+        "magento/module-customer": "0.1.0-alpha97",
+        "magento/module-catalog": "0.1.0-alpha97",
+        "magento/module-core": "0.1.0-alpha97",
+        "magento/module-checkout": "0.1.0-alpha97",
+        "magento/module-theme": "0.1.0-alpha97",
+        "magento/module-catalog-inventory": "0.1.0-alpha97",
+        "magento/module-rss": "0.1.0-alpha97",
+        "magento/module-backend": "0.1.0-alpha97",
+        "magento/module-bundle": "0.1.0-alpha97",
+        "magento/module-sales": "0.1.0-alpha97",
+        "magento/module-grouped-product": "0.1.0-alpha97",
+        "magento/module-configurable-product": "0.1.0-alpha97",
+        "magento/module-downloadable": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/code/Magento/Wishlist/etc/di.xml b/app/code/Magento/Wishlist/etc/di.xml
index 9c210b5cb70..3fbad2723ed 100644
--- a/app/code/Magento/Wishlist/etc/di.xml
+++ b/app/code/Magento/Wishlist/etc/di.xml
@@ -44,9 +44,11 @@
             <argument name="wishlistHelper" xsi:type="object">Magento\Wishlist\Helper\Rss</argument>
         </arguments>
     </virtualType>
-    <type name="Magento\Wishlist\Block\Rss">
+    <type name="Magento\Framework\App\Rss\RssManagerInterface">
         <arguments>
-            <argument name="context" xsi:type="object">Magento\Wishlist\Block\Context</argument>
+            <argument name="dataProviders" xsi:type="array">
+                <item name="wishlist" xsi:type="string">Magento\Wishlist\Model\Rss\Wishlist</item>
+            </argument>
         </arguments>
     </type>
 </config>
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
index a46c5707481..d4861aed666 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_bundle.xml
@@ -24,11 +24,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="value" xsi:type="string">type-bundle</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="type-bundle"/>
+    </body>
     <referenceBlock name="product.info">
         <block class="Magento\Catalog\Block\Product\View" name="bundle.summary" as="form_top" template="Magento_Bundle::catalog/product/view/summary.phtml">
             <block class="Magento\Catalog\Pricing\Render" name="product.price.render.bundle.customization">
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
index 16a3daa2b22..d647a964c3b 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
@@ -24,15 +24,13 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/page.xsd">
+    <body>
+        <attribute name="class" value="type-configurable"/>
+    </body>
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="wishlist_product_view_head_components" template="Magento_Wishlist::js/components.phtml"/>
         <block class="Magento\Framework\View\Element\Js\Components" name="configurableproduct_product_view_head_components" template="Magento_ConfigurableProduct::js/components.phtml"/>
     </referenceBlock>
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="value" xsi:type="string">type-configurable</argument>
-        </action>
-    </referenceBlock>
     <referenceContainer name="product.info.type">
         <block class="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable" name="product.info.configurable" as="product_type_data" template="Magento_Catalog::product/view/type/default.phtml"/>
         <container name="product.info.configurable.extra" after="product.info.configurable" as="product_type_data_extra" label="Product Extra Info"/>
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
index f687d7aff12..4037d5037bb 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
@@ -40,7 +40,6 @@
                 <arguments>
                     <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                     <argument name="price_type_code" xsi:type="string">link_price</argument>
-                    <argument name="display_msrp_help_message" xsi:type="string">1</argument>
                 </arguments>
             </block>
         </block>
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml
index 755f9aeeac8..194bbbdd3e3 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml
@@ -30,6 +30,7 @@
     </referenceBlock>
     <referenceContainer name="content">
         <block class="Magento\Wishlist\Block\Customer\Wishlist" name="customer.wishlist" template="view.phtml" cacheable="false">
+            <block class="Magento\Wishlist\Block\Rss\Link" name="wishlist.rss.link" template="rss/wishlist.phtml"/>
             <block class="Magento\Wishlist\Block\Customer\Wishlist\Items" name="customer.wishlist.items" as="items" template="item/list.phtml" cacheable="false">
                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image" name="customer.wishlist.item.image" template="item/column/image.phtml" cacheable="false" />
                 <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info" name="customer.wishlist.item.name" template="item/column/name.phtml" cacheable="false" />
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_rss.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_rss.xml
deleted file mode 100644
index eef27d07ac2..00000000000
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_rss.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Wishlist\Block\Rss" name="rss.wishlist" cacheable="false"/>
-    </container>
-</layout>
diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/rss.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml
similarity index 75%
rename from app/code/Magento/Wishlist/view/frontend/templates/email/rss.phtml
rename to app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml
index a03e61408d2..875655d4abd 100644
--- a/app/code/Magento/Wishlist/view/frontend/templates/email/rss.phtml
+++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml
@@ -21,9 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
+/* @var $this \Magento\Wishlist\Block\Rss\EmailLink */
 ?>
+<?php if ($this->getLink()): ?>
 <p style="font-size:12px; line-height:16px; margin:0 0 16px;">
-    <?php echo __("RSS link to %1's wishlist",$this->helper('Magento\Wishlist\Helper\Data')->getCustomerName()) ?>
+    <?php echo __("RSS link to %1's wishlist", $this->helper('Magento\Wishlist\Helper\Data')->getCustomerName()) ?>
     <br />
-    <a href="<?php echo $this->helper('Magento\Wishlist\Helper\Data')->getRssUrl($this->getWishlistId()); ?>"><?php echo $this->helper('Magento\Wishlist\Helper\Data')->getRssUrl($this->getWishlistId()); ?></a>
+    <a href="<?php echo $this->getLink(); ?>"><?php echo $this->getLink(); ?></a>
 </p>
+<?php endif; ?>
diff --git a/app/code/Magento/Rss/view/frontend/templates/order/info/buttons/rss.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml
similarity index 74%
rename from app/code/Magento/Rss/view/frontend/templates/order/info/buttons/rss.phtml
rename to app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml
index 8df524dfee6..ccd928f7652 100644
--- a/app/code/Magento/Rss/view/frontend/templates/order/info/buttons/rss.phtml
+++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml
@@ -21,12 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-
-/** @var $this \Magento\Rss\Block\Order\Info\Buttons\Rss */
+/* @var $this \Magento\Wishlist\Block\Rss\Link */
 ?>
-<?php if($this->getOrderHelper()->isStatusNotificationAllow()): ?>
-    <a href="<?php echo $this->getOrderHelper()->getStatusHistoryRssUrl($this->getOrder()) ?>"
-       class="action rss">
-        <span><?php echo __('Subscribe to Order Status') ?></span>
+<?php if ($this->isRssAllowed() && $this->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?>
+    <a href="<?php echo $this->getLink(); ?>" class="action rss wishlist">
+        <span><?php echo __('RSS Feed') ?></span>
     </a>
 <?php endif; ?>
diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml
index 29dda8ffdfa..0f90345affe 100644
--- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml
+++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml
@@ -25,11 +25,7 @@
 ?>
 
 <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?>
-    <?php if ($this->helper('Magento\Wishlist\Helper\Rss')->isRssAllow() && $this->hasWishlistItems()): ?>
-        <a href="<?php echo $this->helper('Magento\Wishlist\Helper\Data')->getRssUrl($this->getWishlistInstance()->getId()); ?>" class="action rss wishlist">
-            <span><?php echo __('RSS Feed') ?></span>
-        </a>
-    <?php endif; ?>
+    <?php echo($this->getChildHtml('wishlist.rss.link'));?>
     <form class="form-wishlist-items" id="wishlist-view-form"
           data-mage-init='{"wishlist":{
           "dataAttribute":"item-id",
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml b/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
index 1396fa1842e..1adabb51b4c 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/layout/default.xml
@@ -24,70 +24,18 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-reset-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/reset.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-base-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/base.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-elements-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/elements.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-form-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/form.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-components-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/components.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="css-styles-admin">
-            <arguments>
-                <argument name="file" xsi:type="string">css/admin.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="css-styles-pages">
-            <arguments>
-                <argument name="file" xsi:type="string">css/pages.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="css-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">css/styles.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="jquery-farbtastic-css-farbtastic-css">
-            <arguments>
-                <argument name="file" xsi:type="string">jquery/farbtastic/css/farbtastic.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-utils-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/utils.css</argument>
-            </arguments>
-        </block>
-        <block class="Magento\Theme\Block\Html\Head\Css" name="magento-core-prototype-magento-css">
-            <arguments>
-                <argument name="file" xsi:type="string">Magento_Core::prototype/magento.css</argument>
-            </arguments>
-        </block>
-        <!-- temporary to debug -->
-        <block class="Magento\Theme\Block\Html\Head\Css" name="mui-print-css">
-            <arguments>
-                <argument name="file" xsi:type="string">mui/print.css</argument>
-                <argument name="properties" xsi:type="array">
-                    <item name="attributes" xsi:type="string">media="print"</item>
-                </argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="mui/reset.css"/>
+        <css src="mui/base.css"/>
+        <css src="mui/elements.css"/>
+        <css src="mui/form.css"/>
+        <css src="mui/components.css"/>
+        <css src="css/admin.css"/>
+        <css src="css/pages.css"/>
+        <css src="css/styles.css"/>
+        <css src="jquery/farbtastic/css/farbtastic.css"/>
+        <css src="mui/utils.css"/>
+        <css src="Magento_Core::prototype/magento.css"/>
+        <css src="mui/print.css" media="print"/>
+    </head>
 </page>
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
new file mode 100644
index 00000000000..6f705d63f3c
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module.less
@@ -0,0 +1,431 @@
+// /**
+// //  * 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
+//  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+//  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+//  */
+
+.listing-tiles {
+  overflow: hidden;
+  margin-top: -10px;
+  margin-left: -10px;
+
+  .listing-tile {
+    background-color: #f2ebde;
+    display: block;
+    width: 238px;
+    height: 200px;
+    float: left;
+    border: 1px solid #676056;
+    margin-top: 10px;
+    margin-left: 10px;
+    border-radius: 4px;
+    text-align: center;
+
+    &.disabled {
+      border-color: red;
+    }
+
+    &.enabled {
+      border-color: green;
+    }
+  }
+}
+
+.listing {
+  .disabled {
+    color: red;
+  }
+  .enabled {
+    color: green;
+  }
+}
+
+.pager {
+    text-align: left;
+    padding-bottom: 10px;
+    .clearfix();
+
+    [data-part=left] {
+        display: inline-block;
+        width: 45%;
+        float: left;
+        text-align: left;
+    }
+
+    [data-part=right] {
+        display: inline-block;
+        width: 45%;
+        text-align: right;
+        float: right;
+        -moz-user-select: none;
+        -webkit-user-select: none;
+        -ms-user-select: none;
+    }
+
+    .action-next{
+        cursor: pointer;
+    }
+
+    .action-previous{
+        cursor: pointer;
+    }
+}
+
+.pager {
+  text-align: left;
+}
+.pager [data-part=left] {
+  display: inline-block;
+  width: 45%;
+  text-align: left;
+}
+.pager [data-part=right] {
+  display: inline-block;
+  width: 45%;
+  text-align: right;
+  float: right;
+}
+.grid .col-title {
+  min-width: 90px;
+  text-align: center;
+}
+.grid-actions [data-part=search] {
+  display: inline-block;
+  margin: 0 30px;
+}
+.grid-actions [data-part=search] input[type=text] {
+  vertical-align: bottom;
+  width: 460px;
+}
+
+.grid {
+  .actions-split .dropdown-menu {
+    right: auto;
+    left: auto;
+    text-align: left;
+    color: #676056;
+    font-weight: normal;
+
+    &:after  {
+      right: auto;
+      left: 9px;
+    }
+    &:before {
+      right: auto;
+      left: 10px;
+    }
+  }
+
+  .grid-actions {
+    padding: 10px 0;
+  }
+
+  .hor-scroll {
+    padding-top: 10px;
+  }
+
+  .select-box {
+    display: inline-block;
+    vertical-align: top;
+    margin: -12px -10px -7px;
+    padding: 12px 10px 7px;
+    width: 100%;
+  }
+}
+.filters {
+    &-toggle {
+        .button(
+            @_button-margin: 3px,
+            @_button-icon-use: true,
+            @_button-font-content: @icon-pointer-down,
+            @_button-icon-font-size: 30px,
+            @_button-icon-font-line-height: 15px,
+            @_button-icon-font-text-hide: false,
+            @_button-icon-font-position: after
+        );
+        .button-reset();
+        &:after {
+            margin-top: 2px;
+            margin-left: -3px;
+        }
+        &.active {
+            outline: 0;
+            &:after {
+                content: @icon-pointer-up;
+            }
+        }
+    }
+    &-current {
+        padding: 10px 0;
+        display: none;
+        &.active{
+            display: block;
+        }
+    }
+    &-items {
+        .list-reset-styles();
+        display: inline;
+    }
+    &-item {
+        display: inline-block;
+        margin:0 5px 5px 0;
+        padding: 2px 2px 2px 4px;
+        border-radius: 3px;
+        background: #f7f3eb;
+        .item-label {
+            font-weight: 600;
+            &:after {
+                content: ": "
+            }
+        }
+        .action-remove {
+            .button(
+                @_button-margin: 3px,
+                @_button-icon-use: true,
+                @_button-font-content: @icon-remove,
+                @_button-icon-font-size: 16px,
+                @_button-icon-font-line-height: 16px,
+                @_button-icon-font-text-hide: true
+            );
+            padding: 0;
+            //.button-reset();
+        }
+    }
+    &-form {
+        position: relative;
+        z-index: 1;
+        margin: 14px 0;
+        background: #ffffff;
+        border: 1px solid #bbbbbb;
+        -webkit-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        -moz-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        .action-close {
+            position: absolute;
+            top: 3px;
+            right: 7px;
+            .button(
+                @_button-margin: 3px,
+                @_button-icon-use: true,
+                @_button-font-content: @icon-remove,
+                @_button-icon-font-size: 42px,
+                @_button-icon-font-line-height: 42px,
+                @_button-icon-font-text-hide: true
+            );
+            .button-reset();
+        }
+    }
+    &-actions {
+        margin: 18px;
+        text-align: right;
+    }
+    &-fieldset {
+        padding-bottom: 0px;
+        .field {
+            border: 0;
+            .form-field(
+                    @_type: inline,
+                    @_column: true,
+                    @_column-number: 3,
+                    @_type-inline-label-width: 35%,
+                    @_type-inline-control-width: 65%
+                );
+            .label {
+                .style2();
+                margin: 0;
+            }
+        }
+    }
+    .field-date .group {
+        .control {
+            .icon-font(
+                @_icon-font-content: @icon-calendar,
+                @_icon-font-position: after,
+                @_icon-font-size: 32px
+            );
+            &:after {
+                position: absolute;
+                right: -10px;
+                top: -5px;
+                cursor: pointer;
+            }
+        }
+        .hasDatepicker {
+            width: 100%;
+            & + img {
+                float: right;
+                width: 20px;
+                margin: 0 -20px 0 0;
+                height: 20px;
+                position: relative;
+                z-index: 2;
+                cursor: pointer;
+                opacity: 0;
+            }
+        }
+    }
+    .field-range .group{
+        .field {
+            margin-bottom: 0;
+        }
+        .label {
+            &:extend(.visually-hidden all);
+        }
+        .control {
+            width: 100%;
+            .box-sizing();
+            padding-right: 20px;
+            position: relative;
+            z-index: 1;
+        }
+    }
+
+}
+
+/* [data-part=filter-form] {
+  width: 650px;
+  left: 150px;
+
+  background: #ffffff;
+  border: 1px solid #bbbbbb;
+  position: absolute;
+  z-index: 100;
+  -webkit-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+  -moz-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+  box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+  margin-top: 4px;
+
+  .title {
+    position: relative;
+    padding: 5px 18px;
+
+    .close {
+      position: absolute;
+      font-size: 0.8em;
+      right: 10px;
+      top: 12px;
+      cursor: pointer;
+
+      &:hover,
+      &:active {
+        text-decoration: underline;
+      }
+    }
+  }
+
+  > .actions {
+    padding: 5px 18px 36px;
+  }
+} */
+
+.mass-select {
+    position: relative;
+    margin: -6px -10px;
+    padding: 6px 2px 6px 10px;
+    z-index: 1;
+    white-space: nowrap;
+    &.active {
+        background: rgba(0,0,0,0.2);
+    }
+    &-toggle {
+        .button(
+            @_button-margin: 3px,
+            @_button-icon-use: true,
+            @_button-font-content: @icon-pointer-down,
+            @_button-icon-font-size: 30px,
+            @_button-icon-font-line-height: 15px,
+            @_button-icon-font-text-hide: true
+        );
+        .button-reset();
+        &:before {
+            margin-top: -2px;
+            text-indent: -5px;
+            color: #fff;
+        }
+        &:hover:before {
+            color: #fff;
+        }
+        &:active,
+        &.active {
+            outline: 0;
+            &:before {
+                content: @icon-pointer-up;
+            }
+        }
+    }
+    &-field {
+        .label {
+            &:extend(.visually-hidden all);
+        }
+        display: inline;
+    }
+    &-menu {
+        display: none;
+        position: absolute; top: 100%; left: 0;
+        text-align: left;
+        .list-reset-styles();
+        background: #ffffff;
+        border: 1px solid #bbbbbb;
+        min-width: 175px;
+        -webkit-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        -moz-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
+        li {
+          margin: 0;
+          padding: 4px 15px;
+          border-bottom: 1px solid #E5E5E5;
+        }
+        li:hover {
+          background: #e8e8e8;
+          cursor: pointer;
+        }
+        span {
+            font-weight: normal;
+            font-size: 13px;
+            color: #645D53;
+        }
+        &.active {
+            display: block;
+        }
+    }
+}
+
+.grid-loading-mask{
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(255, 255, 255, 0.5);
+    z-index: 100;
+
+    .grid-loader{
+        position: absolute;
+        margin: auto;
+        left: 0;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        width: 218px;
+        height: 149px;
+        background: url('@{baseDir}images/loader-2.gif') 50% 50% no-repeat;
+    }
+}
\ No newline at end of file
diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json
index b3e1efa2b7b..53888ad9bdc 100644
--- a/app/design/adminhtml/Magento/backend/composer.json
+++ b/app/design/adminhtml/Magento/backend/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/design/adminhtml/Magento/backend/theme.xml b/app/design/adminhtml/Magento/backend/theme.xml
index 02d98da6145..6c738f9599b 100644
--- a/app/design/adminhtml/Magento/backend/theme.xml
+++ b/app/design/adminhtml/Magento/backend/theme.xml
@@ -24,5 +24,5 @@
 -->
 <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
     <title>Magento 2 backend</title>
-    <version>0.1.0-alpha96</version>
+    <version>0.1.0-alpha97</version>
 </theme>
diff --git a/app/design/adminhtml/Magento/backend/web/css/pages.less b/app/design/adminhtml/Magento/backend/web/css/pages.less
index 9818e97b3c1..e60ccd18444 100644
--- a/app/design/adminhtml/Magento/backend/web/css/pages.less
+++ b/app/design/adminhtml/Magento/backend/web/css/pages.less
@@ -1042,38 +1042,40 @@
     }
 }
 
-.tax.summary-total .summary-collapse {
-    cursor: pointer;
-    display: inline-block;
-    &:before {
-        @iconsize: 16px;
-        content: "\e02d";
-        color: #816063;
-        background: #f2ebde;
+.summary-total {
+    .summary-collapse {
+        cursor: pointer;
         display: inline-block;
-        text-indent: 0;
-        font-size: @iconsize;
-        width:@iconsize;
-        height:@iconsize;
-        line-height: @iconsize;
-        overflow: hidden;
-        font-family: 'MUI-Icons';
-        border:1px solid #ada89e;
-        font-style: normal;
-        vertical-align: top;
-        margin-right:7px;
-        font-weight: normal;
-        speak: none;
-        -webkit-font-smoothing: antialiased;
-        border-radius: 2px;
+        &:before {
+            @iconsize: 16px;
+            content: "\e02d";
+            color: #816063;
+            background: #f2ebde;
+            display: inline-block;
+            text-indent: 0;
+            font-size: @iconsize;
+            width:@iconsize;
+            height:@iconsize;
+            line-height: @iconsize;
+            overflow: hidden;
+            font-family: 'MUI-Icons';
+            border:1px solid #ada89e;
+            font-style: normal;
+            vertical-align: top;
+            margin-right:7px;
+            font-weight: normal;
+            speak: none;
+            -webkit-font-smoothing: antialiased;
+            border-radius: 2px;
+        }
+        &:hover:before {
+            background: #cac3b4;
+        }
     }
-    &:hover:before {
-        background: #cac3b4;
+    &.show-details .summary-collapse:before {
+        content: "\e03a";
     }
 }
-.tax.summary-total.show-details .summary-collapse:before {
-    content: "\e03a";
-}
 
 tr.row-totals:nth-child(even) + tr.summary-details ~ tr.summary-total:not(.show-details):nth-child(even) td,
 tr.row-totals:nth-child(even) + tr.summary-details ~ tr.summary-total:not(.show-details):nth-child(even) ~ tr.row-totals:nth-child(even) td,
@@ -1909,7 +1911,7 @@ table.items-to-invoice tbody tr:hover td {
 /*
     URL rewrite
 -------------------------------------- */
-.adminhtml-urlrewrite-edit .field-url-rewrite-option-select .label {
+.adminhtml-urlrewrite-edit .field-entity-type-selector .label {
     width: auto;
 }
 
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/table.less b/app/design/adminhtml/Magento/backend/web/css/source/table.less
index 447c0997800..cf731ee5501 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/table.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/table.less
@@ -1238,7 +1238,7 @@ td.col-type {
 }
 
 //
-//    Marketing -> URL Redirects
+//    Marketing -> URL Rewrites
 // --------------------------------------
 .adminhtml-urlrewrite-index .col-request_path {
     &:extend(.ellipsis all);
diff --git a/app/design/adminhtml/Magento/backend/web/less/styles/debug.less b/app/design/adminhtml/Magento/backend/web/less/styles/debug.less
index cc6426649f0..6e0ec2f78e4 100644
--- a/app/design/adminhtml/Magento/backend/web/less/styles/debug.less
+++ b/app/design/adminhtml/Magento/backend/web/less/styles/debug.less
@@ -681,7 +681,7 @@
 
     URL Rewrite
 -------------------------------------- */
-.field-url-rewrite-option-select {
+.field-entity-type-selector {
     padding-top: 13px;
 }
 
diff --git a/app/design/adminhtml/Magento/backend/web/less/styles/pages.less b/app/design/adminhtml/Magento/backend/web/less/styles/pages.less
index 3d77a2a7af3..a0ecdfb3a04 100644
--- a/app/design/adminhtml/Magento/backend/web/less/styles/pages.less
+++ b/app/design/adminhtml/Magento/backend/web/less/styles/pages.less
@@ -1889,7 +1889,7 @@ table.items-to-invoice tbody tr:hover td {
 /*
     URL rewrite
 -------------------------------------- */
-.adminhtml-urlrewrite-edit .field-url-rewrite-option-select .label {
+.adminhtml-urlrewrite-edit .field-entity-type-selector .label {
     width: auto;
 }
 
diff --git a/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less
index 60a53b11596..fcab8cc1d04 100644
--- a/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Bundle/web/css/source/module.less
@@ -60,10 +60,14 @@
         }
     }
 
+    .price-notice {
+        &:extend(.abstract-adjustment-incl-excl-tax all);
+    }
+
     .block-bundle-summary {
         padding: @indent-s-base @indent-base;
         background: @color-secondary;
-        &:extend(.add-box-sizing all);
+        &:extend(.abstract-add-box-sizing all);
 
         > .title > strong {
             .heading(h2);
@@ -81,7 +85,7 @@
         }
 
         .bundle.items {
-            &:extend(.reset-list all);
+            &:extend(.abstract-reset-list all);
             > li {
                 margin-bottom: @indent-s-base;
             }
@@ -113,7 +117,7 @@
 .responsive(@break) when (@break = @screen-m) {
     .bundle-options-container {
         .legend.title {
-            &:extend(.reset-left-margin all);
+            &:extend(.abstract-reset-left-margin all);
         }
         .product-options-wrapper {
             float: left;
diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/listings.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/listings.less
index f5074295d65..afe03e58e1b 100644
--- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/listings.less
+++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/listings.less
@@ -47,7 +47,7 @@
 }
 .product {
     &-items {
-        &:extend(.reset-list all);
+        &:extend(.abstract-reset-list all);
         margin-left: -20px;
     }
     &-item {
@@ -92,7 +92,7 @@
                         margin: 0;
                     }
                     span {
-                        &:extend(.visually-hidden all);
+                        &:extend(.abstract-visually-hidden all);
                     }
                 }
             }
@@ -114,35 +114,118 @@
         .price-box {
             margin: @indent-s-base 0 @indent-m-base;
             .price {
+                .font-size(14);
                 font-weight: bold;
             }
             .price-label {
                 font-size: @font-size-s;
                 color: @text-color-muted;
+                &:after {
+                    content: ":";
+                }
             }
-
         }
+
         .special-price,
-        .old-price {
-            display: inline;
+        .minimal-price {
+            .price {
+                .font-size(14);
+                font-weight: bold;
+            }
+            .price-wrapper {
+                display: inline-block;
+            }
+            .price-including-tax + .price-excluding-tax {
+                display: block;
+            }
         }
+
+        .special-price {
+            display: block;
+        }
+
         .old-price {
             color: @text-color-muted;
             .price {
                 font-weight: normal;
             }
         }
+
+        .minimal-price {
+            .price-container {
+                display: block;
+            }
+        }
+
+        .minimal-price-link {
+            margin-top: 5px;
+            .price-label {
+                color: @link-color;
+                .font-size(14);
+            }
+            .price {
+                font-weight: @font-weight-base;
+            }
+        }
+
+        .minimal-price-link,
+        .price-excluding-tax,
+        .price-including-tax {
+            white-space: nowrap;
+            display: block;
+        }
+
+        .price-from,
+        .price-to {
+            margin: 0;
+        }
+
         .tocompare {
             .icon-font-symbol(
                 @icon-compare-empty
             );
         }
+
         .tocart {
             white-space: nowrap;
         }
     }
 }
 
+.price-container {
+    .price {
+        .font-size(14);
+    }
+
+    .price-including-tax + .price-excluding-tax,
+    .weee {
+        margin-top: 5px;
+    }
+
+    .price-including-tax + .price-excluding-tax,
+    .weee,
+    .price-including-tax + .price-excluding-tax .price,
+    .weee .price,
+    .weee + .price-excluding-tax:before,
+    .weee + .price-excluding-tax .price {
+        .font-size(11);
+    }
+
+    .weee {
+        &:before {
+            content: "("attr(data-label) ": ";
+        }
+        &:after {
+            content: ")";
+        }
+        + .price-excluding-tax {
+            &:before {
+                content: attr(data-label) ": ";
+            }
+        }
+    }
+}
+
 .products-list .product {
     &-item {
         display: table;
diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less
index 145a9a0314d..2e9751d4f69 100644
--- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module.less
@@ -58,13 +58,33 @@
 .old.price {
     text-decoration: line-through;
 }
+.price-tier_price {
+    .price-including-tax + .price-excluding-tax {
+        &:before {
+            content: "(" attr(data-label) ": ";
+        }
+        &:last-child:after {
+            content: ")";
+        }
+    }
+
+    .weee[data-label] {
+        display: inline;
+        .price {
+            .font-size(11);
+        }
+        &:before {
+            content: " +" attr(data-label) ": ";
+        }
+    }
+}
 
-.actual.price {
+.actual-price {
     font-weight: @font-weight-bold;
 }
 
 .product.name a {
-    &:extend(.product-link all);
+    &:extend(.abstract-product-link all);
 }
 
 .category {
@@ -190,12 +210,43 @@
     }
 
     .price-box {
-        .price {
-            font-size: @font-size-l;
+        .price-including-tax + .price-excluding-tax,
+        .weee + .price-excluding-tax,
+        .weee {
+            .font-size(12);
+            margin-bottom: 5px;
+            line-height: 14px;
+            .price {
+                .font-size(12);
+                font-weight: @font-weight-bold;
+            }
+        }
+        .price-wrapper .price {
+            .font-size(18);
             font-weight: @font-weight-bold;
         }
     }
 
+    .special-price {
+        display: block;
+        margin: @indent-s-base 0;
+        .price-container {
+            .font-size(14);
+        }
+        .price-label + .price-wrapper {
+            display: inline-block;
+        }
+    }
+
+    .old-price,
+    .special-price {
+        .price-label {
+            &:after {
+                content: ": ";
+            }
+        }
+    }
+
     .box-tocart {
         margin: @indent-base 0;
         .field.qty {
@@ -228,18 +279,23 @@
     }
 }
 
-.prices.tier.items {
-    &:extend(.reset-list all);
+.prices-tier {
+    &:extend(.abstract-reset-list all);
     background: @sidebar-background;
     padding: @indent-s-base (0.75 * @indent-base);
     margin: @indent-s-base 0;
-}
-
-.minimal-price-link,
-.price-excluding-tax,
-.price-including-tax {
-    white-space: nowrap;
-    display: block;
+    .price-tier_price {
+        display: inline-block;
+    }
+    .price-including-tax,
+    .price-excluding-tax,
+    .weee {
+        display: inline-block;
+        .price {
+            .font-size(14);
+            font-weight: @font-weight-bold;
+        }
+    }
 }
 
 .ui-dialog-titlebar-close {
@@ -325,10 +381,15 @@
         padding: 22px;
     }
     .map.add.form {
-        &:extend(.add-clearfix all);
+        &:extend(.abstract-add-clearfix all);
         margin-bottom: 15px;
         .price-box {
             float: left;
+            .label {
+                &:after {
+                    content: ": ";
+                }
+            }
         }
     }
     .form.map.checkout {
@@ -341,7 +402,7 @@
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
     .product-add-form {
-        &:extend(.revert-field-type-desktop all);
+        &:extend(.abstract-revert-field-type-desktop all);
     }
 }
 
@@ -365,7 +426,7 @@ body.catalog-product-compare-index {
     .cell.label.remove,
     .cell.label.product {
         span {
-            .visually-hidden();
+            &:extend(.abstract-visually-hidden all);
         }
     }
 
@@ -439,7 +500,7 @@ body.catalog-product-compare-index {
         padding-bottom: 0;
         text-align: right;
         .action.delete {
-            &:extend(.remove-button-for-blocks all);
+            &:extend(.abstract-remove-button-for-blocks all);
         }
     }
     .product-item-actions {
@@ -467,7 +528,7 @@ body.catalog-product-compare-index {
             margin-left: 22px;
         }
         .action.delete {
-            &:extend(.remove-button-for-blocks all);
+            &:extend(.abstract-remove-button-for-blocks all);
             position: absolute;
             left: -6px;
             top: 0;
diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/toolbar.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/toolbar.less
index fc988c625b7..bb781d36446 100644
--- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/toolbar.less
+++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/toolbar.less
@@ -48,7 +48,7 @@
         margin-bottom: @indent-xl-base;
         text-align: center;
         padding: 0 @indent-s-base;
-        &:extend(.add-clearfix all);
+        &:extend(.abstract-add-clearfix all);
         .pages {
             display: none;
             .products.wrapper ~ & {
@@ -121,7 +121,7 @@
             display: none;
         }
         &-label {
-            .visually-hidden;
+            &:extend(.abstract-visually-hidden-desktop-s all);
         }
         &-mode {
             float: left;
diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/widgets.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/widgets.less
index 03b747dd275..ce46bfbe127 100644
--- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/widgets.less
+++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/widgets.less
@@ -24,13 +24,13 @@
 
 .widget.product.link {
     a {
-        &:extend(.product-link all);
+        &:extend(.abstract-product-link all);
     }
 }
 
 div.widget.product.link,
 div.widget.category.link {
-    &:extend(.margin-for-blocks-and-widgets all);
+    &:extend(.abstract-margin-for-blocks-and-widgets all);
 }
 
 .block.widget.new {
diff --git a/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/module.less
index 1a0ae1bbfae..1d5e06c29b0 100644
--- a/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/module.less
@@ -55,8 +55,8 @@
     .control {
         border-top: 1px solid @border-color-base;
         clear: both;
-        margin: 0 -20px -1px;
-        padding: 0 20px;
+        margin: 0 -@layout-width-xs-indent -1px;
+        padding: 0 @layout-width-xs-indent;
     }
 
     input {
@@ -79,7 +79,7 @@
     z-index: 3;
     overflow: hidden;
     margin-top: -15px;
-    &:extend(.add-box-sizing all);
+    &:extend(.abstract-add-box-sizing all);
     ul {
         .list-reset-styles();
         li {
@@ -165,7 +165,7 @@
         width: 250px;
         z-index: 4;
         .label {
-            .visually-hidden();
+            &:extend(.abstract-visually-hidden-desktop all);
         }
         .control {
             border-top: 0;
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/layout/checkout_cart_index.xml b/app/design/frontend/Magento/blank/Magento_Checkout/layout/checkout_cart_index.xml
index 8c3c7624183..a3555ecc82f 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/layout/checkout_cart_index.xml
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/layout/checkout_cart_index.xml
@@ -46,6 +46,6 @@
     <move element="checkout.cart.widget" destination="checkout.cart.container" after="checkout.cart.form" />
     <move element="checkout.cart.shipping" destination="cart.summary" after="checkout.cart.summary.title" />
     <move element="checkout.cart.coupon" destination="cart.summary" />
-    <move element="checkout.cart.totals" destination="cart.summary"/>
+    <move element="checkout.cart.totals.container" destination="cart.summary"/>
     <move element="checkout.cart.methods.bottom" destination="cart.summary"/>
 </page>
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less
index 3b3d197b82d..c0d7af501df 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/cart.less
@@ -28,7 +28,7 @@
 .cart {
     //  Summary block
     &-summary {
-        &:extend(.add-box-sizing all);
+        &:extend(.abstract-add-box-sizing all);
         background: @sidebar-background;
         margin-bottom: 25px;
         padding: 1px 15px 25px;
@@ -90,6 +90,15 @@
                     }
                 }
             }
+            .fieldset {
+                .methods {
+                    .field {
+                        > .label {
+                            display: inline;
+                        }
+                    }
+                }
+            }
         }
         .actions-toolbar {
             > .primary {
@@ -98,6 +107,7 @@
                 }
             }
         }
+        &:extend(.abstract-adjustment-incl-excl-tax all);
     }
 
     //  Totals block
@@ -187,7 +197,6 @@
             &.subtotal,
             &.msrp {
                 padding-top: 20px;
-                &:extend(.abstract-incl-excl-tax all);
             }
             &.qty {
                 .input-text {
@@ -261,11 +270,8 @@
             font-size: @font-size-s;
             margin-top: @indent-s-base;
             margin-bottom: @indent-s-base;
-            &:extend(.product-options-list all);
-            &:extend(.add-clearfix all);
-        }
-        .cart-tax-total {
-            &:extend(.abstract-tax-total all);
+            &:extend(.abstract-product-options-list all);
+            &:extend(.abstract-add-clearfix all);
         }
     }
     &-container {
@@ -310,7 +316,7 @@
             }
         }
         .checkout-methods-items {
-            &:extend(.reset-list all);
+            &:extend(.abstract-reset-list all);
             text-align: center;
             margin-top: @indent-s-base;
             .action.primary {
@@ -380,7 +386,7 @@
 .responsive(@break) when (@break = @screen-m) {
     .cart {
         &-container {
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
             .form.cart {
                 float: left;
                 width: 73%;
@@ -411,7 +417,7 @@
             width: 23%;
             .actions-toolbar {
                 .column.main & {
-                    &:extend(.reset-left-margin-desktop all);
+                    &:extend(.abstract-reset-left-margin-desktop all);
                     > .secondary {
                         float: none;
                     }
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/minicart.less
index a9dd73a13a2..c8c54aec977 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/minicart.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/minicart.less
@@ -29,12 +29,6 @@
     .subtotal {
         border-top: 1px solid @color-secondary;
         padding-top: 10px;
-        .amount {
-            font-size: @font-size-xl;
-            .incl.tax {
-                display: block;
-            }
-        }
     }
     .subtitle {
         .heading(h3);
@@ -105,32 +99,13 @@
             display: inline;
         }
     }
-    .pricing.details {
-        display: table;
-        .rate,
-        .details.qty {
-            display: table-row;
-        }
-        .value,
-        .label {
-            padding-right:10px;
-            display: table-cell;
-        }
-        .label:after {
-            content: ":";
-        }
-    }
-    .action.edit {
-        .icon-font(
-            @icon-settings,
-            @_icon-font-size: 28px,
-            @_icon-font-line-height: 28px,
-            @_icon-font-text-hide: true,
-            @_icon-font-color: #303030,
-            @_icon-font-color-hover: #303030,
-            @_icon-font-color-active: #303030
-        );
-    }
+    .ui-dialog {
+         .action.close {
+             right: 0;
+             top: 46px;
+             z-index: 100;
+         }
+     }
     .action.close {
         position: absolute;
         right: 14px;
@@ -146,7 +121,7 @@
     }
     .action.showcart {
         .text {
-            &:extend(.visually-hidden all);
+            &:extend(.abstract-visually-hidden all);
         }
         .icon-font(
             @_icon-font-content: @icon-cart,
@@ -178,13 +153,6 @@
             white-space: normal;
         }
     }
-    .ui-dialog {
-        .action.close {
-            right: 0;
-            top: 46px;
-            z-index: 100;
-        }
-    }
 }
 
 .minilist {
@@ -194,25 +162,42 @@
         padding: 15px 0;
         z-index: 1;
     }
+
     .item > .product {
-        &:extend(.add-clearfix all);
+        &:extend(.abstract-add-clearfix all);
     }
+
     .product.photo {
         float: left;
     }
-    .product.details {
+
+    .product-item-details {
         padding-left: 88px;
     }
-    .action.delete {
-        .icon-font(
-            @icon-trash,
-            @_icon-font-size: 28px,
-            @_icon-font-line-height: 28px,
-            @_icon-font-text-hide: true,
-            @_icon-font-color: #303030,
-            @_icon-font-color-hover: #303030,
-            @_icon-font-color-active: #303030
-        );
+
+    .details-qty {
+        .label:after {
+            content: ":";
+        }
+    }
+    .action {
+         &.edit,
+         &.delete {
+             .icon-font(
+                 @icon-settings,
+                 @_icon-font-size: 28px,
+                 @_icon-font-line-height: 28px,
+                 @_icon-font-text-hide: true,
+                 @_icon-font-color: #303030,
+                 @_icon-font-color-hover: #303030,
+                 @_icon-font-color-active: #303030
+             );
+         }
+         &.delete {
+             .icon-font-symbol(
+                 @_icon-font-content: @icon-trash
+             );
+         }
     }
 }
 
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less
index 6e6efca1563..24e85d2518e 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module.less
@@ -31,10 +31,10 @@
 //    One Page Checkout
 //--------------------------------------
 .opc-wrapper {
-    &:extend(.add-box-sizing all);
+    &:extend(.abstract-add-box-sizing all);
     .css(padding-bottom, @indent-xl-base);
     > .opc {
-        &:extend(.reset-list all);
+        &:extend(.abstract-reset-list all);
     }
     .section {
         &.allow .step-title {
@@ -136,8 +136,9 @@
             .price {
                 font-weight: @font-weight-bold;
             }
+            &:extend(.abstract-adjustment-incl-excl-tax all);
         }
-        .price.box {
+        .price-box {
             margin-left: 20px;
             .label + .price {
                 font-weight: @font-weight-bold;
@@ -173,7 +174,7 @@
 
     // Order review
     .data.table {
-        &:extend(.product-options-list all);
+        &:extend(.abstract-product-options-list all);
         .table-caption(@_table-caption-hide: true);
         tbody tr:first-child td {
             border-top: @border-width-base solid @border-color-base;
@@ -189,9 +190,6 @@
                 white-space: nowrap;
             }
         }
-        th.col.subtotal {
-            text-align: center;
-        }
         .mark,
         .amount {
             text-align: right;
@@ -205,7 +203,7 @@
         .review-item-options {
             font-size: @font-size-s;
             margin: 10px 0 0;
-            &:extend(.add-clearfix all);
+            &:extend(.abstract-add-clearfix all);
         }
     }
 
@@ -221,7 +219,7 @@
     .login-wrapper {
         .block {
             > .title {
-                &:extend(.login-block-title all);
+                &:extend(.abstract-login-block-title all);
             }
             .fieldset.guest {
                 margin-top: 20px;
@@ -237,11 +235,15 @@
     }
 }
 
+.cart-tax-info + .cart-tax-total {
+    display: block;
+}
+
 //
 //    Checkout Progress
 //--------------------------------------
 .opc-block-progress {
-    &:extend(.add-box-sizing all);
+    &:extend(.abstract-add-box-sizing all);
     margin-bottom: @indent-l-base;
     > .title {
         background: @sidebar-background;
@@ -318,7 +320,7 @@
 .responsive-smaller(@break) when (@break = @screen-m) {
     .opc-wrapper {
         .data.table {
-            &:extend(.table-vertical-mobile all);
+            &:extend(.abstract-table-vertical-mobile all);
             tbody tr {
                 &:first-child,
                 &:last-child {
@@ -346,12 +348,12 @@
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
     .checkout-onepage-index .column.main {
-        &:extend(.add-clearfix-desktop all);
+        &:extend(.abstract-add-clearfix-desktop all);
     }
 
     .opc-wrapper {
         .layout-column(2, 2, @layout-column-checkout-main-width);
-        &:extend(.add-box-sizing-desktop all);
+        &:extend(.abstract-add-box-sizing-desktop all);
         .step-content {
             padding: 20px 18px 40px;
             .addresses .control {
@@ -362,7 +364,7 @@
                     text-align: right;
                 }
                 &:not(.login) .actions-toolbar {
-                    &:extend(.reset-left-margin-desktop all);
+                    &:extend(.abstract-reset-left-margin-desktop all);
                 }
                 > .field.choice,
                 .fieldset > .field {
@@ -376,7 +378,7 @@
             }
             .fieldset.login {
                 &:after {
-                    &:extend(.margin-for-forms-desktop all);
+                    &:extend(.abstract-margin-for-forms-desktop all);
                     text-align: left;
                 }
             }
@@ -386,11 +388,11 @@
     .opc-block-progress {
         .layout-column(2, 1, @layout-column-checkout-left-width);
         padding-right: @layout-column-main-sidebar-offset;
-        &:extend(.add-box-sizing-desktop all);
+        &:extend(.abstract-add-box-sizing-desktop all);
     }
 
     .login-wrapper {
-        &:extend(.add-clearfix-desktop all);
+        &:extend(.abstract-add-clearfix-desktop all);
         .block {
             &:extend(.blocks-2columns all);
         }
@@ -401,7 +403,7 @@
         }
         .fieldset.login {
             .actions {
-                &:extend(.margin-for-forms-desktop all);
+                &:extend(.abstract-margin-for-forms-desktop all);
             }
         }
     }
diff --git a/app/design/frontend/Magento/blank/Magento_Cms/web/css/source/widgets.less b/app/design/frontend/Magento/blank/Magento_Cms/web/css/source/widgets.less
index c1c650ffcb3..d7864edc5e4 100644
--- a/app/design/frontend/Magento/blank/Magento_Cms/web/css/source/widgets.less
+++ b/app/design/frontend/Magento/blank/Magento_Cms/web/css/source/widgets.less
@@ -26,7 +26,7 @@
 
 .widget.widget-cms-link {
     display: block;
-    &:extend(.margin-for-blocks-and-widgets all);
+    &:extend(.abstract-margin-for-blocks-and-widgets all);
 }
 
 .widget.widget-cms-link-inline {}
diff --git a/app/design/frontend/Magento/blank/Magento_Customer/layout/customer_account.xml b/app/design/frontend/Magento/blank/Magento_Customer/layout/customer_account.xml
index aaaa5b6157d..4fd832a902b 100644
--- a/app/design/frontend/Magento/blank/Magento_Customer/layout/customer_account.xml
+++ b/app/design/frontend/Magento/blank/Magento_Customer/layout/customer_account.xml
@@ -24,16 +24,14 @@
  */
 -->
 <page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Core/etc/page.xsd">
-    <referenceBlock name="body.class">
-        <action method="addBodyClass">
-            <argument name="class" xsi:type="string">account</argument>
-        </action>
-    </referenceBlock>
+    <body>
+        <attribute name="class" value="account"/>
+    </body>
     <referenceContainer name="sidebar.main">
         <block class="Magento\Framework\View\Element\Template" name="customer_account_navigation_block" template="Magento_Theme::html/collapsible.phtml">
             <arguments>
                 <argument name="block_title" translate="true" xsi:type="string">Account Dashboard</argument>
-                <argument name="block_css" xsi:type="string">block-account-nav</argument>
+                <argument name="block_css" xsi:type="string">block-collapsible-nav</argument>
             </arguments>
             <block class="Magento\Framework\View\Element\Html\Links" name="customer_account_navigation" before="-">
                 <arguments>
diff --git a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less
index 5ec79a6c7a0..f5997ab3b43 100644
--- a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/module.less
@@ -22,13 +22,6 @@
 //  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 //  */
 
-@account-nav-background: #e8e8e8;
-@account-nav-color: false;
-@account-nav-current-color: false;
-@account-nav-current-font-weight: @font-weight-base;
-@account-nav-current-border: 3px solid transparent;
-@account-nav-current-border-color: #ff5501;
-
 .login.container {
     .block {
         &.new {
@@ -37,7 +30,7 @@
             }
         }
         .title {
-            &:extend(.login-block-title all);
+            &:extend(.abstract-login-block-title all);
         }
     }
     .fieldset {
@@ -98,81 +91,12 @@
             }
         }
         .block:not(.widget) {
-            .block-title {
-                > strong {
-                    .heading(h3);
-                }
-                margin-bottom: 15px;
-                > .action {
-                    margin-left: 15px;
-                }
-            }
-            .box-title {
-                > span {
-                    .heading(h4);
-                }
-                display: inline-block;
-                margin: 0 0 5px;
-                > .action {
-                    font-weight: 400;
-                    margin-left: 15px;
-                }
-            }
-            .block-content {
-                p:last-child {
-                    margin-bottom: 0;
-                }
-                .box {
-                    margin-bottom: @indent-base;
-                }
-            }
+            &:extend(.abstract-account-blocks all);
         }
     }
-    .sidebar .block-account-nav {
-        .css(background, @sidebar-background);
-    }
     .sidebar-additional {
         margin-top: 40px;
     }
-    .block-account-nav {
-        .title {
-            display: none;
-        }
-        .content {
-            padding: 15px 0;
-        }
-        .nav.items {
-            padding: 0;
-            margin: 0;
-            .nav.item {
-                margin: 3px 0 0;
-                &:first-child {
-                    margin-top: 0;
-                }
-                a,
-                strong {
-                    display: block;
-                    padding: 5px 18px 5px 15px;
-                    border-left: 3px solid transparent;
-                }
-                a {
-                    .css(color, @account-nav-color);
-                    text-decoration: none;
-                    &:hover {
-                        .css(background, @account-nav-background);
-                    }
-                }
-                &.current {
-                    a,
-                    strong {
-                        .css(color, @account-nav-current-color);
-                        .css(border-color, @account-nav-current-border-color);
-                        font-weight: normal;
-                    }
-                }
-            }
-        }
-    }
     .table-wrapper {
         margin-bottom: @indent-base;
         &:last-child {
@@ -196,7 +120,7 @@
 //    Blocks & Widgets
 //--------------------------------------
 .block {
-    &:extend(.margin-for-blocks-and-widgets all);
+    &:extend(.abstract-margin-for-blocks-and-widgets all);
     &:last-child {
         margin-bottom: 0;
     }
@@ -239,12 +163,12 @@
             margin-bottom: 40px;
         }
         .data.table {
-            &:extend(.table-vertical-mobile all);
+            &:extend(.abstract-table-vertical-mobile all);
             .col.actions {
                 padding-top: 9px;
                 padding-bottom: 15px;
                 &:before {
-                    &:extend(.visually-hidden-mobile all);
+                    &:extend(.abstract-visually-hidden-mobile all);
                 }
             }
         }
@@ -255,23 +179,6 @@
                 margin-bottom: 25px;
             }
         }
-        .block-account-nav {
-            margin-left: -@layout-width-xs-indent;
-            margin-right: -@layout-width-xs-indent;
-            margin-top: -(@indent-base + 1);
-            .title {
-                &:extend(.abstract-toggling-title-mobile all);
-                strong {
-                    margin: 0;
-                }
-            }
-            .content {
-                display: none;
-                &.active {
-                    display: block;
-                }
-            }
-        }
     }
     .control.captcha-image {
         .captcha-img {
@@ -286,9 +193,9 @@
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
     .login.container {
-        &:extend(.add-clearfix-desktop all);
+        &:extend(.abstract-add-clearfix-desktop all);
         .block {
-            &:extend(.blocks-2columns all);
+            &:extend(.abstract-blocks-2columns all);
             &.login {
                 .actions-toolbar {
                     > .primary {
@@ -303,7 +210,7 @@
         }
         .fieldset {
             &:after {
-                &:extend(.margin-for-forms-desktop all);
+                &:extend(.abstract-margin-for-forms-desktop all);
                 text-align: left;
             }
             > .field {
@@ -337,9 +244,9 @@
         .column.main {
             .block:not(.widget) {
                 .block-content {
-                    &:extend(.add-clearfix-desktop all);
+                    &:extend(.abstract-add-clearfix-desktop all);
                     .box {
-                        &:extend(.blocks-2columns all);
+                        &:extend(.abstract-blocks-2columns all);
                     }
                 }
             }
@@ -354,7 +261,7 @@
         .toolbar {
             position: relative;
             margin-bottom: @indent-base;
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
             .limiter {
                 float: right;
                 position: relative;
@@ -377,9 +284,9 @@
 
     .block-addresses-list {
         .items.addresses {
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
             > .item {
-                &:extend(.blocks-2columns all);
+                &:extend(.abstract-blocks-2columns all);
                 margin-bottom: @indent-base;
                 &:nth-last-child(1),
                 &:nth-last-child(2) {
diff --git a/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less
index 056e7779ae4..42c54c38859 100644
--- a/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Downloadable/web/css/source/module.less
@@ -33,3 +33,27 @@
         margin-right: 15px;
     }
 }
+.field.downloads {
+    .price-container {
+        display: inline;
+        white-space: nowrap;
+        &:before {
+            content: " + ";
+            display: inline;
+        }
+    }
+    .price-excluding-tax {
+        display: inline;
+        &:before {
+            content: " ("attr(data-label) ": ";
+        }
+        &:after {
+            content: ")";
+        }
+    }
+    .price-including-tax {
+        display: inline;
+        font-weight:  @font-weight-semibold;
+        .font-size(14);
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_GiftMessage/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_GiftMessage/web/css/source/module.less
index 6878cadc320..e15c51ec522 100644
--- a/app/design/frontend/Magento/blank/Magento_GiftMessage/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_GiftMessage/web/css/source/module.less
@@ -76,6 +76,19 @@
             .number {
                 font-size: @font-size-s;
             }
+            .regular-price,
+            .price-including-tax,
+            .price-excluding-tax {
+                &:before {
+                    content: attr(data-label) ": ";
+                }
+                .price {
+                    font-weight: @font-weight-bold;
+                }
+            }
+            .price-including-tax {
+                .font-size(14);
+            }
         }
     }
 }
@@ -87,7 +100,7 @@
                 border-bottom: @border-width-base solid @border-color-base;
                 margin-bottom: 20px;
                 padding-bottom: 10px;
-                &:extend(.add-clearfix-desktop all);
+                &:extend(.abstract-add-clearfix-desktop all);
                 .product {
                     float: left;
                     margin-right: 20px;
@@ -104,7 +117,7 @@
                     overflow: hidden;
                 }
             }
-            .price.box > .price {
+            .price-box > .price {
                 display: block;
             }
         }
diff --git a/app/design/frontend/Magento/blank/Magento_LayeredNavigation/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_LayeredNavigation/web/css/source/module.less
index a485e180fe2..c71bf97067d 100644
--- a/app/design/frontend/Magento/blank/Magento_LayeredNavigation/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_LayeredNavigation/web/css/source/module.less
@@ -57,7 +57,7 @@
         }
     }
     .items {
-        &:extend(.reset-list all);
+        &:extend(.abstract-reset-list all);
     }
     .filtered {
         .items {
@@ -71,7 +71,7 @@
                 font-weight: @font-weight-bold;
             }
             .action.remove {
-                &:extend(.remove-button-for-blocks all);
+                &:extend(.abstract-remove-button-for-blocks all);
                 position: absolute;
                 left: -6px;
                 top: 0;
diff --git a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/module.less
index 4ca592d4e99..2999d80e643 100644
--- a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/module.less
@@ -25,13 +25,13 @@
 .multicheckout {
     &.form {
         > .title {
-            &:extend(.add-clearfix all);
+            &:extend(.abstract-add-clearfix all);
             margin-bottom: 25px;
             > strong {
                 .heading(h3);
             }
             > .action {
-                &:extend(.button-responsive all);
+                &:extend(.abstract-button-responsive all);
                 margin-top: 10px;
             }
         }
@@ -66,10 +66,14 @@
         .product .item.options {
             font-size: @font-size-s;
             margin-top: 10px;
-            &:extend(.product-options-list all);
+            &:extend(.abstract-product-options-list all);
         }
     }
 
+    .box-order-shipping-method {
+        &:extend(.abstract-adjustment-incl-excl-tax all);
+    }
+
     .column.main & {
         .block:not(.widget):not(.widget) {
             &:extend(.account .column.main .block:not(.widget) all);
@@ -128,7 +132,7 @@
     }
 
     .checkout.review .grand.totals {
-        &:extend(.add-clearfix all);
+        &:extend(.abstract-add-clearfix all);
         margin: 0 10px 40px;
         .mark {
             float: left;
@@ -141,7 +145,7 @@
     &.block.progress {
         background: @sidebar-background;
         padding: 15px;
-        &:extend(.reset-list);
+        &:extend(.abstract-reset-list);
         .active {
             font-weight: bold;
         }
@@ -159,7 +163,7 @@
                 > .action {
                     float: right;
                     margin-left: 15px;
-                    &:extend(.button-desktop all);
+                    &:extend(.abstract-button-desktop all);
                 }
             }
             .col {
@@ -178,7 +182,7 @@
             }
             .column.main & {
                 .actions-toolbar {
-                    &:extend(.reset-left-margin-desktop all);
+                    &:extend(.abstract-reset-left-margin-desktop all);
                 }
                 .block:not(.widget):not(.widget) .content .box.items {
                     width: 100%;
@@ -188,15 +192,15 @@
 
         &.change.billing {
             .content {
-                &:extend(.add-clearfix-desktop all);
+                &:extend(.abstract-add-clearfix-desktop all);
             }
             .box {
-                &:extend(.blocks-2columns all);
+                &:extend(.abstract-blocks-2columns all);
             }
         }
 
         .checkout.review .grand.totals {
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
         }
         &.success {
             overflow: hidden;
diff --git a/app/design/frontend/Magento/blank/Magento_Newsletter/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Newsletter/web/css/source/module.less
index cd575fd5926..4cfdb11ae29 100644
--- a/app/design/frontend/Magento/blank/Magento_Newsletter/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Newsletter/web/css/source/module.less
@@ -25,7 +25,6 @@
 //
 //    Newsletter subscription
 //--------------------------------------
-
 .block.newsletter {
     margin-bottom: 40px;
     .form.subscribe {
@@ -46,7 +45,7 @@
                 @_icon-font-size: 35px,
                 @_icon-font-line-height: 33px,
                 @_icon-font-color: @form-element-input-placeholder-color
-                );
+            );
             &:before {
                 position: absolute;
             }
@@ -60,7 +59,7 @@
         display: none;
     }
     .label {
-        .visually-hidden();
+        &:extend(.abstract-visually-hidden all);
     }
     .actions {
         display: table-cell;
diff --git a/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less
index 990abb7f1bf..35d099f9ac1 100644
--- a/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Paypal/web/css/source/module.less
@@ -55,6 +55,140 @@
 
 .form-new-agreement {
     .actions-toolbar {
-        &:extend(.reset-left-margin all);
+        &:extend(.abstract-reset-left-margin all);
+    }
+}
+
+//
+//    PayPal Review Order page
+//--------------------------------------
+.paypal-review {
+    .block {
+        &:extend(.abstract-account-blocks all);
+        .actions-toolbar {
+            .action.primary {
+                &:extend(.abstract-revert-secondary-color all);
+            }
+        }
+    }
+
+    .paypa-review-title {
+        > strong {
+            .heading(h3);
+            display: inline-block;
+        }
+    }
+
+    .items-qty {
+        &:extend(.abstract-reset-list all);
+        .item {
+            white-space: nowrap;
+        }
+        .title {
+            &:after {
+                content: ": ";
+            }
+        }
+    }
+
+    .paypal-review-title {
+        > strong {
+            .heading(h3);
+            display: inline-block;
+        }
+    }
+
+    .table-paypal-review-items {
+        thead {
+            th {
+                border-bottom: 1px solid @border-color-base;
+            }
+        }
+        tbody {
+            tr:last-child td {
+                border-bottom: 1px solid @border-color-base;
+            }
+        }
+        tfoot {
+            tr:first-child td {
+                border-top: @table-border-width @table-border-style @table-border-color;
+            }
+        }
+        .table-caption(@_table-caption-hide: true);
+    }
+
+    .actions-toolbar {
+        margin-top: @indent-s-base;
+    }
+    .review-item-options {
+        dt {
+            display: inline-block;
+            &:after {
+                content: ": ";
+            }
+        }
+        dd {
+            margin: 0;
+        }
+    }
+}
+
+//
+//    Mobile
+//--------------------------------------
+.responsive-smaller(@break) when (@break = @screen-m) {
+    .paypal-review .table-paypal-review-items {
+        &:extend(.abstract-table-vertical-mobile all);
+    }
+}
+
+//
+//    Desktop
+//--------------------------------------
+.responsive(@break) when (@break = @screen-m) {
+    .paypal-review {
+        .block-content {
+            &:extend(.abstract-add-clearfix-desktop all);
+            .box-order-shipping-address,
+            .box-order-shipping-method,
+            .box-order-shipping-method + .box-order-billing-address {
+                .box-sizing();
+                float: left;
+                width: 33%;
+            }
+            .box-order-shipping-address {
+                padding: 0 5%;
+                width: 34%;
+            }
+        }
+        .column.main & {
+            .actions-toolbar {
+                &:extend(.abstract-reset-left-margin-desktop all);
+            }
+        }
+        .table-paypal-review-items {
+            .col {
+                &.price,
+                &.qty {
+                    text-align: center;
+                }
+                &.item {
+                    width: 60%;
+                }
+            }
+        }
+        .col.subtotal,
+        .mark,
+        .amount {
+            text-align: right;
+        }
+    }
+
+    //  Billing Agreement
+    .form-new-agreement {
+        .fieldset .legend,
+        .actions-toolbar {
+            &:extend(.abstract-reset-left-margin-desktop all);
+        }
     }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less
index a3e06509ccd..92e2b1a7d94 100644
--- a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/module.less
@@ -137,7 +137,7 @@
 
 .customer-review {
     .product-details {
-        &:extend(.add-clearfix all);
+        &:extend(.abstract-add-clearfix all);
         margin-bottom: @indent-xl-base;
         .rating-average-label {
         }
@@ -238,7 +238,7 @@
     }
     &-fieldset {}
     .fieldset &-legend.legend {
-        &:extend(.reset-left-margin all);
+        &:extend(.abstract-reset-left-margin all);
         strong {
             display: block;
             margin-left: 0;
diff --git a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less
index f3ceb882267..1dc556680d7 100644
--- a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/module.less
@@ -47,17 +47,8 @@
             display: inline-block;
         }
     }
-    .col {
-        &.price,
-        &.subtotal {
-            &:extend(.abstract-incl-excl-tax all);
-        }
-    }
-    .cart-tax-total {
-        &:extend(.abstract-tax-total all);
-    }
     .items-qty {
-        &:extend(.reset-list all);
+        &:extend(.abstract-reset-list all);
         .item {
             white-space: nowrap;
         }
@@ -78,6 +69,7 @@
                 }
             }
         }
+
         .item.options {
             dt {
                 margin: 0;
@@ -172,6 +164,17 @@
     }
 }
 
+//
+//    Guest order view page
+//--------------------------------------
+.sales-guest-view {
+    .column.main {
+        .block:not(.widget) {
+            &:extend(.abstract-account-blocks all);
+        }
+    }
+}
+
 //
 //    Mobile
 //--------------------------------------
@@ -198,8 +201,8 @@
                 .col {
                     &.price,
                     &.subtotal {
-                        .tax,
-                        .incl.tax + .excl.tax,
+                        .price-including-tax,
+                        .price-excluding-tax,
                         .weee {
                             display: inline-block;
                         }
@@ -249,7 +252,7 @@
             }
         }
         .toolbar {
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
             .pages {
                 float: right;
             }
@@ -286,4 +289,21 @@
             }
         }
     }
+
+    //
+    //    Guest order view page
+    //--------------------------------------
+    .sales-guest-view {
+        .column.main {
+            .block:not(.widget) {
+                .block-content {
+                    &:extend(.abstract-add-clearfix-desktop all);
+                    .box {
+                        &:extend(.abstract-blocks-2columns all);
+                        margin-bottom: @indent-base;
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Sendfriend/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Sendfriend/web/css/source/module.less
index b74bffe3802..29c48d29d9b 100644
--- a/app/design/frontend/Magento/blank/Magento_Sendfriend/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Sendfriend/web/css/source/module.less
@@ -24,7 +24,7 @@
 
 
 .form.send.friend {
-    &:extend(.add-recipients all);
+    &:extend(.abstract-add-recipients all);
 }
 
 .action.mailto.friend {
@@ -47,6 +47,6 @@
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
     .form.send.friend {
-        &:extend(.add-recipients-desktop all);
+        &:extend(.abstract-add-recipients-desktop all);
     }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
index 56cd6b240af..efad0e64b8a 100644
--- a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
+++ b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
@@ -24,11 +24,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Core/etc/page.xsd">
-    <referenceBlock name="head">
-        <block class="Magento\Theme\Block\Html\Head\Css" name="css-styles-css">
-            <arguments>
-                <argument name="file" xsi:type="string">css/styles.css</argument>
-            </arguments>
-        </block>
-    </referenceBlock>
+    <head>
+        <css src="css/styles.css" />
+    </head>
 </page>
diff --git a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/collapsible_navigation.less b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/collapsible_navigation.less
new file mode 100644
index 00000000000..4cc5a8d2c21
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/collapsible_navigation.less
@@ -0,0 +1,104 @@
+// /**
+// //  * 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
+//  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+//  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+//  */
+
+@collapsible-nav-background: @sidebar-background;
+@collapsible-nav-item-hover: #e8e8e8;
+@collapsible-nav-color: false;
+@collapsible-nav-current-color: false;
+@collapsible-nav-current-font-weight: @font-weight-semibold;
+@collapsible-nav-current-border: 3px solid transparent;
+@collapsible-nav-current-border-color: #ff5501;
+
+//
+//    Collapsible navigation
+//--------------------------------------
+.block-collapsible-nav {
+    .content {
+        padding: 15px 0;
+        .css(background, @collapsible-nav-background);
+    }
+    .item {
+        margin: 3px 0 0;
+        &:first-child {
+            margin-top: 0;
+        }
+        a,
+        strong {
+            display: block;
+            padding: 5px 18px 5px 15px;
+            border-left: 3px solid transparent;
+            .css(color, @collapsible-nav-color);
+        }
+        a {
+            text-decoration: none;
+            &:hover {
+                .css(background, @collapsible-nav-item-hover);
+            } 
+        }
+        &.current {
+            a,
+            strong {
+                .css(color, @collapsible-nav-current-color);
+                .css(border-color, @collapsible-nav-current-border-color);
+                .css(font-weight, @collapsible-nav-current-font-weight);
+            }
+            a {
+                .css(border-color, @collapsible-nav-current-border-color);
+            }
+
+        }
+    }
+}
+
+//
+//    Desktop
+//--------------------------------------
+.responsive(@break) when (@break = @screen-m) {
+    .block-collapsible-nav {
+        .title {
+            &:extend(.abstract-visually-hidden-desktop all);
+        }
+    }
+}
+
+//
+//    Mobile
+//--------------------------------------
+.responsive-smaller(@break) when (@break = @screen-m) {
+    .block-collapsible-nav {
+        margin-left: -@layout-width-xs-indent;
+        margin-right: -@layout-width-xs-indent;
+        margin-bottom: 20px !important;
+        .title {
+            &:extend(.abstract-toggling-title-mobile all);
+        }
+        .content {
+            border-bottom: @border-width-base solid @border-color-base;
+            display: none;
+            &.active {
+                display: block;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/module.less
index 2d5cf98ca27..9cac5a97a06 100644
--- a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/module.less
@@ -22,6 +22,8 @@
 //  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 //  */
 
+@import "collapsible_navigation.less";
+
 @message-global-note-color: @text-color;
 @message-global-note-background: #ffee9c;
 @message-global-note-link-color: @link-color;
@@ -84,7 +86,7 @@ body {
 }
 
 .action.skip {
-    .visually-hidden();
+    &:extend(.abstract-visually-hidden all);
 }
 
 //
@@ -134,7 +136,7 @@ body {
         padding-bottom: 25px;
         border-top: 1px solid @border-color-base;
         ul {
-            &:extend(.reset-list all);
+            &:extend(.abstract-reset-list all);
             padding: 0 50px 0 0;
         }
         .links {
@@ -144,11 +146,11 @@ body {
         }
         .links {
             li {
-                margin: 0 0 8px 0;
+                margin: 0 0 8px;
             }
         }
-        .switcher.store {
-            margin: 0 0 30px 0;
+        .switcher-store {
+            margin: 0 0 30px;
         }
     }
     .copyright,
@@ -188,7 +190,7 @@ body {
             font-size: @font-size-s;
         }
         .label {
-            .visually-hidden();
+            &:extend(.abstract-visually-hidden all);
         }
         strong {
             font-weight: @font-weight-base;
@@ -200,6 +202,9 @@ body {
 //    Desktop
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
+    .navigation ul {
+        padding: 0 8px;
+    }
     .header {
         &.panel {
             > .header.links {
@@ -217,7 +222,7 @@ body {
         }
         &.content {
             padding: 30px 20px 0;
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
         }
     }
 
@@ -230,7 +235,7 @@ body {
         .header.panel {
             padding-top: 10px;
             padding-bottom: 10px;
-            &:extend(.add-clearfix-desktop all);
+            &:extend(.abstract-add-clearfix-desktop all);
         }
         .switcher {
             display: inline-block;
@@ -269,7 +274,7 @@ body {
             }
         }
         .copyright {
-            &:extend(.add-clearfix all);
+            &:extend(.abstract-add-clearfix all);
         }
     }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Weee/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Weee/web/css/source/module.less
new file mode 100644
index 00000000000..491070c9cee
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Weee/web/css/source/module.less
@@ -0,0 +1,39 @@
+// /**
+// //  * 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
+//  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+//  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+//  */
+
+.minilist {
+    .weee {
+        display: table-row;
+        .font-size(11);
+        &:before {
+            display: none;
+        }
+    }
+}
+
+.price-container.weee {
+    &:before {
+        display: none;
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less
index 472caa4ef5d..15372373964 100644
--- a/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Wishlist/web/css/source/module.less
@@ -24,7 +24,7 @@
 
 .form.wishlist.items {
     .actions-toolbar {
-        &:extend(.reset-left-margin all);
+        &:extend(.abstract-reset-left-margin all);
     }
 }
 
@@ -114,7 +114,7 @@
     .actions {
         margin: 7px 0;
         .action.delete {
-            &:extend(.remove-button-for-blocks all);
+            &:extend(.abstract-remove-button-for-blocks all);
             position: absolute;
             right: 0;
             top: 0;
@@ -137,6 +137,15 @@
             display: none;
         }
     }
+    .minilist {
+        .price {
+            display: inline;
+            padding: 0;
+        }
+        .weee:before {
+            display: inline-block;
+        }
+    }
 }
 
 .products-grid.wishlist {
diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json
index 936d524e03f..ff9957a1d87 100644
--- a/app/design/frontend/Magento/blank/composer.json
+++ b/app/design/frontend/Magento/blank/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/design/frontend/Magento/blank/theme.xml b/app/design/frontend/Magento/blank/theme.xml
index e19bb77aa43..4ce39439c7b 100644
--- a/app/design/frontend/Magento/blank/theme.xml
+++ b/app/design/frontend/Magento/blank/theme.xml
@@ -24,7 +24,7 @@
 -->
 <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
     <title>Magento Blank</title>
-    <version>0.1.0-alpha96</version>
+    <version>0.1.0-alpha97</version>
     <media>
         <preview_image>media/preview.jpg</preview_image>
     </media>
diff --git a/app/design/frontend/Magento/blank/web/css/source/abstract.less b/app/design/frontend/Magento/blank/web/css/source/abstract.less
index 4fb54beb6d1..59159a88275 100644
--- a/app/design/frontend/Magento/blank/web/css/source/abstract.less
+++ b/app/design/frontend/Magento/blank/web/css/source/abstract.less
@@ -25,7 +25,7 @@
 //
 //    List default styles reset
 //--------------------------------------
-.reset-list {
+.abstract-reset-list {
     .list-reset-styles();
     > li {
         margin: 0;
@@ -35,7 +35,7 @@
 //
 //    Link as a button
 //--------------------------------------
-.action-link-button {
+.abstract-action-link-button {
     .button();
     .link-as-button();
     border-radius: @button-border-radius;
@@ -48,7 +48,7 @@
 //
 //    Product options list
 //--------------------------------------
-.product-options-list {
+.abstract-product-options-list {
     dt:after {
         content: ': ';
     }
@@ -67,12 +67,12 @@
 //
 //    Button reset width, floats, margins
 //--------------------------------------
-.button-responsive {
+.abstract-button-responsive {
     .button-responsive();
 }
 
 .responsive(@break) when (@break = @screen-m) {
-    .button-desktop {
+    .abstract-button-desktop {
         width: auto;
     }
 }
@@ -87,7 +87,7 @@
 //    Blocks in 2 columns
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
-    .blocks-2columns {
+    .abstract-blocks-2columns {
         width: 48.8%;
         &:nth-child(odd) {
             float: left;
@@ -102,7 +102,7 @@
 //
 //    Title for login blocks
 //--------------------------------------
-.login-block-title {
+.abstract-login-block-title {
     strong {
         font-weight: 500;
     }
@@ -111,6 +111,40 @@
     border-bottom: 1px solid @color-secondary;
 }
 
+//
+//    Account blocks
+//--------------------------------------
+.abstract-account-blocks {
+    .block-title {
+        > strong {
+            .heading(h3);
+        }
+        margin-bottom: 15px;
+        > .action {
+            margin-left: 15px;
+        }
+    }
+    .box-title {
+        > span {
+            .heading(h4);
+        }
+        display: inline-block;
+        margin: 0 0 5px;
+        > .action {
+            font-weight: 400;
+            margin-left: 15px;
+        }
+    }
+    .block-content {
+        p:last-child {
+            margin-bottom: 0;
+        }
+        .box {
+            margin-bottom: @indent-base;
+        }
+    }
+}
+
 //
 //    Simple Dropdown
 //--------------------------------------
@@ -134,14 +168,14 @@
 //
 //    Marging for blocks & widgets
 //--------------------------------------
-.margin-for-blocks-and-widgets {
+.abstract-margin-for-blocks-and-widgets {
     margin-bottom: @indent-xl-base;
 }
 
 //
 //    Remove button for blocks
 //--------------------------------------
-.remove-button-for-blocks {
+.abstract-remove-button-for-blocks {
     .icon-font(
         @icon-remove,
         @_icon-font-size: 26px,
@@ -156,7 +190,7 @@
 //
 //    Product link
 //--------------------------------------
-.product-link {
+.abstract-product-link {
     .link(
         @_link-color: #303030,
         @_link-color-hover: #303030,
@@ -165,23 +199,15 @@
     );
 }
 
-//
-//    Link
-//--------------------------------------
-.like-link {
-    .link();
-    cursor: pointer;
-}
-
 //
 //   Reset left margin
 //--------------------------------------
-.reset-left-margin {
+.abstract-reset-left-margin {
     margin-left: 0;
 }
 
 .responsive(@break) when (@break = @screen-m) {
-    .reset-left-margin-desktop {
+    .abstract-reset-left-margin-desktop {
         margin-left: 0;
     }
 }
@@ -189,9 +215,10 @@
 //
 //    Action with icon remove with text
 //--------------------------------------
-.action-remove {
+.abstract-action-remove {
     .button-reset();
-    &:extend(.like-link all);
+    .link();
+    cursor: pointer;
     width: auto;
     line-height: normal;
     position: absolute;
@@ -204,7 +231,7 @@
 //    Action with icon remove with text for desktop
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
-    .action-remove-desktop when not (@form-field-type-inline-label-width = false) and not (@form-field-type-inline-label-width = '') {
+    .abstract-action-remove-desktop when not (@form-field-type-inline-label-width = false) and not (@form-field-type-inline-label-width = '') {
         top: 6px;
         margin-left: @form-field-type-inline-label-width + 50%;
     }
@@ -213,7 +240,7 @@
 //
 //    Add Recipient
 //--------------------------------------
-.add-recipients {
+.abstract-add-recipients {
     .recipients {
         margin-bottom: 50px;
         .field {
@@ -225,7 +252,7 @@
             margin-top: 55px;
             position: relative;
             .action.remove {
-                &:extend(.action-remove all);
+                &:extend(.abstract-action-remove all);
             }
         }
         .actions-toolbar {
@@ -251,11 +278,11 @@
 //    Add Recipient for desktop
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
-    .add-recipients-desktop {
+    .abstract-add-recipients-desktop {
         .recipients {
             .additional {
                 .action.remove {
-                    &:extend(.action-remove-desktop all);
+                    &:extend(.abstract-action-remove-desktop all);
                 }
             }
         }
@@ -266,7 +293,7 @@
 //    Margin for forms
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
-    .margin-for-forms-desktop when not (@form-field-type-inline-label-width = false) and not (@form-field-type-inline-label-width = '') {
+    .abstract-margin-for-forms-desktop when not (@form-field-type-inline-label-width = false) and not (@form-field-type-inline-label-width = '') {
         margin-left: @form-field-type-inline-label-width;
     }
 }
@@ -274,18 +301,30 @@
 //
 //    Visually hidden / show visually hidden
 //--------------------------------------
-.visually-hidden {
+.abstract-visually-hidden {
     .visually-hidden();
 }
 
 .responsive-smaller(@break) when (@break = @screen-s) {
-    .visually-hidden-mobile {
+    .abstract-visually-hidden-mobile {
         .visually-hidden();
-    } 
+    }
 }
 
 .responsive-smaller(@break) when (@break = @screen-m) {
-    .visually-hidden-mobile-m {
+    .abstract-visually-hidden-mobile-m {
+        .visually-hidden();
+    }
+}
+
+.responsive(@break) when (@break = @screen-s) {
+    .abstract-visually-hidden-desktop-s {
+        .visually-hidden();
+    }
+}
+
+.responsive(@break) when (@break = @screen-m) {
+    .abstract-visually-hidden-desktop {
         .visually-hidden();
     }
 }
@@ -293,18 +332,18 @@
 //
 //    Clearfix
 //--------------------------------------
-.add-clearfix {
+.abstract-add-clearfix {
     .clearfix();
 }
 
 .responsive(@break) when (@break = @screen-m) {
-    .add-clearfix-desktop {
+    .abstract-add-clearfix-desktop {
         .clearfix();
     }
 }
 
 .responsive-smaller(@break) when (@break = @screen-s) {
-    .add-clearfix-mobile {
+    .abstract-add-clearfix-mobile {
         .clearfix();
     }
 }
@@ -312,12 +351,12 @@
 //
 //    Box-sizing
 //--------------------------------------
-.add-box-sizing {
+.abstract-add-box-sizing {
     .box-sizing();
 }
 
 .responsive(@break) when (@break = @screen-m) {
-    .add-box-sizing-desktop {
+    .abstract-add-box-sizing-desktop {
         .box-sizing();
     }
 }
@@ -326,7 +365,7 @@
 //    Revert field type
 //--------------------------------------
 .responsive(@break) when (@break = @screen-m) {
-    .revert-field-type-desktop {
+    .abstract-revert-field-type-desktop {
         .fieldset {
             > .field,
             .fields > .field {
@@ -342,7 +381,7 @@
 //
 //    Settings icons
 //--------------------------------------
-.navigation-icon {
+.abstract-navigation-icon {
     .icon-font(
         @_icon-font-content: @icon-down,
         @_icon-font-size: 34px,
@@ -360,7 +399,6 @@
 //
 //    Split button
 //--------------------------------------
-
 .abstract-split-button {
     .dropdown-split(
         @_options-selector : ~".items",
@@ -373,7 +411,7 @@
 //    Action addto
 //--------------------------------------
 .abstract-action-addto-product {
-    &:extend(.action-link-button all);
+    &:extend(.abstract-action-link-button all);
     .button-s();
 }
 
@@ -431,7 +469,7 @@
 //    Vertical Table
 //--------------------------------------
 .responsive-smaller(@break) when (@break = @screen-m) {
-    .table-vertical-mobile {
+    .abstract-table-vertical-mobile {
         .table-responsive();
         tbody > tr {
             > td {
@@ -450,26 +488,22 @@
 //
 //    Excl/Incl tax
 //--------------------------------------
-.abstract-incl-excl-tax {
-    .tax {
-        display: block;
-        .font-size(18);
-        line-height: 1;
-        .price {
-            font-weight: @font-weight-bold;
-        }
-    }
-
-    .incl.tax + .excl.tax,
+.abstract-adjustment-incl-excl-tax {
+    .price-including-tax,
+    .price-excluding-tax,
     .weee {
-        display: block;
-        .font-size(18);
+        white-space: nowrap;
+        display: inline-block;
+        .font-size(14);
+    }
+    .price-including-tax + .price-excluding-tax {
+        display: inline-block;
+        .font-size(11);
         &:before {
-            content: attr(data-th) ": ";
-            .font-size(11);
+            content: "("attr(data-label)": ";
         }
-        .price {
-            .font-size(11);
+        &:after {
+            content:")";
         }
     }
 }
@@ -490,7 +524,7 @@
     );
     &:after {
         position: absolute;
-        right: -7px;
+        right: -10px;
         top: 3px;
     }
     &-expanded {
@@ -501,6 +535,13 @@
     }
 }
 
+.abstract-tax-total-expanded {
+    .icon-font-symbol(
+        @_icon-font-content: @icon-up,
+        @_icon-font-position: after
+    );
+}
+
 //
 //    Add colon
 //--------------------------------------
@@ -519,8 +560,9 @@
         @_icon-font-size: 10px,
         @_icon-font-line-height: 10px,
         @_icon-font-vertical-align: middle
-    ); 
+    );
 }
+
 .responsive-smaller(@break) when (@break = @screen-m) {
     .abstract-icon-add-mobile {
         .icon-font(
@@ -530,7 +572,7 @@
             @_icon-font-vertical-align: middle,
             @_icon-font-margin: 0 5px 0 0,
             @_icon-font-display: block
-        ); 
+        );
     }
 }
 
@@ -561,7 +603,7 @@
         border-bottom: @border-width-base solid @border-color-base;
         cursor: pointer;
         margin-bottom: 0;
-        padding: 10px 40px 10px 20px;
+        padding: 10px 40px 10px @layout-width-xs-indent;
         position: relative;
         .icon-font(
             @_icon-font-content: @icon-down,
diff --git a/app/design/frontend/Magento/blank/web/css/source/actions-toolbar.less b/app/design/frontend/Magento/blank/web/css/source/actions-toolbar.less
index 629a3748202..7d3db81dc1e 100644
--- a/app/design/frontend/Magento/blank/web/css/source/actions-toolbar.less
+++ b/app/design/frontend/Magento/blank/web/css/source/actions-toolbar.less
@@ -27,7 +27,7 @@
     > .secondary {
         text-align: center;
         .action {
-            &:extend(.button-responsive all);
+            &:extend(.abstract-button-responsive all);
             margin-bottom: @indent-s-base;
             &:last-child {
                 margin-bottom: 0;
@@ -59,7 +59,7 @@
         .actions-toolbar {
             .column:not(.sidebar-main) &,
             .column:not(.sidebar-additional) & {
-                &:extend(.margin-for-forms-desktop all);
+                &:extend(.abstract-margin-for-forms-desktop all);
             }
         }
     }
diff --git a/app/design/frontend/Magento/blank/web/css/source/forms.less b/app/design/frontend/Magento/blank/web/css/source/forms.less
index 6a0b4f72cda..1da2ea7b287 100644
--- a/app/design/frontend/Magento/blank/web/css/source/forms.less
+++ b/app/design/frontend/Magento/blank/web/css/source/forms.less
@@ -40,7 +40,7 @@
         .form-field();
         &.no-label {
             > .label {
-                .visually-hidden();
+                &:extend(.abstract-visually-hidden all);
             }
         }
         &.choice {
@@ -97,7 +97,7 @@ select:focus ~ .tooltip .tooltip-content {
 .responsive(@break) when (@break = @screen-m) {
     .fieldset {
         .legend {
-            &:extend(.margin-for-forms-desktop all);
+            &:extend(.abstract-margin-for-forms-desktop all);
         }
         > .field {
             .form-field-type-revert();
diff --git a/app/design/frontend/Magento/blank/web/css/source/layout.less b/app/design/frontend/Magento/blank/web/css/source/layout.less
index 4c00f8bc03a..95aac6d1fe4 100644
--- a/app/design/frontend/Magento/blank/web/css/source/layout.less
+++ b/app/design/frontend/Magento/blank/web/css/source/layout.less
@@ -25,40 +25,43 @@
 @layout-column-main-sidebar-offset: 2%;
 @layout-column-additional-sidebar-offset: @layout-column-main-sidebar-offset;
 
-.navigation,
-.breadcrumbs,
-.page-header .header.panel,
-.header.content,
-.footer.content,
-.page.main,
-.page-wrapper > .widget,
-.page-wrapper > .page.bottom,
-.block.category.event {
-    padding-left: @layout-width-xs-indent;
-    padding-right: @layout-width-xs-indent;
-}
-
-
 .columns {
     #layout-columns();
     .column.main {
-        &:extend(.add-box-sizing all);
+        &:extend(.abstract-add-box-sizing all);
         .mix-flex-flex(@_basis: 100%);
         .css(padding-bottom, @indent-xl-base);
         .mix-flex-order(1);
     }
     .sidebar-main {
-        &:extend(.add-box-sizing all);
+        &:extend(.abstract-add-box-sizing all);
         .mix-flex-flex(@_basis: 100%);
         .mix-flex-order(0);
     }
     .sidebar-additional {
-        &:extend(.add-box-sizing all);
+        &:extend(.abstract-add-box-sizing all);
         .mix-flex-flex(@_basis: 100%);
         .mix-flex-order(2);
     }
 }
 
+//
+//    Mobile
+//--------------------------------------
+.responsive-smaller(@break) when (@break = @screen-m) {
+    .navigation,
+    .breadcrumbs,
+    .page-header .header.panel,
+    .header.content,
+    .footer.content,
+    .page.main,
+    .page-wrapper > .widget,
+    .page-wrapper > .page.bottom,
+    .block.category.event {
+        padding-left: @layout-width-xs-indent;
+        padding-right: @layout-width-xs-indent;
+    }
+}
 
 //
 //    Desktop
@@ -73,6 +76,8 @@
     .page-wrapper > .widget,
     .page-wrapper > .page.bottom,
     .block.category.event {
+        padding-left: @layout-indent;
+        padding-right: @layout-indent;
         margin-left: auto;
         margin-right: auto;
         width: auto;
@@ -85,14 +90,14 @@
 
     .column.main {
         #layout-columns > .main();
-        &:extend(.add-box-sizing-desktop all);
+        &:extend(.abstract-add-box-sizing-desktop all);
         min-height: 300px;
     }
 
     .sidebar-main {
         #layout-columns > .left();
         padding-right: @layout-column-main-sidebar-offset;
-        &:extend(.add-box-sizing-desktop all);
+        &:extend(.abstract-add-box-sizing-desktop all);
     }
 
     .page-layout-2columns-right .sidebar-main {
@@ -104,7 +109,7 @@
         #layout-columns > .right();
         padding-left: @layout-column-additional-sidebar-offset;
         clear: right;
-        &:extend(.add-box-sizing-desktop all);
+        &:extend(.abstract-add-box-sizing-desktop all);
     }
 
     .page-layout-2columns-left {
diff --git a/app/design/frontend/Magento/blank/web/css/source/price.less b/app/design/frontend/Magento/blank/web/css/source/price.less
index 4d2b5da5d10..8438b8de546 100644
--- a/app/design/frontend/Magento/blank/web/css/source/price.less
+++ b/app/design/frontend/Magento/blank/web/css/source/price.less
@@ -26,25 +26,13 @@
 // Prices
 .price-style-1() {
     .price {
-        &-container {}
-        &-wrapper[data-label]:before {
-            content: attr(data-label)":";
-        }
         &-tier_price .price-excluding-tax,
         &-tier_price .price-including-tax {
             display: inline;
         }
-        &-tier_price .price-adjustments {
-            font-size: .9em;
-            &:before {
-                content: "(";
-            }
-            &:after {
-                content: ")";
-            }
-        }
     }
 }
+
 .price-style-2() {
     .price {
         &-including-tax,
@@ -60,4 +48,35 @@
     }
 }
 
+.price-style-3() {
+    .price-including-tax,
+    .price-excluding-tax {
+        display: block;
+        .font-size(18);
+        line-height: 1;
+        .price {
+            font-weight: @font-weight-bold;
+        }
+        .cart-tax-total {
+            &:extend(.abstract-tax-total all);
+            &-expanded {
+                &:extend(.abstract-tax-total-expanded all);
+            }
+        }
+    }
+    .price-including-tax + .price-excluding-tax,
+    .weee[data-label] {
+        display: block;
+        .font-size(18);
+        &:before {
+            content: attr(data-label) ": ";
+            .font-size(11);
+        }
+        .price {
+            .font-size(11);
+        }
+    }
+}
+
 .price-style-1();
+.price-style-3();
diff --git a/app/design/frontend/Magento/plushe/composer.json b/app/design/frontend/Magento/plushe/composer.json
index f5a727c0ef4..a4be706b5b2 100644
--- a/app/design/frontend/Magento/plushe/composer.json
+++ b/app/design/frontend/Magento/plushe/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/theme-frontend-blank": "0.1.0-alpha96",
-        "magento/framework": "0.1.0-alpha96",
+        "magento/theme-frontend-blank": "0.1.0-alpha97",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "extra": {
         "map": [
             [
diff --git a/app/design/frontend/Magento/plushe/theme.xml b/app/design/frontend/Magento/plushe/theme.xml
index 1182853d1d6..99f74b8f2eb 100644
--- a/app/design/frontend/Magento/plushe/theme.xml
+++ b/app/design/frontend/Magento/plushe/theme.xml
@@ -24,7 +24,7 @@
 -->
 <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
     <title>Magento Plushe</title>
-    <version>0.1.0-alpha96</version>
+    <version>0.1.0-alpha97</version>
     <parent>Magento/blank</parent>
     <media>
         <preview_image>media/preview.jpg</preview_image>
diff --git a/app/design/install/Magento/basic/theme.xml b/app/design/install/Magento/basic/theme.xml
index 5fcbf8bc81b..2f2fbec2347 100644
--- a/app/design/install/Magento/basic/theme.xml
+++ b/app/design/install/Magento/basic/theme.xml
@@ -24,5 +24,5 @@
 -->
 <theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
     <title>Magento Basic</title>
-    <version>0.1.0-alpha96</version>
+    <version>0.1.0-alpha97</version>
 </theme>
diff --git a/app/etc/di.xml b/app/etc/di.xml
index b78142a7655..100b0b76a5c 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -92,6 +92,7 @@
     <preference for="Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface" type="Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat"/>
     <preference for="Magento\Framework\Service\Data\AttributeMetadataBuilderInterface" type="Magento\Framework\Service\Data\AttributeMetadataBuilder"/>
     <preference for="Magento\Framework\Service\Data\MetadataServiceInterface" type="Magento\Framework\Service\Config\MetadataConfig"/>
+    <preference for="Magento\Framework\App\Rss\UrlBuilderInterface" type="Magento\Framework\App\Rss\UrlBuilder"/>
     <type name="Magento\Framework\Model\Context">
         <arguments>
             <argument name="actionValidator" xsi:type="object">Magento\Framework\Model\ActionValidator\RemoveAction\Proxy</argument>
@@ -415,29 +416,15 @@
         </arguments>
     </type>
     <type name="Magento\Framework\View\Layout\ScheduledStructure" shared="false" />
-
-
-    <virtualType name="Magento\Framework\Search\Config\Reader\Filesystem" type="Magento\Framework\Config\Reader\Filesystem">
-        <arguments>
-            <argument name="fileName" xsi:type="string">search_request.xml</argument>
-            <argument name="schemaLocator" xsi:type="object">Magento\Framework\Search\Request\Config\SchemaLocator</argument>
-            <argument name="converter" xsi:type="object">Magento\Framework\Search\Request\Config\Converter</argument>
-            <argument name="idAttributes" xsi:type="array">
-                <item name="/requests/request" xsi:type="string">@name</item>
-                <item name="/requests/request/queries/query" xsi:type="string">@name</item>
-                <item name="/requests/request/filters/filter" xsi:type="string">@name</item>
-                <item name="/requests/request/aggregation/bucket" xsi:type="string">@name</item>
-            </argument>
-        </arguments>
-    </virtualType>
-    <type name="Magento\Framework\Search\Request\Config">
+    <type name="Magento\Framework\Module\ModuleList">
         <arguments>
-            <argument name="reader" xsi:type="object">Magento\Framework\Search\Config\Reader\Filesystem</argument>
+            <argument name="reader" xsi:type="object">Magento\Framework\Module\Declaration\Reader\Filesystem\Proxy</argument>
         </arguments>
     </type>
-    <type name="Magento\Framework\Module\ModuleList">
+
+    <type name="Magento\Framework\View\Result\Page">
         <arguments>
-            <argument name="reader" xsi:type="object">Magento\Framework\Module\Declaration\Reader\Filesystem\Proxy</argument>
+            <argument name="template" xsi:type="string">Magento_Theme::root.phtml</argument>
         </arguments>
     </type>
 </config>
diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json
index 7799d47a4b1..f985c2c20c5 100644
--- a/app/i18n/magento/de_de/composer.json
+++ b/app/i18n/magento/de_de/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-de_de",
     "description": "German (Germany) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/en_us/composer.json b/app/i18n/magento/en_us/composer.json
index 9e84730bff0..14c9283de5b 100644
--- a/app/i18n/magento/en_us/composer.json
+++ b/app/i18n/magento/en_us/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-en_us",
     "description": "English (United States) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/es_es/composer.json b/app/i18n/magento/es_es/composer.json
index 1de56573c19..8bfa7b0685d 100644
--- a/app/i18n/magento/es_es/composer.json
+++ b/app/i18n/magento/es_es/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-es_es",
     "description": "Spanish (Spain) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/fr_fr/composer.json b/app/i18n/magento/fr_fr/composer.json
index 89bbe3f6460..162eba88f30 100644
--- a/app/i18n/magento/fr_fr/composer.json
+++ b/app/i18n/magento/fr_fr/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-fr_fr",
     "description": "French (France) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/nl_nl/composer.json b/app/i18n/magento/nl_nl/composer.json
index 8a4d86ec40c..9a85fa702e1 100644
--- a/app/i18n/magento/nl_nl/composer.json
+++ b/app/i18n/magento/nl_nl/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-nl_nl",
     "description": "Dutch (Netherlands) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/pt_br/composer.json b/app/i18n/magento/pt_br/composer.json
index 03c2a3959d6..7d62abb5167 100644
--- a/app/i18n/magento/pt_br/composer.json
+++ b/app/i18n/magento/pt_br/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-pt_br",
     "description": "Portuguese (Brazil) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/zh_cn/composer.json b/app/i18n/magento/zh_cn/composer.json
index bb4c25950d3..16562ae1971 100644
--- a/app/i18n/magento/zh_cn/composer.json
+++ b/app/i18n/magento/zh_cn/composer.json
@@ -1,9 +1,9 @@
 {
     "name": "magento/language-zh_cn",
     "description": "Chinese (China) language",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
-        "magento/framework": "0.1.0-alpha96",
+        "magento/framework": "0.1.0-alpha97",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/composer.json b/composer.json
index e30435820aa..43976dfad94 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/project-community-edition",
     "description": "Magento project (Community Edition)",
     "type": "project",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
         "php": "~5.4.11|~5.5.0"
     },
@@ -51,12 +51,12 @@
         "magento/module-grouped-import-export": "self.version",
         "magento/module-grouped-product": "self.version",
         "magento/module-import-export": "self.version",
-        "magento/module-index": "self.version",
         "magento/module-indexer": "self.version",
         "magento/module-install": "self.version",
         "magento/module-integration": "self.version",
         "magento/module-layered-navigation": "self.version",
         "magento/module-log": "self.version",
+        "magento/module-msrp": "self.version",
         "magento/module-multishipping": "self.version",
         "magento/module-newsletter": "self.version",
         "magento/module-offline-payments": "self.version",
@@ -84,8 +84,8 @@
         "magento/module-tax-import-export": "self.version",
         "magento/module-theme": "self.version",
         "magento/module-translation": "self.version",
+        "magento/module-ui": "self.version",
         "magento/module-ups": "self.version",
-        "magento/module-url-redirect": "self.version",
         "magento/module-url-rewrite": "self.version",
         "magento/module-user": "self.version",
         "magento/module-usps": "self.version",
@@ -170,8 +170,7 @@
             ],
             "twbs/bootstrap": [
                 "lib/web/jquery/jquery.tabs.js",
-                "lib/web/jquery/jquery.popups.js",
-                "lib/web/jquery/bootstrap-carousel"
+                "lib/web/jquery/jquery.popups.js"
             ],
             "tinymce/tinymce": "lib/web/tiny_mce"
         }
diff --git a/dev/shell/indexer.php b/dev/shell/indexer.php
index 41703be84e9..9e675d2b667 100644
--- a/dev/shell/indexer.php
+++ b/dev/shell/indexer.php
@@ -30,6 +30,6 @@ $params = $_SERVER;
 $params[StoreManager::PARAM_RUN_CODE] = 'admin';
 $params[StoreManager::PARAM_RUN_TYPE] = 'store';
 $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
-/** @var \Magento\Index\App\Shell $application */
-$app = $bootstrap->createApplication('Magento\Index\App\Shell', ['entryFileName' => basename(__FILE__)]);
+/** @var \Magento\Indexer\App\Shell $application */
+$app = $bootstrap->createApplication('Magento\Indexer\App\Shell', ['entryFileName' => basename(__FILE__)]);
 $bootstrap->run($app);
diff --git a/dev/shell/newindexer.php b/dev/shell/newindexer.php
deleted file mode 100644
index d3e76fa7097..00000000000
--- a/dev/shell/newindexer.php
+++ /dev/null
@@ -1,35 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-use Magento\Framework\App\Bootstrap;
-use Magento\Store\Model\StoreManager;
-
-require __DIR__ . '/../../app/bootstrap.php';
-$params = $_SERVER;
-$params[StoreManager::PARAM_RUN_CODE] = 'admin';
-$params[StoreManager::PARAM_RUN_TYPE] = 'store';
-$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
-/** @var Magento\Indexer\App\Shell $app */
-$app = $bootstrap->createApplication('Magento\Indexer\App\Shell', ['entryFileName' => basename(__FILE__)]);
-$bootstrap->run($app);
diff --git a/dev/shell/run_data_fixtures.php b/dev/shell/run_data_fixtures.php
index 51001b2fa16..2841bec11d7 100644
--- a/dev/shell/run_data_fixtures.php
+++ b/dev/shell/run_data_fixtures.php
@@ -22,13 +22,12 @@
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-use Magento\Framework\App\Bootstrap;
 use Magento\Framework\App\State as AppState;
 
 require __DIR__ . '/../../app/bootstrap.php';
 $params = $_SERVER;
 if (!isset($params[AppState::PARAM_MODE])) {
-    $extra[AppState::PARAM_MODE] = AppState::MODE_DEVELOPER;
+    $params[AppState::PARAM_MODE] = AppState::MODE_DEVELOPER;
 }
 $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
 /** @var \Magento\Framework\Module\Updater $updater */
diff --git a/dev/shell/run_schema_updater.php b/dev/shell/run_schema_updater.php
index 9a329a4105f..1e4d4a97e6a 100644
--- a/dev/shell/run_schema_updater.php
+++ b/dev/shell/run_schema_updater.php
@@ -26,9 +26,8 @@ use Magento\Framework\App\State as AppState;
 
 require __DIR__ . '/../../app/bootstrap.php';
 $params = $_SERVER;
-$extra = [];
 if (!isset($params[AppState::PARAM_MODE])) {
-    $extra[AppState::PARAM_MODE] = AppState::MODE_DEVELOPER;
+    $params[AppState::PARAM_MODE] = AppState::MODE_DEVELOPER;
 }
 $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
 /** @var \Magento\Framework\Module\Updater $updater */
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php
index 426c7bb383f..ad185157e02 100644
--- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/ConditionsElement.php
@@ -286,6 +286,7 @@ class ConditionsElement extends AbstractElement
             $value = $param->find('select', Locator::SELECTOR_CSS, 'select');
             if ($value->isVisible()) {
                 $value->setValue($rule);
+                $this->click();
                 continue;
             }
             $value = $param->find('input');
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/GlobalSearchElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/GlobalSearchElement.php
new file mode 100644
index 00000000000..7b9e478309d
--- /dev/null
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/GlobalSearchElement.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Mtf\Client\Driver\Selenium\Element;
+
+use Mtf\Client\Driver\Selenium\Element;
+
+/**
+ * Class GlobalSearchElement
+ * Typified element class for global search element
+ */
+class GlobalSearchElement extends Element
+{
+    /**
+     * Selector suggest input
+     *
+     * @var string
+     */
+    protected $suggest = '.mage-suggest-inner > [class^="search"]';
+
+    /**
+     * Result dropdown selector
+     *
+     * @var string
+     */
+    protected $searchResult = '.search-global-menu';
+
+    /**
+     * Item selector of search result
+     *
+     * @var string
+     */
+    protected $resultItem = 'li';
+
+    /**
+     * Search icon selector
+     *
+     * @var string
+     */
+    protected $searchIcon = '[for="search-global"]';
+
+    /**
+     * Set value
+     *
+     * @param string $value
+     * @return void
+     */
+    public function setValue($value)
+    {
+        $this->_eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]);
+
+        $this->find($this->searchIcon)->click();
+        $this->find($this->suggest)->setValue($value);
+        $this->waitResult();
+    }
+
+    /**
+     * Wait for search result is visible
+     *
+     * @return void
+     */
+    public function waitResult()
+    {
+        $browser = $this;
+        $selector = $this->searchResult;
+        $browser->waitUntil(
+            function () use ($browser, $selector) {
+                return $browser->find($selector)->isVisible() ? true : null;
+            }
+        );
+    }
+
+    /**
+     * Get value
+     *
+     * @throws \BadMethodCallException
+     */
+    public function getValue()
+    {
+        throw new \BadMethodCallException('Not applicable for this class of elements (GlobalSearch)');
+    }
+
+    /**
+     * Checking exist value in search result
+     *
+     * @param string $value
+     * @return bool
+     */
+    public function isExistValueInSearchResult($value)
+    {
+        $searchResult = $this->find($this->searchResult);
+        if (!$searchResult->isVisible()) {
+            return false;
+        }
+        $searchResults = $this->getSearchResults();
+        return in_array($value, $searchResults);
+    }
+
+    /**
+     * Get search results
+     *
+     * @return array
+     */
+    protected function getSearchResults()
+    {
+        /** @var Element $searchResult */
+        $searchResult = $this->find($this->searchResult);
+        $resultItems = $searchResult->find($this->resultItem)->getElements();
+        $resultArray = [];
+        /** @var Element $resultItem */
+        foreach ($resultItems as $resultItem) {
+            $resultText = explode("\n", $resultItem->getText())[0];
+            $resultArray[] = $resultText;
+        }
+        return $resultArray;
+    }
+}
diff --git a/dev/tests/functional/phpunit.xml.dist b/dev/tests/functional/phpunit.xml.dist
index 4c50e1d1b00..6e12b62c5e9 100755
--- a/dev/tests/functional/phpunit.xml.dist
+++ b/dev/tests/functional/phpunit.xml.dist
@@ -24,10 +24,12 @@
  */
 -->
 <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
          bootstrap="bootstrap.php"
          backupGlobals="false"
-         verbose="true">
+         verbose="true"
+>
     <testsuites>
         <testsuite name="All Tests">
             <directory suffix="Test.php">tests</directory>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
index 737bb5c4618..23c2357a376 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Page/Header.php
@@ -47,6 +47,13 @@ class Header extends Block
      */
     protected $signOutLink = '.account-signout';
 
+    /**
+     * Selector for Search Link
+     *
+     * @var string
+     */
+    protected $searchSelector = '#form-search';
+
     /**
      * Log out Admin User
      */
@@ -68,4 +75,30 @@ class Header extends Block
     {
         return $this->_rootElement->find($this->adminAccountLink)->isVisible();
     }
+
+    /**
+     * Search the query text
+     *
+     * @param string $query
+     * @return void
+     */
+    public function search($query)
+    {
+        /** @var \Mtf\Client\Driver\Selenium\Element\GlobalSearchElement $search */
+        $search = $this->_rootElement->find($this->searchSelector, Locator::SELECTOR_CSS, 'globalSearch');
+        $search->setValue($query);
+    }
+
+    /**
+     * Is search result is visible in suggestion dropdown
+     *
+     * @param string $query
+     * @return bool
+     */
+    public function isSearchResultVisible($query)
+    {
+        /** @var \Mtf\Client\Driver\Selenium\Element\GlobalSearchElement $search */
+        $search = $this->_rootElement->find($this->searchSelector, Locator::SELECTOR_CSS, 'globalSearch');
+        return $search->isExistValueInSearchResult($query);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
index c65e426bbd4..7c11952fad3 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
@@ -150,6 +150,13 @@ abstract class Grid extends Block
      */
     protected $option = '[name="status"]';
 
+    /**
+     * Selector for action expand Filter
+     *
+     * @var string
+     */
+    protected $filterOpen = '.action.filters-toggle';
+
     /**
      * Get backend abstract block
      *
@@ -254,6 +261,10 @@ abstract class Grid extends Block
      */
     public function resetFilter()
     {
+        $expandFilterButton = $this->_rootElement->find($this->filterOpen, Locator::SELECTOR_CSS);
+        if ($expandFilterButton->isVisible()) {
+            $expandFilterButton->click();
+        }
         $this->_rootElement->find($this->resetButton, Locator::SELECTOR_CSS)->click();
         $this->getTemplateBlock()->waitLoader();
         $this->reinitRootElement();
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchCustomerName.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchCustomerName.php
new file mode 100644
index 00000000000..78802043d96
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchCustomerName.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Constraint;
+
+use Magento\Backend\Test\Fixture\GlobalSearch;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertGlobalSearchCustomerName
+ * Assert that customer name is present in search results
+ */
+class AssertGlobalSearchCustomerName extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that customer name is present in search results
+     *
+     * @param Dashboard $dashboard
+     * @param GlobalSearch $search
+     * @return void
+     */
+    public function processAssert(Dashboard $dashboard, GlobalSearch $search)
+    {
+        $customer = $search->getDataFieldConfig('query')['source']->getEntity();
+        $customerName = $customer->getFirstname() . " " . $customer->getLastname();
+        $isVisibleInResult = $dashboard->getAdminPanelHeader()->isSearchResultVisible($customerName);
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isVisibleInResult,
+            'Customer name ' . $customerName . ' is absent in search results'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer name is present in search results';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchNoRecordsFound.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchNoRecordsFound.php
new file mode 100644
index 00000000000..1529566598b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchNoRecordsFound.php
@@ -0,0 +1,72 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Constraint;
+
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertGlobalSearchNoRecordsFound
+ * Assert that search result contains expected text
+ */
+class AssertGlobalSearchNoRecordsFound extends AbstractConstraint
+{
+    /**
+     * Expected search result text
+     */
+    const EXPECTED_RESULT = 'No records found.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that search result contains expected text
+     *
+     * @param Dashboard $dashboard
+     * @return void
+     */
+    public function processAssert(Dashboard $dashboard)
+    {
+        $isVisibleInResult = $dashboard->getAdminPanelHeader()->isSearchResultVisible(self::EXPECTED_RESULT);
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isVisibleInResult,
+            'Expected text ' . self::EXPECTED_RESULT . ' is absent in search results'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '"No records found." is present in search results';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchOrderId.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchOrderId.php
new file mode 100644
index 00000000000..951ffeaebf9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchOrderId.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Constraint;
+
+use Magento\Backend\Test\Fixture\GlobalSearch;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertGlobalSearchOrderId
+ * Assert that order Id is present in search results
+ */
+class AssertGlobalSearchOrderId extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that order Id is present in search results
+     *
+     * @param Dashboard $dashboard
+     * @param GlobalSearch $search
+     * @return void
+     */
+    public function processAssert(Dashboard $dashboard, GlobalSearch $search)
+    {
+        $order = $search->getDataFieldConfig('query')['source']->getEntity();
+        $orderId = "Order #" . $order->getId();
+        $isVisibleInResult = $dashboard->getAdminPanelHeader()->isSearchResultVisible($orderId);
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isVisibleInResult,
+            'Order Id ' . $order->getId() . ' is absent in search results'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Order Id is present in search results';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchProductName.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchProductName.php
new file mode 100644
index 00000000000..dac793b437d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertGlobalSearchProductName.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Constraint;
+
+use Magento\Backend\Test\Fixture\GlobalSearch;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertGlobalSearchProductName
+ * Assert that product name is present in search results
+ */
+class AssertGlobalSearchProductName extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that product name is present in search results
+     *
+     * @param Dashboard $dashboard
+     * @param GlobalSearch $search
+     * @return void
+     */
+    public function processAssert(Dashboard $dashboard, GlobalSearch $search)
+    {
+        $entity = $search->getDataFieldConfig('query')['source']->getEntity();
+        $product = $entity instanceof OrderInjectable
+            ? $entity->getEntityId()['products'][0]
+            : $entity;
+        $productName = $product->getName();
+        $isVisibleInResult = $dashboard->getAdminPanelHeader()->isSearchResultVisible($productName);
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isVisibleInResult,
+            'Product name ' . $productName . ' is absent in search results'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product name is present in search results';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.php
new file mode 100644
index 00000000000..1b4c215cf16
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class GlobalSearch
+ * Global Search fixture
+ */
+class GlobalSearch extends InjectableFixture
+{
+    protected $defaultDataSet = [
+        'query' => 'catalogProductSimple::default::name'
+    ];
+
+    protected $query = [
+        'attribute_code' => 'query',
+        'backend_type' => 'virtual',
+        'source' => 'Magento\Backend\Test\Fixture\GlobalSearch\Query'
+    ];
+
+    public function getQuery()
+    {
+        return $this->getData('query');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.xml
new file mode 100644
index 00000000000..445d468e232
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Backend\Test\Fixture\Search">
+    <module>Magento_Backend</module>
+    <fields>
+        <query>
+            <attribute_code>query</attribute_code>
+            <backend_type>virtual</backend_type>
+            <fixture>Magento\Backend\Test\Fixture\Search\Query</fixture>
+        </query>
+    </fields>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch/Query.php
similarity index 52%
rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php
rename to dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch/Query.php
index 9c0905a2456..4355453631f 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/GlobalSearch/Query.php
@@ -22,65 +22,79 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+namespace Magento\Backend\Test\Fixture\GlobalSearch;
 
 use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
 
 /**
- * Class IdPath
- * Prepare ID Path
+ * Class Query
+ * Global Search query data provider
  */
-class IdPath implements FixtureInterface
+class Query implements FixtureInterface
 {
     /**
-     * Resource data
+     * Prepared dataSet data
      *
-     * @var string
+     * @var array
      */
     protected $data;
 
     /**
-     * Return entity
+     * Data set configuration settings
      *
-     * @var FixtureInterface
+     * @var array
      */
-    protected $entity = null;
+    protected $params;
 
     /**
-     * Data set configuration settings
+     * Data source entity
      *
-     * @var array
+     * @var InjectableFixture
      */
-    protected $params;
+    protected $entity = null;
 
     /**
+     * Constructor
+     *
+     * @constructor
      * @param FixtureFactory $fixtureFactory
-     * @param array $params
-     * @param array $data [optional]
+     * @param string $data
+     * @param array $params [optional]
      */
-    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    public function __construct(FixtureFactory $fixtureFactory, $data, array $params = [])
     {
         $this->params = $params;
-        if (!isset($data['entity']) || $data['entity'] === '-') {
-            $this->data = array_shift($data);
-            return;
-        }
-        preg_match('`%(.*?)%`', $data['entity'], $dataSet);
-        $entityConfig = isset($dataSet[1]) ? explode('::', $dataSet[1]) : [];
-        if (count($entityConfig) > 1) {
-            /** @var FixtureInterface $fixture */
-            $this->entity = $fixtureFactory->createByCode($entityConfig[0], ['dataSet' => $entityConfig[1]]);
-            $this->entity->persist();
-            $id = $this->entity->hasData('id') ? $this->entity->getId() : $this->entity->getPageId();
-            $this->data = preg_replace('`(%.*?%)`', $id, $data['entity']);
-        } else {
-            $this->data = strval($data['entity']);
+        $explodedData = explode('::', $data);
+        switch (sizeof($explodedData)) {
+            case 1:
+                $this->data = $explodedData[0];
+                break;
+            case 3:
+                list($fixture, $dataSet, $field) = $explodedData;
+                $entity = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                if (!$entity->hasData('id')) {
+                    $entity->persist();
+                }
+                $this->data = $entity->getData($field);
+                $this->entity = $entity;
+                break;
+            case 4:
+                list($fixture, $dataSet, $source, $field) = $explodedData;
+                $entity = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                if (!$entity->hasData('id')) {
+                    $entity->persist();
+                }
+                $source = $source == 'product' ? $entity->getEntityId()['products'][0] : $entity->getData($source);
+                $this->data = $source->getData($field);
+                $this->entity = $entity;
+                break;
         }
     }
 
     /**
-     * Persist custom selections products
+     * Persist order products
      *
      * @return void
      */
@@ -90,10 +104,10 @@ class IdPath implements FixtureInterface
     }
 
     /**
-     * Return prepared data
+     * Return prepared data set
      *
-     * @param string|null $key
-     * @return string
+     * @param string $key [optional]
+     * @return mixed
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
@@ -103,22 +117,22 @@ class IdPath implements FixtureInterface
     }
 
     /**
-     * Return data set configuration settings
+     * Get entity for global search
      *
-     * @return array
+     * @return InjectableFixture
      */
-    public function getDataConfig()
+    public function getEntity()
     {
-        return $this->params;
+        return $this->entity;
     }
 
     /**
-     * Return entity
+     * Return data set configuration settings
      *
-     * @return FixtureInterface|null
+     * @return string
      */
-    public function getEntity()
+    public function getDataConfig()
     {
-        return $this->entity;
+        return $this->params;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php
new file mode 100644
index 00000000000..7fe1d5330ca
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php
@@ -0,0 +1,82 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\TestCase;
+
+use Magento\Backend\Test\Fixture\GlobalSearch;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for GlobalSearchEntity
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer
+ * 2. Create two simple products
+ * 3. Create order with one of created simple product
+ *
+ * Steps:
+ * 1. Login to backend
+ * 2. Click on Search button on the top of page
+ * 3. Fill in data according dataSet
+ * 4. Perform assertions
+ *
+ * @group Search_Core_(MX)
+ * @ZephyrId MAGETWO-28457
+ */
+class GlobalSearchEntityTest extends Injectable
+{
+    /**
+     * Backend Dashboard page
+     *
+     * @var Dashboard
+     */
+    protected $dashboard;
+
+    /**
+     * Preparing pages for test
+     *
+     * @param Dashboard $dashboard
+     * @return void
+     */
+    public function __inject(Dashboard $dashboard)
+    {
+        $this->dashboard = $dashboard;
+    }
+
+    /**
+     * Run Global Search Entity Test
+     *
+     * @param GlobalSearch $search
+     * @return void
+     */
+    public function test(GlobalSearch $search)
+    {
+        //Steps:
+        $this->dashboard->open();
+        $this->dashboard->getAdminPanelHeader()->search($search->getQuery());
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest/test.csv
new file mode 100644
index 00000000000..d72d76a461c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest/test.csv
@@ -0,0 +1,6 @@
+"description";"search/data/query";"constraint";"issue"
+"search existed product and order created with this product";"orderInjectable::default::product::name";"assertGlobalSearchProductName, assertGlobalSearchOrderId";"Bug: MAGETWO-28448"
+"search with 2 sign return no results";":)";"assertGlobalSearchNoRecordsFound";""
+"search product by sku";"orderInjectable::default::product::sku";"assertGlobalSearchProductName";""
+"search existed customer";"customerInjectable::johndoe_unique::lastname";"assertGlobalSearchCustomerName";""
+"search order (by order id)";"orderInjectable::default::id";"assertGlobalSearchOrderId";""
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/constraint.xml
new file mode 100644
index 00000000000..793b6c55aa6
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/constraint.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<constraint>
+    <assertGlobalSearchProductName module="Magento_Backend">
+        <severeness>low</severeness>
+    </assertGlobalSearchProductName>
+    <assertGlobalSearchOrderId module="Magento_Backend">
+        <severeness>low</severeness>
+    </assertGlobalSearchOrderId>
+    <assertGlobalSearchNoRecordsFound module="Magento_Backend">
+        <severeness>low</severeness>
+    </assertGlobalSearchNoRecordsFound>
+    <assertGlobalSearchCustomerName module="Magento_Backend">
+        <severeness>low</severeness>
+    </assertGlobalSearchCustomerName>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/etc/fixture.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/fixture.xml
new file mode 100644
index 00000000000..5258f0c88ba
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/fixture.xml
@@ -0,0 +1,31 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture>
+    <globalSearch module="Magento_Backend">
+        <type>virtual</type>
+        <entity_type>global_search</entity_type>
+    </globalSearch>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
index c470e783806..53eb2373b89 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php
@@ -110,7 +110,9 @@ class View extends \Magento\Catalog\Test\Block\Product\View
             /** @var \Magento\Bundle\Test\Fixture\BundleFixed $product */
             $bundleCheckoutData = $product->getSelectionData();
         }
-        $this->_rootElement->find($this->customizeButton)->click();
+        if (!$this->getBundleBlock()->isVisible()) {
+            $this->_rootElement->find($this->customizeButton)->click();
+        }
         $this->getBundleBlock()->fillBundleOptions($bundleCheckoutData);
 
         parent::fillOptions($product);
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php
index 67a89015153..1da8099492b 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertTierPriceOnBundleProductPage.php
@@ -58,12 +58,12 @@ class AssertTierPriceOnBundleProductPage extends AssertProductTierPriceOnProduct
     /**
      * Assertion that tier prices are displayed correctly
      *
+     * @param Browser $browser
      * @param CatalogProductView $catalogProductView
      * @param FixtureInterface $product
-     * @param Browser $browser
      * @return void
      */
-    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product, Browser $browser)
+    public function processAssert(Browser $browser, CatalogProductView $catalogProductView, FixtureInterface $product)
     {
         //Open product view page
         $browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html');
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.php
index 316272a7b0b..e4ff9e0ad53 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.php
@@ -295,14 +295,6 @@ class BundleProduct extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $msrp_enabled = [
-        'attribute_code' => 'msrp_enabled',
-        'backend_type' => 'varchar',
-        'is_required' => '0',
-        'default_value' => '2',
-        'input' => 'select',
-    ];
-
     protected $name = [
         'attribute_code' => 'name',
         'backend_type' => 'varchar',
@@ -774,11 +766,6 @@ class BundleProduct extends InjectableFixture
         return $this->getData('msrp_display_actual_price_type');
     }
 
-    public function getMsrpEnabled()
-    {
-        return $this->getData('msrp_enabled');
-    }
-
     public function getName()
     {
         return $this->getData('name');
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
index e3fc0c495c5..313e142623b 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
@@ -187,13 +187,6 @@
             <default_value>4</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
-        <msrp_enabled>
-            <attribute_code>msrp_enabled</attribute_code>
-            <backend_type>varchar</backend_type>
-            <is_required>0</is_required>
-            <default_value>2</default_value>
-            <input>select</input>
-        </msrp_enabled>
         <name>
             <attribute_code>name</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct/CheckoutData.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct/CheckoutData.php
index 90b511ea4a3..7467f1d2bd0 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct/CheckoutData.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct/CheckoutData.php
@@ -86,11 +86,12 @@ class CheckoutData extends \Magento\Catalog\Test\Fixture\CatalogProductSimple\Ch
                                 'name' => '100_dollar_product'
                             ]
                         ]
-                    ]
+                    ],
+                    'qty' => 2
                 ],
                 'cartItem' => [
                     'price' => 756,
-                    'qty' => 1,
+                    'qty' => 2,
                     'subtotal' => 756
                 ]
             ],
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.php
index 9195294fb1e..fc9e2b0f5d1 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.php
@@ -57,7 +57,8 @@ class BundleProduct extends AbstractRepository
             'weight_type' => '0',
             'status' => 'Product online',
             'shipment_type' => '1',
-            'mtf_dataset_name' => 'BundleDynamic_sku_1073507449'
+            'mtf_dataset_name' => 'BundleDynamic_sku_1073507449',
+            'website_ids' => ['Main Website']
         ];
 
         $this->_data['BundleDynamic_sku_215249172'] = [
@@ -74,7 +75,8 @@ class BundleProduct extends AbstractRepository
             'weight_type' => '0',
             'price_type' => '0',
             'shipment_type' => '1',
-            'mtf_dataset_name' => 'BundleDynamic_sku_215249172'
+            'mtf_dataset_name' => 'BundleDynamic_sku_215249172',
+            'website_ids' => ['Main Website']
         ];
 
         $this->_data['bundle_dynamic_product'] = [
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest.php
new file mode 100644
index 00000000000..9ad154674ea
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest.php
@@ -0,0 +1,51 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Bundle\Test\TestCase;
+
+use Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest as AddProductsToCartFromWishlist;
+
+/**
+ * Test Creation for Adding Bundle product from Wishlist to Cart
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer and login to frontend
+ * 2. Bundle product is created
+ * 3. Add bundle product to customer's wishlist
+ *
+ * Steps:
+ * 1. Navigate to My Account -> My Wishlist
+ * 2. Fill qty and update wish list
+ * 3. Click "Add to Cart"
+ * 4. Perform asserts
+ *
+ * @group Wishlist_(CS)
+ * @ZephyrId MAGETWO-25268
+ */
+class AddBundleProductToCartFromCustomerWishlistOnFrontendTest extends AddProductsToCartFromWishlist
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest/test.csv b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest/test.csv
new file mode 100644
index 00000000000..3e389686633
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/AddBundleProductToCartFromCustomerWishlistOnFrontendTest/test.csv
@@ -0,0 +1,3 @@
+"products";"qty";"constraint"
+"bundleProduct::bundle_dynamic_product";"2";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
+"bundleProduct::bundle_fixed_product";"2";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
index 6958549d155..28fa631ac95 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
@@ -75,7 +75,7 @@ class ListProduct extends Block
      *
      * @var string
      */
-    protected $oldPrice = ".old-price .price";
+    protected $oldPrice = ".old-price .price-container";
 
     /**
      * 'Add to Card' button
@@ -91,6 +91,13 @@ class ListProduct extends Block
      */
     protected $priceBox = '.price-box #product-price-%s .price';
 
+    /**
+     * Popup map price
+     *
+     * @var string
+     */
+    protected $mapPopupPrice = '//ancestor::*[@id="map-popup-click-for-price"]';
+
     /**
      * This method returns the price box block for the named product.
      *
@@ -170,6 +177,7 @@ class ListProduct extends Block
     public function openMapBlockOnCategoryPage($productName)
     {
         $this->_rootElement->find(sprintf($this->clickForPrice, $productName), Locator::SELECTOR_XPATH)->click();
+        $this->waitForElementVisible($this->mapPopupPrice, Locator::SELECTOR_XPATH);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
index 4143c18833f..b1a3c5c52d1 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
@@ -40,16 +40,16 @@ class Price extends Block
      */
     protected $mapTypePrices = [
         'price' => [
-            'selector' => '.price .price'
+            'selector' => '.price-container .price'
         ],
         'old_price' => [
-            'selector' => '.old-price .price'
+            'selector' => '.old-price .price-wrapper'
         ],
         'map_old_price' => [
-            'selector' => '.old.price .price'
+            'selector' => '.old-price .price'
         ],
         'actual_price' => [
-            'selector' => '.actual.price .price'
+            'selector' => '.actual-price .price'
         ],
         'special_price' => [
             'selector' => '.special-price .price'
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
index b3dfb41ab92..ea5dadf6dbb 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
@@ -186,12 +186,15 @@ class View extends Block
      */
     public function addToCart(FixtureInterface $product)
     {
-        /** @var CatalogProductSimple $product */
-        $checkoutData = $product->getCheckoutData();
+        $checkoutData = null;
+        if ($product instanceof InjectableFixture) {
+            /** @var CatalogProductSimple $product */
+            $checkoutData = $product->getCheckoutData();
+        }
 
         $this->fillOptions($product);
-        if (isset($checkoutData['qty'])) {
-            $this->_rootElement->find($this->qty)->setValue($checkoutData['qty']);
+        if (isset($checkoutData['options']['qty'])) {
+            $this->_rootElement->find($this->qty)->setValue($checkoutData['options']['qty']);
         }
         $this->clickAddToCart();
     }
@@ -218,6 +221,17 @@ class View extends Block
         $this->clickAddToCart();
     }
 
+    /**
+     * Set quantity
+     *
+     * @param int $qty
+     * @return void
+     */
+    public function setQty($qty)
+    {
+        $this->_rootElement->find($this->qty, Locator::SELECTOR_CSS)->setValue($qty);
+    }
+
     /**
      * Find Add To Cart button
      *
@@ -334,10 +348,6 @@ class View extends Block
 
             $this->getCustomOptionsBlock()->fillCustomOptions($checkoutCustomOptions);
         }
-
-        if (isset($checkoutData['options']['qty'])) {
-            $this->_rootElement->find($this->qty)->setValue($checkoutData['options']['qty']);
-        }
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php
index 0df9934ce05..39c86790468 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceOnProductPage.php
@@ -59,14 +59,14 @@ class AssertProductTierPriceOnProductPage extends AbstractConstraint implements
     /**
      * Assertion that tier prices are displayed correctly
      *
-     * @param CatalogProductView $catalogProductView
      * @param Browser $browser
+     * @param CatalogProductView $catalogProductView
      * @param FixtureInterface $product
      * @return void
      */
     public function processAssert(
-        CatalogProductView $catalogProductView,
         Browser $browser,
+        CatalogProductView $catalogProductView,
         FixtureInterface $product
     ) {
         // TODO fix initialization url for frontend page
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Cart/Item.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Cart/Item.php
index 8ce2ab916b3..ea2967a46fa 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Cart/Item.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Cart/Item.php
@@ -77,6 +77,10 @@ class Item implements FixtureInterface
         $cartItem['options'] = isset($cartItem['options'])
             ? $cartItem['options'] + $checkoutCustomOptions
             : $checkoutCustomOptions;
+        $cartItem['qty'] = isset($checkoutData['options']['qty'])
+                ? $checkoutData['options']['qty']
+                : 1;
+
         $this->data = $cartItem;
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
index 29ec7ec1e25..06ee669b373 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
@@ -206,6 +206,12 @@ class CatalogCategory extends InjectableFixture
         'group' => 'general_information',
     ];
 
+    protected $is_anchor = [
+        'attribute_code' => 'is_anchor',
+        'backend_type' => 'virtual',
+        'group' => 'general_information',
+    ];
+
     protected $url_key = [
         'attribute_code' => 'url_key',
         'backend_type' => 'virtual',
@@ -334,6 +340,11 @@ class CatalogCategory extends InjectableFixture
         return $this->getData('is_active');
     }
 
+    public function getIsAnchor()
+    {
+        return $this->getData('is_anchor');
+    }
+
     public function getUrlKey()
     {
         return $this->getData('url_key');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
index ef393c01c95..50c37f4dead 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
@@ -156,6 +156,11 @@
             <backend_type>virtual</backend_type>
             <group>general_information</group>
         </is_active>
+        <is_anchor>
+            <attribute_code>is_anchor</attribute_code>
+            <backend_type>virtual</backend_type>
+            <group>general_information</group>
+        </is_anchor>
         <url_key>
             <attribute_code>url_key</attribute_code>
             <backend_type>virtual</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
index cc5c4476db5..3588eb403a5 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
@@ -264,7 +264,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'textarea',
     ];
 
@@ -273,7 +273,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'text',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'textarea',
     ];
 
@@ -282,7 +282,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'text',
     ];
 
@@ -310,14 +310,6 @@ class CatalogProductSimple extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $msrp_enabled = [
-        'attribute_code' => 'msrp_enabled',
-        'backend_type' => 'varchar',
-        'is_required' => '0',
-        'default_value' => 'In Cart',
-        'input' => 'select',
-    ];
-
     protected $name = [
         'attribute_code' => 'name',
         'backend_type' => 'varchar',
@@ -731,11 +723,6 @@ class CatalogProductSimple extends InjectableFixture
         return $this->getData('msrp_display_actual_price_type');
     }
 
-    public function getMsrpEnabled()
-    {
-        return $this->getData('msrp_enabled');
-    }
-
     public function getName()
     {
         return $this->getData('name');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index 659821b132b..395b2745e59 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -167,7 +167,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>textarea</input>
         </meta_description>
         <meta_keyword>
@@ -175,7 +175,7 @@
             <backend_type>text</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>textarea</input>
         </meta_keyword>
         <meta_title>
@@ -183,7 +183,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>text</input>
         </meta_title>
         <minimal_price>
@@ -207,13 +207,6 @@
             <default_value>Use config</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
-        <msrp_enabled>
-            <attribute_code>msrp_enabled</attribute_code>
-            <backend_type>varchar</backend_type>
-            <is_required>0</is_required>
-            <default_value>In Cart</default_value>
-            <input>select</input>
-        </msrp_enabled>
         <name>
             <attribute_code>name</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php
index 5162898840f..9fc2f413279 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CheckoutData.php
@@ -57,10 +57,10 @@ class CheckoutData implements FixtureInterface
     public function __construct(array $params, array $data = [])
     {
         $this->params = $params;
-        $this->data =  isset($data['preset']) ? $this->getPreset($data['preset']) : [];
+        $this->data = isset($data['preset']) ? $this->getPreset($data['preset']) : [];
 
-        if (isset($data['value'])) {
-            $this->data = array_replace_recursive($this->data, $data['value']);
+        if (isset($data['data'])) {
+            $this->data = array_replace_recursive($this->data, $data['data']);
         }
     }
 
@@ -121,7 +121,6 @@ class CheckoutData implements FixtureInterface
                 ],
                 'cartItem' => [
                     'price' => 340,
-                    'qty' => 1,
                     'subtotal' => 340
                 ]
             ],
@@ -170,15 +169,23 @@ class CheckoutData implements FixtureInterface
             'order_default' => [
                 'options' => [
                     'qty' => 1
-                ]
+                ],
+                'cartItem' => []
             ],
-            'order_big_qty' => [
+            'two_products' => [
                 'options' => [
                     'qty' => 2
                 ],
                 'cartItem' => [
-                    'qty' => 2
+                    'price' => 100,
+                    'subtotal' => 200
                 ]
+            ],
+            'order_big_qty' => [
+                'options' => [
+                    'qty' => 2
+                ],
+                'cartItem' => []
             ]
         ];
         return isset($presets[$name]) ? $presets[$name] : [];
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
index a50685ccf89..02a73c9f117 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
@@ -267,7 +267,7 @@ class CatalogProductVirtual extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'textarea',
     ];
 
@@ -276,7 +276,7 @@ class CatalogProductVirtual extends InjectableFixture
         'backend_type' => 'text',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'textarea',
     ];
 
@@ -285,7 +285,7 @@ class CatalogProductVirtual extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
-        'group' => 'search-optimization',
+        'group' => 'search-engine-optimization',
         'input' => 'text',
     ];
 
@@ -313,14 +313,6 @@ class CatalogProductVirtual extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $msrp_enabled = [
-        'attribute_code' => 'msrp_enabled',
-        'backend_type' => 'varchar',
-        'is_required' => '0',
-        'default_value' => 'In Cart',
-        'input' => 'select',
-    ];
-
     protected $name = [
         'attribute_code' => 'name',
         'backend_type' => 'varchar',
@@ -716,11 +708,6 @@ class CatalogProductVirtual extends InjectableFixture
         return $this->getData('msrp_display_actual_price_type');
     }
 
-    public function getMsrpEnabled()
-    {
-        return $this->getData('msrp_enabled');
-    }
-
     public function getName()
     {
         return $this->getData('name');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
index 1a9729dd4c0..d3e4f7ade69 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
@@ -167,7 +167,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>textarea</input>
         </meta_description>
         <meta_keyword>
@@ -175,7 +175,7 @@
             <backend_type>text</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>textarea</input>
         </meta_keyword>
         <meta_title>
@@ -183,7 +183,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <group>search-optimization</group>
+            <group>search-engine-optimization</group>
             <input>text</input>
         </meta_title>
         <minimal_price>
@@ -207,13 +207,6 @@
             <default_value>Use config</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
-        <msrp_enabled>
-            <attribute_code>msrp_enabled</attribute_code>
-            <backend_type>varchar</backend_type>
-            <is_required>0</is_required>
-            <default_value>In Cart</default_value>
-            <input>select</input>
-        </msrp_enabled>
         <name>
             <attribute_code>name</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual/CheckoutData.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual/CheckoutData.php
index fc9e2fbed90..065ca948351 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual/CheckoutData.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual/CheckoutData.php
@@ -42,6 +42,11 @@ class CheckoutData extends \Magento\Catalog\Test\Fixture\CatalogProductSimple\Ch
     protected function getPreset($name)
     {
         $presets = [
+            'order_default' => [
+                'options' => [
+                    'qty' => 1
+                ]
+            ],
             '50_dollar_product' => [
                 'cartItem' => [
                     'price' => 50,
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product.php
index a394c45e5fa..511551329a9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product.php
@@ -33,7 +33,7 @@ class Product extends DataFixture
      * Attribute set for mapping data into ui tabs
      */
     const GROUP_PRODUCT_DETAILS     = 'product-details';
-    const GROUP_ADVANCED_SEO        = 'search-optimization';
+    const GROUP_ADVANCED_SEO        = 'search-engine-optimization';
     const GROUP_PRODUCT_WEBSITE     = 'websites';
     const GROUP_PRODUCT_INVENTORY   = 'advanced-inventory';
     const GROUP_PRODUCT_PRICING     = 'advanced-pricing';
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php
index 7f3ec0347d1..747d379fd7b 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategory/Curl.php
@@ -58,6 +58,10 @@ class Curl extends AbstractCurl implements CatalogCategoryInterface
             'Yes' => 1,
             'No' => 0,
         ],
+        'is_anchor' => [
+            'Yes' => 1,
+            'No' => 0,
+        ],
         'include_in_menu' => [
             'Yes' => 1,
             'No' => 0,
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeIndex.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeIndex.xml
index 7ac2b1f9488..97d95351093 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeIndex.xml
@@ -32,7 +32,7 @@
         </messagesBlock>
         <pageActionsBlock>
             <class>Magento\Backend\Test\Block\GridPageActions</class>
-            <locator>#page-main-actions</locator>
+            <locator>.page-main-actions</locator>
             <strategy>css selector</strategy>
         </pageActionsBlock>
         <grid>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeNew.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeNew.xml
index f483bd56503..ce18f781b3f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeNew.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductAttributeNew.xml
@@ -37,7 +37,7 @@
         </pageActions>
         <attributeForm>
             <class>Magento\Catalog\Test\Block\Adminhtml\Product\Attribute\Edit\AttributeForm</class>
-            <locator>#edit_form</locator>
+            <locator>[id="page:main-container"]</locator>
             <strategy>css selector</strategy>
         </attributeForm>
     </blocks>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
index 2303a597c96..934cd9f9a7b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
@@ -56,6 +56,15 @@ class CatalogCategory extends AbstractRepository
             'include_in_menu' => 'Yes',
         ];
 
+        $this->_data['default_anchor_subcategory'] = [
+            'name' => 'DefaultSubcategory%isolation%',
+            'url_key' => 'default-subcategory-%isolation%',
+            'parent_id' => ['dataSet' => 'default_category'],
+            'is_active' => 'Yes',
+            'is_anchor' => 'Yes',
+            'include_in_menu' => 'Yes',
+        ];
+
         $this->_data['root_category'] = [
             'name' => 'RootCategory%isolation%',
             'url_key' => 'root-category-%isolation%',
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
index 7c79a7148b4..ac624606352 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
@@ -39,6 +39,7 @@ class CatalogProductAttribute extends AbstractRepository
      * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
     public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
@@ -108,5 +109,45 @@ class CatalogProductAttribute extends AbstractRepository
                 ],
             ]
         ];
+
+        $this->_data['color'] = [
+            'frontend_label' => 'color_%isolation%',
+            'attribute_code' => 'color_%isolation%',
+            'frontend_input' => 'Dropdown',
+            'is_required' => 'No',
+            'is_configurable' => 'Yes',
+            'options' => [
+                [
+                    'is_default' => 'Yes',
+                    'admin' => 'black',
+                    'view' => 'black_%isolation%',
+                ],
+                [
+                    'is_default' => 'No',
+                    'admin' => 'white',
+                    'view' => 'white_%isolation%',
+                ]
+            ]
+        ];
+
+        $this->_data['size'] = [
+            'frontend_label' => 'size_%isolation%',
+            'attribute_code' => 'size_%isolation%',
+            'frontend_input' => 'Dropdown',
+            'is_required' => 'No',
+            'is_configurable' => 'Yes',
+            'options' => [
+                [
+                    'is_default' => 'Yes',
+                    'admin' => 'xl',
+                    'view' => 'xl_%isolation%',
+                ],
+                [
+                    'is_default' => 'No',
+                    'admin' => 'xxl',
+                    'view' => 'xxl_%isolation%',
+                ]
+            ]
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
index 73402bfe930..b6b51204c00 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
@@ -87,6 +87,7 @@ class CatalogProductSimple extends AbstractRepository
             'attribute_set_id' => ['dataSet' => 'default'],
             'price' => ['value' => 100, 'preset' => '-'],
             'website_ids' => ['Main Website'],
+            'checkout_data' => ['preset' => 'two_products']
         ];
 
         $this->_data['40_dollar_product'] = [
@@ -192,6 +193,15 @@ class CatalogProductSimple extends AbstractRepository
             'website_ids' => ['Main Website'],
         ];
 
+        $this->_data['product_with_special_price'] = [
+            'sku' => 'simple_product_with_special_price_and_category%isolation%',
+            'name' => 'Simple with Special Price 1$ off %isolation%',
+            'attribute_set_id' => ['dataSet' => 'default'],
+            'price' => ['value' => 10, 'preset' => ''],
+            'special_price' => 9,
+            'website_ids' => ['Main Website'],
+        ];
+
         $this->_data['adc_123_simple_for_advancedsearch'] = [
             'name' => 'adc_123',
             'sku' => 'adc_123',
@@ -208,6 +218,38 @@ class CatalogProductSimple extends AbstractRepository
             'visibility' => 'Catalog, Search',
         ];
 
+        $this->_data['product_with_weight_0_1'] = [
+            'name' => 'Simple with Weight 0.1 %isolation%',
+            'sku' => 'adc_123',
+            'price' => ['value' => 100.00, 'preset' => '-'],
+            'tax_class_id' => ['dataSet' => 'None'],
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'weight' => 0.1,
+            'description' => '<p>Simple with Weight 0.1</p>',
+            'status' => 'Product online',
+            'website_ids' => ['Main Website'],
+            'visibility' => 'Catalog, Search',
+        ];
+
+        $this->_data['product_with_weight_150_1'] = [
+            'name' => 'Simple with Weight 150.1 %isolation%',
+            'sku' => 'adc_123',
+            'price' => ['value' => 100.00, 'preset' => '-'],
+            'tax_class_id' => ['dataSet' => 'None'],
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'weight' => 150.1,
+            'description' => '<p>Simple with Weight 150.1</p>',
+            'status' => 'Product online',
+            'website_ids' => ['Main Website'],
+            'visibility' => 'Catalog, Search',
+        ];
+
         $this->_data['abc_dfj_simple_for_advancedsearch'] = [
             'name' => 'abc_dfj',
             'sku' => 'abc_dfj',
@@ -283,7 +325,7 @@ class CatalogProductSimple extends AbstractRepository
         $this->_data['with_all_custom_option'] = [
             'type_id' => 'simple',
             'attribute_set_id' => ['dataSet' => 'default'],
-            'name' => 'Simple Product %isolation%',
+            'name' => 'Simple Product With Custom Option %isolation%',
             'sku' => 'sku_simple_product_%isolation%',
             'price' => ['value' => 300, 'preset' => '-'],
             'weight' => 1,
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php
index 5882d7f55c9..4727bf50ba9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php
@@ -60,24 +60,6 @@ class CatalogProductVirtual extends AbstractRepository
             'checkout_data' => ['preset' => 'order_default'],
         ];
 
-        $this->_data['virtual_big_qty'] = [
-            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
-            'status' => 'Product online',
-            'website_ids' => ['Main Website'],
-            'is_virtual' => 'Yes',
-            'url_key' => 'virtual-product%isolation%',
-            'visibility' => 'Catalog, Search',
-            'attribute_set_id' => ['dataSet' => 'default'],
-            'name' => 'Virtual product %isolation%',
-            'sku' => 'sku_virtual_product_%isolation%',
-            'quantity_and_stock_status' => [
-                'qty' => 1000.0000,
-                'is_in_stock' => 'In Stock',
-            ],
-            'price' => ['value' => 10.00, 'preset' => '-'],
-            'checkout_data' => ['preset' => 'order_big_qty'],
-        ];
-
         $this->_data['50_dollar_product'] = [
             'name' => '50_dollar_product %isolation%',
             'sku' => '50_dollar_product_%isolation%',
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/SimpleProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/SimpleProduct.php
index b9766e52dae..7aa4be74e6d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/SimpleProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/SimpleProduct.php
@@ -187,12 +187,6 @@ class SimpleProduct extends Product
         $pricing = [
             'data' => [
                 'fields' => [
-                    'msrp_enabled' => [
-                        'value' => 'Yes',
-                        'input_value' => '1',
-                        'group' => Fixture\Product::GROUP_PRODUCT_PRICING,
-                        'input' => 'select'
-                    ],
                     'msrp_display_actual_price_type' => [
                         'value' => 'On Gesture',
                         'input_value' => '1',
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
index c3d8aae6597..5b91970cf3e 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
@@ -77,11 +77,6 @@ class AssignProductTest extends Functional
         $cachePage->open();
         $cachePage->getActionsBlock()->flushMagentoCache();
         $cachePage->getMessagesBlock()->assertSuccessMessage();
-        //Indexing
-        $indexPage = Factory::getPageFactory()->getAdminProcessList();
-        $indexPage->open();
-        $indexPage->getActionsBlock()->reindexAll();
-        $indexPage->getMessagesBlock()->assertSuccessMessage();
         //Verifying
         $this->assertProductsOnCategory($category, $products);
     }
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/AdvancedResult.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/AdvancedResult.xml
index 1595b810500..9976e324fcc 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/AdvancedResult.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Page/AdvancedResult.xml
@@ -32,8 +32,8 @@
         </searchResultBlock>
         <bottomToolbar>
             <class>Magento\Catalog\Test\Block\Product\ProductList\BottomToolbar</class>
-            <locator>.column.main</locator>
-            <strategy>css selector</strategy>
+            <locator>.//*[contains(@class,"toolbar-products")][2]</locator>
+            <strategy>xpath</strategy>
         </bottomToolbar>
         <listProductBlock>
             <class>Magento\Catalog\Test\Block\Product\ListProduct</class>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
index 58594105029..018a42b6c05 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
@@ -43,7 +43,7 @@ class Cart extends Block
      *
      * @var string
      */
-    protected $cartItemByProductName = './/tr[contains(@class,"item-info") and (.//*[contains(@class,"product-item-name")]/a[.="%s"])]';
+    protected $cartItemByProductName = './/tbody[contains(@class,"cart item") and (.//*[contains(@class,"product-item-name")]/a[.="%s"])]';
     // @codingStandardsIgnoreEnd
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/AbstractCartItem.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/AbstractCartItem.php
index cd01d802c50..7b106283eb0 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/AbstractCartItem.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/AbstractCartItem.php
@@ -44,7 +44,7 @@ class AbstractCartItem extends Block
      *
      * @var string
      */
-    protected $price = './/td[@class="col price"]/*[@class="excl tax"]/span';
+    protected $price = './/td[@class="col price"]/*[@class="price-excluding-tax"]/span';
 
     /**
      * Quantity input selector
@@ -58,7 +58,7 @@ class AbstractCartItem extends Block
      *
      * @var string
      */
-    protected $subtotalPrice = './/td[@class="col subtotal"]//*[@class="excl tax"]//span[@class="price"]';
+    protected $subtotalPrice = './/td[@class="col subtotal"]//*[@class="price-excluding-tax"]//span[@class="price"]';
 
     /**
      *  Selector for options block
diff --git a/dev/tests/functional/tests/app/Magento/Index/Test/Block/Adminhtml/Process/Index.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartEmpty.php
similarity index 63%
rename from dev/tests/functional/tests/app/Magento/Index/Test/Block/Adminhtml/Process/Index.php
rename to dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartEmpty.php
index a6ed3acf913..4aa782932b6 100644
--- a/dev/tests/functional/tests/app/Magento/Index/Test/Block/Adminhtml/Process/Index.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartEmpty.php
@@ -21,35 +21,42 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+ 
+namespace Magento\Checkout\Test\Block\Cart;
 
-namespace Magento\Index\Test\Block\Adminhtml\Process;
-
+use Mtf\Block\Block;
 use Mtf\Client\Element\Locator;
-use Magento\Backend\Test\Block\Widget\Grid;
 
 /**
- * Class Index
- * Index management grid
- *
+ * Class CartEmpty
+ * Block for text of empty cart
  */
-class Index extends Grid
+class CartEmpty extends Block
 {
     /**
+     * Selector for link "here" to main page
+     *
      * @var string
      */
-    protected $actionsDropdown = '#massaction-select';
+    protected $linkToMainPage = './/a';
 
     /**
-     * @var string
+     * Get test for empty cart
+     *
+     * @return string
      */
-    protected $selectAll = './/option[@value="selectAll"]';
+    public function getText()
+    {
+        return str_replace("\n", ' ', $this->_rootElement->getText());
+    }
 
     /**
-     * Mass action for Reindex Data
+     * Click link to main page
+     *
+     * @return void
      */
-    public function reindexAll()
+    public function clickLinkToMainPage()
     {
-        $this->_rootElement->find($this->actionsDropdown, Locator::SELECTOR_CSS, 'select')->setValue('Select All');
-        $this->_rootElement->find($this->massactionSubmit, Locator::SELECTOR_CSS)->click();
+        $this->_rootElement->find($this->linkToMainPage, Locator::SELECTOR_XPATH)->click();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartItem.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartItem.php
index e26787694f4..01b0d7a87ee 100755
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartItem.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/CartItem.php
@@ -32,6 +32,20 @@ use Mtf\Client\Element\Locator;
  */
 class CartItem extends AbstractCartItem
 {
+    /**
+     * Selector for "Edit" button
+     *
+     * @var string
+     */
+    protected $edit = '.action.edit';
+
+    /**
+     * Selector for "Remove item" button
+     *
+     * @var string
+     */
+    protected $removeItem = '.action.delete';
+
     /**
      * Get bundle options
      *
@@ -160,6 +174,26 @@ class CartItem extends AbstractCartItem
         return trim($this->_rootElement->find($formatPrice, Locator::SELECTOR_XPATH)->getText(), $currency);
     }
 
+    /**
+     * Edit product item in cart
+     *
+     * @return void
+     */
+    public function edit()
+    {
+        $this->_rootElement->find($this->edit)->click();
+    }
+
+    /**
+     * Remove product item from cart
+     *
+     * @return void
+     */
+    public function removeItem()
+    {
+        $this->_rootElement->find($this->removeItem)->click();
+    }
+
     /**
      * Escape currency in option label
      *
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php
new file mode 100644
index 00000000000..1d1ea004564
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php
@@ -0,0 +1,87 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Checkout\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Checkout\Test\Fixture\Cart;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+
+/**
+ * Class AssertCartIsEmpty
+ * Check that Shopping Cart is empty
+ */
+class AssertCartIsEmpty extends AbstractConstraint
+{
+    /**
+     * Text of empty cart.
+     */
+    const TEXT_EMPTY_CART = 'You have no items in your shopping cart. Click here to continue shopping.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'middle';
+
+    /**
+     * Check that Shopping Cart is empty, opened page contains text "You have no items in your shopping cart.
+     * Click here to continue shopping." where 'here' is link that leads to index page
+     *
+     * @param CheckoutCart $checkoutCart
+     * @param Browser $browser
+     * @return void
+     */
+    public function processAssert(CheckoutCart $checkoutCart, Browser $browser)
+    {
+        $checkoutCart->open();
+        $cartEmptyBlock = $checkoutCart->getCartEmptyBlock();
+
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::TEXT_EMPTY_CART,
+            $cartEmptyBlock->getText(),
+            'Wrong text on empty cart page.'
+        );
+
+        $cartEmptyBlock->clickLinkToMainPage();
+        \PHPUnit_Framework_Assert::assertEquals(
+            $_ENV['app_frontend_url'],
+            $browser->getUrl(),
+            'Wrong link to main page on empty cart page.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Shopping Cart is empty.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInMiniShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInMiniShoppingCart.php
index d13ad060413..4fcbc3cfe7b 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInMiniShoppingCart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInMiniShoppingCart.php
@@ -24,15 +24,18 @@
 
 namespace Magento\Checkout\Test\Constraint;
 
-use Mtf\Constraint\AbstractConstraint;
+use Mtf\Constraint\AbstractAssertForm;
 use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Fixture\FixtureInterface;
 use Magento\Checkout\Test\Fixture\Cart;
+use Magento\Checkout\Test\Fixture\Cart\Items;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
 /**
  * Class AssertProductQtyInMiniShoppingCart
+ * Assert that product quantity in the mini shopping cart is equals to expected quantity from data set
  */
-class AssertProductQtyInMiniShoppingCart extends AbstractConstraint
+class AssertProductQtyInMiniShoppingCart extends AbstractAssertForm
 {
     /**
      * Constraint severeness
@@ -46,21 +49,37 @@ class AssertProductQtyInMiniShoppingCart extends AbstractConstraint
      *
      * @param CmsIndex $cmsIndex
      * @param Cart $cart
-     * @param CatalogProductSimple $product
      * @return void
      */
     public function processAssert(
         CmsIndex $cmsIndex,
-        Cart $cart,
-        CatalogProductSimple $product
+        Cart $cart
     ) {
-        $productQtyInMiniCart = $cmsIndex->open()->getCartSidebarBlock()->getProductQty($product->getName());
-        \PHPUnit_Framework_Assert::assertEquals(
-            $productQtyInMiniCart,
-            $cart->getQty(),
-            'Mini shopping cart product qty: \'' . $productQtyInMiniCart
-            . '\' not equals with qty from data set: \'' . $cart->getQty() . '\''
-        );
+        $cmsIndex->open();
+        /** @var Items $sourceProducts */
+        $sourceProducts = $cart->getDataFieldConfig('items')['source'];
+        $products = $sourceProducts->getProducts();
+        $items = $cart->getItems();
+        $productsData = [];
+        $miniCartData = [];
+
+        foreach ($items as $key => $item) {
+            /** @var CatalogProductSimple $product */
+            $product = $products[$key];
+            $productName = $product->getName();
+            /** @var FixtureInterface $item */
+            $checkoutItem = $item->getData();
+
+            $productsData[$productName] = [
+                'qty' => $checkoutItem['qty']
+            ];
+            $miniCartData[$productName] = [
+                'qty' => $cmsIndex->getCartSidebarBlock()->getProductQty($productName)
+            ];
+        }
+
+        $error = $this->verifyData($productsData, $miniCartData, true);
+        \PHPUnit_Framework_Assert::assertEmpty($error, $error);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.xml
index 72ad124e646..c4accd206ba 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.xml
@@ -30,6 +30,11 @@
             <locator>//div[contains(@class, "column main")]</locator>
             <strategy>xpath</strategy>
         </cartBlock>
+        <cartEmptyBlock>
+            <class>Magento\Checkout\Test\Block\Cart\CartEmpty</class>
+            <locator>.cart-empty</locator>
+            <strategy>css selector</strategy>
+        </cartEmptyBlock>
         <messagesBlock>
             <class>Magento\Core\Test\Block\Messages</class>
             <locator>.messages .messages</locator>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/AddProductsToTheCartStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/AddProductsToTheCartStep.php
index 3e1d2c64515..549237fd211 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/AddProductsToTheCartStep.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/AddProductsToTheCartStep.php
@@ -105,7 +105,7 @@ class AddProductsToTheCartStep implements TestStepInterface
 
         foreach ($this->products as $product) {
             $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html');
-            $this->catalogProductView->getViewBlock()->clickAddToCart();
+            $this->catalogProductView->getViewBlock()->addToCart($product);
         }
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/constraint.xml
index 876ef16b539..74fa1c3719e 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/constraint.xml
@@ -24,6 +24,9 @@
  */
 -->
 <constraint>
+    <assertCartIsEmpty module="Magento_Checkout">
+        <severeness>middle</severeness>
+    </assertCartIsEmpty>
     <assertPriceInShoppingCart module="Magento_Checkout">
         <severeness>low</severeness>
     </assertPriceInShoppingCart>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml
index 55bb1786b4f..9fa7731d6c2 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml
@@ -42,7 +42,7 @@
         </titleBlock>
         <footerBlock>
             <class>Magento\Theme\Test\Block\Html\Footer</class>
-            <locator>footer.page.footer</locator>
+            <locator>footer.page-footer</locator>
             <strategy>css selector</strategy>
         </footerBlock>
         <linksBlock>
@@ -70,5 +70,10 @@
             <locator>.switcher.currency</locator>
             <strategy>css selector</strategy>
         </currencyBlock>
+        <cmsPageBlock>
+            <class>Magento\Cms\Test\Block\Page</class>
+            <locator>.page.main</locator>
+            <strategy>css selector</strategy>
+        </cmsPageBlock>
     </blocks>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInItemsOrderedGrid.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInItemsOrderedGrid.php
index ae25bd0d715..25f61afc91a 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInItemsOrderedGrid.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInItemsOrderedGrid.php
@@ -55,7 +55,7 @@ class AssertConfigurableProductInItemsOrderedGrid extends AssertProductInItemsOr
             return 0;
         }
         $attributesData = $product->getConfigurableAttributesData()['attributes_data'];
-        foreach ($checkoutData['configurable_options'] as $option) {
+        foreach ($checkoutData['options']['configurable_options'] as $option) {
             $itemOption = $attributesData[$option['title']]['options'][$option['value']];
             $itemPrice = $itemOption['is_percent'] == 'No'
                 ? $itemOption['pricing_value']
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
index 83964414380..c04069b4418 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
@@ -72,7 +72,7 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
         $productGrid->getGridPageActionBlock()->addProduct('configurable');
 
         $productConfigurable = $fixtureFactory->createByCode(
-            'catalogProductConfigurable',
+            'configurableProductInjectable',
             [
                 'dataSet' => 'default',
                 'data' => [
@@ -88,7 +88,7 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
 
         $productBlockForm = $newProductPage->getProductForm();
         $productBlockForm->fill($productConfigurable);
-
+        $productBlockForm->openTab('variations');
         \PHPUnit_Framework_Assert::assertTrue(
             $productBlockForm->checkAttributeInSearchAttributeForm($this->attribute),
             "Product attribute is absent on the product page."
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.php
index fd65fadaad2..5ad5aae37b6 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.php
@@ -313,14 +313,6 @@ class ConfigurableProductInjectable extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $msrp_enabled = [
-        'attribute_code' => 'msrp_enabled',
-        'backend_type' => 'varchar',
-        'is_required' => '0',
-        'default_value' => '',
-        'input' => 'select',
-    ];
-
     protected $name = [
         'attribute_code' => 'name',
         'backend_type' => 'varchar',
@@ -744,11 +736,6 @@ class ConfigurableProductInjectable extends InjectableFixture
         return $this->getData('msrp_display_actual_price_type');
     }
 
-    public function getMsrpEnabled()
-    {
-        return $this->getData('msrp_enabled');
-    }
-
     public function getName()
     {
         return $this->getData('name');
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.xml
index f778c74eadb..61b74199dbf 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable.xml
@@ -219,13 +219,6 @@
             <default_value>4</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
-        <msrp_enabled>
-            <attribute_code>msrp_enabled</attribute_code>
-            <backend_type>varchar</backend_type>
-            <is_required>0</is_required>
-            <default_value>2</default_value>
-            <input>select</input>
-        </msrp_enabled>
         <name>
             <attribute_code>name</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable/ConfigurableAttributesData.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable/ConfigurableAttributesData.php
index 819c239687c..7fdf2610f35 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable/ConfigurableAttributesData.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProductInjectable/ConfigurableAttributesData.php
@@ -227,7 +227,7 @@ class ConfigurableAttributesData implements FixtureInterface
                 'attribute_key_0' => [
                     'options' => [
                         'option_key_0' => [
-                            'label' => 'option_1_%isolation%',
+                            'label' => 'option_key_1_%isolation%',
                             'pricing_value' => 1,
                             'is_percent' => 'Yes',
                             'include' => 'Yes'
@@ -346,7 +346,110 @@ class ConfigurableAttributesData implements FixtureInterface
                     'weight' => 2
                 ]
             ]
-        ]
+        ],
+        'color_and_size' => [
+            'attributes_data' => [
+                'attribute_key_0' => [
+                    'options' => [
+                        'option_key_0' => [
+                            'pricing_value' => 0.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                        'option_key_1' => [
+                            'pricing_value' => 0.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                    ]
+                ],
+                'attribute_key_1' => [
+                    'options' => [
+                        'option_key_0' => [
+                            'pricing_value' => 5.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                        'option_key_1' => [
+                            'pricing_value' => 10.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                    ]
+                ]
+            ],
+            'products' => [
+
+            ],
+            'attributes' => [
+                'attribute_key_0' => 'catalogProductAttribute::color',
+                'attribute_key_1' => 'catalogProductAttribute::size',
+            ],
+            'matrix' => [
+                'attribute_key_0:option_key_0 attribute_key_1:option_key_0' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 100
+                    ],
+                    'weight' => 1
+                ],
+                'attribute_key_0:option_key_0 attribute_key_1:option_key_1' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 100
+                    ],
+                    'weight' => 1
+                ],
+                'attribute_key_0:option_key_1 attribute_key_1:option_key_0' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 100
+                    ],
+                    'weight' => 1
+                ],
+                'attribute_key_0:option_key_1 attribute_key_1:option_key_1' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 100
+                    ],
+                    'weight' => 1
+                ],
+            ]
+        ],
+        'size' => [
+            'attributes_data' => [
+                'attribute_key_0' => [
+                    'options' => [
+                        'option_key_0' => [
+                            'pricing_value' => 0.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                        'option_key_1' => [
+                            'pricing_value' => 0.00,
+                            'include' => 'Yes',
+                            'is_percent' => 'No'
+                        ],
+                    ]
+                ]
+            ],
+            'products' => [
+
+            ],
+            'attributes' => [
+                'attribute_key_0' => 'catalogProductAttribute::size',
+            ],
+            'matrix' => [
+                'attribute_key_0:option_key_0' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 10
+                    ],
+                    'weight' => 1
+                ],
+                'attribute_key_0:option_key_1' => [
+                    'quantity_and_stock_status' => [
+                        'qty' => 10
+                    ],
+                    'weight' => 1
+                ],
+            ]
+        ],
     ];
 
 
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.php
index 79069c70ee1..f3223fa4cbf 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.php
@@ -92,12 +92,6 @@ class ConfigurableProduct extends Product
         $pricing = array(
             'data' => array(
                 'fields' => array(
-                    'msrp_enabled' => array(
-                        'value' => 'Yes',
-                        'input_value' => '1',
-                        'group' => ConfigurableProductFixture::GROUP_PRODUCT_PRICING,
-                        'input' => 'select'
-                    ),
                     'msrp_display_actual_price_type' => array(
                         'value' => 'On Gesture',
                         'input_value' => '1',
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProductInjectable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProductInjectable.php
index 0b94381dc4c..0f698312e4f 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProductInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProductInjectable.php
@@ -60,6 +60,42 @@ class ConfigurableProductInjectable extends AbstractRepository
             'checkout_data' => ['preset' => 'default']
         ];
 
+        $this->_data['product_with_size'] = [
+            'name' => 'Test configurable product with size %isolation%',
+            'sku' => 'sku_test_configurable_product_%isolation%',
+            'price' => ['value' => 120.00],
+            'weight' => 30.0000,
+            'status' => 'Product online',
+            'visibility' => 'Catalog, Search',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'url_key' => 'configurable-product-%isolation%',
+            'configurable_attributes_data' => ['preset' => 'size'],
+            'quantity_and_stock_status' => [
+                'is_in_stock' => 'In Stock',
+            ],
+            'website_ids' => ['Main Website'],
+            'attribute_set_id' => ['dataSet' => 'default'],
+            'checkout_data' => ['preset' => 'default'],
+        ];
+
+        $this->_data['product_with_color_and_size'] = [
+            'name' => 'Test configurable product with color and size %isolation%',
+            'sku' => 'sku_test_configurable_product_%isolation%',
+            'price' => ['value' => 120.00],
+            'weight' => 30.0000,
+            'status' => 'Product online',
+            'visibility' => 'Catalog, Search',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'url_key' => 'configurable-product-%isolation%',
+            'configurable_attributes_data' => ['preset' => 'color_and_size'],
+            'quantity_and_stock_status' => [
+                'is_in_stock' => 'In Stock',
+            ],
+            'website_ids' => ['Main Website'],
+            'attribute_set_id' => ['dataSet' => 'default'],
+            'checkout_data' => ['preset' => 'default'],
+        ];
+
         $this->_data['one_variation'] = [
             'name' => 'Test configurable product %isolation%',
             'sku' => 'sku_test_configurable_product_%isolation%',
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest.php
new file mode 100644
index 00000000000..74578baac70
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest.php
@@ -0,0 +1,51 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\ConfigurableProduct\Test\TestCase;
+
+use Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest as AddProductsToCartFromWishlist;
+
+/**
+ * Test Creation for Adding Configurable product from Wishlist to Cart
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer and login to frontend
+ * 2. Configurable product is created
+ * 3. Add configurable product to customer's wishlist
+ *
+ * Steps:
+ * 1. Navigate to My Account -> My Wishlist
+ * 2. Fill qty and update wish list
+ * 3. Click "Add to Cart"
+ * 4. Perform asserts
+ *
+ * @group Wishlist_(CS)
+ * @ZephyrId MAGETWO-25268
+ */
+class AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest extends AddProductsToCartFromWishlist
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest/test.csv b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
new file mode 100644
index 00000000000..36bcde341f1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/AddConfigurableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
@@ -0,0 +1,2 @@
+"products";"qty";"constraint"
+"configurableProductInjectable::default";"3";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/constraint.xml
index 07c56238913..83557c27bca 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/constraint.xml
@@ -48,4 +48,7 @@
     <assertProductAttributeAbsenceInVariationsSearch module="Magento_ConfigurableProduct">
         <severeness>low</severeness>
     </assertProductAttributeAbsenceInVariationsSearch>
+    <assertProductAttributeIsConfigurable module="Magento_ConfigurableProduct">
+        <severeness>high</severeness>
+    </assertProductAttributeIsConfigurable>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
index 31297e06bdc..272bc300d5a 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
@@ -61,6 +61,13 @@ class Messages extends Block
      */
     protected $noticeMessage = '[data-ui-id$=message-notice]';
 
+    /**
+     * Warning message selector.
+     *
+     * @var string
+     */
+    protected $warningMessage = '[data-ui-id$=message-warning]';
+
     /**
      * Check for success message
      *
@@ -179,4 +186,15 @@ class Messages extends Block
         $this->waitForElementVisible($this->noticeMessage);
         return $this->_rootElement->find($this->noticeMessage)->getText();
     }
+
+    /**
+     * Get warning message which is present on the page
+     *
+     * @return string
+     */
+    public function getWarningMessages()
+    {
+        $this->waitForElementVisible($this->warningMessage);
+        return $this->_rootElement->find($this->warningMessage)->getText();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php
index e844c3e1d1c..fa2ef9a0f08 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertCustomVariableInPage.php
@@ -69,19 +69,22 @@ class AssertCustomVariableInPage extends AbstractConstraint
             'cmsPage',
             [
                 'dataSet' => 'default',
-                'data' => ['content' => '{{customVar code=' . $customVariable->getCode() . '}}'],
+                'data' => [
+                    'content' => [
+                        'content' => '{{customVar code=' . $customVariable->getCode() . '}}'
+                    ]
+                ],
             ]
         );
         $cmsPage->persist();
-        $url = $_ENV['app_frontend_url'] . $cmsPage->getIdentifier();
-        $browser->open($url);
+        $browser->open($_ENV['app_frontend_url'] . $cmsPage->getIdentifier());
 
         $cmsIndex->getStoreSwitcherBlock()->selectStoreView('Default Store View');
 
-        $htmlValue = ($customVariableOrigin !== null)
+        $htmlValue = $customVariableOrigin
             ? $this->getHtmlValue($customVariable, $customVariableOrigin)
             : strip_tags($customVariable->getHtmlValue());
-        $pageContent = $cmsIndex->getMainContentBlock()->getPageContent();
+        $pageContent = $cmsIndex->getCmsPageBlock()->getPageContent();
         $this->checkVariable($htmlValue, $pageContent);
 
         if ($storeOrigin !== null) {
@@ -90,7 +93,7 @@ class AssertCustomVariableInPage extends AbstractConstraint
             if ($htmlValue === '') {
                 $htmlValue = strip_tags($variable->getHtmlValue());
             }
-            $pageContent = $cmsIndex->getMainContentBlock()->getPageContent();
+            $pageContent = $cmsIndex->getCmsPageBlock()->getPageContent();
             $this->checkVariable($htmlValue, $pageContent);
         }
     }
@@ -134,7 +137,6 @@ class AssertCustomVariableInPage extends AbstractConstraint
             . "\nExpected: " . $htmlValue
             . "\nActual: " . $pageContent
         );
-
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php
index 1bc24e83d56..31841881598 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/UpdateCustomVariableEntityTest.php
@@ -153,6 +153,6 @@ class UpdateCustomVariableEntityTest extends Injectable
         $storeNew->getFormPageActions()->delete();
         $storeDelete = ObjectManager::getInstance()->create('Magento\Backend\Test\Page\Adminhtml\StoreDelete');
         $storeDelete->getStoreForm()->fillForm(['create_backup' => 'No']);
-        $storeDelete->getFormPageActions()->delete();
+        $storeDelete->getFormPageFooterActions()->delete();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php
index 118acfc34e7..ba8c863d01e 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php
@@ -114,7 +114,6 @@ class CustomerInjectable extends AbstractRepository
             'password_confirmation' => '123123q',
         ];
 
-
         $this->_data['johndoe_unique'] = [
             'firstname' => 'John',
             'lastname' => 'Doe%isolation%',
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php
new file mode 100644
index 00000000000..1e23a248d8f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php
@@ -0,0 +1,97 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\TestStep;
+
+use Mtf\TestStep\TestStepInterface;
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Customer\Test\Page\CustomerAccountLogin;
+use Magento\Customer\Test\Page\CustomerAccountLogout;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+
+/**
+ * Class LoginCustomerOnFrontendStep
+ * Login customer on frontend
+ */
+class LoginCustomerOnFrontendStep implements TestStepInterface
+{
+    /**
+     * Customer fixture
+     *
+     * @var CustomerInjectable
+     */
+    protected $customer;
+
+    /**
+     * Cms index page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Customer login page
+     *
+     * @var CustomerAccountLogin
+     */
+    protected $customerAccountLogin;
+
+    /**
+     * Customer account logout page
+     *
+     * @var CustomerAccountLogout
+     */
+    protected $customerAccountLogout;
+
+    /**
+     * @constructor
+     * @param CmsIndex $cmsIndex
+     * @param CustomerAccountLogin $customerAccountLogin
+     * @param CustomerAccountLogout $customerAccountLogout
+     * @param CustomerInjectable $customer
+     */
+    public function __construct(
+        CmsIndex $cmsIndex,
+        CustomerAccountLogin $customerAccountLogin,
+        CustomerAccountLogout $customerAccountLogout,
+        CustomerInjectable $customer
+    ) {
+        $this->cmsIndex = $cmsIndex;
+        $this->customerAccountLogin = $customerAccountLogin;
+        $this->customer = $customer;
+        $this->customerAccountLogout = $customerAccountLogout;
+    }
+
+    /**
+     * Login customer
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $this->customerAccountLogout->open();
+        $this->cmsIndex->getLinksBlock()->openLink("Log In");
+        $this->customerAccountLogin->getLoginBlock()->login($this->customer);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php
index bd751951e37..51ec5ea134d 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php
@@ -46,7 +46,7 @@ class View extends \Magento\Catalog\Test\Block\Product\View
      *
      * @var string
      */
-    protected $blockDownloadableSamples = '.downloadable.samples';
+    protected $blockDownloadableSamples = '.items.samples';
 
     /**
      * Get downloadable link block
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php
index 30855d14874..d622b3b91e4 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php
@@ -82,7 +82,7 @@ class Links extends Block
      *
      * @var string
      */
-    protected $priceForChoice = '.price-wrapper .price';
+    protected $priceForChoice = '.price-wrapper';
 
     /**
      * Checkbox selector item links
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php
index 8719348b063..b7594d5aad4 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php
@@ -38,14 +38,14 @@ class Samples extends Block
      *
      * @var string
      */
-    protected $titleBlock = '.samples.title';
+    protected $titleBlock = '.item-title';
 
     /**
      * Title selector item sample link
      *
      * @var string
      */
-    protected $linkTitle = '.sample.link';
+    protected $linkTitle = '.item-link';
 
     /**
      * Get title for Samples block
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php
index 498f67d092f..e0f8329ef5b 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php
@@ -79,7 +79,9 @@ class AssertDownloadableSamplesData extends AbstractAssertForm
 
         $fixtureSampleLinks = $this->prepareFixtureData($product);
         $pageOptions = $productView->getViewBlock()->getOptions($product);
-        $pageSampleLinks = $this->preparePageData($pageOptions['downloadable_options']['downloadable_sample']);
+        $pageSampleLinks = isset($pageOptions['downloadable_options']['downloadable_sample'])
+            ? $this->preparePageData($pageOptions['downloadable_options']['downloadable_sample'])
+            : [];
         $error = $this->verifyData($fixtureSampleLinks, $pageSampleLinks);
         \PHPUnit_Framework_Assert::assertEmpty($error, $error);
     }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.php
index f9c8e601043..d137958d3de 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.php
@@ -319,14 +319,6 @@ class DownloadableProductInjectable extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $msrp_enabled = [
-        'attribute_code' => 'msrp_enabled',
-        'backend_type' => 'varchar',
-        'is_required' => '0',
-        'default_value' => '2',
-        'input' => 'select',
-    ];
-
     protected $name = [
         'attribute_code' => 'name',
         'backend_type' => 'varchar',
@@ -781,11 +773,6 @@ class DownloadableProductInjectable extends InjectableFixture
         return $this->getData('msrp_display_actual_price_type');
     }
 
-    public function getMsrpEnabled()
-    {
-        return $this->getData('msrp_enabled');
-    }
-
     public function getName()
     {
         return $this->getData('name');
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.xml
index a67f158eca5..f95a61f5379 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProductInjectable.xml
@@ -209,13 +209,6 @@
             <default_value>4</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
-        <msrp_enabled>
-            <attribute_code>msrp_enabled</attribute_code>
-            <backend_type>varchar</backend_type>
-            <is_required>0</is_required>
-            <default_value>2</default_value>
-            <input>select</input>
-        </msrp_enabled>
         <name>
             <attribute_code>name</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest.php
new file mode 100644
index 00000000000..65e4c5d94ea
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest.php
@@ -0,0 +1,51 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\TestCase;
+
+use Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest as AddProductsToCartFromWishlist;
+
+/**
+ * Test Creation for Adding Downloadable product from Wishlist to Cart
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer and login to frontend
+ * 2. Downloadable product is created
+ * 3. Add downloadable product to customer's wishlist
+ *
+ * Steps:
+ * 1. Navigate to My Account -> My Wishlist
+ * 2. Fill qty and update wish list
+ * 3. Click "Add to Cart"
+ * 4. Perform asserts
+ *
+ * @group Wishlist_(CS)
+ * @ZephyrId MAGETWO-25268
+ */
+class AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest extends AddProductsToCartFromWishlist
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest/test.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
new file mode 100644
index 00000000000..1f973a746f8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/AddDownloadableProductToCartFromCustomerWishlistOnFrontendTest/test.csv
@@ -0,0 +1,2 @@
+"products";"qty";"constraint"
+"downloadableProductInjectable::with_two_separately_links";"2";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
index bdb8d901464..9e6d75508a7 100755
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
@@ -1,4 +1,4 @@
-"product/data/name";"product/data/sku";"product/data/price/value";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/is_virtual";"product/data/category";"product/data/description";"product/data/short_description";"product/data/stock_data/manage_stock";"product/data/stock_data/qty";"product/data/stock_data/use_config_min_qty";"product/data/stock_data/min_qty";"product/data/downloadable_sample/preset";"product/data/downloadable_links/preset";"product/data/custom_options/preset";"product/data/custom_options/import_products";"product/data/special_price";"product/data/group_price/preset";"product/data/tier_price/preset";"constraint";
+"product/data/name";"product/data/sku";"product/data/price/value";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/is_virtual";"product/data/category";"product/data/description";"product/data/short_description";"product/data/stock_data/manage_stock";"product/data/stock_data/qty";"product/data/stock_data/use_config_min_qty";"product/data/stock_data/min_qty";"product/data/downloadable_sample/preset";"product/data/downloadable_links/preset";"product/data/custom_options/preset";"product/data/custom_options/import_products";"product/data/special_price";"product/data/group_price/preset";"product/data/tier_price/preset";"constraint"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"100";"Taxable Goods";"1";"In Stock";"Yes";"Default Category";"-";"-";"-";"-";"-";"-";"-";"default";"-";"-";"-";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertProductInStock"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"1";"Taxable Goods";"10";"In Stock";"Yes";"category %isolation%";"-";"-";"-";"-";"-";"-";"default";"default";"-";"-";"-";"-";"-";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertDownloadableSamplesData, assertDownloadableLinksData"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"33";"Taxable Goods";"10";"In Stock";"Yes";"category %isolation%";"-";"-";"-";"-";"-";"-";"-";"default";"default";"-";"-";"-";"-";"assertProductSaveMessage, assertDownloadableProductForm, assertProductCustomOptionsOnProductPage, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData"
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
index ea82808e17c..774c3fa7be8 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Block/Checkout/Cart/CartItem.php
@@ -121,4 +121,18 @@ class CartItem extends AbstractCartItem
 
         return $result;
     }
+
+    /**
+     * Remove associated products items from cart
+     *
+     * @return void
+     */
+    public function removeItem()
+    {
+        foreach ($this->config['associated_cart_items'] as $cartItem) {
+            /** @var CheckoutCartItem $cartItem */
+            $cartItem->reinitRootElement();
+            $cartItem->removeItem();
+        }
+    }
 }
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Enabled.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest.php
similarity index 57%
rename from app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Enabled.php
rename to dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest.php
index 3963743d5f6..5c48aa0bae3 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Msrp/Enabled.php
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest.php
@@ -22,25 +22,30 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\GroupedProduct\Test\TestCase;
+
+use Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest as AddProductsToCartFromWishlist;
+
 /**
- * Product form MAP Enabled field helper
+ * Test Creation for Adding Grouped product from Wishlist to Cart
+ *
+ * Test Flow:
  *
- * @author     Magento Core Team <core@magentocommerce.com>
+ * Preconditions:
+ * 1. Create customer and login to frontend
+ * 2. Grouped product is created
+ * 3. Add grouped product to customer's wishlist
+ *
+ * Steps:
+ * 1. Navigate to My Account -> My Wishlist
+ * 2. Fill qty and update wish list
+ * 3. Click "Add to Cart"
+ * 4. Perform asserts
+ *
+ * @group Wishlist_(CS)
+ * @ZephyrId MAGETWO-25268
  */
-namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Msrp;
-
-class Enabled extends \Magento\Framework\Data\Form\Element\Select
+class AddGroupedProductToCartFromCustomerWishlistOnFrontendTest extends AddProductsToCartFromWishlist
 {
-    /**
-     * Retrieve Element HTML fragment
-     *
-     * @return string
-     */
-    public function getElementHtml()
-    {
-        if (is_null($this->getValue())) {
-            $this->setValue(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_USE_CONFIG);
-        }
-        return parent::getElementHtml();
-    }
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest/test.csv b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest/test.csv
new file mode 100644
index 00000000000..304ff5bc9fe
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/AddGroupedProductToCartFromCustomerWishlistOnFrontendTest/test.csv
@@ -0,0 +1,2 @@
+"products";"qty";"constraint"
+"groupedProductInjectable::three_simple_products";"-";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
diff --git a/dev/tests/functional/tests/app/Magento/Index/Test/Page/ProcessList.php b/dev/tests/functional/tests/app/Magento/Index/Test/Page/ProcessList.php
deleted file mode 100644
index 8c33f707ee1..00000000000
--- a/dev/tests/functional/tests/app/Magento/Index/Test/Page/ProcessList.php
+++ /dev/null
@@ -1,89 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Index\Test\Page;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class ProcessList
- * Index Management page
- *
- */
-class ProcessList extends Page
-{
-    /**
-     * URL part for index process page
-     */
-    const MCA = 'admin/process/list/';
-
-
-    /**
-     * Index management grid
-     *
-     * @var string
-     */
-    protected $indexProcessGrid = '#indexer_processes_grid';
-
-    /**
-     * Global messages block
-     *
-     * @var string
-     */
-    protected $messagesBlock = '#messages .messages';
-
-    /**
-     * Constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Get index grid block
-     *
-     * @return \Magento\Index\Test\Block\Adminhtml\Process\Index
-     */
-    public function getActionsBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoIndexAdminhtmlProcessIndex(
-            $this->_browser->find($this->indexProcessGrid, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Filter.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/AbstractFilter.php
similarity index 52%
rename from dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Filter.php
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/AbstractFilter.php
index 6358623e206..999dc3888e5 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Filter.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/AbstractFilter.php
@@ -22,29 +22,30 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Reports\Test\Block\Adminhtml\Product\Viewed;
+namespace Magento\Reports\Test\Block\Adminhtml;
 
 use Mtf\Block\Form;
 use Mtf\ObjectManager;
 
 /**
- * Class Filter
- * Filter for Product Views Report
+ * Abstract Class Filter
+ * Filter for Report
  */
-class Filter extends Form
+abstract class AbstractFilter extends Form
 {
     /**
-     * Search products in report grid
+     * Date fields
      *
-     * @var array $productsReport
-     * @return void
+     * @var array
      */
-    public function viewsReport(array $viewsReport)
-    {
-        $viewsReport = $this->prepareData($viewsReport);
-        $data = $this->dataMapping($viewsReport);
-        $this->_fill($data);
-    }
+    protected $dateFields = ['from', 'to'];
+
+    /**
+     * Refresh button css selector
+     *
+     * @var string
+     */
+    protected $refresh = '[data-ui-id="adminhtml-report-grid-refresh-button"]';
 
     /**
      * Prepare data
@@ -54,16 +55,38 @@ class Filter extends Form
      */
     protected function prepareData(array $viewsReport)
     {
-        foreach ($viewsReport as $name => $reportFilter) {
-            if ($name === 'period_type' || $name === 'show_empty_rows') {
-                continue;
+        foreach ($viewsReport as $key => $reportFilter) {
+            if (in_array($key, $this->dateFields)) {
+                $date = ObjectManager::getInstance()->create(
+                    '\Magento\Backend\Test\Fixture\Date',
+                    ['params' => [], 'data' => ['pattern' => $reportFilter]]
+                );
+                $viewsReport[$key] = $date->getData();
             }
-            $date = ObjectManager::getInstance()->create(
-                '\Magento\Backend\Test\Fixture\Date',
-                ['params' => [], 'data' => ['pattern' => $reportFilter]]
-            );
-            $viewsReport[$name] = $date->getData();
         }
         return $viewsReport;
     }
+
+    /**
+     * Search entity in report grid
+     *
+     * @var array $report
+     * @return void
+     */
+    public function viewsReport(array $report)
+    {
+        $report = $this->prepareData($report);
+        $data = $this->dataMapping($report);
+        $this->_fill($data);
+    }
+
+    /**
+     * Click refresh filter button
+     *
+     * @return void
+     */
+    public function refreshFilter()
+    {
+        $this->_rootElement->find($this->refresh)->click();
+    }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.php
similarity index 74%
rename from app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.php
index c9288d01e6e..ae00eb9357b 100644
--- a/app/code/Magento/CatalogUrlRewrite/Service/V1/CategoryUrlGeneratorInterface.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.php
@@ -21,18 +21,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CatalogUrlRewrite\Service\V1;
+
+namespace Magento\Reports\Test\Block\Adminhtml\Customer\Counts;
+
+use Mtf\ObjectManager;
+use Magento\Reports\Test\Block\Adminhtml\AbstractFilter;
 
 /**
- * Product Generator
+ * Class Filter
+ * Filter for Order count Report
  */
-interface CategoryUrlGeneratorInterface
+class Filter extends AbstractFilter
 {
     /**
-     * Generate list of urls
+     * Date fields
      *
-     * @param \Magento\Catalog\Model\Category $category
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
+     * @var array
      */
-    public function generate($category);
+    protected $dateFields = ['report_from', 'report_to'];
 }
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.xml
new file mode 100644
index 00000000000..2c5357b6a1e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Filter.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <report_from>
+            <input>datepicker</input>
+        </report_from>
+        <report_to>
+            <input>datepicker</input>
+        </report_to>
+        <report_period>
+            <input>select</input>
+        </report_period>
+    </fields>
+</mapping>
diff --git a/app/code/Magento/Rss/Controller/Catalog/Category.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Grid.php
similarity index 80%
rename from app/code/Magento/Rss/Controller/Catalog/Category.php
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Grid.php
index 28cc586d36f..50d4670dc10 100644
--- a/app/code/Magento/Rss/Controller/Catalog/Category.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Counts/Grid.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,15 +21,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Catalog;
 
-class Category extends \Magento\Rss\Controller\Catalog
+namespace Magento\Reports\Test\Block\Adminhtml\Customer\Counts;
+
+use Mtf\Client\Element;
+
+/**
+ * Class Grid
+ * Order count report grid
+ */
+class Grid extends \Magento\Reports\Test\Block\Adminhtml\Customer\Totals\Grid
 {
-    /**
-     * @return void
-     */
-    public function execute()
-    {
-        $this->_genericAction('category');
-    }
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.php
new file mode 100644
index 00000000000..6f0cc04f910
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.php
@@ -0,0 +1,42 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Block\Adminhtml\Customer\Totals;
+
+use Mtf\ObjectManager;
+use Magento\Reports\Test\Block\Adminhtml\AbstractFilter;
+
+/**
+ * Class Filter
+ * Filter for Order Total Report
+ */
+class Filter extends AbstractFilter
+{
+    /**
+     * Date fields
+     *
+     * @var array
+     */
+    protected $dateFields = ['report_from', 'report_to'];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.xml
new file mode 100644
index 00000000000..2c5357b6a1e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Filter.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <report_from>
+            <input>datepicker</input>
+        </report_from>
+        <report_to>
+            <input>datepicker</input>
+        </report_to>
+        <report_period>
+            <input>select</input>
+        </report_period>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Grid.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Grid.php
new file mode 100644
index 00000000000..74f5e075054
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Customer/Totals/Grid.php
@@ -0,0 +1,102 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Block\Adminhtml\Customer\Totals;
+
+use Mtf\Client\Element;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Class Grid
+ * Order total report grid
+ */
+class Grid extends \Magento\Backend\Test\Block\Widget\Grid
+{
+    /**
+     * Preceding sibling
+     *
+     * @var string
+     */
+    protected $preceding = 'tr[contains(@class,"pointer") and *[contains(@class,"col-period") and contains(.,"%s")]]';
+
+    /**
+     * Following sibling
+     *
+     * @var string
+     */
+    protected $following = 'tr[contains(@class,"pointer")]';
+
+    /**
+     * Current pointer
+     *
+     * @var string
+     */
+    protected $date = 'td[contains(@class,"col-period") and contains(.,"%s")]';
+
+    /**
+     * Filters array mapping
+     *
+     * @var array
+     */
+    protected $filters = [
+        'customer' => [
+            'selector' => 'td[contains(@class,"col-name") and normalize-space(.)="%s"]',
+        ],
+        'orders' => [
+            'selector' => 'td[contains(@class,"col-orders_count") and normalize-space(.)="%s"]',
+        ],
+        'average' => [
+            'selector' => 'td[contains(@class,"col-average") and contains(.,"%s")]',
+        ],
+        'total' => [
+            'selector' => 'td[contains(@class,"col-total") and contains(.,"%s")]',
+        ],
+    ];
+
+    /**
+     * Obtain specific row in grid
+     *
+     * @param array $filter
+     * @param bool $isSearchable
+     * @param bool $isStrict
+     * @return Element
+     */
+    protected function getRow(array $filter, $isSearchable = true, $isStrict = true)
+    {
+        $this->date = sprintf($this->date, $filter['date']);
+        $location = '//div[@class="grid"]//tr[((preceding-sibling::' . sprintf($this->preceding, $filter['date'])
+            . ' and following-sibling::' . $this->following . ') or ' . $this->date . ') and ';
+        unset($filter['date']);
+        $rows = [];
+        foreach ($filter as $key => $value) {
+            $rows[] = sprintf($this->filters[$key]['selector'], $value);
+        }
+        $location = $location . implode(' and ', $rows) . ']';
+        if (!$this->_rootElement->find($location, Locator::SELECTOR_XPATH)->isVisible()) {
+            $location = str_replace($this->following, 'tr[last()]', $location);
+            $location = str_replace($this->date, $this->date . ' or last()', $location);
+        }
+        return $this->_rootElement->find($location, Locator::SELECTOR_XPATH);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Action.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Action.php
similarity index 95%
rename from dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Action.php
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Action.php
index 08d497acfc1..bccabb9ab18 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Action.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Action.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Reports\Test\Block\Adminhtml\Product\Viewed;
+namespace Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed;
 
 use Magento\Backend\Test\Block\GridPageActions;
 
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.php
new file mode 100644
index 00000000000..60382368756
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.php
@@ -0,0 +1,36 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed;
+
+use Magento\Reports\Test\Block\Adminhtml\AbstractFilter;
+
+/**
+ * Class Filter
+ * Filter for Product Views Report
+ */
+class Filter extends AbstractFilter
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.xml
similarity index 100%
rename from dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/Filter.xml
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/Filter.xml
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/ProductGrid.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/ProductGrid.php
similarity index 80%
rename from dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/ProductGrid.php
rename to dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/ProductGrid.php
index 43c2bebd7e4..6e5c59abd47 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Viewed/ProductGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Review/Products/Viewed/ProductGrid.php
@@ -22,10 +22,10 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Reports\Test\Block\Adminhtml\Product\Viewed;
+namespace Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed;
 
-use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\Grid;
+use Mtf\Client\Element\Locator;
 
 /**
  * Class ProductGrid
@@ -51,21 +51,12 @@ class ProductGrid extends Grid
      * Get views Results from Products Report grid
      *
      * @param array $products
-     * @param string $date
      * @return array
      */
-    public function getViewsResults(array $products, $date = '')
+    public function getViewsResults(array $products)
     {
         $views = [];
-        $date = date($date);
-        if ($date) {
-            $text = $this->_rootElement->getText();
-            preg_match("`$date([^\n]*\n){1,5}`", $text, $match);
-        }
         foreach ($products as $product) {
-            if (isset($match[0]) && !strstr($match[0], $product->getName())) {
-                continue;
-            }
             $productLocator = sprintf($this->product . $this->productView, $product->getName(), $product->getPrice());
             $views[] = $this->_rootElement->find($productLocator, Locator::SELECTOR_XPATH)->getText();
         }
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.php
index 1e6594dd135..8b5af42a138 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.php
@@ -24,48 +24,14 @@
 
 namespace Magento\Reports\Test\Block\Adminhtml\Sales\Coupons;
 
-use Mtf\Block\Form;
 use Mtf\ObjectManager;
+use Magento\Reports\Test\Block\Adminhtml\AbstractFilter;
 
 /**
  * Class Filter
  * Filter for Coupons Views Report
  */
-class Filter extends Form
+class Filter extends AbstractFilter
 {
-    /**
-     * Search coupons in report grid
-     *
-     * @var array $productsReport
-     * @return void
-     */
-    public function viewsReport(array $viewsReport)
-    {
-        $viewsReport = $this->prepareData($viewsReport);
-        $data = $this->dataMapping($viewsReport);
-        $this->_fill($data);
-    }
-
-    /**
-     * Prepare data
-     *
-     * @param array $viewsReport
-     * @return array
-     */
-    protected function prepareData(array $viewsReport)
-    {
-        foreach ($viewsReport as $name => $reportFilter) {
-            if ($reportFilter == '-') {
-                unset($viewsReport[$name]);
-            }
-            if ($name === 'from' || $name === 'to') {
-                $date = ObjectManager::getInstance()->create(
-                    '\Magento\Backend\Test\Fixture\Date',
-                    ['params' => [], 'data' => ['pattern' => $reportFilter]]
-                );
-                $viewsReport[$name] = $date->getData();
-            }
-        }
-        return $viewsReport;
-    }
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Shopcart/Abandoned/Grid.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Shopcart/Abandoned/Grid.php
new file mode 100644
index 00000000000..85acf8ac55a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Shopcart/Abandoned/Grid.php
@@ -0,0 +1,60 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Block\Adminhtml\Shopcart\Abandoned;
+
+/**
+ * Class Grid
+ * Abandoned Carts Report grid
+ */
+class Grid extends \Magento\Backend\Test\Block\Widget\Grid
+{
+    /**
+     * Filters array mapping
+     *
+     * @var array
+     */
+    protected $filters = [
+        'customer_name' => [
+            'selector' => 'input[name="customer_name"]',
+        ],
+        'email' => [
+            'selector' => 'input[name="email"]',
+        ],
+        'items_count' => [
+            'selector' => 'input[name="items_count[from]"]',
+        ],
+        'items_qty' => [
+            'selector' => 'input[name="items_qty[from]"]',
+        ],
+        'created_at' => [
+            'selector' => 'input[name="created_at[from]"]',
+            'input' => 'datepicker'
+        ],
+        'updated_at' => [
+            'selector' => 'input[name="updated_at[from]"]',
+            'input' => 'datepicker'
+        ],
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AbstractAssertCustomerOrderReportResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AbstractAssertCustomerOrderReportResult.php
new file mode 100644
index 00000000000..65223f60c61
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AbstractAssertCustomerOrderReportResult.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+
+/**
+ * Class AbstractAssertCustomerOrderReportResult
+ * Check Order report grid for all params
+ */
+abstract class AbstractAssertCustomerOrderReportResult extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Prepare filter
+     *
+     * @param CustomerInjectable $customer
+     * @param array $columns
+     * @param array $report
+     * @return array
+     */
+    public function prepareFilter(CustomerInjectable $customer, array $columns, array $report)
+    {
+        $format = '';
+        switch ($report['report_period']) {
+            case 'Day':
+                $format = 'M j, Y';
+                break;
+            case 'Month':
+                $format = 'j/Y';
+                break;
+            case 'Year':
+                $format = 'Y';
+                break;
+        }
+
+        return [
+            'date' => date($format),
+            'customer' => $customer->getFirstname() . ' ' . $customer->getLastname(),
+            'orders' => $columns['orders'],
+            'average' => number_format($columns['average'], 2),
+            'total' => number_format($columns['total'], 2)
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertAbandonedCartCustomerInfoResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertAbandonedCartCustomerInfoResult.php
new file mode 100644
index 00000000000..4c7787a3421
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertAbandonedCartCustomerInfoResult.php
@@ -0,0 +1,89 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Reports\Test\Page\Adminhtml\AbandonedCarts;
+
+/**
+ * Class AssertAbandonedCartCustomerInfoResult
+ * Assert customer info in Abandoned Carts report
+ */
+class AssertAbandonedCartCustomerInfoResult extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert customer info in Abandoned Carts report (Reports > Abandoned carts):
+     * – name and email
+     * – products and qty
+     * – created and updated date
+     *
+     * @param AbandonedCarts $abandonedCarts
+     * @param array $products
+     * @param CustomerInjectable $customer
+     * @return void
+     */
+    public function processAssert(AbandonedCarts $abandonedCarts, $products, CustomerInjectable $customer)
+    {
+        $abandonedCarts->open();
+        $qty = 0;
+        foreach ($products as $product) {
+            $qty += $product->getCheckoutData()['options']['qty'];
+        }
+        $filter = [
+            'customer_name' => $customer->getFirstname() . " " . $customer->getLastname(),
+            'email' => $customer->getEmail(),
+            'items_count' => count($products),
+            'items_qty' => $qty,
+            'created_at' => date('m/j/Y'),
+            'updated_at' => date('m/j/Y')
+        ];
+        $abandonedCarts->getGridBlock()->search($filter);
+        $filter['created_at'] = date('M j, Y');
+        $filter['updated_at'] = date('M j, Y');
+        \PHPUnit_Framework_Assert::assertTrue(
+            $abandonedCarts->getGridBlock()->isRowVisible($filter, false, false),
+            'Expected customer info is absent in Abandoned Carts report grid.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer info in Abandoned Carts report grid is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderCountReportResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderCountReportResult.php
new file mode 100644
index 00000000000..0a3fce637e4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderCountReportResult.php
@@ -0,0 +1,75 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Constraint;
+
+use Magento\Reports\Test\Page\Adminhtml\CustomerOrdersReport;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+
+/**
+ * Class AssertCustomerOrderCountReportResult
+ * Assert OrderCountReport grid for all params
+ */
+class AssertCustomerOrderCountReportResult extends AbstractAssertCustomerOrderReportResult
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert OrderCountReport grid for all params
+     *
+     * @param CustomerOrdersReport $customerOrdersReport
+     * @param CustomerInjectable $customer
+     * @param array $columns
+     * @param array $report
+     * @return void
+     */
+    public function processAssert(
+        CustomerOrdersReport $customerOrdersReport,
+        CustomerInjectable $customer,
+        array $columns,
+        array $report
+    ) {
+        $filter = $this->prepareFilter($customer, $columns, $report);
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $customerOrdersReport->getGridBlock()->isRowVisible($filter),
+            'Order does not present in count grid.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Order count is present in count grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderTotalReportResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderTotalReportResult.php
new file mode 100644
index 00000000000..e9942b965ca
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertCustomerOrderTotalReportResult.php
@@ -0,0 +1,75 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\Constraint;
+
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Reports\Test\Page\Adminhtml\CustomerTotalsReport;
+
+/**
+ * Class AssertCustomerOrderTotalReportResult
+ * Assert OrderTotalReport grid for all params
+ */
+class AssertCustomerOrderTotalReportResult extends AbstractAssertCustomerOrderReportResult
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert OrderTotalReport grid for all params
+     *
+     * @param CustomerTotalsReport $customerTotalsReport
+     * @param CustomerInjectable $customer
+     * @param array $columns
+     * @param array $report
+     * @return void
+     */
+    public function processAssert(
+        CustomerTotalsReport $customerTotalsReport,
+        CustomerInjectable $customer,
+        array $columns,
+        array $report
+    ) {
+        $filter = $this->prepareFilter($customer, $columns, $report);
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $customerTotalsReport->getGridBlock()->isRowVisible($filter),
+            'Order does not present in report grid.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Order total is present in reports grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/AbandonedCarts.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/AbandonedCarts.xml
new file mode 100644
index 00000000000..44cd625632a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/AbandonedCarts.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="reports/report_shopcart/abandoned" module="Magento_Reports">
+    <blocks>
+        <gridBlock>
+            <class>Magento\Reports\Test\Block\Adminhtml\Shopcart\Abandoned\Grid</class>
+            <locator>#gridAbandoned</locator>
+            <strategy>css selector</strategy>
+        </gridBlock>
+    </blocks>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/Bestsellers.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/Bestsellers.xml
deleted file mode 100644
index 60c537110ec..00000000000
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/Bestsellers.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<page mca="reports/report_sales/bestsellers" module="Magento_Reports">
-    <blocks>
-        <messagesBlock>
-            <class>Magento\Core\Test\Block\Messages</class>
-            <locator>#messages .messages</locator>
-            <strategy>css selector</strategy>
-        </messagesBlock>
-        <actionsBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\Action</class>
-            <locator>.page-main-actions</locator>
-            <strategy>css selector</strategy>
-        </actionsBlock>
-        <filterBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\Filter</class>
-            <locator>#filter_form</locator>
-            <strategy>css selector</strategy>
-        </filterBlock>
-        <gridBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\ProductGrid</class>
-            <locator>.grid</locator>
-            <strategy>css selector</strategy>
-        </gridBlock>
-    </blocks>
-</page>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerOrdersReport.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerOrdersReport.xml
new file mode 100644
index 00000000000..535f644cfaa
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerOrdersReport.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="reports/report_customer/orders" module="Magento_Reports">
+    <blocks>
+        <filterBlock>
+            <class>Magento\Reports\Test\Block\Adminhtml\Customer\Counts\Filter</class>
+            <locator>#gridOrdersCustomer_period_date_range</locator>
+            <strategy>css selector</strategy>
+        </filterBlock>
+        <gridBlock>
+            <class>Magento\Reports\Test\Block\Adminhtml\Customer\Counts\Grid</class>
+            <locator>#gridOrdersCustomer_table</locator>
+            <strategy>css selector</strategy>
+        </gridBlock>
+    </blocks>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerTotalsReport.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerTotalsReport.xml
new file mode 100644
index 00000000000..65e6d0ef201
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/CustomerTotalsReport.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="reports/report_customer/totals" module="Magento_Reports">
+    <blocks>
+        <filterBlock>
+            <class>Magento\Reports\Test\Block\Adminhtml\Customer\Totals\Filter</class>
+            <locator>#gridTotalsCustomer_period_date_range</locator>
+            <strategy>css selector</strategy>
+        </filterBlock>
+        <gridBlock>
+            <class>Magento\Reports\Test\Block\Adminhtml\Customer\Totals\Grid</class>
+            <locator>#gridTotalsCustomer_table</locator>
+            <strategy>css selector</strategy>
+        </gridBlock>
+    </blocks>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/ProductReportView.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/ProductReportView.xml
index fc2df3729db..32c82d39a3a 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/ProductReportView.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/ProductReportView.xml
@@ -26,17 +26,17 @@
 <page mca="reports/report_product/viewed/" module="Magento_Reports">
     <blocks>
         <actionsBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\Action</class>
+            <class>Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed\Action</class>
             <locator>.page-main-actions</locator>
             <strategy>css selector</strategy>
         </actionsBlock>
         <gridBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\ProductGrid</class>
+            <class>Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed\ProductGrid</class>
             <locator>.grid</locator>
             <strategy>css selector</strategy>
         </gridBlock>
         <filterBlock>
-            <class>Magento\Reports\Test\Block\Adminhtml\Product\Viewed\Filter</class>
+            <class>Magento\Reports\Test\Block\Adminhtml\Review\Products\Viewed\Filter</class>
             <locator>#filter_form</locator>
             <strategy>css selector</strategy>
         </filterBlock>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
new file mode 100644
index 00000000000..0bcee8ecb6e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php
@@ -0,0 +1,170 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\TestCase;
+
+use Mtf\Client\Browser;
+use Mtf\TestCase\Injectable;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Customer\Test\Page\CustomerAccountLogin;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Test Creation for AbandonedCartsReportEntity
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create simple product
+ * 2. Create customer
+ * 3. Go to frontend
+ * 4. Login as customer
+ * 5. Add simple product to cart
+ * 6. Logout
+ *
+ * Steps:
+ * 1. Open Backend
+ * 2. Go to Reports > Abandoned Carts
+ * 3. Click "Reset Filter"
+ * 4. Perform all assertions
+ *
+ * @group Reports_(MX)
+ * @ZephyrId MAGETWO-28558
+ */
+class AbandonedCartsReportEntityTest extends Injectable
+{
+    /**
+     * Cms Index page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Customer Account Login page
+     *
+     * @var CustomerAccountLogin
+     */
+    protected $customerAccountLogin;
+
+    /**
+     * Catalog Product View page
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Browser interface
+     *
+     * @var Browser
+     */
+    protected $browser;
+
+    /**
+     * Fixture factory
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Inject pages
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CustomerAccountLogin $customerAccountLogin
+     * @param Browser $browser
+     * @param FixtureFactory $fixtureFactory
+     * @param CatalogProductView $catalogProductView
+     * @return void
+     */
+    public function __inject(
+        CmsIndex $cmsIndex,
+        CustomerAccountLogin $customerAccountLogin,
+        Browser $browser,
+        FixtureFactory $fixtureFactory,
+        CatalogProductView $catalogProductView
+    ) {
+        $this->cmsIndex = $cmsIndex;
+        $this->customerAccountLogin = $customerAccountLogin;
+        $this->browser = $browser;
+        $this->catalogProductView = $catalogProductView;
+        $this->fixtureFactory = $fixtureFactory;
+    }
+
+    /**
+     * Create product and add it to cart
+     *
+     * @param string $products
+     * @param CustomerInjectable $customer
+     * @return array
+     */
+    public function test($products, CustomerInjectable $customer)
+    {
+        // Precondition
+        $products = $this->createProducts($products);
+        $customer->persist();
+        $this->cmsIndex->open();
+        $this->cmsIndex->getLinksBlock()->openLink("Log In");
+        $this->customerAccountLogin->getLoginBlock()->login($customer);
+        $this->addProductsToCart($products);
+        $this->cmsIndex->getLinksBlock()->openLink("Log Out");
+
+        return ['products' => $products];
+    }
+
+    /**
+     * Create products
+     *
+     * @param string $products
+     * @return array
+     */
+    protected function createProducts($products)
+    {
+        $createProductsStep = $this->objectManager->create(
+            'Magento\Catalog\Test\TestStep\CreateProductsStep',
+            ['products' => $products]
+        );
+
+        return $createProductsStep->run()['products'];
+    }
+
+    /**
+     * Add products to cart
+     *
+     * @param array $products
+     * @return void
+     */
+    protected function addProductsToCart(array $products)
+    {
+        $addProductsToCart = $this->objectManager->create(
+            'Magento\Checkout\Test\TestStep\AddProductsToTheCartStep',
+            ['products' => $products]
+        );
+        $addProductsToCart->run();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest/test.csv
new file mode 100644
index 00000000000..2c61b4ec2b3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest/test.csv
@@ -0,0 +1,3 @@
+"description";"customer/dataSet";"products";"constraint"
+"add product to cart as registered user and check product in Report";"default";"catalogProductSimple::100_dollar_product";"assertAbandonedCartCustomerInfoResult"
+"add two products to cart as registered user and check product in Report";"default";"catalogProductSimple::100_dollar_product,catalogProductSimple::100_dollar_product";"assertAbandonedCartCustomerInfoResult"
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php
deleted file mode 100644
index 07d00943142..00000000000
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php
+++ /dev/null
@@ -1,89 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Reports\Test\TestCase;
-
-use Mtf\TestCase\Injectable;
-use Magento\Sales\Test\Fixture\OrderInjectable;
-use Magento\Reports\Test\Page\Adminhtml\Bestsellers;
-
-/**
- * Test Creation for BestsellerProductsReportEntity
- *
- * Test Flow:
- * Preconditions:
- * 1. Create customer
- * 2. Create product
- * 3. Place order
- * 4. Refresh statistic
- *
- * Steps:
- * 1. Open Backend
- * 2. Go to Reports > Products > Bestsellers
- * 3. Select time range, report period
- * 4. Click "Show report"
- * 5. Perform all assertions
- *
- * @group Reports_(MX)
- * @ZephyrId MAGETWO-28222
- */
-class BestsellerProductsReportEntityTest extends Injectable
-{
-    /**
-     * Bestsellers page
-     *
-     * @var Bestsellers
-     */
-    protected $bestsellers;
-
-    /**
-     * Inject pages
-     *
-     * @param Bestsellers $bestsellers
-     * @return void
-     */
-    public function __inject(Bestsellers $bestsellers)
-    {
-        $this->bestsellers = $bestsellers;
-    }
-
-    /**
-     * Bestseller Products Report
-     *
-     * @param OrderInjectable $order
-     * @param array $bestsellerReport
-     * @return void
-     */
-    public function test(OrderInjectable $order, array $bestsellerReport)
-    {
-        // Preconditions
-        $order->persist();
-        $this->bestsellers->open();
-        $this->bestsellers->getMessagesBlock()->clickLinkInMessages('notice', 'here');
-
-        // Steps
-        $this->bestsellers->getFilterBlock()->viewsReport($bestsellerReport);
-        $this->bestsellers->getActionsBlock()->showReport();
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest/test.csv
deleted file mode 100644
index 78dc2381483..00000000000
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest/test.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-"order/dataSet";"bestsellerReport/period_type";"bestsellerReport/from";"bestsellerReport/to";"bestsellerReport/show_empty_rows";"date";"constraint"
-"simple_big_qty";"Year";"m/d/Y -1 year";"m/d/Y";"No";"Y";"assertBestsellerReportResult"
-"virtual_big_qty";"Month";"m/d/Y -1 month";"m/d/Y";"Yes";"n/Y";"assertBestsellerReportResult"
-"simple_big_qty";"Day";"m/d/Y -1 day";"m/d/Y +1 day";"No";"M d, Y";"assertBestsellerReportResult"
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
new file mode 100644
index 00000000000..10ee743001a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php
@@ -0,0 +1,101 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Reports\Test\Page\Adminhtml\CustomerOrdersReport;
+
+/**
+ * Test Creation for OrderCountReportEntity
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer
+ * 2. Create orders for customer
+ *
+ * Steps:
+ * 1. Login to backend
+ * 2. Open Reports > Customer > Order Count
+ * 3. Fill data from dataSet
+ * 4. Click button Refresh
+ * 5. Perform all assertions
+ *
+ * @group Reports_(MX)
+ * @ZephyrId MAGETWO-28521
+ */
+class CustomersOrderCountReportEntityTest extends Injectable
+{
+    /**
+     * Order count report page
+     *
+     * @var CustomerOrdersReport
+     */
+    protected $customerOrdersReport;
+
+    /**
+     * Inject page
+     *
+     * @param CustomerOrdersReport $customerOrdersReport
+     * @return void
+     */
+    public function __inject(CustomerOrdersReport $customerOrdersReport)
+    {
+        $this->customerOrdersReport = $customerOrdersReport;
+    }
+
+    /**
+     * Order count report view
+     *
+     * @param CustomerInjectable $customer
+     * @param string $orders
+     * @param array $report
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function test(CustomerInjectable $customer, $orders, array $report, FixtureFactory $fixtureFactory)
+    {
+        // Precondition
+        $customer->persist();
+        $orders = explode(',', $orders);
+        foreach ($orders as $order) {
+            $order = $fixtureFactory->createByCode(
+                'orderInjectable',
+                ['dataSet' => $order, 'data' => ['customer_id' => ['customer' => $customer]]]
+            );
+            $order->persist();
+        }
+
+        // Steps
+        $this->customerOrdersReport->open();
+        $this->customerOrdersReport->getFilterBlock()->viewsReport($report);
+        $this->customerOrdersReport->getFilterBlock()->refreshFilter();
+
+        return['customer' => $customer];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest/test.csv
new file mode 100644
index 00000000000..37a31a8ba85
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest/test.csv
@@ -0,0 +1,4 @@
+"orders";"report/report_from";"report/report_to";"report/report_period";"columns/orders";"columns/average";"columns/total";"constraint"
+"default,virtual_product";"m/d/Y";"m/d/Y";"Day";"2";"285";"570";"assertCustomerOrderCountReportResult"
+"default,virtual_product";"m/d/Y";"m/d/Y";"Month";"2";"285";"570";"assertCustomerOrderCountReportResult"
+"default";"m/d/Y";"m/d/Y";"Year";"1";"560";"560";"assertCustomerOrderCountReportResult"
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php
new file mode 100644
index 00000000000..b45d64380c5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php
@@ -0,0 +1,101 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Reports\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Reports\Test\Page\Adminhtml\CustomerTotalsReport;
+
+/**
+ * Test Creation for OrderTotalReportEntity
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer
+ * 2. Create orders for customer
+ *
+ * Steps:
+ * 1. Login to backend
+ * 2. Open Reports > Customer > Order Total
+ * 3. Fill data from dataSet
+ * 4. Click button Refresh
+ * 5. Perform all assertions
+ *
+ * @group Reports_(MX)
+ * @ZephyrId MAGETWO-28358
+ */
+class CustomersOrderTotalReportEntityTest extends Injectable
+{
+    /**
+     * Order total report page
+     *
+     * @var CustomerTotalsReport
+     */
+    protected $customerTotalsReport;
+
+    /**
+     * Inject page
+     *
+     * @param CustomerTotalsReport $customerTotalsReport
+     * @return void
+     */
+    public function __inject(CustomerTotalsReport $customerTotalsReport)
+    {
+        $this->customerTotalsReport = $customerTotalsReport;
+    }
+
+    /**
+     * Order total report view
+     *
+     * @param CustomerInjectable $customer
+     * @param string $orders
+     * @param array $report
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function test(CustomerInjectable $customer, $orders, array $report, FixtureFactory $fixtureFactory)
+    {
+        // Precondition
+        $customer->persist();
+        $orders = explode(',', $orders);
+        foreach ($orders as $order) {
+            $order = $fixtureFactory->createByCode(
+                'orderInjectable',
+                ['dataSet' => $order, 'data' => ['customer_id' => ['customer' => $customer]]]
+            );
+            $order->persist();
+        }
+
+        // Steps
+        $this->customerTotalsReport->open();
+        $this->customerTotalsReport->getFilterBlock()->viewsReport($report);
+        $this->customerTotalsReport->getFilterBlock()->refreshFilter();
+
+        return['customer' => $customer];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest/test.csv
new file mode 100644
index 00000000000..0649f36d48f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest/test.csv
@@ -0,0 +1,4 @@
+"orders";"report/report_from";"report/report_to";"report/report_period";"columns/orders";"columns/average";"columns/total";"constraint"
+"default,virtual_product";"m/d/Y";"m/d/Y";"Day";"2";"285";"570";"assertCustomerOrderTotalReportResult"
+"default,virtual_product";"m/d/Y";"m/d/Y";"Month";"2";"285";"570";"assertCustomerOrderTotalReportResult"
+"default";"m/d/Y";"m/d/Y";"Year";"1";"560";"560";"assertCustomerOrderTotalReportResult"
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
index 5be39cf1135..58f573b1937 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
@@ -94,7 +94,7 @@ class SearchTermsReportEntityTest extends Injectable
      */
     public function test(CatalogProductSimple $product, $countProducts, $countSearch)
     {
-        $this->markTestIncomplete('MAGETWO-27150, MAGETWO-27151');
+        $this->markTestIncomplete('MAGETWO-27150');
         // Preconditions
         $productName = $this->createProducts($product, $countProducts);
 
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest/test.csv
index 430790d9c78..390345cb820 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest/test.csv
@@ -1,4 +1,4 @@
 "description";"total";"products";"viewsReport/period_type";"viewsReport/from";"viewsReport/to";"viewsReport/show_empty_rows";"constraint"
 "view products on front and verify they all reflected in Year report";"2, 1";"catalogProductSimple::default, catalogProductVirtual::default";"Year";"m/d/Y -1 year";"m/d/Y";"No";"assertProductViewsReportTotalResult"
-"view products on front and verify they all reflected in Month report";"1, 1";"catalogProductDownloadable::default, catalogProductBundle::bundle_dynamic_product";"Month";"m/d/Y";"m/d/Y";"No";"assertProductViewsReportTotalResult"
-"view products on front and verify they all reflected in Day report";"1, 1";"catalogProductConfigurable::default, catalogProductGrouped::default";"Day";"m/d/Y -1 day";"m/d/Y +1 day";"Yes";"assertProductViewsReportTotalResult"
+"view products on front and verify they all reflected in Month report";"1, 1";"downloadableProductInjectable::default, catalogProductBundle::bundle_dynamic_product";"Month";"m/d/Y";"m/d/Y";"No";"assertProductViewsReportTotalResult"
+"view products on front and verify they all reflected in Day report";"1, 1";"configurableProductInjectable::default, catalogProductGrouped::default";"Day";"m/d/Y -1 day";"m/d/Y +1 day";"Yes";"assertProductViewsReportTotalResult"
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/etc/constraint.xml
index 23c4f8a0c9c..2b6f8a53df0 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/etc/constraint.xml
@@ -63,7 +63,16 @@
     <assertBestsellerReportResult module="Magento_Reports">
         <severeness>low</severeness>
     </assertBestsellerReportResult>
-    <assertCouponReportResult  module="Magento_Reports">
+    <assertCouponReportResult module="Magento_Reports">
         <severeness>low</severeness>
     </assertCouponReportResult>
+    <assertCustomerOrderTotalReportResult module="Magento_Reports">
+        <severeness>low</severeness>
+    </assertCustomerOrderTotalReportResult>
+    <assertAbandonedCartCustomerInfoResult module="Magento_Reports">
+        <severeness>low</severeness>
+    </assertAbandonedCartCustomerInfoResult>
+    <assertCustomerOrderCountReportResult module="Magento_Reports">
+        <severeness>low</severeness>
+    </assertCustomerOrderCountReportResult>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/etc/page.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/etc/page.xml
index 9850ac960de..6f89be33865 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/etc/page.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/etc/page.xml
@@ -64,11 +64,6 @@
         <area>adminhtml</area>
         <class>Magento\Reports\Test\Page\Adminhtml\OrderedProductsReport</class>
     </orderedProductsReport>
-    <bestsellers>
-        <mca>reports/report_sales/bestsellers</mca>
-        <area>adminhtml</area>
-        <class>Magento\Reports\Test\Page\Adminhtml\Bestsellers</class>
-    </bestsellers>
     <statistics>
         <mca>reports/report_statistics</mca>
         <area>adminhtml</area>
@@ -79,4 +74,19 @@
         <area>adminhtml</area>
         <class>Magento\Reports\Test\Page\Adminhtml\SalesCouponReportView</class>
     </salesCouponReportView>
+    <customerTotalsReport>
+        <mca>reports/report_customer/totals</mca>
+        <area>adminhtml</area>
+        <class>Magento\Reports\Test\Page\Adminhtml\OrderTotalReport</class>
+    </customerTotalsReport>
+    <abandonedCarts>
+        <mca>reports/report_shopcart/abandoned</mca>
+        <area>adminhtml</area>
+        <class>Magento\Reports\Test\Page\Adminhtml\AbandonedCarts</class>
+    </abandonedCarts>
+    <customerOrdersReport>
+        <mca>reports/report_customer/orders</mca>
+        <area>adminhtml</area>
+        <class>Magento\Reports\Test\Page\Adminhtml\CustomerOrdersReport</class>
+    </customerOrdersReport>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php b/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php
index 592979ef677..70006040631 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Block/Switcher.php
@@ -29,6 +29,10 @@ use Mtf\Block\Block;
 use Mtf\Client\Element\Locator;
 use Magento\Store\Test\Fixture\Store;
 
+/**
+ * Class Switcher
+ * Store switcher block
+ */
 class Switcher extends Block
 {
     /**
@@ -49,6 +53,7 @@ class Switcher extends Block
      * Select store
      *
      * @param string $name
+     * @return void
      */
     public function selectStoreView($name)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
index 58a6e8c4543..e0beba40b68 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Store/Curl.php
@@ -33,7 +33,7 @@ use Mtf\Handler\Curl as AbstractCurl;
 
 /**
  * Class Curl
- * Curl handler for creating Store view.
+ * Curl handler for creating Store view
  */
 class Curl extends AbstractCurl implements StoreInterface
 {
@@ -71,7 +71,7 @@ class Curl extends AbstractCurl implements StoreInterface
         $data = $this->prepareData($fixture);
         $url = $_ENV['app_backend_url'] . $this->saveUrl;
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
+        $curl->write(CurlInterface::POST, $url, '1.1', [], $data);
         $response = $curl->read();
         $curl->close();
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
@@ -89,10 +89,13 @@ class Curl extends AbstractCurl implements StoreInterface
      */
     protected function prepareData(FixtureInterface $fixture)
     {
-        $data['store'] = $this->replaceMappingData($fixture->getData());
-        $data['store_action'] = isset($data['store_action']) ? $data['store_action'] : 'add';
-        $data['store_type'] = isset($data['store_type']) ? $data['store_type'] : 'store';
+        $data = [
+            'store' => $this->replaceMappingData($fixture->getData()),
+            'store_action' => 'add',
+            'store_type' => 'store',
+        ];
         $data['store']['group_id'] = $fixture->getDataFieldConfig('group_id')['source']->getStoreGroup()->getGroupId();
+        $data['store']['store_id'] = isset($data['store']['store_id']) ? $data['store']['store_id'] : '';
 
         return $data;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
index 14dc9ddc08e..afe23ed97cd 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php
@@ -33,7 +33,7 @@ use Mtf\Handler\Curl as AbstractCurl;
 
 /**
  * Class Curl
- * Curl handler for creating Store Group.
+ * Curl handler for creating Store Group
  */
 class Curl extends AbstractCurl implements StoreGroupInterface
 {
@@ -47,9 +47,9 @@ class Curl extends AbstractCurl implements StoreGroupInterface
     public function persist(FixtureInterface $fixture = null)
     {
         $data = $this->prepareData($fixture);
-        $url = $_ENV['app_backend_url'] . 'admin/system_store/save/';
+        $url = $_ENV['app_backend_url'] . 'admin/system_store/save';
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
+        $curl->write(CurlInterface::POST, $url, '1.1', [], $data);
         $response = $curl->read();
         $curl->close();
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
@@ -97,11 +97,16 @@ class Curl extends AbstractCurl implements StoreGroupInterface
     {
         $categoryId = $fixture->getDataFieldConfig('root_category_id')['source']->getCategory()->getId();
         $websiteId = $fixture->getDataFieldConfig('website_id')['source']->getWebsite()->getWebsiteId();
-        $data['group']['name'] = $fixture->getName();
-        $data['group']['root_category_id'] = $categoryId;
-        $data['group']['website_id'] = $websiteId;
-        $data['store_action'] = isset($data['store_action']) ? $data['store_action'] : 'add';
-        $data['store_type'] = isset($data['store_type']) ? $data['store_type'] : 'group';
+        $data = [
+            'group' => [
+                'name' => $fixture->getName(),
+                'root_category_id' => $categoryId,
+                'website_id' => $websiteId,
+                'group_id' => $fixture->hasData('group_id') ? $fixture->getGroupId() : ''
+            ],
+            'store_action' => 'add',
+            'store_type' => 'group'
+        ];
 
         return $data;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
index d8bf3cd4bd8..6832c976811 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
@@ -33,14 +33,14 @@ use Mtf\Handler\Curl as AbstractCurl;
 
 /**
  * Class Curl
- * Curl handler for creating Website.
+ * Curl handler for creating Website
  */
 class Curl extends AbstractCurl implements WebsiteInterface
 {
     /**
      * POST request for creating Website
      *
-     * @param FixtureInterface $fixture
+     * @param FixtureInterface|null $fixture [optional]
      * @return array
      * @throws \Exception
      */
@@ -49,7 +49,7 @@ class Curl extends AbstractCurl implements WebsiteInterface
         $data = $this->prepareData($fixture);
         $url = $_ENV['app_backend_url'] . 'admin/system_store/save/';
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
+        $curl->write(CurlInterface::POST, $url, '1.1', [], $data);
         $response = $curl->read();
         $curl->close();
         if (!strpos($response, 'data-ui-id="messages-message-success"')) {
@@ -81,7 +81,7 @@ class Curl extends AbstractCurl implements WebsiteInterface
         preg_match('/' . $expectedUrl . '([0-9]*)\/(.)*>' . $websiteName . '<\/a>/', $response, $matches);
 
         if (empty($matches)) {
-            throw new \Exception('Cannot find website id');
+            throw new \Exception('Cannot find website id.');
         }
 
         return intval($matches[1]);
@@ -95,9 +95,12 @@ class Curl extends AbstractCurl implements WebsiteInterface
      */
     protected function prepareData(FixtureInterface $fixture)
     {
-        $data['website']= $fixture->getData();
-        $data['store_action'] = isset($data['store_action']) ? $data['store_action'] : 'add';
-        $data['store_type'] = isset($data['store_type']) ? $data['store_type'] : 'website';
+        $data = [
+            'website' => $fixture->getData(),
+            'store_action' => 'add',
+            'store_type' => 'website'
+        ];
+        $data['website']['website_id'] = isset($data['website']['website_id']) ? $data['website']['website_id'] : '';
 
         return $data;
     }
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php
index 62257154991..59aa6b6188c 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php
@@ -33,10 +33,12 @@ use Magento\Store\Test\Fixture\StoreGroup;
 /**
  * Test Creation for CreateStoreEntity (Store Management)
  *
+ * Test Flow:
+ *
  * Preconditions:
  * 1. Create Store Group
  *
- * Test Flow:
+ * Steps:
  * 1. Open Backend
  * 2. Go to Stores -> All Stores
  * 3. Click "Create Store View" button
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest/test.csv
index ab0eb22bdb5..e1b8bfbae8e 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest/test.csv
@@ -1,4 +1,4 @@
-"store/data/group_id/dataSet";"store/data/name";"store/data/code";"store/data/is_active";"constraint";"issue"
-"default";"store_name_%isolation%";"storecode_%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend";""
-"default";"store_name_%isolation%";"storecode_%isolation%";"Disabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreNotOnFrontend";""
-"custom";"store_name_%isolation%";"storecode_%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend";"Bug: MAGETWO-27726"
\ No newline at end of file
+"store/data/group_id/dataSet";"store/data/name";"store/data/code";"store/data/is_active";"constraint"
+"default";"store_name_%isolation%";"storecode_%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend"
+"default";"store_name_%isolation%";"storecode_%isolation%";"Disabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreNotOnFrontend"
+"custom";"store_name_%isolation%";"storecode_%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php
index 888a7f09943..474e14a1b56 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php
@@ -33,6 +33,7 @@ use Mtf\TestCase\Injectable;
  * Test Creation for UpdateStoreEntity (Store Management)
  *
  * Test Flow:
+ *
  * Preconditions:
  * 1.Create store view
  *
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest/test.csv
index 57998422915..87bfdcc36e2 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest/test.csv
@@ -1,2 +1,2 @@
-"store/data/group_id/dataSet";"store/data/name";"store/data/code";"store/data/is_active";"constraint";"issue"
-"default";"storename_updated%isolation%";"storecode_updated%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend";"Bug: MAGETWO-27726"
+"store/data/group_id/dataSet";"store/data/name";"store/data/code";"store/data/is_active";"constraint"
+"default";"storename_updated%isolation%";"storecode_updated%isolation%";"Enabled";"assertStoreSuccessSaveMessage, assertStoreInGrid, assertStoreForm, assertStoreBackend, assertStoreFrontend"
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest/test.csv
index 5364df963ff..68509a54d32 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest/test.csv
@@ -1,3 +1,3 @@
 "storeGroupOrigin/dataSet";"storeGroup/data/website_id/dataSet";"storeGroup/data/name";"storeGroup/data/root_category_id/dataSet";"constraint"
-"default";"main_website";"store_name_updated_%isolation%";"default_category";"assertStoreGroupSuccessSaveMessage, assertStoreGroupInGrid, assertStoreGroupForm, assertStoreGroupOnStoreViewForm"
-"default";"custom_website";"store_name_updated_%isolation%";"root_category";"assertStoreGroupSuccessSaveMessage, assertStoreGroupInGrid, assertStoreGroupForm, assertStoreGroupOnStoreViewForm"
+"custom";"main_website";"store_name_updated_%isolation%";"default_category";"assertStoreGroupSuccessSaveMessage, assertStoreGroupInGrid, assertStoreGroupForm, assertStoreGroupOnStoreViewForm"
+"custom";"custom_website";"store_name_updated_%isolation%";"root_category";"assertStoreGroupSuccessSaveMessage, assertStoreGroupInGrid, assertStoreGroupForm, assertStoreGroupOnStoreViewForm"
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
index 16822ef185d..1857bc34566 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
@@ -149,6 +149,7 @@ class Form extends FormInterface
      */
     protected function addNewTaxRates($taxRule)
     {
+        $this->waitForElementVisible($this->taxRateBlock);
         $taxRateBlock = $this->_rootElement->find($this->taxRateBlock, Locator::SELECTOR_CSS, 'multiselectlist');
         /** @var \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate $taxRateForm */
         $taxRateForm = $this->blockFactory->create(
diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php
index bb64ed04fa7..2ad347f31c4 100644
--- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php
+++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php
@@ -109,11 +109,14 @@ class Footer extends Block
     public function selectStoreGroup(Store $store)
     {
         $storeGroupName = explode("/", $store->getGroupId())[1];
-        $this->_rootElement->find($this->storeGroupSwitch)->click();
         $storeGroup = $this->_rootElement->find(
             sprintf($this->storeGroupSelector, $storeGroupName),
             Locator::SELECTOR_XPATH
         );
+        if (!$storeGroup->isVisible()) {
+            $this->_rootElement->find($this->storeGroupSwitch)->click();
+        }
+
         $storeGroup->click();
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Category/Grid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Category/Grid.php
index 35b318a1b3f..2c0674e1632 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Category/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Category/Grid.php
@@ -28,7 +28,7 @@ use Magento\Backend\Test\Block\Widget\Grid as ParentGrid;
 
 /**
  * Class Grid
- * URL Redirect grid
+ * URL Rewrite grid
  */
 class Grid extends ParentGrid
 {
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml
index 4e4369a77d2..68067a0b9ad 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.xml
@@ -25,28 +25,24 @@
 -->
 <mapping strict="0">
     <fields>
-        <type>
-            <selector>[name='is_system']</selector>
-        </type>
-        <id_path/>
         <store_id>
-            <selector>[name='store_id']</selector>
+            <selector>[name=store_id]</selector>
             <input>selectstore</input>
         </store_id>
-        <options>
-            <selector>[name='options']</selector>
+        <redirect_type>
+            <selector>[name=redirect_type]</selector>
             <input>select</input>
-        </options>
+        </redirect_type>
         <request_path>
-            <selector>[name='request_path']</selector>
+            <selector>[name=request_path]</selector>
             <input>text</input>
         </request_path>
         <target_path>
-            <selector>[name='target_path']</selector>
+            <selector>[name=target_path]</selector>
             <input>text</input>
         </target_path>
         <description>
-            <selector>[name='description']</selector>
+            <selector>[name=description]</selector>
             <input>text</input>
         </description>
         <redirect/>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Cms/Page/Grid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Cms/Page/Grid.php
index efe4eafe95e..eba44ce9389 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Cms/Page/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Cms/Page/Grid.php
@@ -28,7 +28,7 @@ use Magento\Backend\Test\Block\Widget\Grid as ParentGrid;
 
 /**
  * Class Grid
- * URL Redirect grid
+ * URL Rewrite grid
  */
 class Grid extends ParentGrid
 {
@@ -46,7 +46,7 @@ class Grid extends ParentGrid
      */
     protected $filters = [
         'title' => [
-            'selector' => '#cmsPageGrid_filter_title'
+            'selector' => 'input[name="title"]'
         ]
     ];
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php
index c987eeef5a1..30a5a73d8f4 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Selector.php
@@ -30,7 +30,7 @@ use Mtf\Client\Element\Locator;
 
 /**
  * Class Selector
- * URL rewrite type selector
+ * URL rewrite entity type selector
  */
 class Selector extends Block
 {
@@ -42,7 +42,7 @@ class Selector extends Block
      */
     public function selectType($urlrewriteType)
     {
-        $this->_rootElement->find("[id=url-rewrite-option-select]", Locator::SELECTOR_CSS, 'select')
+        $this->_rootElement->find("[data-role=entity-type-selector]", Locator::SELECTOR_CSS, 'select')
             ->setValue($urlrewriteType);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
index c5ba06e20a1..5c361ffc66f 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
@@ -56,7 +56,7 @@ class AssertUrlRewriteCategoryRedirect extends AbstractConstraint
         Browser $browser
     ) {
         $browser->open($_ENV['app_frontend_url'] . $urlRewrite->getRequestPath());
-        $url = $urlRewrite->getOptions() == 'No'
+        $url = $urlRewrite->getRedirectType() == 'No'
             ? $urlRewrite->getRequestPath()
             : $category->getUrlKey() . '.html';
 
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php
index 287bf259b31..99045c1470c 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php
@@ -24,7 +24,7 @@
 
 namespace Magento\UrlRewrite\Test\Constraint;
 
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\Constraint\AbstractConstraint;
 
 /**
@@ -48,10 +48,10 @@ class AssertUrlRewriteDeletedMessage extends AbstractConstraint
     /**
      * Assert that delete message is displayed
      *
-     * @param UrlrewriteIndex $index
+     * @param UrlRewriteIndex $index
      * @return void
      */
-    public function processAssert(UrlrewriteIndex $index)
+    public function processAssert(UrlRewriteIndex $index)
     {
         $actualMessage = $index->getMessagesBlock()->getSuccessMessages();
         \PHPUnit_Framework_Assert::assertEquals(
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteInGrid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteInGrid.php
index d6ceac89143..657a78cf308 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteInGrid.php
@@ -25,7 +25,7 @@
 namespace Magento\UrlRewrite\Test\Constraint;
 
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\Constraint\AbstractConstraint;
 
 /**
@@ -44,17 +44,17 @@ class AssertUrlRewriteInGrid extends AbstractConstraint
     /**
      * Assert that url rewrite category in grid
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlRewriteIndex $urlRewriteIndex
      * @param UrlRewrite $urlRewrite
      * @return void
      */
-    public function processAssert(UrlrewriteIndex $urlRewriteIndex, UrlRewrite $urlRewrite)
+    public function processAssert(UrlRewriteIndex $urlRewriteIndex, UrlRewrite $urlRewrite)
     {
         $urlRewriteIndex->open();
         $filter = ['request_path' => $urlRewrite->getRequestPath()];
         \PHPUnit_Framework_Assert::assertTrue(
-            $urlRewriteIndex->getUrlRedirectGrid()->isRowVisible($filter),
-            'URL Redirect with request path \'' . $urlRewrite->getRequestPath() . '\' is absent in grid.'
+            $urlRewriteIndex->getUrlRewriteGrid()->isRowVisible($filter),
+            'URL Rewrite with request path \'' . $urlRewrite->getRequestPath() . '\' is absent in grid.'
         );
     }
 
@@ -65,6 +65,6 @@ class AssertUrlRewriteInGrid extends AbstractConstraint
      */
     public function toString()
     {
-        return 'URL Redirect is present in grid.';
+        return 'URL Rewrite is present in grid.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php
index a47ff883bb8..a82eb459192 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php
@@ -25,7 +25,7 @@
 namespace Magento\UrlRewrite\Test\Constraint;
 
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\Constraint\AbstractConstraint;
 
 /**
@@ -44,17 +44,17 @@ class AssertUrlRewriteNotInGrid extends AbstractConstraint
     /**
      * Assert that url rewrite not in grid
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlRewriteIndex $urlRewriteIndex
      * @param UrlRewrite $productRedirect
      * @return void
      */
-    public function processAssert(UrlrewriteIndex $urlRewriteIndex, UrlRewrite $productRedirect)
+    public function processAssert(UrlRewriteIndex $urlRewriteIndex, UrlRewrite $productRedirect)
     {
         $urlRewriteIndex->open();
         $filter = ['request_path' => $productRedirect->getRequestPath()];
         \PHPUnit_Framework_Assert::assertFalse(
-            $urlRewriteIndex->getUrlRedirectGrid()->isRowVisible($filter),
-            'URL Redirect with request path \'' . $productRedirect->getRequestPath() . '\' is present in grid.'
+            $urlRewriteIndex->getUrlRewriteGrid()->isRowVisible($filter),
+            'URL Rewrite with request path \'' . $productRedirect->getRequestPath() . '\' is present in grid.'
         );
     }
 
@@ -65,6 +65,6 @@ class AssertUrlRewriteNotInGrid extends AbstractConstraint
      */
     public function toString()
     {
-        return 'URL Redirect is not present in grid.';
+        return 'URL Rewrite is not present in grid.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSaveMessage.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSaveMessage.php
index 3b0c0e083ae..9944e5e224e 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSaveMessage.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteSaveMessage.php
@@ -24,7 +24,7 @@
 
 namespace Magento\UrlRewrite\Test\Constraint;
 
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\Constraint\AbstractConstraint;
 
 /**
@@ -45,10 +45,10 @@ class AssertUrlRewriteSaveMessage extends AbstractConstraint
     /**
      * Assert that url rewrite success message is displayed
      *
-     * @param UrlrewriteIndex $index
+     * @param UrlRewriteIndex $index
      * @return void
      */
-    public function processAssert(UrlrewriteIndex $index)
+    public function processAssert(UrlRewriteIndex $index)
     {
         $actualMessage = $index->getMessagesBlock()->getSuccessMessages();
         \PHPUnit_Framework_Assert::assertEquals(
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
index 1e6dbe108fe..0d4c8dd0911 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
@@ -51,12 +51,6 @@ class UrlRewrite extends InjectableFixture
         'backend_type' => 'virtual',
     ];
 
-    protected $id_path = [
-        'attribute_code' => 'id_path',
-        'backend_type' => 'virtual',
-        'source' => 'Magento\UrlRewrite\Test\Fixture\UrlRewrite\IdPath',
-    ];
-
     protected $store_id = [
         'attribute_code' => 'store_id',
         'backend_type' => 'varchar',
@@ -66,9 +60,9 @@ class UrlRewrite extends InjectableFixture
         'input' => 'select',
     ];
 
-    protected $options = [
-        'attribute_code' => 'options',
-        'backend_type' => 'varchar',
+    protected $redirect_type = [
+        'attribute_code' => 'redirect_type',
+        'backend_type' => 'int',
         'is_required' => '0',
         'input' => 'select',
     ];
@@ -101,19 +95,14 @@ class UrlRewrite extends InjectableFixture
         return $this->getData('id');
     }
 
-    public function getIdPath()
-    {
-        return $this->getData('id_path');
-    }
-
     public function getStoreId()
     {
         return $this->getData('store_id');
     }
 
-    public function getOptions()
+    public function getRedirectType()
     {
-        return $this->getData('options');
+        return $this->getData('redirect_type');
     }
 
     public function getRequestPath()
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
index f5be3f2336e..1f91f13f2d6 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
@@ -26,29 +26,24 @@
 <fixture class="Magento\UrlRewrite\Test\Fixture\UrlRewrite">
     <module>Magento_Backend</module>
     <type>virtual</type>
-    <entity_type>core_url_rewrite</entity_type>
-    <collection>Magento\UrlRewrite\Model\Resource\UrlRewrite\Collection</collection>
+    <entity_type>url_rewrite</entity_type>
+    <collection>Magento\UrlRewrite\Model\Resource\UrlRewriteCollection</collection>
     <identifier>request_path</identifier>
     <fields>
         <id>
             <attribute_code>id</attribute_code>
             <backend_type>virtual</backend_type>
         </id>
-        <id_path>
-            <attribute_code>id_path</attribute_code>
-            <backend_type>virtual</backend_type>
-            <source>Magento\UrlRewrite\Test\Fixture\UrlRewrite\IdPath</source>
-        </id_path>
         <store_id>
             <attribute_code>store_id</attribute_code>
             <backend_type>virtual</backend_type>
         </store_id>
-        <options>
-            <attribute_code>options</attribute_code>
-            <backend_type>varchar</backend_type>
+        <redirect_type>
+            <attribute_code>redirect_type</attribute_code>
+            <backend_type>int</backend_type>
             <is_required>0</is_required>
             <input>select</input>
-        </options>
+        </redirect_type>
         <request_path>
             <attribute_code>request_path</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewriteCategory.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewriteCategory.php
index 00bc895001f..e716c27748f 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewriteCategory.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewriteCategory.php
@@ -89,6 +89,16 @@ class UrlRewriteCategory extends DataFixture
         return $this->category->getCategoryName();
     }
 
+    /**
+     * Retrieve URL rewrite type
+     *
+     * @return string
+     */
+    public function getUrlRewriteType()
+    {
+        return $this->getData('url_rewrite_type');
+    }
+
     /**
      * Initialize fixture data
      */
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
index f33ecd7dae8..92c8e9956e4 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
@@ -47,10 +47,10 @@ class Curl extends AbstractCurl implements UrlRewriteInterface
             'Default Store View' => 1,
             'Main Website/Main Website Store/Default Store View' => 1,
         ],
-        'options' => [
-            'Temporary (302)' => 'R',
-            'Permanent (301)' => 'RP',
-            'No' => ''
+        'redirect_type' => [
+            'Temporary (302)' => 302,
+            'Permanent (301)' => 301,
+            'No' => 0
         ]
     ];
 
@@ -59,7 +59,7 @@ class Curl extends AbstractCurl implements UrlRewriteInterface
      *
      * @var string
      */
-    protected $url = 'admin/urlrewrite/save/';
+    protected $url = 'admin/url_rewrite/save/';
 
     /**
      * Post request for creating url rewrite
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteEdit.xml
similarity index 94%
rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml
rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteEdit.xml
index c26f551bb49..a125fae6947 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteEdit.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteEdit.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page mca="admin/urlrewrite/edit" module="Magento_UrlRewrite">
+<page mca="admin/url_rewrite/edit" module="Magento_UrlRewrite">
     <blocks>
         <treeBlock>
             <class>Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Category\Tree</class>
@@ -52,7 +52,7 @@
         </productGridBlock>
         <urlRewriteTypeSelectorBlock>
             <class>Magento\UrlRewrite\Test\Block\Adminhtml\Selector</class>
-            <locator>[data-ui-id="urlrewrite-type-selector"]</locator>
+            <locator>[data-container-for="entity-type-selector"]</locator>
             <strategy>css selector</strategy>
         </urlRewriteTypeSelectorBlock>
         <cmsGridBlock>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteIndex.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteIndex.xml
similarity index 96%
rename from dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteIndex.xml
rename to dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteIndex.xml
index 03983342ab6..6747e249752 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlrewriteIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Page/Adminhtml/UrlRewriteIndex.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<page mca="admin/urlrewrite/index" module="Magento_UrlRewrite">
+<page mca="admin/url_rewrite/index" module="Magento_UrlRewrite">
     <blocks>
         <pageActionsBlock>
             <class>Magento\Backend\Test\Block\GridPageActions</class>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php
index 44d17464bcb..958746a7152 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php
@@ -43,14 +43,13 @@ class UrlRewrite extends AbstractRepository
         $this->_data['default'] = [
             'request_path' => 'test-test-test%isolation%.html',
             'target_path' => 'http://www.ebayinc.com/',
-            'options' => 'Temporary (302)',
+            'redirect_type' => 'Temporary (302)',
             'store_id' => 'Main Website/Main Website Store/Default Store View',
-            'id_path' =>  ["test%isolation%"]
         ];
 
         $this->_data['default_without_target'] = [
             'request_path' => 'test-test-test%isolation%.html',
-            'options' => 'Temporary (302)',
+            'redirect_type' => 'Temporary (302)',
             'store_id' => 'Main Website/Main Website Store/Default Store View',
         ];
 
@@ -58,9 +57,8 @@ class UrlRewrite extends AbstractRepository
             'store_id' => 'Main Website/Main Website Store/Default Store View',
             'request_path' => 'wishlist/%isolation%',
             'target_path' => 'http://google.com',
-            'options' => 'Temporary (302)',
+            'redirect_type' => 'Temporary (302)',
             'description' => 'test description',
-            'id_path' => ['entity' => "wishlist/%catalogProductSimple::100_dollar_product%"]
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php
index fbbac527e33..c5178ccd636 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteCategory.php
@@ -44,6 +44,7 @@ class UrlRewriteCategory extends AbstractRepository
         $this->_data['default'] = [
             'config' => $defaultConfig,
             'data' => [
+                'url_rewrite_type' => 'For category',
                 'fields' => [
                     'request_path' => [
                         'value' => '%rewritten_category_request_path%',
@@ -55,7 +56,7 @@ class UrlRewriteCategory extends AbstractRepository
             ],
         ];
         $this->_data['category_with_permanent_redirect'] = $this->_data['default'];
-        $this->_data['category_with_permanent_redirect']['data']['fields']['options'] = [
+        $this->_data['category_with_permanent_redirect']['data']['fields']['redirect_type'] = [
             'value' => 'Permanent (301)',
         ];
     }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php
index 18d16944793..e3f693efc6a 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewriteProduct.php
@@ -56,7 +56,7 @@ class UrlRewriteProduct extends AbstractRepository
             ],
         ];
         $this->_data['product_with_temporary_redirect'] = $this->_data['default'];
-        $this->_data['product_with_temporary_redirect']['data']['fields']['options'] = [
+        $this->_data['product_with_temporary_redirect']['data']['fields']['redirect_type'] = [
             'value' => 'Temporary (302)',
         ];
     }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php
index 476fe956f19..bd215188a0a 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryTest.php
@@ -29,7 +29,7 @@ use Magento\UrlRewrite\Test\Fixture\UrlRewriteCategory;
 use Mtf\TestCase\Injectable;
 
 /**
- * Class UrlrewriteTest
+ * Class UrlRewriteTest
  * Category URL rewrite creation test
  */
 class CategoryTest extends Injectable
@@ -44,18 +44,19 @@ class CategoryTest extends Injectable
     public function test(\Magento\UrlRewrite\Test\Fixture\UrlRewriteCategory $urlRewriteCategory)
     {
         $urlRewriteCategory->switchData('category_with_permanent_redirect');
-
         //Pages & Blocks
-        $urlRewriteIndexPage = Factory::getPageFactory()->getAdminUrlrewriteIndex();
+        $urlRewriteIndexPage = Factory::getPageFactory()->getAdminUrlRewriteIndex();
         $pageActionsBlock = $urlRewriteIndexPage->getPageActionsBlock();
-        $urlRewriteEditPage = Factory::getPageFactory()->getAdminUrlrewriteEdit();
+        $urlRewriteEditPage = Factory::getPageFactory()->getAdminUrlRewriteEdit();
         $categoryTreeBlock = $urlRewriteEditPage->getTreeBlock();
         $urlRewriteInfoForm = $urlRewriteEditPage->getFormBlock();
+        $typeSelectorBlock = $urlRewriteEditPage->getUrlRewriteTypeSelectorBlock();
 
         //Steps
         Factory::getApp()->magentoBackendLoginUser();
         $urlRewriteIndexPage->open();
         $pageActionsBlock->addNew();
+        $typeSelectorBlock->selectType($urlRewriteCategory->getUrlRewriteType());
         $categoryTreeBlock->selectCategory($urlRewriteCategory->getCategoryName());
         $urlRewriteInfoForm->fill($urlRewriteCategory);
         $urlRewriteEditPage->getPageMainActions()->save();
@@ -64,7 +65,7 @@ class CategoryTest extends Injectable
             $urlRewriteIndexPage->getMessagesBlock()->getSuccessMessages()
         );
 
-        $this->assertUrlRedirect(
+        $this->assertUrlRewrite(
             $_ENV['app_frontend_url'] . $urlRewriteCategory->getRewrittenRequestPath(),
             $_ENV['app_frontend_url'] . $urlRewriteCategory->getOriginalRequestPath()
         );
@@ -78,7 +79,7 @@ class CategoryTest extends Injectable
      * @param string $message
      * @return void
      */
-    protected function assertUrlRedirect($requestUrl, $targetUrl, $message = '')
+    protected function assertUrlRewrite($requestUrl, $targetUrl, $message = '')
     {
         $browser = Factory::getClientBrowser();
         $browser->open($requestUrl);
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php
index d3a7cc9de79..0b511d59707 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php
@@ -25,8 +25,8 @@
 namespace Magento\UrlRewrite\Test\TestCase;
 
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\Fixture\FixtureFactory;
 use Magento\Catalog\Test\Fixture\CatalogCategory;
 use Mtf\TestCase\Injectable;
@@ -39,7 +39,7 @@ use Mtf\TestCase\Injectable;
  *
  * Test Flow:
  * 1. Login to backend as Admin
- * 2. Go to the Marketing-> SEO & Search->URL Redirects
+ * 2. Go to the Marketing-> SEO & Search->URL Rewrites
  * 3. Click "+" button
  * 4. Select "For Category" in Create URL Rewrite dropdown
  * 5. Select Category in "Category tree"
@@ -55,27 +55,27 @@ class CreateCategoryRewriteEntityTest extends Injectable
     /**
      * Page of url rewrite edit category
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Main page of url rewrite
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Inject page
      *
-     * @param UrlrewriteEdit $urlRewriteEdit
-     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
      * @param FixtureFactory $fixtureFactory
      * @return array
      */
     public function __inject(
-        UrlrewriteEdit $urlRewriteEdit,
+        UrlRewriteEdit $urlRewriteEdit,
         UrlRewriteIndex $urlRewriteIndex,
         FixtureFactory $fixtureFactory
     ) {
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest/testCreateCategoryRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest/testCreateCategoryRewrite.csv
index ac49d009b06..1d4ab32a0f0 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest/testCreateCategoryRewrite.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest/testCreateCategoryRewrite.csv
@@ -1,4 +1,4 @@
-"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"constraint"
 "Main Website/Main Website Store/Default Store View";"test_request%isolation%";"No";"test description";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid"
 "Main Website/Main Website Store/Default Store View";"request_path%isolation%";"Temporary (302)";"test description";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
 "Main Website/Main Website Store/Default Store View";"request_path%isolation%";"Permanent (301)";"test description";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php
index ca87d5cc21b..5edc2e13e79 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Mtf\TestCase\Injectable;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 
 /**
  * Test Creation for CreateCustomUrlRewriteEntity
@@ -41,14 +41,14 @@ use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
  *
  * Steps:
  * 1. Login to backend as Admin
- * 2. Go to the Marketing-> SEO & Search->URL Redirects
+ * 2. Go to the Marketing-> SEO & Search->URL Rewrites
  * 3. Click "Add Url Rewrite" button
  * 4. Select "Custom" in Create URL Rewrite dropdown
  * 5. Fill data according to data set
  * 6. Save Rewrite
  * 7. Perform all assertions
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId MAGETWO-25474
  */
 class CreateCustomUrlRewriteEntityTest extends Injectable
@@ -56,25 +56,25 @@ class CreateCustomUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Inject pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
-    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    public function __inject(UrlRewriteIndex $urlRewriteIndex, UrlRewriteEdit $urlRewriteEdit)
     {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv
index b8daef7681e..d5e9c7b1679 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv
@@ -1,4 +1,4 @@
-"urlRewrite/data/store_id";"urlRewrite/data/id_path/entity";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"urlRewrite/data/store_id";"urlRewrite/data/id_path/entity";"urlRewrite/data/request_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"constraint"
 "Main Website/Main Website Store/Default Store View";"category/%catalogCategory::default_subcategory%";"category_request_path%isolation%";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
 "Main Website/Main Website Store/Default Store View";"product/%catalogProductSimple::default%";"product_request_path%isolation%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
 "Main Website/Main Website Store/Default Store View";"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"No";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php
index 14d53054878..d582f2986c0 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php
@@ -27,8 +27,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Mtf\TestCase\Injectable;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
 
 /**
  * Test Creation for Product URL Rewrites Entity
@@ -48,7 +48,7 @@ use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
  * 7. Fill data according to dataSet
  * 8. Perform all assertions
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId MAGETWO-25150
  */
 class CreateProductUrlRewriteEntityTest extends Injectable
@@ -56,25 +56,25 @@ class CreateProductUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Prepare pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
-    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    public function __inject(UrlRewriteIndex $urlRewriteIndex, UrlRewriteEdit $urlRewriteEdit)
     {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest/testProductUrlRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest/testProductUrlRewrite.csv
index 5c712f8e5b9..fdfce8c0919 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest/testProductUrlRewrite.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest/testProductUrlRewrite.csv
@@ -1,4 +1,4 @@
-"product/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"product/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"constraint"
 "default";"Main Website/Main Website Store/Default Store View";"test_%isolation%.html";"No";"description_%isolation%";"assertUrlRewriteSaveMessage"
 "default";"Main Website/Main Website Store/Default Store View";"test_%isolation%.html";"Temporary (302)";"description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteProductRedirect"
-"default";"Main Website/Main Website Store/Default Store View";"test_%isolation%.html";"Permanent (301)";"description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteProductRedirect"
\ No newline at end of file
+"default";"Main Website/Main Website Store/Default Store View";"test_%isolation%.html";"Permanent (301)";"description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteProductRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php
index 02943ff1a55..a1f6f3f5418 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
 use Mtf\TestCase\Injectable;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 
 /**
  * Test Creation for Delete Category URL Rewrites Entity
@@ -39,12 +39,12 @@ use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
  *
  * Steps:
  * 1. Open Backend
- * 2. Go to Marketing->URL Redirects
- * 3. Search and open created URL Redirect
- * 4. Delete URL Redirect
+ * 2. Go to Marketing->URL Rewrites
+ * 3. Search and open created URL Rewrite
+ * 4. Delete URL Rewrite
  * 5. Perform all assertions
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId MAGETWO-25086
  */
 class DeleteCategoryUrlRewriteEntityTest extends Injectable
@@ -52,25 +52,25 @@ class DeleteCategoryUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Inject pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
-    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    public function __inject(UrlRewriteIndex $urlRewriteIndex, UrlRewriteEdit $urlRewriteEdit)
     {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
@@ -93,7 +93,7 @@ class DeleteCategoryUrlRewriteEntityTest extends Injectable
         } else {
             $filter = ['id_path' => $urlRewrite->getIdPath()];
         }
-        $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter);
+        $this->urlRewriteIndex->getUrlRewriteGrid()->searchAndOpen($filter);
         $this->urlRewriteEdit->getPageMainActions()->delete();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest/testDeleteCategoryUrlRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest/testDeleteCategoryUrlRewrite.csv
index d56bf6e4537..1f9003b2a5f 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest/testDeleteCategoryUrlRewrite.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest/testDeleteCategoryUrlRewrite.csv
@@ -1,3 +1,3 @@
-"urlRewrite/data/id_path/entity";"urlRewrite/data/options";"urlRewrite/data/request_path";"constraint"
+"urlRewrite/data/id_path/entity";"urlRewrite/data/redirect_type";"urlRewrite/data/request_path";"constraint"
 "category/%catalogCategory::default%";"No";"-";"assertUrlRewriteDeletedMessage, assertPageByUrlRewriteIsNotFound"
 "category/%catalogCategory::default%";"No";"example%isolation%.html";"assertUrlRewriteDeletedMessage, assertPageByUrlRewriteIsNotFound"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php
index 6a525d65302..8d170ff11dd 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Mtf\TestCase\Injectable;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 
 /**
  * Test Creation for DeleteCustomUrlRewriteEntity
@@ -51,25 +51,25 @@ class DeleteCustomUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Inject pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
-    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    public function __inject(UrlRewriteIndex $urlRewriteIndex, UrlRewriteEdit $urlRewriteEdit)
     {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php
index 1c0765dcd66..eeb9c3c4cb7 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 use Mtf\TestCase\Injectable;
 
 /**
@@ -40,12 +40,12 @@ use Mtf\TestCase\Injectable;
  *
  * Test Flow:
  * 1. Login to backend.
- * 2. Navigate to MARKETING > URL Redirects.
+ * 2. Navigate to MARKETING > URL Rewrites.
  * 3. Click Redirect from grid.
  * 4. Click 'Delete' button.
  * 5. Perform asserts.
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId  MAGETWO-23287
  */
 class DeleteProductUrlRewriteEntityTest extends Injectable
@@ -53,27 +53,27 @@ class DeleteProductUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Prepare pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
     public function __inject(
-        UrlrewriteIndex $urlRewriteIndex,
-        UrlrewriteEdit $urlRewriteEdit
+        UrlRewriteIndex $urlRewriteIndex,
+        UrlRewriteEdit $urlRewriteEdit
     ) {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
@@ -92,7 +92,7 @@ class DeleteProductUrlRewriteEntityTest extends Injectable
         // Steps
         $this->urlRewriteIndex->open();
         $filter = ['request_path' => $productRedirect->getRequestPath()];
-        $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter);
+        $this->urlRewriteIndex->getUrlRewriteGrid()->searchAndOpen($filter);
         $this->urlRewriteEdit->getPageMainActions()->delete();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php
index df23c9eed19..570a1aebc15 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/ProductTest.php
@@ -29,7 +29,7 @@ use Mtf\TestCase\Functional;
 use Magento\UrlRewrite\Test\Fixture\UrlRewriteProduct;
 
 /**
- * Class UrlrewriteTest
+ * Class UrlRewriteTest
  * Product URL rewrite creation test
  */
 class ProductTest extends Functional
@@ -47,9 +47,9 @@ class ProductTest extends Functional
         $urlRewriteProduct->switchData('product_with_temporary_redirect');
 
         //Pages & Blocks
-        $urlRewriteGridPage = Factory::getPageFactory()->getAdminUrlrewriteIndex();
+        $urlRewriteGridPage = Factory::getPageFactory()->getAdminUrlRewriteIndex();
         $pageActionsBlock = $urlRewriteGridPage->getPageActionsBlock();
-        $urlRewriteEditPage = Factory::getPageFactory()->getAdminUrlrewriteEdit();
+        $urlRewriteEditPage = Factory::getPageFactory()->getAdminUrlRewriteEdit();
         $categoryTreeBlock = $urlRewriteEditPage->getTreeBlock();
         $productGridBlock = $urlRewriteEditPage->getProductGridBlock();
         $typeSelectorBlock = $urlRewriteEditPage->getUrlRewriteTypeSelectorBlock();
@@ -69,7 +69,7 @@ class ProductTest extends Functional
             $urlRewriteGridPage->getMessagesBlock()->getSuccessMessages()
         );
 
-        $this->assertUrlRedirect(
+        $this->assertUrlRewrite(
             $_ENV['app_frontend_url'] . $urlRewriteProduct->getRewrittenRequestPath(),
             $_ENV['app_frontend_url'] . $urlRewriteProduct->getOriginalRequestPath()
         );
@@ -83,7 +83,7 @@ class ProductTest extends Functional
      * @param string $message
      * @return void
      */
-    protected function assertUrlRedirect($requestUrl, $targetUrl, $message = '')
+    protected function assertUrlRewrite($requestUrl, $targetUrl, $message = '')
     {
         $browser = Factory::getClientBrowser();
         $browser->open($requestUrl);
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php
index 330a7445562..12fe1baed06 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Magento\Catalog\Test\Fixture\CatalogCategory;
 use Mtf\TestCase\Injectable;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
 use Mtf\Fixture\FixtureFactory;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
 
@@ -42,13 +42,13 @@ use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
  *
  * Steps:
  * 1. Log in to backend as Admin.
- * 2. Go to the Marketing-> SEO & Search->URL Redirects.
+ * 2. Go to the Marketing-> SEO & Search->URL Rewrites.
  * 3. Click Category URL Rewrite from grid.
  * 4. Edit test value(s) according to dataSet.
  * 5. Click 'Save' button.
  * 6. Perform all asserts.
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId MAGETWO-24838
  */
 class UpdateCategoryUrlRewriteEntityTest extends Injectable
@@ -56,29 +56,29 @@ class UpdateCategoryUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Prepare dataSets and pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @param FixtureFactory $fixtureFactory
      * @param CatalogCategory $category
      * @return array
      */
     public function __inject(
-        UrlrewriteIndex $urlRewriteIndex,
-        UrlrewriteEdit $urlRewriteEdit,
+        UrlRewriteIndex $urlRewriteIndex,
+        UrlRewriteEdit $urlRewriteEdit,
         FixtureFactory $fixtureFactory,
         CatalogCategory $category
     ) {
@@ -110,7 +110,7 @@ class UpdateCategoryUrlRewriteEntityTest extends Injectable
         //Steps
         $this->urlRewriteIndex->open();
         $filter = ['request_path' => $categoryRedirect->getRequestPath()];
-        $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter);
+        $this->urlRewriteIndex->getUrlRewriteGrid()->searchAndOpen($filter);
         $this->urlRewriteEdit->getFormBlock()->fill($urlRewrite);
         $this->urlRewriteEdit->getPageMainActions()->save();
     }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv
index 6f831e43646..738ee1e52bf 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest/test.csv
@@ -1,5 +1,5 @@
-"urlRewrite/data/store_id";"category/dataSet";"categoryRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"urlRewrite/data/store_id";"category/dataSet";"categoryRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"constraint"
 "Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"test_request%isolation%";"No";"test_description_defalt";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
 "Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.html";"Temporary (302)";"test description_302";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
 "Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.htm";"Permanent (301)";"test description_301";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
-"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.aspx";"Temporary (302)";"test description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
\ No newline at end of file
+"Main Website/Main Website Store/Default Store View";"default_subcategory";"default";"-";"request_path%isolation%.aspx";"Temporary (302)";"test description_%isolation%";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCategoryRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php
index 07a643add2c..19cd6d6c6ad 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Mtf\TestCase\Injectable;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
 
 /**
  * Test Creation for UpdateCustomUrlRewritesEntity
@@ -54,25 +54,25 @@ class UpdateCustomUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Inject pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return void
      */
-    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    public function __inject(UrlRewriteIndex $urlRewriteIndex, UrlRewriteEdit $urlRewriteEdit)
     {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv
index c614a683f0e..c9014c79ec4 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest/test.csv
@@ -1,3 +1,3 @@
-"initialRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/target_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"initialRewrite/dataSet";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/target_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"constraint"
 "default";"Main Website/Main Website Store/Default Store View";"wishlist/%isolation%";"http://www.magentocommerce.com/magento-connect/";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteSuccessOutsideRedirect"
 "custom_rewrite_wishlist";"Main Website/Main Website Store/Default Store View";"wishlist/%isolation%";"catalogsearch/result/?q=%name%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomSearchRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php
index bead2feb702..d8f55f58822 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php
@@ -26,8 +26,8 @@ namespace Magento\UrlRewrite\Test\TestCase;
 
 use Mtf\TestCase\Injectable;
 use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
-use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit;
 use Mtf\Fixture\FixtureFactory;
 
 /**
@@ -47,7 +47,7 @@ use Mtf\Fixture\FixtureFactory;
  * 4. Fill data according to dataset
  * 5. Perform all assertions
  *
- * @group URL_Rewrites_(PS)
+ * @group URL_Rewrites_(MX)
  * @ZephyrId MAGETWO-24819
  */
 class UpdateProductUrlRewriteEntityTest extends Injectable
@@ -55,27 +55,27 @@ class UpdateProductUrlRewriteEntityTest extends Injectable
     /**
      * Url rewrite index page
      *
-     * @var UrlrewriteIndex
+     * @var UrlRewriteIndex
      */
     protected $urlRewriteIndex;
 
     /**
      * Url rewrite edit page
      *
-     * @var UrlrewriteEdit
+     * @var UrlRewriteEdit
      */
     protected $urlRewriteEdit;
 
     /**
      * Prepare dataSets and pages
      *
-     * @param UrlrewriteIndex $urlRewriteIndex
-     * @param UrlrewriteEdit $urlRewriteEdit
+     * @param UrlRewriteIndex $urlRewriteIndex
+     * @param UrlRewriteEdit $urlRewriteEdit
      * @return array
      */
     public function __inject(
-        UrlrewriteIndex $urlRewriteIndex,
-        UrlrewriteEdit $urlRewriteEdit
+        UrlRewriteIndex $urlRewriteIndex,
+        UrlRewriteEdit $urlRewriteEdit
     ) {
         $this->urlRewriteIndex = $urlRewriteIndex;
         $this->urlRewriteEdit = $urlRewriteEdit;
@@ -104,7 +104,7 @@ class UpdateProductUrlRewriteEntityTest extends Injectable
         //Steps
         $this->urlRewriteIndex->open();
         $filter = ['request_path' => $productRedirect->getRequestPath()];
-        $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter);
+        $this->urlRewriteIndex->getUrlRewriteGrid()->searchAndOpen($filter);
         $this->urlRewriteEdit->getFormBlock()->fill($urlRewrite);
         $this->urlRewriteEdit->getPageMainActions()->save();
     }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest/testUpdateProductUrlRewrite.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest/testUpdateProductUrlRewrite.csv
index 4a76b6aaf18..8c5250503db 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest/testUpdateProductUrlRewrite.csv
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest/testUpdateProductUrlRewrite.csv
@@ -1,2 +1,2 @@
-"urlRewrite/data/id_path/entity";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"isRequired";"constraint"
+"urlRewrite/data/id_path/entity";"urlRewrite/data/store_id";"urlRewrite/data/request_path";"urlRewrite/data/redirect_type";"urlRewrite/data/description";"isRequired";"constraint"
 "product/%catalogProductSimple::100_dollar_product%";"Main Website/Main Website Store/Default Store View";"test_%isolation%.html";"Temporary (302)";"description_%isolation%";"Yes";"assertUrlRewriteSaveMessage, assertUrlRewriteProductRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/constraint.xml
index e16f263cf17..e31fa6d8213 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/constraint.xml
@@ -49,13 +49,13 @@
     <assertUrlRewriteDeletedMessage module="Magento_UrlRewrite">
         <severeness>low</severeness>
         <require>
-            <index class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex"/>
+            <index class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex"/>
         </require>
     </assertUrlRewriteDeletedMessage>
     <assertUrlRewriteNotInGrid module="Magento_UrlRewrite">
         <severeness>low</severeness>
         <require>
-            <urlRewriteIndex class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex"/>
+            <urlRewriteIndex class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex"/>
             <productRedirect class="Magento\UrlRewrite\Test\Fixture\UrlRewrite"/>
         </require>
     </assertUrlRewriteNotInGrid>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/fixture.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/fixture.xml
index e88ee8df4bd..9c2c75c8f71 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/fixture.xml
@@ -26,8 +26,8 @@
 <fixture>
     <urlRewrite module="Magento_UrlRewrite">
         <type>virtual</type>
-        <entity_type>core_url_rewrite</entity_type>
-        <collection>Magento\UrlRewrite\Model\Resource\UrlRewrite\Collection</collection>
+        <entity_type>url_rewrite</entity_type>
+        <collection>Magento\UrlRewrite\Model\Resource\UrlRewriteCollection</collection>
         <identifier>request_path</identifier>
         <fields>
             <id>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/page.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/page.xml
index db3e292876b..41e71808f2a 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/page.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/page.xml
@@ -24,14 +24,14 @@
  */
 -->
 <page module="Magento_UrlRewrite">
-    <urlrewriteIndex>
-        <mca>admin/urlrewrite/index</mca>
+    <urlRewriteIndex>
+        <mca>admin/url_rewrite/index</mca>
         <area>adminhtml</area>
-        <class>Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex</class>
-    </urlrewriteIndex>
-    <urlrewriteEdit>
-        <mca>admin/urlrewrite/edit</mca>
+        <class>Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex</class>
+    </urlRewriteIndex>
+    <urlRewriteEdit>
+        <mca>admin/url_rewrite/edit</mca>
         <area>adminhtml</area>
-        <class>Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit</class>
-    </urlrewriteEdit>
+        <class>Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteEdit</class>
+    </urlRewriteEdit>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.xml b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.xml
index 0541a6bf871..8c49b9b0141 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.xml
@@ -35,6 +35,7 @@
             <email />
             <password />
             <password_confirmation />
+            <current_password />
             <is_active>
                 <input>select</input>
             </is_active>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUser.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUser.php
index 00457d7374d..fb49416721b 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUser.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUser.php
@@ -27,6 +27,7 @@ namespace Magento\User\Test\Fixture;
 use Mtf\Fixture\DataFixture;
 use Mtf\Factory\Factory;
 use Mtf\System\Config;
+use Mtf\ObjectManager;
 
 /**
  * Fixture with all necessary data for user creation on backend
@@ -64,6 +65,9 @@ class AdminUser extends DataFixture
      */
     protected function _initData()
     {
+        /** @var \Mtf\System\Config $systemConfig */
+        $systemConfig = ObjectManager::getInstance()->create('Mtf\System\Config');
+        $superAdminPassword = $systemConfig->getConfigParam('application/backend_user_credentials/password');
         $this->_data = array(
             'fields' => array(
                 'email' => array(
@@ -87,6 +91,9 @@ class AdminUser extends DataFixture
                 'username' => array(
                     'value' => 'admin%isolation%'
                 ),
+                'current_password' => array(
+                    'value' => $superAdminPassword
+                ),
             ),
         );
     }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
index 4b3699c2d06..1b3ce331a49 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
@@ -24,7 +24,12 @@
 
 namespace Magento\User\Test\Fixture;
 
+use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\InjectableFixture;
+use Mtf\Handler\HandlerFactory;
+use Mtf\Repository\RepositoryFactory;
+use Mtf\System\Config;
+use Mtf\System\Event\EventManagerInterface;
 
 /**
  * Class User
@@ -198,6 +203,48 @@ class User extends InjectableFixture
         'group' => 'user-info'
     ];
 
+    protected $current_password = [
+        'attribute_code' => 'current_password',
+        'backend_type' => 'virtual',
+        'group' => 'user-info'
+    ];
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Config $configuration
+     * @param RepositoryFactory $repositoryFactory
+     * @param FixtureFactory $fixtureFactory
+     * @param HandlerFactory $handlerFactory
+     * @param EventManagerInterface $eventManager
+     * @param array $data
+     * @param string $dataSet
+     * @param bool $persist
+     */
+    public function __construct(
+        Config $configuration,
+        RepositoryFactory $repositoryFactory,
+        FixtureFactory $fixtureFactory,
+        HandlerFactory $handlerFactory,
+        EventManagerInterface $eventManager,
+        array $data = [],
+        $dataSet = '',
+        $persist = false
+    ) {
+        $this->defaultDataSet['current_password'] = $configuration
+            ->getConfigParam('application/backend_user_credentials/password');
+        parent::__construct(
+            $configuration,
+            $repositoryFactory,
+            $fixtureFactory,
+            $handlerFactory,
+            $eventManager,
+            $data,
+            $dataSet,
+            $persist
+        );
+    }
+
     public function getUserId()
     {
         return $this->getData('user_id');
@@ -287,4 +334,9 @@ class User extends InjectableFixture
     {
         return $this->getData('password_confirmation');
     }
+
+    public function getCurrentPassword()
+    {
+        return $this->getData('current_password');
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
index 2945e1bb245..9d4d9d5d224 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
@@ -151,6 +151,10 @@
             <attribute_code>password_confirmation</attribute_code>
             <backend_type>virtual</backend_type>
         </password_confirmation>
+        <current_password>
+            <attribute_code>current_password</attribute_code>
+            <backend_type>virtual</backend_type>
+        </current_password>
     </fields>
     <repository_class>Magento\User\Test\Repository\User</repository_class>
     <handler_interface>Magento\User\Test\Handler\User\UserInterface</handler_interface>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php b/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
index fd01fe32638..dcdd9cf34b4 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
@@ -25,6 +25,7 @@
 namespace Magento\User\Test\Repository;
 
 use Mtf\Repository\AbstractRepository;
+use Mtf\ObjectManager;
 
 /**
  * Class User
@@ -41,6 +42,9 @@ class User extends AbstractRepository
      */
     public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
+        /** @var \Mtf\System\Config $systemConfig */
+        $systemConfig = ObjectManager::getInstance()->create('Mtf\System\Config');
+        $superAdminPassword = $systemConfig->getConfigParam('application/backend_user_credentials/password');
         $this->_data['default'] = [
             'username' => 'admin',
             'firstname' => 'FirstName%isolation%',
@@ -48,7 +52,8 @@ class User extends AbstractRepository
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
             'password_confirmation' => '123123q',
-            'user_id' => 1
+            'user_id' => 1,
+            'current_password' => $superAdminPassword
         ];
 
         $this->_data['custom_admin'] = [
@@ -57,7 +62,8 @@ class User extends AbstractRepository
             'lastname' => 'LastName%isolation%',
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
-            'password_confirmation' => '123123q'
+            'password_confirmation' => '123123q',
+            'current_password' => $superAdminPassword
         ];
 
         $this->_data['custom_admin_with_default_role'] = [
@@ -67,7 +73,8 @@ class User extends AbstractRepository
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
             'password_confirmation' => '123123q',
-            'role_id' => ['dataSet' => 'default']
+            'role_id' => ['dataSet' => 'default'],
+            'current_password' => $superAdminPassword
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv
index ec5ef067904..178ac7b96f4 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv
@@ -1,7 +1,7 @@
-"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"isDuplicated";"constraint"
-"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
-"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Inactive";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
-"-";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"username";"assertUserDuplicateMessage"
-"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"-";"123123q";"123123q";"Active";"Administrators";"email";"assertUserDuplicateMessage"
-"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"-";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
-"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.cim";"123123q";"123123q";"Active";"-";"-";"assertUserInvalidEmailMessage"
\ No newline at end of file
+"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"isDuplicated";"constraint";"user/data/current_password"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"; "123123q"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Inactive";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"; "123123q"
+"-";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"username";"assertUserDuplicateMessage"; "123123q"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"-";"123123q";"123123q";"Active";"Administrators";"email";"assertUserDuplicateMessage"; "123123q"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"-";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"; "123123q"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.cim";"123123q";"123123q";"Active";"-";"-";"assertUserInvalidEmailMessage"; "123123q"
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
index aef3614251b..bdaf615f23f 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
@@ -1,4 +1,4 @@
-"initialUser/dataSet";"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"loginAsDefaultAdmin";"constraint"
-"custom_admin_with_default_role";"NewAdminUser%isolation%";"NewFirstName%isolation%";"NewLastName%isolation%";"NewEmail%isolation%@example.com";"123123qa";"123123qa";"-";"-";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
-"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"-";"role_sales";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"
-"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"Inactive";"-";"1";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
+"initialUser/dataSet";"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"loginAsDefaultAdmin";"constraint";"user/data/current_password"
+"custom_admin_with_default_role";"NewAdminUser%isolation%";"NewFirstName%isolation%";"NewLastName%isolation%";"NewEmail%isolation%@example.com";"123123qa";"123123qa";"-";"-";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"; "123123q"
+"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"-";"role_sales";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"; "123123q"
+"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"Inactive";"-";"1";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"; "123123q"
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv
index a90ad495b8a..40e2c721a2b 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv
@@ -1,3 +1,3 @@
-"user/dataSet";"role/data/rolename";"role/data/resource_access";"role/data/roles_resources";"role/data/in_role_users/dataSet";"constraint"
-"custom_admin_with_default_role";"NewAdminRole%isolation%";"-";"-";"-";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
-"default";"-";"Custom";"Sales";"custom_admin";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"
+"user/dataSet";"role/data/rolename";"role/data/resource_access";"role/data/roles_resources";"role/data/in_role_users/dataSet";"constraint";"issue"
+"custom_admin_with_default_role";"NewAdminRole%isolation%";"-";"-";"-";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin";""
+"default";"-";"Custom";"Sales";"custom_admin";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess";"Bug: MAGETWO-28587"
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items.php
index 9bb947f4b96..483c564b7e7 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items.php
@@ -27,6 +27,7 @@ namespace Magento\Wishlist\Test\Block\Customer\Wishlist;
 use Mtf\Block\Block;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
+use Magento\Wishlist\Test\Block\Customer\Wishlist\Items\Product;
 
 /**
  * Class Items
@@ -35,22 +36,24 @@ use Mtf\Client\Element\Locator;
 class Items extends Block
 {
     /**
-     * Product name link selector
+     * Item product block
      *
      * @var string
      */
-    protected $productName = '//a[contains(@class,"product-item-link") and contains(.,"%s")]';
+    protected $itemBlock = '//li[.//a[contains(.,"%s")]]';
 
     /**
-     * Check that product present in wishlist
+     * Get item product block
      *
      * @param string $productName
-     * @return bool
+     * @return Product
      */
-    public function isProductPresent($productName)
+    public function getItemProductByName($productName)
     {
-        $productNameSelector = sprintf($this->productName, $productName);
-
-        return $this->_rootElement->find($productNameSelector, Locator::SELECTOR_XPATH)->isVisible();
+        $productBlock = sprintf($this->itemBlock, $productName);
+        return $this->blockFactory->create(
+            'Magento\Wishlist\Test\Block\Customer\Wishlist\Items\Product',
+            ['element' => $this->_rootElement->find($productBlock, Locator::SELECTOR_XPATH)]
+        );
     }
 }
diff --git a/app/code/Magento/Index/Model/Indexer/Factory.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
similarity index 60%
rename from app/code/Magento/Index/Model/Indexer/Factory.php
rename to dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
index 99b20a50317..55709268310 100644
--- a/app/code/Magento/Index/Model/Indexer/Factory.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php
@@ -22,36 +22,42 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Wishlist\Test\Block\Customer\Wishlist\Items;
+
+use Mtf\Block\Form;
+
 /**
- * Indexer factory
+ * Class Product
+ * Wishlist item product form
  */
-namespace Magento\Index\Model\Indexer;
-
-class Factory
+class Product extends Form
 {
     /**
-     * @var \Magento\Framework\ObjectManager|null
+     * Selector for 'Add to Cart' button
+     *
+     * @var string
      */
-    protected $_objectManager = null;
+    protected $addToCart = '.action.tocart';
 
     /**
-     * @param \Magento\Framework\ObjectManager $objectManager
+     * Fill item product details
+     *
+     * @param array $fields
+     * @return void
      */
-    public function __construct(\Magento\Framework\ObjectManager $objectManager)
+    public function fillProduct(array $fields)
     {
-        $this->_objectManager = $objectManager;
+        $mapping = $this->dataMapping($fields);
+        $this->_fill($mapping);
     }
 
     /**
-     * @param string $indexerInstanceName
-     * @return \Magento\Index\Model\Indexer\AbstractIndexer|null
+     * Click button 'Add To Cart'
+     *
+     * @return void
      */
-    public function create($indexerInstanceName)
+    public function clickAddToCart()
     {
-        if ($indexerInstanceName) {
-            return $this->_objectManager->create($indexerInstanceName);
-        }
-
-        return null;
+        $this->_rootElement->find($this->addToCart)->click();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.xml
new file mode 100644
index 00000000000..236f27a2417
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <qty>
+            <selector>[data-role="qty"]</selector>
+        </qty>
+        <description>
+            <selector>textarea</selector>
+        </description>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductIsAbsentInWishlist.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductsIsAbsentInWishlist.php
similarity index 80%
rename from dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductIsAbsentInWishlist.php
rename to dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductsIsAbsentInWishlist.php
index d5d194f202e..c7e997387af 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductIsAbsentInWishlist.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductsIsAbsentInWishlist.php
@@ -34,10 +34,10 @@ use Magento\Customer\Test\Page\CustomerAccountLogout;
 use Mtf\Fixture\InjectableFixture;
 
 /**
- * Class AssertProductIsAbsentInWishlist
- * Assert that product is absent in Wishlist on Frontend
+ * Class AssertProductsIsAbsentInWishlist
+ * Assert products is absent in Wishlist on Frontend
  */
-class AssertProductIsAbsentInWishlist extends AbstractConstraint
+class AssertProductsIsAbsentInWishlist extends AbstractConstraint
 {
     /**
      * Constraint severeness
@@ -51,7 +51,7 @@ class AssertProductIsAbsentInWishlist extends AbstractConstraint
      *
      * @param CustomerAccountIndex $customerAccountIndex
      * @param WishlistIndex $wishlistIndex
-     * @param InjectableFixture $product
+     * @param InjectableFixture[] $products
      * @param CustomerInjectable $customer
      * @param CmsIndex $cmsIndex
      * @param CustomerAccountLogin $customerAccountLogin
@@ -61,21 +61,25 @@ class AssertProductIsAbsentInWishlist extends AbstractConstraint
     public function processAssert(
         CustomerAccountIndex $customerAccountIndex,
         WishlistIndex $wishlistIndex,
-        InjectableFixture $product,
+        $products,
         CustomerInjectable $customer,
         CmsIndex $cmsIndex,
         CustomerAccountLogin $customerAccountLogin,
         CustomerAccountLogout $customerAccountLogout
     ) {
-        $productName = $product->getName();
         $customerAccountLogout->open();
         $cmsIndex->getLinksBlock()->openLink('Log In');
         $customerAccountLogin->getLoginBlock()->login($customer);
         $customerAccountIndex->open()->getAccountMenuBlock()->openMenuItem("My Wish List");
-        \PHPUnit_Framework_Assert::assertFalse(
-            $wishlistIndex->getWishlistBlock()->getProductItemsBlock()->isProductPresent($productName),
-            'Product \'' . $productName . '\' is present in Wishlist on Frontend.'
-        );
+        $itemBlock = $wishlistIndex->getWishlistBlock()->getProductItemsBlock();
+
+        foreach ($products as $itemProduct) {
+            $productName = $itemProduct->getName();
+            \PHPUnit_Framework_Assert::assertFalse(
+                $itemBlock->getItemProductByName($productName)->isVisible(),
+                'Product \'' . $productName . '\' is present in Wishlist on Frontend.'
+            );
+        }
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertWishlistIsEmpty.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertWishlistIsEmpty.php
new file mode 100644
index 00000000000..70a9e86d12f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertWishlistIsEmpty.php
@@ -0,0 +1,73 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Wishlist\Test\Constraint;
+
+use Mtf\Fixture\InjectableFixture;
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Wishlist\Test\Page\WishlistIndex;
+
+/**
+ * Class AssertWishlistIsEmpty
+ * Check that there are no Products in Wishlist
+ */
+class AssertWishlistIsEmpty extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Check that there are no Products in Wishlist
+     *
+     * @param InjectableFixture[] $products
+     * @param CmsIndex $cmsIndex
+     * @param WishlistIndex $wishlistIndex
+     * @return void
+     */
+    public function processAssert(array $products, CmsIndex $cmsIndex, WishlistIndex $wishlistIndex)
+    {
+        $cmsIndex->getLinksBlock()->openLink("My Wish List");
+        foreach ($products as $itemProduct) {
+            \PHPUnit_Framework_Assert::assertFalse(
+                $wishlistIndex->getItemsBlock()->getItemProductByName($itemProduct->getName())->isVisible(),
+                '"' . $itemProduct->getName() . '" product is present in Wishlist.'
+            );
+        }
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Wishlist is empty.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
new file mode 100644
index 00000000000..cd9bcf388f7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php
@@ -0,0 +1,230 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Wishlist\Test\TestCase;
+
+use Mtf\ObjectManager;
+use Mtf\Client\Browser;
+use Mtf\TestCase\Injectable;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Checkout\Test\Fixture\Cart;
+use Magento\Wishlist\Test\Page\WishlistIndex;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Test Creation for Adding products from Wishlist to Cart
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create customer and login to frontend
+ * 2. Create products
+ * 3. Add products to customer's wishlist
+ *
+ * Steps:
+ * 1. Navigate to My Account -> My Wishlist
+ * 2. Fill qty and update wish list
+ * 3. Click "Add to Cart"
+ * 4. Perform asserts
+ *
+ * @group Wishlist_(CS)
+ * @ZephyrId MAGETWO-25268
+ */
+class AddProductsToCartFromCustomerWishlistOnFrontendTest extends Injectable
+{
+    /**
+     * Object Manager
+     *
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Cms index page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Product view page
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Fixture factory
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Browser
+     *
+     * @var Browser
+     */
+    protected $browser;
+
+    /**
+     * Wishlist index page
+     *
+     * @var WishlistIndex
+     */
+    protected $wishlistIndex;
+
+    /**
+     * Injection data
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureFactory $fixtureFactory
+     * @param Browser $browser
+     * @param WishlistIndex $wishlistIndex
+     * @param ObjectManager $objectManager
+     * @return void
+     */
+    public function __inject(
+        CmsIndex $cmsIndex,
+        CatalogProductView $catalogProductView,
+        FixtureFactory $fixtureFactory,
+        Browser $browser,
+        WishlistIndex $wishlistIndex,
+        ObjectManager $objectManager
+    ) {
+        $this->cmsIndex = $cmsIndex;
+        $this->catalogProductView = $catalogProductView;
+        $this->fixtureFactory = $fixtureFactory;
+        $this->browser = $browser;
+        $this->wishlistIndex = $wishlistIndex;
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Run suggest searching result test
+     *
+     * @param CustomerInjectable $customer
+     * @param string $products
+     * @param int $qty
+     * @return array
+     */
+    public function test(CustomerInjectable $customer, $products, $qty)
+    {
+        // Preconditions
+        $customer->persist();
+        $this->loginCustomer($customer);
+        $products = $this->createProducts($products);
+        $this->addToWishlist($products);
+
+        // Steps
+        $this->addToCart($products, $qty);
+
+        // Prepare data for asserts
+        $cart = $this->createCart($products);
+
+        return ['products' => $products, 'customer' => $customer, 'cart' => $cart];
+    }
+
+    /**
+     * Login customer
+     *
+     * @param CustomerInjectable $customer
+     * @return void
+     */
+    protected function loginCustomer(CustomerInjectable $customer)
+    {
+        $loginCustomerOnFrontendStep = $this->objectManager->create(
+            'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep',
+            ['customer' => $customer]
+        );
+        $loginCustomerOnFrontendStep->run();
+    }
+
+    /**
+     * Create products
+     *
+     * @param string $products
+     * @return array
+     */
+    protected function createProducts($products)
+    {
+        $createProductsStep = $this->objectManager->create(
+            'Magento\Catalog\Test\TestStep\CreateProductsStep',
+            ['products' => $products]
+        );
+
+        return $createProductsStep->run()['products'];
+    }
+
+    /**
+     * Add products to wish list
+     *
+     * @param array $products
+     * @return void
+     */
+    protected function addToWishlist(array $products)
+    {
+        foreach ($products as $product) {
+            $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html');
+            $this->catalogProductView->getViewBlock()->addToWishlist();
+        }
+    }
+
+    /**
+     * Add products from wish list to cart
+     *
+     * @param array $products
+     * @param int $qty
+     * @return void
+     */
+    protected function addToCart(array $products, $qty)
+    {
+        foreach ($products as $product) {
+            $this->cmsIndex->getLinksBlock()->openLink("My Wish List");
+            if ($qty != '-') {
+                $this->wishlistIndex->getItemsBlock()->getItemProductByName($product->getName())
+                    ->fillProduct(['qty' => $qty]);
+                $this->wishlistIndex->getWishlistBlock()->clickUpdateWishlist();
+            }
+            $this->wishlistIndex->getItemsBlock()->getItemProductByName($product->getName())->clickAddToCart();
+            if (strpos($this->browser->getUrl(), 'checkout/cart/') === false) {
+                $this->catalogProductView->getViewBlock()->addToCart($product);
+            }
+        }
+    }
+
+    /**
+     * Create cart fixture
+     *
+     * @param array $products
+     * @return Cart
+     */
+    protected function createCart(array $products)
+    {
+        return $this->fixtureFactory->createByCode('cart', ['data' => ['items' => ['products' => $products]]]);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest/test.csv b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest/test.csv
new file mode 100644
index 00000000000..3a96f1fbf2b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest/test.csv
@@ -0,0 +1,4 @@
+"products";"qty";"constraint"
+"catalogProductSimple::100_dollar_product";"2";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
+"catalogProductVirtual::50_dollar_product";"1";"assertProductQtyInShoppingCart, assertProductsIsAbsentInWishlist"
+"catalogProductSimple::default,catalogProductVirtual::50_dollar_product,catalogProductSimple::default,catalogProductVirtual::50_dollar_product";"-";"assertProductQtyInShoppingCart, assertWishlistIsEmpty"
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php
index 42dc56f3d80..e856c74d5c9 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php
@@ -139,7 +139,6 @@ class DeleteProductFromCustomerWishlistOnBackendTest extends Injectable
         $this->catalogProductView = $catalogProductView;
         $this->customerIndex = $customerIndex;
         $this->customerIndexEdit = $customerIndexEdit;
-
     }
 
     /**
@@ -170,7 +169,7 @@ class DeleteProductFromCustomerWishlistOnBackendTest extends Injectable
         $filter = ['product_name' => $product->getName()];
         $customerForm->getTabElement('wishlist')->getSearchGridBlock()->searchAndDelete($filter);
 
-        return ['product' => $product];
+        return ['products' => [$product]];
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest/test.csv b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest/test.csv
index 1991656cea3..de3b5311561 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest/test.csv
@@ -1,3 +1,3 @@
 "product";"constraint"
-"configurableProductInjectable::default";"assertProductIsAbsentInWishlist"
-"catalogProductSimple::simple_for_composite_products";"assertProductIsAbsentInWishlist"
+"configurableProductInjectable::default";"assertProductsIsAbsentInWishlist"
+"catalogProductSimple::simple_for_composite_products";"assertProductsIsAbsentInWishlist"
diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/etc/constraint.xml
index 3645f787454..7d593d18794 100644
--- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/etc/constraint.xml
@@ -27,7 +27,10 @@
     <assertWishlistShareMessage module="Magento_Wishlist">
         <severeness>low</severeness>
     </assertWishlistShareMessage>
-    <assertProductIsAbsentInWishlist module="Magento_Wishlist">
+    <assertProductsIsAbsentInWishlist module="Magento_Wishlist">
         <severeness>low</severeness>
-    </assertProductIsAbsentInWishlist>
+    </assertProductsIsAbsentInWishlist>
+    <assertWishlistIsEmpty module="Magento_Wishlist">
+        <severeness>low</severeness>
+    </assertWishlistIsEmpty>
 </constraint>
diff --git a/dev/tests/integration/framework/tests/unit/phpunit.xml.dist b/dev/tests/integration/framework/tests/unit/phpunit.xml.dist
index 31ac99e87b5..736e45759ce 100644
--- a/dev/tests/integration/framework/tests/unit/phpunit.xml.dist
+++ b/dev/tests/integration/framework/tests/unit/phpunit.xml.dist
@@ -23,7 +23,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <!-- Test suites definition -->
     <testsuites>
         <testsuite name="Unit Tests for Integration Tests Framework">
diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist
index 2f406070a79..e4604cea0b1 100644
--- a/dev/tests/integration/phpunit.xml.dist
+++ b/dev/tests/integration/phpunit.xml.dist
@@ -23,7 +23,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <!-- Test suites definition -->
     <testsuites>
         <!-- Memory tests run first to prevent influence of other tests on accuracy of memory measurements -->
diff --git a/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php b/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
index d5d21196479..a2e65415972 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
@@ -67,7 +67,7 @@ class RouterTest extends \PHPUnit_Framework_TestCase
     public function getControllerClassNameDataProvider()
     {
         return array(
-            array('Magento_Index', 'process', 'Magento\Index\Controller\Adminhtml\Process'),
+            array('Magento_Module', 'controller', 'Magento\Module\Controller\Adminhtml\Controller'),
         );
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Page/HeadTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Page/HeadTest.php
deleted file mode 100644
index 76e4d0b2985..00000000000
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Page/HeadTest.php
+++ /dev/null
@@ -1,42 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block\Page;
-
-/**
- * @magentoAppArea adminhtml
- */
-class HeadTest extends \PHPUnit_Framework_TestCase
-{
-    public function testConstruct()
-    {
-        $this->assertInstanceOf(
-            'Magento\Backend\Block\Page\Head',
-            \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-                'Magento\Framework\View\LayoutInterface'
-            )->createBlock(
-                'Magento\Backend\Block\Page\Head'
-            )
-        );
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php
index eb03107eba5..747d0d40d29 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Backend\Controller\Adminhtml\System;
 
+use Magento\TestFramework\Bootstrap;
+
 /**
  * @magentoAppArea adminhtml
  */
@@ -62,6 +64,9 @@ class AccountTest extends \Magento\Backend\Utility\Controller
         )->setParam(
             'password_confirmation',
             $passwordConfirmation
+        )->setParam(
+            \Magento\Backend\Block\System\Account\Edit\Form::IDENTITY_VERIFICATION_PASSWORD_FIELD,
+            Bootstrap::ADMIN_PASSWORD
         );
         $this->dispatch('backend/admin/system_account/save');
 
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlrewriteTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
similarity index 92%
rename from dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlrewriteTest.php
rename to dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
index f407159ae7b..40d98f02c2f 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlrewriteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
@@ -26,7 +26,7 @@ namespace Magento\Backend\Controller\Adminhtml;
 /**
  * @magentoAppArea adminhtml
  */
-class UrlrewriteTest extends \Magento\Backend\Utility\Controller
+class UrlRewriteTest extends \Magento\Backend\Utility\Controller
 {
     /**
      * Check save cms page rewrite
@@ -47,12 +47,12 @@ class UrlrewriteTest extends \Magento\Backend\Utility\Controller
                 'cms_page' => $page->getId()
             ]
         );
-        $this->dispatch('backend/admin/urlrewrite/save');
+        $this->dispatch('backend/admin/url_rewrite/save');
 
         $this->assertSessionMessages(
             $this->contains('The URL Rewrite has been saved.'),
             \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
         );
-        $this->assertRedirect($this->stringContains('backend/admin/urlrewrite/index'));
+        $this->assertRedirect($this->stringContains('backend/admin/url_rewrite/index'));
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
similarity index 81%
rename from dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php
rename to dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
index fec92ee622f..f58deb26edf 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
@@ -21,11 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Model\Config\Backend;
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
 use Magento\Framework\Model\Exception;
 
 /**
- * Test \Magento\Backend\Model\Config\Backend\Domain
+ * Test \Magento\Backend\Model\Config\Backend\Cookie\Domain
  *
  * @magentoAppArea adminhtml
  */
@@ -39,9 +40,9 @@ class DomainTest extends \PHPUnit_Framework_TestCase
      */
     public function testBeforeSave($value, $exceptionMessage = null)
     {
-        /** @var $domain \Magento\Backend\Model\Config\Backend\Domain */
+        /** @var $domain \Magento\Backend\Model\Config\Backend\Cookie\Domain */
         $domain = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Backend\Model\Config\Backend\Domain'
+            'Magento\Backend\Model\Config\Backend\Cookie\Domain'
         );
         $domain->setValue($value);
         try {
@@ -53,7 +54,7 @@ class DomainTest extends \PHPUnit_Framework_TestCase
             }
         } catch (Exception $e) {
             $this->assertContains('Invalid domain name: ', $e->getMessage());
-            $this->assertContains($exceptionMessage, $e->getMessage());
+            $this->assertEquals($exceptionMessage, $e->getMessage());
             $this->assertNull($domain->getId());
         }
     }
@@ -64,10 +65,10 @@ class DomainTest extends \PHPUnit_Framework_TestCase
     public function beforeSaveDataProvider()
     {
         return [
-            'not string' => [['array'], 'Invalid type given. String expected'],
+            'not string' => [['array'], 'Invalid domain name: must be a string'],
             'invalid hostname' => [
                 'http://',
-                'The input does not match the expected structure for a DNS hostname; '
+                'Invalid domain name: The input does not match the expected structure for a DNS hostname; '
                 . 'The input does not appear to be a valid URI hostname; '
                 . 'The input does not appear to be a valid local network name'
             ],
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
new file mode 100644
index 00000000000..2750681c66b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Integration test for Magento\Backend\Model\Config\Backend\Cookie\Lifetime
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+class LifetimeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Invalid cookie lifetime: must be numeric
+     */
+    public function testBeforeSaveException()
+    {
+        $invalidCookieLifetime = 'invalid lifetime';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Backend\Model\Config\Backend\Cookie\Lifetime $model */
+        $model = $objectManager->create('Magento\Backend\Model\Config\Backend\Cookie\Lifetime');
+        $model->setValue($invalidCookieLifetime);
+        $model->save();
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
new file mode 100644
index 00000000000..d4390c39ab4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Integration test for Magento\Backend\Model\Config\Backend\Cookie\Path
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+class PathTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Invalid cookie path
+     */
+    public function testBeforeSaveException()
+    {
+        $invalidPath = 'invalid path';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Backend\Model\Config\Backend\Cookie\Lifetime $model */
+        $model = $objectManager->create('Magento\Backend\Model\Config\Backend\Cookie\Path');
+        $model->setValue($invalidPath);
+        $model->save();
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
new file mode 100644
index 00000000000..24882bb6b6f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
@@ -0,0 +1,68 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Session;
+
+use PHPUnit_Framework_TestCase;
+
+/**
+ * Test class for \Magento\Backend\Model\Session\AdminConfig.
+ *
+ * @magentoAppArea adminhtml
+ */
+class AdminConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        \Magento\TestFramework\Helper\Bootstrap::getInstance()
+            ->loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE);
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    public function testConstructor()
+    {
+        $model = $this->objectManager->create('Magento\Backend\Model\Session\AdminConfig');
+        $this->assertEquals('/backend', $model->getCookiePath());
+    }
+
+    /**
+     * Test for setting session name for admin
+     *
+     */
+    public function testSetSessionNameByConstructor()
+    {
+        $sessionName = 'adminHtmlSession';
+        $adminConfig = $this->objectManager->create(
+            'Magento\Backend\Model\Session\AdminConfig',
+            ['sessionName' => $sessionName]
+        );
+        $this->assertSame($sessionName, $adminConfig->getName());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/AbstractTest.php
index 2a13632919c..0188df4e8ad 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/AbstractTest.php
@@ -27,6 +27,7 @@ namespace Magento\Catalog\Block\Product;
  * Test class for \Magento\Catalog\Block\Product\Abstract.
  *
  * @magentoDataFixture Magento/Catalog/_files/product_with_image.php
+ * @magentoAppArea frontend
  */
 class AbstractTest extends \PHPUnit_Framework_TestCase
 {
@@ -88,9 +89,15 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
         $this->_block->setProduct($this->_product);
     }
 
+    /**
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_simple.php
+     * @magentoAppIsolation enabled
+     */
     public function testGetAddToCartUrl()
     {
-        $url = $this->_block->getAddToCartUrl($this->_product);
+        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+        $product->load(1);
+        $url = $this->_block->getAddToCartUrl($product);
         $this->assertStringEndsWith('?options=cart', $url);
         $this->assertStringMatchesFormat('%ssimple-product.html%s', $url);
     }
@@ -146,9 +153,17 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('Image Alt Text', $this->_block->getImageLabel());
     }
 
+    /**
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_simple.php
+     * @magentoAppIsolation enabled
+     */
     public function testGetProductUrl()
     {
-        $this->assertStringEndsWith('simple-product.html', $this->_block->getProductUrl($this->_product));
+        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create('Magento\Catalog\Model\Product');
+        $product->load(1);
+
+        $this->assertStringEndsWith('simple-product.html', $this->_block->getProductUrl($product));
     }
 
     public function testHasProductUrl()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php
index 95cc145deb7..53335fb4eb2 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php
@@ -52,17 +52,19 @@ class ViewTest extends \PHPUnit_Framework_TestCase
 
     public function testSetLayout()
     {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
         /** @var $layout \Magento\Framework\View\Layout */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\LayoutInterface'
-        );
-        $headBlock = $layout->createBlock('Magento\Framework\View\Element\Template', 'head');
+        $layout = $objectManager->get('Magento\Framework\View\LayoutInterface');
+        /** @var $pageConfig \Magento\Framework\View\Page\Config */
+        $pageConfig = $objectManager->get('Magento\Framework\View\Page\Config');
+
         $layout->addBlock($this->_block);
 
-        $this->assertNotEmpty($headBlock->getTitle());
-        $this->assertEquals($this->_product->getMetaTitle(), $headBlock->getTitle());
-        $this->assertEquals($this->_product->getMetaKeyword(), $headBlock->getKeywords());
-        $this->assertEquals($this->_product->getMetaDescription(), $headBlock->getDescription());
+        $this->assertNotEmpty($pageConfig->getTitle());
+        $this->assertEquals($this->_product->getMetaTitle(), $pageConfig->getTitle());
+        $this->assertEquals($this->_product->getMetaKeyword(), $pageConfig->getKeywords());
+        $this->assertEquals($this->_product->getMetaDescription(), $pageConfig->getDescription());
     }
 
     public function testGetProduct()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/CategoryTest.php
index 7613d13fa8c..7b09d6c5d39 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/CategoryTest.php
@@ -27,6 +27,7 @@ namespace Magento\Catalog\Controller;
  * Test class for \Magento\Catalog\Controller\Category.
  *
  * @magentoDataFixture Magento/Catalog/_files/categories.php
+ * @magentoAppArea frontend
  */
 class CategoryTest extends \Magento\TestFramework\TestCase\AbstractController
 {
@@ -45,7 +46,7 @@ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractController
                 '$categoryId' => 5,
                 array('catalog_category_view_type_default', 'catalog_category_view_type_default_without_children'),
                 array(
-                    '%acategorypath-category-1-category-1-1-category-1-1-1-html%a',
+                    '%acategorypath-category-1-category-1-1-category-1-1-1%a',
                     '%acategory-category-1-1-1%a',
                     '%a<title>Category 1.1.1 - Category 1.1 - Category 1</title>%a',
                     '%a<h1%S>%SCategory 1.1.1%S</h1>%a',
@@ -57,7 +58,7 @@ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractController
                 '$categoryId' => 4,
                 array('catalog_category_view_type_layered'),
                 array(
-                    '%acategorypath-category-1-category-1-1-html%a',
+                    '%acategorypath-category-1-category-1-1%a',
                     '%acategory-category-1-1%a',
                     '%a<title>Category 1.1 - Category 1</title>%a',
                     '%a<h1%S>%SCategory 1.1%S</h1>%a',
@@ -75,6 +76,7 @@ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractController
      */
     public function testViewAction($categoryId, array $expectedHandles, array $expectedContent)
     {
+        $this->markTestSkipped('MAGETWO-27621');
         $this->dispatch("catalog/category/view/id/{$categoryId}");
 
         /** @var $objectManager \Magento\TestFramework\ObjectManager */
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
index 331b44bbe0d..27a00c053c1 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php
@@ -108,51 +108,6 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
         $this->assertFalse($this->_helper->canShow($category));
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     */
-    public function testGetCategoryUrlSuffixDefault()
-    {
-        $this->assertEquals('.html', $this->_helper->getCategoryUrlSuffix());
-    }
-
-    /**
-     * @magentoConfigFixture current_store catalog/seo/category_url_suffix .htm
-     * @magentoAppIsolation enabled
-     */
-    public function testGetCategoryUrlSuffix()
-    {
-        $this->assertEquals('.htm', $this->_helper->getCategoryUrlSuffix());
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     */
-    public function testGetCategoryUrlPathDefault()
-    {
-        $this->assertEquals(
-            'http://example.com/category',
-            $this->_helper->getCategoryUrlPath('http://example.com/category.html')
-        );
-
-        $this->assertEquals(
-            'http://example.com/category/',
-            $this->_helper->getCategoryUrlPath('http://example.com/category.html/', true)
-        );
-    }
-
-    /**
-     * @magentoConfigFixture current_store catalog/seo/category_url_suffix .htm
-     * @magentoAppIsolation enabled
-     */
-    public function testGetCategoryUrlPath()
-    {
-        $this->assertEquals(
-            'http://example.com/category.html',
-            $this->_helper->getCategoryUrlPath('http://example.com/category.html')
-        );
-    }
-
     public function testCanUseCanonicalTagDefault()
     {
         $this->assertEquals(0, $this->_helper->canUseCanonicalTag());
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
index 6b90f42df52..c883c8c1465 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php
@@ -204,19 +204,6 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $this->assertFalse($this->helper->isPriceGlobal());
     }
 
-    public function testShouldSaveUrlRewritesHistoryDefault()
-    {
-        $this->assertTrue($this->helper->shouldSaveUrlRewritesHistory());
-    }
-
-    /**
-     * @magentoConfigFixture current_store catalog/seo/save_rewrites_history 0
-     */
-    public function testShouldSaveUrlRewritesHistory()
-    {
-        $this->assertFalse($this->helper->shouldSaveUrlRewritesHistory());
-    }
-
     public function testIsUsingStaticUrlsAllowedDefault()
     {
         $this->assertFalse($this->helper->isUsingStaticUrlsAllowed());
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/ViewTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/ViewTest.php
index 12ba98a6d3d..dc678b54cb3 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/ViewTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/ViewTest.php
@@ -107,7 +107,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase
         $pageConfig = $this->objectManager->get('Magento\Framework\View\Page\Config');
         $bodyClass = $pageConfig->getElementAttribute(
             \Magento\Framework\View\Page\Config::ELEMENT_TYPE_BODY,
-            'classes'
+            \Magento\Framework\View\Page\Config::BODY_ATTRIBUTE_CLASS
         );
         $this->assertContains("product-{$uniqid}", $bodyClass);
         $handles = $this->_layout->getUpdate()->getHandles();
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
index bc539b1a0d5..905b333b22f 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php
@@ -40,7 +40,8 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @magentoDataFixture Magento/Catalog/_files/products.php
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_simple.php
+     * @magentoAppIsolation enabled
      */
     public function testGetProductUrl()
     {
@@ -162,11 +163,6 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->_helper->canShow(1));
     }
 
-    public function testGetProductUrlSuffix()
-    {
-        $this->assertEquals('.html', $this->_helper->getProductUrlSuffix());
-    }
-
     public function testCanUseCanonicalTagDefault()
     {
         $this->assertEquals('0', $this->_helper->canUseCanonicalTag());
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
index 5465f19b8a1..a788b07f415 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
@@ -76,13 +76,6 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
         $this->assertSame($instance, $this->_model->getUrlInstance());
     }
 
-    public function testGetUrlRewrite()
-    {
-        $rewrite = $this->_model->getUrlRewrite();
-        $this->assertInstanceOf('Magento\UrlRewrite\Model\UrlRewrite', $rewrite);
-        $this->assertSame($rewrite, $this->_model->getUrlRewrite());
-    }
-
     public function testGetTreeModel()
     {
         $model = $this->_model->getTreeModel();
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
index 38548347e36..9cccbb49e8b 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php
@@ -110,11 +110,15 @@ class CategoryTreeTest extends \PHPUnit_Framework_TestCase
         $this->_model->move(100, 0);
     }
 
+    /**
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
+     * @magentoAppIsolation enabled
+     */
     public function testGetUrlPath()
     {
         $this->assertNull($this->_model->getUrlPath());
-        $this->_model->load(5);
-        $this->assertEquals('category-1/category-1-1/category-1-1-1.html', $this->_model->getUrlPath());
+        $this->_model->load(4);
+        $this->assertEquals('category-1/category-1-1', $this->_model->getUrlPath());
     }
 
     public function testGetParentCategory()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Category/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Category/ProductTest.php
index aac883886e3..f79c35a1c47 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Category/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Category/ProductTest.php
@@ -92,6 +92,8 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @magentoAppArea adminhtml
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
+     * @magentoAppIsolation enabled
      * @depends testReindexAll
      */
     public function testCategoryMove()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php
index 8fe9bed103e..26881b519ba 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php
@@ -27,6 +27,7 @@ namespace Magento\Catalog\Model\Product;
  * Test class for \Magento\Catalog\Model\Product\Url.
  *
  * @magentoDataFixture Magento/Catalog/_files/url_rewrites.php
+ * @magentoAppArea frontend
  */
 class UrlTest extends \PHPUnit_Framework_TestCase
 {
@@ -35,11 +36,19 @@ class UrlTest extends \PHPUnit_Framework_TestCase
      */
     protected $_model;
 
+    /**
+     * @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
+     */
+    protected $urlPathGenerator;
+
     protected function setUp()
     {
         $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             'Magento\Catalog\Model\Product\Url'
         );
+        $this->urlPathGenerator = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator'
+        );
     }
 
     public function testGetUrlInstance()
@@ -49,13 +58,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $this->assertSame($instance, $this->_model->getUrlInstance());
     }
 
-    public function testGetUrlRewrite()
-    {
-        $instance = $this->_model->getUrlRewrite();
-        $this->assertInstanceOf('Magento\UrlRewrite\Model\UrlRewrite', $instance);
-        $this->assertSame($instance, $this->_model->getUrlRewrite());
-    }
-
     public function testGetUrlInStore()
     {
         $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
@@ -89,11 +91,13 @@ class UrlTest extends \PHPUnit_Framework_TestCase
 
         /** @var $category \Magento\Catalog\Model\Category */
         $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Category'
+            'Magento\Catalog\Model\Category',
+            ['data' => ['url_path' => 'category', 'entity_id' => 5, 'path_ids' => [2, 3, 5]]]
         );
-        $category->setUrlPath('category.html');
-        $this->assertEquals('product.html', $this->_model->getUrlPath($product));
-        $this->assertEquals('category/product.html', $this->_model->getUrlPath($product, $category));
+        $category->setOrigData();
+
+        $this->assertEquals('product.html', $this->urlPathGenerator->getUrlPath($product));
+        $this->assertEquals('category/product.html', $this->urlPathGenerator->getUrlPath($product, $category));
     }
 
     public function testGetUrl()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
index ea43aa2b92d..ae282bfc459 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php
@@ -253,12 +253,17 @@ class ProductExternalTest extends \PHPUnit_Framework_TestCase
         $this->_model->setUrlPath('test');
         $this->assertEquals('test', $this->_model->getUrlPath());
 
+        $urlPathGenerator = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator'
+        );
+
         /** @var $category \Magento\Catalog\Model\Category */
         $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Category'
+            'Magento\Catalog\Model\Category',
+            ['data' => ['url_path' => 'category', 'entity_id' => 5, 'path_ids' => [2, 3, 5]]]
         );
-        $category->setUrlPath('category');
-        $this->assertEquals('category/test', $this->_model->getUrlPath($category));
+        $category->setOrigData();
+        $this->assertEquals('category/test', $urlPathGenerator->getUrlPath($this->_model, $category));
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/_files/url_rewrites.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/_files/url_rewrites.php
index 53fa35cea71..17c005a9beb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/_files/url_rewrites.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/_files/url_rewrites.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('adminhtml');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
 $category->setId(
@@ -44,7 +44,7 @@ $category->setId(
     1
 )->save();
 
-$urlKeys = array('url-key-', 'url-key-1', 'url-key-2', 'url-key-5', 'url-key-1000', 'url-key-999', 'url-key-asdf');
+$urlKeys = array('url-key', 'url-key-1', 'url-key-2', 'url-key-5', 'url-key-1000', 'url-key-999', 'url-key-asdf');
 
 foreach ($urlKeys as $i => $urlKey) {
     $id = $i + 1;
@@ -74,6 +74,6 @@ foreach ($urlKeys as $i => $urlKey) {
     )->setUrlKey(
         $urlKey
     )->setUrlPath(
-        $urlKey . '.html'
+        $urlKey //. '.html'
     )->save();
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/UrlTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/UrlTest.php
deleted file mode 100644
index cf10e800439..00000000000
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/UrlTest.php
+++ /dev/null
@@ -1,218 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model;
-
-/**
- * Test class for \Magento\Catalog\Model\Url.
- *
- * @magentoDataFixture Magento/Catalog/_files/url_rewrites.php
- */
-class UrlTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_model;
-
-    protected function setUp()
-    {
-        $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Url'
-        );
-    }
-
-    /**
-     * Retrieve loaded url rewrite
-     *
-     * @param string $idPath
-     * @return \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    protected function _loadRewrite($idPath)
-    {
-        /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-        $rewrite = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\UrlRewrite\Model\UrlRewrite'
-        );
-        $rewrite->loadByIdPath($idPath);
-        return $rewrite;
-    }
-
-    public function testGetStores()
-    {
-        $stores = $this->_model->getStores();
-        $this->assertArrayHasKey(1, $stores); /* Current store identifier */
-    }
-
-    public function testGetResource()
-    {
-        $resource = $this->_model->getResource();
-        $this->assertInstanceOf('Magento\Catalog\Model\Resource\Url', $resource);
-        $this->assertSame($resource, $this->_model->getResource());
-    }
-
-    public function testGetCategoryModel()
-    {
-        $this->assertInstanceOf('Magento\Catalog\Model\Category', $this->_model->getCategoryModel());
-    }
-
-    public function testGetStoreRootCategory()
-    {
-        $root = $this->_model->getStoreRootCategory(1);
-        $this->assertNotEmpty($root);
-        $this->assertInstanceOf('Magento\Framework\Object', $root);
-        $this->assertEquals(2, $root->getId());
-        $this->assertEquals(1, $root->getParentId());
-    }
-
-    public function testSetGetShouldSaveRewritesHistory()
-    {
-        $this->assertTrue($this->_model->getShouldSaveRewritesHistory());
-        /* default value */
-        $this->_model->setShouldSaveRewritesHistory(false);
-        $this->assertFalse($this->_model->getShouldSaveRewritesHistory());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/url_rewrites_invalid.php
-     */
-    public function testRefreshRewrites()
-    {
-        $this->assertNotEmpty($this->_loadRewrite('product/1/4')->getId());
-        $this->assertInstanceOf('Magento\Catalog\Model\Url', $this->_model->refreshRewrites());
-        $this->assertEmpty($this->_loadRewrite('product/1/4')->getId());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/url_rewrites_invalid.php
-     */
-    public function testRefreshCategoryRewrite()
-    {
-        $this->assertNotEmpty($this->_loadRewrite('product/1/4')->getId());
-        $this->_model->refreshCategoryRewrite(4);
-        $this->assertEmpty($this->_loadRewrite('product/1/4')->getId());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/url_rewrites_invalid.php
-     */
-    public function testRefreshProductRewrite()
-    {
-        $this->assertNotEmpty($this->_loadRewrite('product/1/4')->getId());
-        $this->_model->refreshProductRewrite(1);
-        $this->assertEmpty($this->_loadRewrite('product/1/4')->getId());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/url_rewrites_invalid.php
-     */
-    public function testRefreshProductRewrites()
-    {
-        $this->assertNotEmpty($this->_loadRewrite('product/1/4')->getId());
-        $this->_model->refreshProductRewrites(1);
-
-        $this->markTestIncomplete('Rewrite was not removed after refresh, method responsibility is not clear.');
-        $this->assertEmpty($this->_loadRewrite('product/1/4')->getId());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/url_rewrites_invalid.php
-     */
-    public function testClearStoreInvalidRewrites()
-    {
-        $this->assertNotEmpty($this->_loadRewrite('product/1/5')->getId());
-        $this->_model->clearStoreInvalidRewrites();
-        $this->assertEmpty($this->_loadRewrite('product/1/5')->getId());
-    }
-
-    public function testGetUnusedPath()
-    {
-        $this->assertEquals(
-            'simple-product-1.html',
-            $this->_model->getUnusedPath(1, 'simple-product.html', 'product/2', 'simple-product')
-        );
-
-        $this->assertEquals(
-            'category-2-1.html',
-            $this->_model->getUnusedPath(1, 'category-2.html', 'category/5', 'category-2')
-        );
-    }
-
-    public function testGetProductUrlSuffix()
-    {
-        $this->assertEquals('.html', $this->_model->getProductUrlSuffix(1));
-    }
-
-    public function testGetCategoryUrlSuffix()
-    {
-        $this->assertEquals('.html', $this->_model->getCategoryUrlSuffix(1));
-    }
-
-    public function testGetProductRequestPath()
-    {
-        $product = new \Magento\Framework\Object();
-        $product->setName('test product')->setId(uniqid());
-
-        $category = new \Magento\Framework\Object();
-        $category->setName('test category')->setId(uniqid())->setLevel(2)->setUrlPath('test/category');
-
-        $this->assertEquals(
-            'test/category/test-product.html',
-            $this->_model->getProductRequestPath($product, $category)
-        );
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Model\Exception
-     */
-    public function testGeneratePathDefault()
-    {
-        $this->_model->generatePath();
-    }
-
-    public function generatePathDataProvider()
-    {
-        $product = new \Magento\Framework\Object();
-        $product->setName('test product')->setId(111);
-
-        $category = new \Magento\Framework\Object();
-        $category->setName('test category')->setId(999)->setLevel(2)->setUrlPath('test/category')->setParentId(3);
-
-        return array(
-            array('target', $product, null, null, 'catalog/product/view/id/111'),
-            array('target', null, $category, null, 'catalog/category/view/id/999'),
-            array('id', $product, null, null, 'product/111'),
-            array('id', null, $category, null, 'category/999'),
-            array('request', $product, $category, null, 'test/category/test-product.html'),
-            array('request', null, $category, null, 'category-1/test-category.html')
-        );
-    }
-
-    /**
-     * @dataProvider generatePathDataProvider
-     */
-    public function testGeneratePath($type, $product, $category, $parentPath, $result)
-    {
-        $this->assertEquals($result, $this->_model->generatePath($type, $product, $category, $parentPath));
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend.php
new file mode 100644
index 00000000000..8f6465a93f4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend.php
@@ -0,0 +1,26 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('adminhtml');
+require_once __DIR__ . '/category.php';
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend_rollback.php
new file mode 100644
index 00000000000..b3937385572
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_backend_rollback.php
@@ -0,0 +1,38 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $category \Magento\Catalog\Model\Category */
+$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
+$category->load(333);
+if ($category->getId()) {
+    $category->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php
index 48fe277589b..7a200acfdf8 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php
@@ -35,7 +35,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
     ->setDescription('description')
     ->setShortDescription('short description')
     ->setOptionsContainer('container1')
-    ->setMsrpDisplayActualPriceType(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_IN_CART)
+    ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_IN_CART)
     ->setPrice(10)
     ->setWeight(1)
     ->setMetaTitle('meta title')
@@ -59,8 +59,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
     ->setDescription('description')
     ->setShortDescription('short description')
     ->setOptionsContainer('container1')
-    ->setMsrpEnabled(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_YES)
-    ->setMsrpDisplayActualPriceType(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_ON_GESTURE)
+    ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_ON_GESTURE)
     ->setPrice(20)
     ->setWeight(1)
     ->setMetaTitle('meta title')
@@ -83,7 +82,6 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
     ->setTaxClassId('none')
     ->setDescription('description')
     ->setShortDescription('short description')
-    ->setMsrpEnabled(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_NO)
     ->setPrice(30)
     ->setWeight(1)
     ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG)
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites.php
index eee04d92960..4a16bcea2eb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/url_rewrites.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('adminhtml');
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
 /** @var $category \Magento\Catalog\Model\Category */
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
index 230b0a75749..8f48895ee56 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
@@ -63,25 +63,24 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
     public function prepareAttributesWithDefaultValueForSaveDataProvider()
     {
         return array(
-            'Updating existing product with attributes that don\'t have default values' => array(
+            'Updating existing product with attributes that do not have default values' => array(
                 array('sku' => 'simple_product_1', 'price' => 55, '_attribute_set' => 'Default', '_type' => 'simple'),
                 false,
                 array('price' => 55)
             ),
-            'Updating existing product with attributes that do have default values' => array(
+            'Updating existing product with attributes that have default values' => array(
                 array(
                     'sku' => 'simple_product_2',
                     'price' => 65,
                     '_attribute_set' => 'Default',
                     '_type' => 'simple',
                     'visibility' => 1,
-                    'msrp_enabled' => 'Yes',
                     'tax_class_id' => ''
                 ),
                 false,
-                array('price' => 65, 'visibility' => 1, 'msrp_enabled' => 1, 'tax_class_id' => '')
+                array('price' => 65, 'visibility' => 1, 'tax_class_id' => '')
             ),
-            'Adding new product with attributes that don\'t have default values' => array(
+            'Adding new product with attributes that do not have default values' => array(
                 array(
                     'sku' => 'simple_product_3',
                     '_store' => '',
@@ -109,11 +108,10 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'short_description' => 'a',
                     'visibility' => 1,
                     'options_container' => 'container2',
-                    'msrp_enabled' => 2,
-                    'msrp_display_actual_price_type' => 4
+                    'msrp_display_actual_price_type' => 0
                 )
             ),
-            'Adding new product with attributes that do have default values' => array(
+            'Adding new product with attributes that have default values' => array(
                 array(
                     'sku' => 'simple_product_4',
                     '_store' => '',
@@ -129,7 +127,6 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'description' => 'a',
                     'short_description' => 'a',
                     'visibility' => 2,
-                    'msrp_enabled' => 'Yes',
                     'msrp_display_actual_price_type' => 'In Cart'
                 ),
                 true,
@@ -143,7 +140,6 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'short_description' => 'a',
                     'visibility' => 2,
                     'options_container' => 'container2',
-                    'msrp_enabled' => 1,
                     'msrp_display_actual_price_type' => 2
                 )
             )
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/categories.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/categories.php
new file mode 100644
index 00000000000..43f25b2c9eb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/categories.php
@@ -0,0 +1,84 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()
+    ->loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE);
+
+$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+    'Magento\Catalog\Model\Resource\Setup',
+    array('resourceName' => 'catalog_setup')
+);
+/**
+ * After installation system has two categories: root one with ID:1 and Default category with ID:2
+ */
+/** @var $category \Magento\Catalog\Model\Category */
+$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
+$category->setId(3)
+    ->setName('Category 1')
+    ->setParentId(2)
+    ->setPath('1/2/3')
+    ->setLevel(2)
+    ->setAvailableSortBy('name')
+    ->setDefaultSortBy('name')
+    ->setIsActive(true)
+    ->setPosition(1)
+    ->save();
+
+$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
+$category->setId(4)
+    ->setName('Category 1.1')
+    ->setParentId(3)
+    ->setPath('1/2/3/4')
+    ->setLevel(3)
+    ->setAvailableSortBy('name')
+    ->setDefaultSortBy('name')
+    ->setIsActive(true)
+    ->setIsAnchor(true)
+    ->setPosition(1)
+    ->save();
+$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
+$category->setId(5)
+    ->setName('Category 1.1.1')
+    ->setParentId(4)
+    ->setPath('1/2/3/4/5')
+    ->setLevel(4)
+    ->setAvailableSortBy('name')
+    ->setDefaultSortBy('name')
+    ->setIsActive(true)
+    ->setPosition(1)
+    ->setCustomUseParentSettings(0)
+    ->setCustomDesign('Magento/blank')
+    ->save();
+
+$category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category');
+$category->setId(6)
+    ->setName('Category 2')
+    ->setParentId(2)
+    ->setPath('1/2/6')
+    ->setLevel(2)
+    ->setAvailableSortBy('name')
+    ->setDefaultSortBy('name')
+    ->setIsActive(true)
+    ->setPosition(2)
+    ->save();
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_simple.php
new file mode 100644
index 00000000000..4361117e999
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_simple.php
@@ -0,0 +1,28 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()
+    ->loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE);
+
+require __DIR__ . '/../../Catalog/_files/product_simple.php';
diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
index 3e91e58008e..a3c22505224 100644
--- a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
+++ b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
@@ -23,6 +23,9 @@
  */
 namespace Magento\Cms\Model;
 
+/**
+ * @magentoAppArea adminhtml
+ */
 class PageTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -30,6 +33,21 @@ class PageTest extends \PHPUnit_Framework_TestCase
      */
     protected $model;
 
+    protected function setUp()
+    {
+        $user = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\User\Model\User'
+        )->loadByUsername(
+            \Magento\TestFramework\Bootstrap::ADMIN_NAME
+        );
+
+        /** @var $session \Magento\Backend\Model\Auth\Session */
+        $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Backend\Model\Auth\Session'
+        );
+        $session->setUser($user);
+    }
+
     /**
      * @magentoDbIsolation enabled
      * @dataProvider generateIdentifierFromTitleDataProvider
@@ -47,13 +65,13 @@ class PageTest extends \PHPUnit_Framework_TestCase
     public function generateIdentifierFromTitleDataProvider()
     {
         return array(
-            array('data' => array('title' => 'Test title'), 'expectedIdentifier' => 'test-title'),
+            array('data' => array('title' => 'Test title', 'stores' => [1]), 'expectedIdentifier' => 'test-title'),
             array(
-                'data' => array('title' => 'Кирилический заголовок'),
+                'data' => array('title' => 'Кирилический заголовок', 'stores' => [1]),
                 'expectedIdentifier' => 'kirilicheskij-zagolovok'
             ),
             array(
-                'data' => array('title' => 'Test title', 'identifier' => 'custom-identifier'),
+                'data' => array('title' => 'Test title', 'identifier' => 'custom-identifier', 'stores' => [1]),
                 'expectedIdentifier' => 'custom-identifier'
             )
         );
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
index 11f1b7a6fd6..bcbcd0e6068 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
@@ -49,9 +49,6 @@ class ProductTest extends \Magento\Backend\Utility\Controller
         /** @var $product \Magento\Catalog\Model\Product */
         $product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
         $this->assertEquals($associatedProductIds, $product->getAssociatedProductIds());
-
-        /** @see \Magento\Backend\Utility\Controller::assertPostConditions() */
-        $this->markTestIncomplete('Suppressing admin error messages validation until the bug MAGETWO-7044 is fixed.');
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Core/Model/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml b/dev/tests/integration/testsuite/Magento/Core/Model/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
index 2527584dfef..daac0d65c2a 100644
--- a/dev/tests/integration/testsuite/Magento/Core/Model/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
+++ b/dev/tests/integration/testsuite/Magento/Core/Model/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
@@ -23,26 +23,20 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../../../app/code/Magento/Core/etc/layout_single.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <head>
+        <title>Magento Admin</title>
+        <script src="prototype/prototype.js"/>
+        <script src="prototype/window.js"/>
+        <script src="prototype/deprecation.js"/>
+    </head>
+    <referenceBlock name="after.body.start">
+        <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
+    </referenceBlock>
     <block class="Magento\Backend\Block\Page" name="root" output="1" template="page.phtml">
-        <block class="Magento\Backend\Block\Page\Head" name="head" as="head" template="page/head.phtml">
-            <action method="setTitle">
-                <argument translate="true" name="title" xsi:type="string">Magento Admin</argument>
-            </action>
-            <action method="addJs">
-                <argument name="file" xsi:type="string">prototype/prototype.js</argument>
-            </action>
-            <action method="addJs">
-                <argument name="file" xsi:type="string">prototype/window.js</argument>
-            </action>
-            <action method="addJs" ifconfig="dev/js/deprecation">
-                <argument name="file" xsi:type="string">prototype/deprecation.js</argument>
-            </action>
-            <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
-        </block>
         <block class="Magento\Backend\Block\Page\Header" name="header" as="header"/>
         <block class="Magento\Backend\Block\Menu" name="menu" as="menu"/>
         <block class="Magento\Framework\View\Element\Messages" name="messages" as="messages"/>
         <block class="Magento\Framework\View\Element\Text" as="no_name"/>
     </block>
-</layout>
+</page>
diff --git a/dev/tests/integration/testsuite/Magento/Core/_files/url_rewrite.php b/dev/tests/integration/testsuite/Magento/Core/_files/url_rewrite.php
deleted file mode 100644
index 887a6d6e733..00000000000
--- a/dev/tests/integration/testsuite/Magento/Core/_files/url_rewrite.php
+++ /dev/null
@@ -1,47 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$cmsPageId = 1;
-$rewriteUrl = 'test_rewrite_path';
-
-// get CMS page
-/** @var $cmsPage \Magento\Cms\Model\Page */
-$cmsPage = $objectManager->create('Magento\Cms\Model\Page');
-$cmsPage->load($cmsPageId);
-if ($cmsPage->isObjectNew()) {
-    $cmsPage->setId($cmsPageId);
-    $cmsPage->save();
-}
-
-// create URL rewrite
-/** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-$rewrite = $objectManager->create('Magento\UrlRewrite\Model\UrlRewrite');
-$rewrite->setIdPath(
-    'cms_page/' . $cmsPage->getId()
-)->setRequestPath(
-    $rewriteUrl
-)->setTargetPath(
-    'cms/page/view/page_id/' . $cmsPage->getId()
-)->save();
diff --git a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Model/System/CurrencysymbolTest.php b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Model/System/CurrencysymbolTest.php
new file mode 100644
index 00000000000..670ec5aa2cc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Model/System/CurrencysymbolTest.php
@@ -0,0 +1,108 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CurrencySymbol\Model\System;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * Test for Magento\CurrencySymbol\Model\System\Currencysymbol
+ *
+ * @magentoAppArea adminhtml
+ */
+class CurrencysymbolTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CurrencySymbol\Model\System\Currencysymbol
+     */
+    protected $currencySymbolModel;
+
+    protected function setUp()
+    {
+        $this->currencySymbolModel = Bootstrap::getObjectManager()->create(
+            'Magento\CurrencySymbol\Model\System\Currencysymbol'
+        );
+    }
+
+    protected function tearDown()
+    {
+        $this->currencySymbolModel = null;
+        Bootstrap::getObjectManager()->get('Magento\Framework\App\Config\ReinitableConfigInterface')->reinit();
+        Bootstrap::getObjectManager()->create('Magento\Framework\StoreManagerInterface')->reinitStores();
+    }
+
+    public function testGetCurrencySymbolsData()
+    {
+        $currencySymbolsData = $this->currencySymbolModel->getCurrencySymbolsData();
+        $this->assertArrayHasKey('USD', $currencySymbolsData, 'Default currency option for USD is missing.');
+        $this->assertArrayHasKey('EUR', $currencySymbolsData, 'Default currency option for EUR is missing.');
+    }
+
+    public function testSetEmptyCurrencySymbolsData()
+    {
+        $currencySymbolsDataBefore = $this->currencySymbolModel->getCurrencySymbolsData();
+
+        $this->currencySymbolModel->setCurrencySymbolsData([]);
+
+        $currencySymbolsDataAfter = $this->currencySymbolModel->getCurrencySymbolsData();
+
+        //Make sure symbol data is unchanged
+        $this->assertEquals($currencySymbolsDataBefore, $currencySymbolsDataAfter);
+    }
+
+    public function testSetCurrencySymbolsData()
+    {
+        $currencySymbolsData = $this->currencySymbolModel->getCurrencySymbolsData();
+        $this->assertArrayHasKey('EUR', $currencySymbolsData);
+
+        //Change currency symbol
+        $currencySymbolsData = [
+            'EUR' => '@'
+        ];
+        $this->currencySymbolModel->setCurrencySymbolsData($currencySymbolsData);
+
+        //Verify if the new symbol is set
+        $this->assertEquals(
+            '@',
+            $this->currencySymbolModel->getCurrencySymbolsData()['EUR']['displaySymbol'],
+            'Symbol not set correctly.'
+        );
+
+        $this->assertEquals('@', $this->currencySymbolModel->getCurrencySymbol('EUR'), 'Symbol not set correctly.');
+    }
+
+    /**
+     * @depends testSetCurrencySymbolsData
+     */
+    public function testGetCurrencySymbol()
+    {
+        //dependency is added for now since tear down (or app isolation) is not helping clear the configuration data
+        $this->assertEquals('@', $this->currencySymbolModel->getCurrencySymbol('EUR'));
+    }
+
+    public function testGetCurrencySymbolNonExistent()
+    {
+        $this->assertFalse($this->currencySymbolModel->getCurrencySymbol('AUD'));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
index 324101bbcbf..028863666d5 100755
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
@@ -1024,7 +1024,7 @@ class IndexTest extends \Magento\Backend\Utility\Controller
         $this->assertContains('Please correct this email address: \"*\".', $body);
         $this->assertContains('\"First Name\" is a required value.', $body);
         $this->assertContains('\"Last Name\" is a required value.', $body);
-        $this->assertContains('\"Telephone\" is a required value.', $body);
+        $this->assertContains('\"Phone Number\" is a required value.', $body);
         $this->assertContains('\"Country\" is a required value.', $body);
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/AddressMetadataServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/AddressMetadataServiceTest.php
index 83d41be208c..2f92b21558b 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/AddressMetadataServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/AddressMetadataServiceTest.php
@@ -68,6 +68,33 @@ class AddressMetadataServiceTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+     * @magentoDataFixture Magento/Customer/_files/attribute_user_defined_address_custom_attribute.php
+     */
+    public function testGetCustomAttributesMetadataWithAttributeNamedCustomAttribute()
+    {
+        $customAttributesMetadata = $this->_service->getCustomAttributesMetadata();
+        $customAttributeCode = 'custom_attribute';
+        $customAttributeFound = false;
+        $customAttributesCode = 'custom_attributes';
+        $customAttributesFound = false;
+        foreach ($customAttributesMetadata as $attribute) {
+            if ($attribute->getAttributeCode() == $customAttributeCode) {
+                $customAttributeFound = true;
+            }
+            if ($attribute->getAttributeCode() == $customAttributesCode) {
+                $customAttributesFound = true;
+            }
+        }
+        if (!$customAttributeFound) {
+            $this->fail("Custom attribute declared in the config not found.");
+        }
+        if (!$customAttributesFound) {
+            $this->fail("Custom attributes declared in the config not found.");
+        }
+        $this->assertCount(4, $customAttributesMetadata, "Invalid number of attributes returned.");
+    }
+
     public function testGetAddressAttributeMetadata()
     {
         $vatValidMetadata = $this->_service->getAttributeMetadata('vat_is_valid');
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
index 328bfeb7f02..1d3538e9684 100755
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
@@ -558,7 +558,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         );
         $this->_customerBuilder->populateWithArray($newCustomer);
         $this->_customerDetailsBuilder->setCustomer($this->_customerBuilder->create());
-        $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+        $this->_customerAccountService->updateCustomer($customerId, $this->_customerDetailsBuilder->create());
 
         $newCustomerDetails = $this->_customerAccountService->getCustomerDetails($customerId);
         $this->assertEquals($firstName, $newCustomerDetails->getCustomer()->getFirstname());
@@ -586,7 +586,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerDetailsBuilder
             ->setCustomer($customerDetails->getCustomer())
             ->setAddresses([$this->_addressBuilder->create(), $addresses[1]]);
-        $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+        $this->_customerAccountService->updateCustomer($customerId, $this->_customerDetailsBuilder->create());
 
         $newCustomerDetails = $this->_customerAccountService->getCustomerDetails($customerId);
         $this->assertEquals(2, count($newCustomerDetails->getAddresses()));
@@ -613,7 +613,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerDetailsBuilder
             ->setCustomer($customerDetails->getCustomer())->setAddresses([$addresses[1]]);
 
-        $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+        $this->_customerAccountService->updateCustomer($customerId, $this->_customerDetailsBuilder->create());
 
         $newCustomerDetails = $this->_customerAccountService->getCustomerDetails($customerId);
         $this->assertEquals(1, count($newCustomerDetails->getAddresses()));
@@ -631,7 +631,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $customerDetails = $this->_customerAccountService->getCustomerDetails($customerId);
         $this->_customerDetailsBuilder->setCustomer($customerDetails->getCustomer())
             ->setAddresses([]);
-        $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+        $this->_customerAccountService->updateCustomer($customerId, $this->_customerDetailsBuilder->create());
 
         $newCustomerDetails = $this->_customerAccountService->getCustomerDetails($customerId);
         $this->assertEquals(0, count($newCustomerDetails->getAddresses()));
@@ -662,7 +662,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerBuilder->populateWithArray($customerData);
         $modifiedCustomer = $this->_customerBuilder->create();
         $customerDetails = $this->_customerDetailsBuilder->setCustomer($modifiedCustomer)->create();
-        $this->_customerAccountService->updateCustomer($customerDetails);
+        $this->_customerAccountService->updateCustomer($existingCustId, $customerDetails);
         $customerAfter = $this->_customerAccountService->getCustomer($existingCustId);
         $this->assertEquals($email, $customerAfter->getEmail());
         $this->assertEquals($firstName, $customerAfter->getFirstname());
@@ -719,7 +719,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $modifiedCustomer = $this->_customerBuilder->create();
 
         $customerDetails = $this->_customerDetailsBuilder->setCustomer($modifiedCustomer)->create();
-        $this->_customerAccountService->updateCustomer($customerDetails);
+        $this->_customerAccountService->updateCustomer($existingCustId, $customerDetails);
         $customerAfter = $this->_customerAccountService->getCustomer($existingCustId);
         $this->assertEquals($email, $customerAfter->getEmail());
         $this->assertEquals($firstName, $customerAfter->getFirstname());
@@ -785,7 +785,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerBuilder->populateWithArray($customerData);
         $modifiedCustomer = $this->_customerBuilder->create();
         $customerDetails = $this->_customerDetailsBuilder->setCustomer($modifiedCustomer)->create();
-        $this->_customerAccountService->updateCustomer($customerDetails);
+        $this->_customerAccountService->updateCustomer($existingCustId, $customerDetails);
         $customerAfter = $this->_customerAccountService->getCustomer($existingCustId);
         $this->assertEquals($email, $customerAfter->getEmail());
         $this->assertEquals($firstName, $customerAfter->getFirstname());
@@ -1029,7 +1029,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $customerDetails = $this->_customerDetailsBuilder->setCustomer($newCustomerEntity)->create();
         /** @var \Magento\Framework\Math\Random $mathRandom */
         $password = $this->_objectManager->get('Magento\Framework\Math\Random')->getRandomString(
-            CustomerAccountServiceInterface::DEFAULT_PASSWORD_LENGTH
+            CustomerAccountServiceInterface::MIN_PASSWORD_LENGTH
         );
         /** @var \Magento\Framework\Encryption\EncryptorInterface $encryptor */
         $encryptor = $this->_objectManager->get('Magento\Framework\Encryption\EncryptorInterface');
@@ -1115,7 +1115,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerBuilder->populate($customer);
         $this->_customerBuilder->setFirstname('Tested');
         $customerDetails = $this->_customerDetailsBuilder->setCustomer($this->_customerBuilder->create())->create();
-        $this->_customerAccountService->updateCustomer($customerDetails);
+        $this->_customerAccountService->updateCustomer($customer->getId(), $customerDetails);
 
         $customer = $this->_customerAccountService->getCustomer($customer->getId());
 
@@ -1556,7 +1556,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerDetailsBuilder->setCustomer(($this->_customerBuilder->create()))
             ->setAddresses([$this->_addressBuilder->create(), $addresses[1]]);
 
-        $this->_customerAccountService->updateCustomerDetailsByEmail(
+        $this->_customerAccountService->updateCustomerByEmail(
             $email,
             $this->_customerDetailsBuilder->create(),
             $websiteId
@@ -1595,7 +1595,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         );
         $this->_customerBuilder->populateWithArray($customerData);
         $this->_customerDetailsBuilder->setCustomer(($this->_customerBuilder->create()))->setAddresses([]);
-        $this->_customerAccountService->updateCustomerDetailsByEmail($email, $this->_customerDetailsBuilder->create());
+        $this->_customerAccountService->updateCustomerByEmail($email, $this->_customerDetailsBuilder->create());
 
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
index 572f8770bf1..d6ac2f7158b 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
@@ -145,7 +145,7 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
     {
         $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
         $group = $builder->setId(null)->setCode('Test Group')->setTaxClassId(3)->create();
-        $groupId = $this->_groupService->saveGroup($group);
+        $groupId = $this->_groupService->createGroup($group);
         $this->assertNotNull($groupId);
 
         $newGroup = $this->_groupService->getGroup($groupId);
@@ -154,11 +154,23 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($group->getTaxClassId(), $newGroup->getTaxClassId());
     }
 
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage ID is not expected for this request.
+     * @magentoDbIsolation enabled
+     */
+    public function testCreateGroupWithId()
+    {
+        $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
+        $group = $builder->setId(88)->setCode('Test Create Group With Id')->setTaxClassId(3)->create();
+        $this->_groupService->createGroup($group);
+    }
+
     public function testUpdateGroup()
     {
         $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
         $group = $builder->setId(null)->setCode('New Group')->setTaxClassId(3)->create();
-        $groupId = $this->_groupService->saveGroup($group);
+        $groupId = $this->_groupService->createGroup($group);
         $this->assertNotNull($groupId);
 
         $newGroup = $this->_groupService->getGroup($groupId);
@@ -168,8 +180,7 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
 
         $updates = $builder->setId($groupId)->setCode('Updated Group')->setTaxClassId(3)
             ->create();
-        $newId = $this->_groupService->saveGroup($updates);
-        $this->assertEquals($newId, $groupId);
+        $this->assertTrue($this->_groupService->updateGroup($groupId, $updates));
         $updatedGroup = $this->_groupService->getGroup($groupId);
         $this->assertEquals($updates->getCode(), $updatedGroup->getCode());
         $this->assertEquals($updates->getTaxClassId(), $updatedGroup->getTaxClassId());
@@ -298,7 +309,7 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
             ],
         ];
     }
-    
+
     /**
      * @param $testGroup
      * @param $storeId
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
index 1d283986e74..f0806fb5736 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
@@ -69,6 +69,52 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    public function testGetNestedOptionsCustomAttributesMetadata()
+    {
+        $nestedOptionsAttribute = 'store_id';
+        $customAttributesMetadata = $this->_service->getAttributeMetadata($nestedOptionsAttribute);
+        $options = $customAttributesMetadata->getOptions();
+        $nestedOptionExists = false;
+        foreach ($options as $option) {
+            if (strpos($option->getLabel(), 'Main Website Store') !== false) {
+                $this->assertNotEmpty($option->getOptions());
+                //Check nested option
+                $this->assertTrue(strpos($option->getOptions()[0]->getLabel(), 'Default Store View') !== false);
+                $nestedOptionExists = true;
+            }
+        }
+        if (!$nestedOptionExists) {
+            $this->fail('Nested attribute options were expected.');
+        }
+    }
+
+    /**
+     * @magentoDataFixture Magento/Customer/_files/attribute_user_defined_custom_attribute.php
+     */
+    public function testGetCustomAttributesMetadataWithAttributeNamedCustomAttribute()
+    {
+        $customAttributesMetadata = $this->_service->getCustomAttributesMetadata();
+        $customAttributeCode = 'custom_attribute';
+        $customAttributeFound = false;
+        $customAttributesCode = 'custom_attributes';
+        $customAttributesFound = false;
+        foreach ($customAttributesMetadata as $attribute) {
+            if ($attribute->getAttributeCode() == $customAttributeCode) {
+                $customAttributeFound = true;
+            }
+            if ($attribute->getAttributeCode() == $customAttributesCode) {
+                $customAttributesFound = true;
+            }
+        }
+        if (!$customAttributeFound) {
+            $this->fail("Custom attribute declared in the config not found.");
+        }
+        if (!$customAttributesFound) {
+            $this->fail("Custom attributes declared in the config not found.");
+        }
+        $this->assertCount(5, $customAttributesMetadata, "Invalid number of attributes returned.");
+    }
+
     /**
      * @magentoDataFixture Magento/Customer/_files/customer.php
      */
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_address_custom_attribute.php b/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_address_custom_attribute.php
new file mode 100644
index 00000000000..2bc793e66c2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_address_custom_attribute.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Customer\Model\Attribute');
+$model->setName(
+    'custom_attribute'
+)->setEntityTypeId(
+    2
+)->setAttributeSetId(
+    2
+)->setAttributeGroupId(
+    1
+)->setFrontendInput(
+    'text'
+)->setFrontendLabel(
+    'custom_attribute_frontend_label'
+)->setIsUserDefined(
+    1
+);
+$model->save();
+
+$model2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Customer\Model\Attribute');
+$model2->setName(
+    'custom_attributes'
+)->setEntityTypeId(
+    2
+)->setAttributeSetId(
+    2
+)->setAttributeGroupId(
+    1
+)->setFrontendInput(
+    'text'
+)->setFrontendLabel(
+    'custom_attribute_frontend_label'
+)->setIsUserDefined(
+    1
+);
+$model2->save();
+
+/** @var \Magento\Customer\Model\Resource\Setup $setupResource */
+$setupResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+    'Magento\Customer\Model\Resource\Setup',
+    array('resourceName' => 'customer_setup')
+);
+
+$data = array(array('form_code' => 'customer_address_edit', 'attribute_id' => $model->getAttributeId()));
+$setupResource->getConnection()->insertMultiple($setupResource->getTable('customer_form_attribute'), $data);
+
+$data2 = array(array('form_code' => 'customer_address_edit', 'attribute_id' => $model2->getAttributeId()));
+$setupResource->getConnection()->insertMultiple($setupResource->getTable('customer_form_attribute'), $data2);
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_custom_attribute.php b/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_custom_attribute.php
new file mode 100644
index 00000000000..0a405795533
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/attribute_user_defined_custom_attribute.php
@@ -0,0 +1,68 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var Magento\Customer\Model\Attribute $model */
+$model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Customer\Model\Attribute');
+
+$model->setName(
+    'custom_attribute'
+)->setEntityTypeId(
+    1
+)->setIsUserDefined(
+    1
+)->setAttributeSetId(
+    1
+)->setAttributeGroupId(
+    1
+)->setFrontendInput(
+    'text'
+)->setFrontendLabel(
+    'custom_attribute_frontend_label'
+)->setSortOrder(
+    1221
+);
+
+$model->save();
+
+$model2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Customer\Model\Attribute');
+
+$model2->setName(
+    'custom_attributes'
+)->setEntityTypeId(
+    1
+)->setIsUserDefined(
+    1
+)->setAttributeSetId(
+    1
+)->setAttributeGroupId(
+    1
+)->setFrontendInput(
+    'text'
+)->setFrontendLabel(
+    'custom_attributes_frontend_label'
+)->setSortOrder(
+    1222
+);
+
+$model2->save();
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
index 2bbf2c1bed2..caac45c034e 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
@@ -32,4 +32,4 @@ $builder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
 $customerGroupBuilder = $builder->setCode('custom_group')->setTaxClassId(3);
 
 $customerGroup = new Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder);
-$customerGroupService->saveGroup($customerGroup);
+$customerGroupService->createGroup($customerGroup);
diff --git a/dev/tests/integration/testsuite/Magento/DesignEditor/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/DesignEditor/Model/ObserverTest.php
index fe03dd16521..f905ce5b1cd 100644
--- a/dev/tests/integration/testsuite/Magento/DesignEditor/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Magento/DesignEditor/Model/ObserverTest.php
@@ -39,13 +39,15 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
      */
     public function testCleanJs($area, $designMode, $expectedAssets)
     {
+        /** @var \Magento\Framework\Registry $registry */
+        $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\Registry'
+        );
+        $registry->register('vde_design_mode', $designMode);
+
         $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         );
-        /** @var $headBlock \Magento\Theme\Block\Html\Head */
-        $headBlock = $layout->createBlock('Magento\Theme\Block\Html\Head', 'head');
-        $headBlock->setData('vde_design_mode', $designMode);
-
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
         /** @var \Magento\Framework\View\Asset\Repository $assetRepo */
@@ -63,7 +65,9 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
 
         foreach ($fixtureAssets as $asset) {
             $pageAssets->add(
-                $asset['file'], $assetRepo->createAsset($asset['file']), $asset['params']
+                $asset['file'],
+                $assetRepo->createAsset($asset['file']),
+                $asset['params']
             );
         }
 
diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/ObserverTest.php
new file mode 100644
index 00000000000..22584342409
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Directory/Model/ObserverTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Directory\Model;
+
+use Magento\Framework\ObjectManager;
+use Magento\Store\Model\ScopeInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * Integration test for \Magento\Directory\Model\Observer
+ */
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  ObjectManager */
+    protected $objectManager;
+
+    /** @var Observer */
+    protected $observer;
+
+    /** @var \Magento\Framework\App\MutableScopeConfig */
+    protected $scopeConfig;
+
+    /** @var string */
+    protected $baseCurrency = 'USD';
+
+    /** @var string */
+    protected $baseCurrencyPath = 'currency/options/base';
+
+    /** @var string */
+    protected $allowedCurrenciesPath = 'currency/options/allow';
+
+    /** @var \Magento\Core\Model\Resource\Config */
+    protected $configResource;
+
+    public function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+
+        $this->scopeConfig = $this->objectManager->create('Magento\Framework\App\MutableScopeConfig');
+        $this->scopeConfig->setValue(Observer::IMPORT_ENABLE, 1, ScopeInterface::SCOPE_STORE);
+        $this->scopeConfig->setValue(Observer::CRON_STRING_PATH, 'cron-string-path', ScopeInterface::SCOPE_STORE);
+        $this->scopeConfig->setValue(Observer::IMPORT_SERVICE, 'webservicex', ScopeInterface::SCOPE_STORE);
+
+        $this->configResource = $this->objectManager->get('Magento\Core\Model\Resource\Config');
+        $this->configResource->saveConfig(
+            $this->baseCurrencyPath,
+            $this->baseCurrency,
+            ScopeInterface::SCOPE_STORE,
+            0
+        );
+
+        $this->observer = $this->objectManager->create('Magento\Directory\Model\Observer');
+    }
+
+    public function testScheduledUpdateCurrencyRates()
+    {
+        $allowedCurrencies = 'USD,GBP,EUR';
+        $this->configResource->saveConfig(
+            $this->allowedCurrenciesPath,
+            $allowedCurrencies,
+            ScopeInterface::SCOPE_STORE,
+            0
+        );
+        $this->observer->scheduledUpdateCurrencyRates(null);
+        /** @var Currency $currencyResource */
+        $currencyResource = $this->objectManager
+            ->create('Magento\Directory\Model\CurrencyFactory')
+            ->create()
+            ->getResource();
+        $rates = $currencyResource->getCurrencyRates($this->baseCurrency, explode(',', $allowedCurrencies));
+        $this->assertEquals(3, count($rates));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Required parameter 'area' was not passed
+     */
+    public function testScheduledUpdateCurrencyRates_invalidCurrency()
+    {
+        $allowedCurrencies = 'USD,GBP,XXX';
+        $this->configResource->saveConfig(
+            $this->allowedCurrenciesPath,
+            $allowedCurrencies,
+            ScopeInterface::SCOPE_STORE,
+            0
+        );
+        $this->observer->scheduledUpdateCurrencyRates(null);
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
index 7c63a2eb0c4..5918afc2f33 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
@@ -27,15 +27,16 @@ use Magento\TestFramework\Helper\Bootstrap;
 
 class AdapterTest extends \PHPUnit_Framework_TestCase
 {
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Adapter
      */
     private $adapter;
 
     /**
-     * @var \Magento\Framework\Search\RequestFactory
+     * @var \Magento\Framework\Search\Request\Builder
      */
-    private $requestFactory;
+    private $requestBuilder;
 
     /**
      * @var \Magento\Framework\ObjectManager
@@ -57,9 +58,8 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
         $config = $this->objectManager->create('Magento\Framework\Search\Request\Config');
         $config->merge($requestConfig);
 
-        /** @var \Magento\Framework\Search\RequestFactory $requestFactory */
-        $this->requestFactory = $this->objectManager->create(
-            'Magento\Framework\Search\RequestFactory',
+        $this->requestBuilder = $this->objectManager->create(
+            'Magento\Framework\Search\Request\Builder',
             ['config' => $config]
         );
 
@@ -77,15 +77,41 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testMatchQuery()
     {
-        $bindValues = [
-            '%request.title%' => 'socks',
-        ];
-        $requestName = 'one_match';
+        $this->requestBuilder->bind('fulltext_search_query', 'socks');
+        $this->requestBuilder->setRequestName('one_match');
+
+        $queryResponse = $this->executeQuery();
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
         $this->assertEquals(1, $queryResponse->count());
     }
 
+    /**
+     * @return \Magento\Framework\Search\QueryResponse
+     */
+    private function executeQuery()
+    {
+        $this->reindexAll();
+
+        /** @var \Magento\Framework\Search\Request $queryRequest */
+        $queryRequest = $this->requestBuilder->create();
+
+        $queryResponse = $this->adapter->query($queryRequest);
+
+        return $queryResponse;
+    }
+
+    private function reindexAll()
+    {
+        /** @var \Magento\Indexer\Model\Indexer[] $indexerList */
+        $indexerList = $this->objectManager->get('\Magento\Indexer\Model\Indexer\CollectionFactory')
+            ->create()
+            ->getItems();
+
+        foreach ($indexerList as $indexer) {
+            $indexer->reindexAll();
+        }
+    }
+
     /**
      * Sample test
      *
@@ -97,15 +123,13 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testMatchQueryFilters()
     {
-        $bindValues = [
-            '%request.title%' => 'socks',
-            '%pidm_from%' => 1,
-            '%pidm_to%' => 3,
-            '%pidsh%' => 4
-        ];
-        $requestName = 'one_match_filters';
-
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $this->requestBuilder->bind('fulltext_search_query', 'socks');
+        $this->requestBuilder->bind('pidm_from', 1);
+        $this->requestBuilder->bind('pidm_to', 3);
+        $this->requestBuilder->bind('pidsh', 4);
+        $this->requestBuilder->setRequestName('one_match_filters');
+
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(1, $queryResponse->count());
     }
 
@@ -120,13 +144,11 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testRangeFilterWithAllFields()
     {
-        $bindValues = [
-            '%request.product_id.from%' => 1,
-            '%request.product_id.to%' => 3,
-        ];
-        $requestName = 'range_filter';
+        $this->requestBuilder->bind('range_filter_from', 1);
+        $this->requestBuilder->bind('range_filter_to', 3);
+        $this->requestBuilder->setRequestName('range_filter');
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(2, $queryResponse->count());
     }
 
@@ -141,12 +163,10 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testRangeFilterWithoutFromField()
     {
-        $bindValues = [
-            '%request.product_id.to%' => 4,
-        ];
-        $requestName = 'range_filter_without_from_field';
+        $this->requestBuilder->bind('range_filter_to', 4);
+        $this->requestBuilder->setRequestName('range_filter_without_from_field');
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(3, $queryResponse->count());
     }
 
@@ -161,12 +181,10 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testRangeFilterWithoutToField()
     {
-        $bindValues = [
-            '%request.product_id.from%' => 2,
-        ];
-        $requestName = 'range_filter_without_to_field';
+        $this->requestBuilder->bind('range_filter_from', 2);
+        $this->requestBuilder->setRequestName('range_filter_without_to_field');
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(4, $queryResponse->count());
     }
 
@@ -183,16 +201,50 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
     {
         $id = 4;
 
-        $bindValues = [
-            '%request.product_id%' => $id,
-        ];
-        $requestName = 'term_filter';
+        $this->requestBuilder->bind('request.product_id', $id);
+        $this->requestBuilder->setRequestName('term_filter');
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(1, $queryResponse->count());
         $this->assertEquals($id, $queryResponse->getIterator()->offsetGet(0)->getId());
     }
 
+    /**
+     * Term filter test
+     *
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoConfigFixture current_store catalog/search/engine Magento\CatalogSearch\Model\Resource\Fulltext\Engine
+     * @magentoConfigFixture current_store catalog/search/search_type 2
+     * @magentoDataFixture Magento/Framework/Search/_files/products.php
+     */
+    public function testTermFilterArray()
+    {
+        $this->requestBuilder->bind('request.product_id', [3, 4]);
+        $this->requestBuilder->setRequestName('term_filter');
+
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(2, $queryResponse->count());
+    }
+
+    /**
+     * Term filter test
+     *
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoConfigFixture current_store catalog/search/engine Magento\CatalogSearch\Model\Resource\Fulltext\Engine
+     * @magentoConfigFixture current_store catalog/search/search_type 2
+     * @magentoDataFixture Magento/Framework/Search/_files/products.php
+     */
+    public function testWildcardFilter()
+    {
+        $this->requestBuilder->bind('wildcard_filter', 're');
+        $this->requestBuilder->setRequestName('one_wildcard');
+
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(4, $queryResponse->count());
+    }
+
     /**
      * Bool filter test
      *
@@ -204,24 +256,18 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
      */
     public function testBoolFilter()
     {
-        /*
-         * TODO: Remove test skipping after fixing issue
-         */
-        $this->markTestSkipped('Bool filter doesn\'t work correctly and we have issue in bug tracker');
         $expectedIds = [2, 3];
-        $bindValues = [
-            '%request.must.range_filter1.from%' => 1,
-            '%request.must.range_filter1.to%' => 5,
-            '%request.should.term_filter1%' => 1,
-            '%request.should.term_filter2%' => 2,
-            '%request.should.term_filter3%' => 3,
-            '%request.should.term_filter4%' => 4,
-            '%request.not.term_filter1%' => 1,
-            '%request.not.term_filter2%' => 4,
-        ];
-        $requestName = 'bool_filter';
-
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
+        $this->requestBuilder->bind('must_range_filter1_from', 1);
+        $this->requestBuilder->bind('must_range_filter1_to', 6);
+        $this->requestBuilder->bind('should_term_filter1', 1);
+        $this->requestBuilder->bind('should_term_filter2', 2);
+        $this->requestBuilder->bind('should_term_filter3', 3);
+        $this->requestBuilder->bind('should_term_filter4', 4);
+        $this->requestBuilder->bind('not_term_filter1', 1);
+        $this->requestBuilder->bind('not_term_filter2', 4);
+        $this->requestBuilder->setRequestName('bool_filter');
+
+        $queryResponse = $this->executeQuery();
         $this->assertEquals(count($expectedIds), $queryResponse->count());
         $actualIds = [];
         foreach ($queryResponse as $document) {
@@ -232,93 +278,98 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Sample Advanced search request test
+     * Test bool filter with nested negative bool filter
      *
-     * @dataProvider advancedSearchDataProvider
      * @magentoDbIsolation enabled
      * @magentoAppIsolation enabled
      * @magentoConfigFixture current_store catalog/search/engine Magento\CatalogSearch\Model\Resource\Fulltext\Engine
      * @magentoConfigFixture current_store catalog/search/search_type 2
      * @magentoDataFixture Magento/Framework/Search/_files/products.php
      */
-    public function testSimpleAdvancedSearch($bindValues, $expectedRecorsCount)
+    public function testBoolFilterWithNestedNegativeBoolFilter()
     {
-        $requestName = 'advanced_search_test';
+        $expectedIds = [1];
+        $this->requestBuilder->bind('not_range_filter_from', 2);
+        $this->requestBuilder->bind('not_range_filter_to', 5);
+        $this->requestBuilder->bind('nested_not_term_filter', 1);
+        $this->requestBuilder->setRequestName('bool_filter_with_nested_bool_filter');
 
-        $queryResponse = $this->executeQuery($requestName, $bindValues);
-        $this->assertEquals($expectedRecorsCount, $queryResponse->count());
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(count($expectedIds), $queryResponse->count());
+        $actualIds = [];
+        foreach ($queryResponse as $document) {
+            /** @var \Magento\Framework\Search\Document $document */
+            $actualIds[] = $document->getId();
+        }
+        $this->assertEquals($expectedIds, $actualIds);
     }
 
     /**
-     * @return array
+     * Test range inside nested negative bool filter
+     *
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoConfigFixture current_store catalog/search/engine Magento\CatalogSearch\Model\Resource\Fulltext\Engine
+     * @magentoConfigFixture current_store catalog/search/search_type 2
+     * @magentoDataFixture Magento/Framework/Search/_files/products.php
      */
-    public function advancedSearchDataProvider()
+    public function testBoolFilterWithNestedRangeInNegativeBoolFilter()
     {
-        return array(
-            [
-                [
-                    '%request.name%' => 'white',
-                    '%request.description%' => 'shorts',
-                    '%request.store_id%' => '1',
-                    '%request.from_product_id%' => '3',
-                    '%request.to_product_id%' => '4',
-                ],
-                0 // Record is not in filter range
-            ],
-            [
-                [
-                    '%request.name%' => 'white',
-                    '%request.description%' => 'shorts',
-                    '%request.store_id%' => '1',
-                    '%request.from_product_id%' => '1',
-                    '%request.to_product_id%' => '4',
-                ],
-                1 // One record is expected
-            ],
-            [
-                [
-                    '%request.name%' => 'white',
-                    '%request.description%' => 'shorts',
-                    '%request.store_id%' => '5',
-                    '%request.from_product_id%' => '1',
-                    '%request.to_product_id%' => '4',
-                ],
-                0 // store_id filter is invalid
-            ],
-            [
-                [
-                    '%request.name%' => 'black',
-                    '%request.description%' => 'tshirts',
-                    '%request.store_id%' => '1',
-                    '%request.from_product_id%' => '1',
-                    '%request.to_product_id%' => '5',
-                ],
-                0 // Non existing search terms
-            ],
-        );
-    }
-
-    private function executeQuery($requestName, $bindValues)
-    {
-        $this->reindexAll();
-
-        /** @var \Magento\Framework\Search\Request $queryRequest */
-        $queryRequest = $this->requestFactory->create($requestName, $bindValues);
+        $expectedIds = [1, 4, 5];
+        $this->requestBuilder->bind('nested_must_range_filter_from', 2);
+        $this->requestBuilder->bind('nested_must_range_filter_to', 4);
+        $this->requestBuilder->setRequestName('bool_filter_with_range_in_nested_negative_filter');
 
-        $queryResponse = $this->adapter->query($queryRequest);
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals(count($expectedIds), $queryResponse->count());
+        $actualIds = [];
+        foreach ($queryResponse as $document) {
+            /** @var \Magento\Framework\Search\Document $document */
+            $actualIds[] = $document->getId();
+        }
+        sort($actualIds);
+        $this->assertEquals($expectedIds, $actualIds);
+    }
 
-        return $queryResponse;
+    /**
+     * Sample Advanced search request test
+     *
+     * @dataProvider advancedSearchDataProvider
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoConfigFixture current_store catalog/search/engine Magento\CatalogSearch\Model\Resource\Fulltext\Engine
+     * @magentoConfigFixture current_store catalog/search/search_type 2
+     * @magentoDataFixture Magento/Framework/Search/_files/products.php
+     */
+    public function testSimpleAdvancedSearch(
+        $nameQuery,
+        $descriptionQuery,
+        $storeFilter,
+        $rangeFilter,
+        $expectedRecordsCount
+    ) {
+        $this->requestBuilder->bind('name_query', $nameQuery);
+        $this->requestBuilder->bind('description_query', $descriptionQuery);
+        $this->requestBuilder->bind('store_filter', $storeFilter);
+        $this->requestBuilder->bind('request.from_product_id', $rangeFilter['from']);
+        $this->requestBuilder->bind('request.to_product_id', $rangeFilter['to']);
+        $this->requestBuilder->setRequestName('advanced_search_test');
+
+        $queryResponse = $this->executeQuery();
+        $this->assertEquals($expectedRecordsCount, $queryResponse->count());
     }
 
-    private function reindexAll()
+    /**
+     * @return array
+     */
+    public function advancedSearchDataProvider()
     {
-        /** @var \Magento\Indexer\Model\Indexer[] $indexerList */
-        $indexerList = $this->objectManager->get('\Magento\Indexer\Model\Indexer\CollectionFactory')
-            ->create()
-            ->getItems();
-
-        foreach ($indexerList as $indexer) {
-            $indexer->reindexAll();
-        }
+        return array(
+            ['white', 'shorts', '1', ['from' => '3', 'to' => '4'], 0],
+            ['white', 'shorts', '1', ['from' => '1', 'to' => '4'], 1],
+            ['white', 'shorts', '5', ['from' => '1', 'to' => '4'], 0],
+            ['black', 'tshirts', '1', ['from' => '1', 'to' => '5'], 0],
+            ['peoples', 'green', '1', ['from' => '1', 'to' => '6'], 2],
+        );
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
index 30bb7fa1d3f..1b2fd46eb11 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
@@ -39,10 +39,17 @@ class MatchTest extends \PHPUnit_Framework_TestCase
         $this->objectManager = Bootstrap::getObjectManager();
     }
 
-    public function testBuildQuery()
+    /**
+     * @param string $conditionType
+     * @param string $expectedSuffix
+     * @dataProvider buildQueryProvider
+     */
+    public function testBuildQuery($conditionType, $expectedSuffix)
     {
-        $expectedSql = "SELECT `table`.* FROM `table` WHERE (MATCH (with_boost) AGAINST ('-wb' IN BOOLEAN MODE)) " .
-            "AND (MATCH (without_boost) AGAINST ('-wob' IN BOOLEAN MODE))";
+        $expectedScoreCondition = "(MATCH (with_boost, without_boost) AGAINST ('{$expectedSuffix}someValue' " .
+            "IN BOOLEAN MODE) * 3.14) AS global_score";
+        $expectedSql = "SELECT `someTable`.* FROM `someTable` WHERE (MATCH (with_boost, without_boost) " .
+            "AGAINST ('{$expectedSuffix}someValue' IN BOOLEAN MODE))";
 
         /** @var \Magento\Framework\Search\Adapter\Mysql\ScoreBuilder $scoreBuilder */
         $scoreBuilder = $this->objectManager->create('Magento\Framework\Search\Adapter\Mysql\ScoreBuilder');
@@ -54,9 +61,10 @@ class MatchTest extends \PHPUnit_Framework_TestCase
             [
                 'name' => 'Match query',
                 'boost' => 3.14,
+                'value' => 'someValue',
                 'matches' => [
-                    ['field' => 'with_boost', 'value' => 'wb', 'boost' => 2.15],
-                    ['field' => 'without_boost', 'value' => 'wob']
+                    ['field' => 'with_boost', 'boost' => 2.15],
+                    ['field' => 'without_boost']
                 ]
             ]
         );
@@ -64,9 +72,22 @@ class MatchTest extends \PHPUnit_Framework_TestCase
         $resource = $this->objectManager->create('Magento\Framework\App\Resource');
         /** @var \Magento\Framework\DB\Select $select */
         $select = $resource->getConnection(Config::DEFAULT_SETUP_CONNECTION)->select();
-        $select->from('table');
+        $select->from('someTable');
 
-        $resultSelect = $match->build($scoreBuilder, $select, $query, Bool::QUERY_CONDITION_NOT);
+        $resultSelect = $match->build($scoreBuilder, $select, $query, $conditionType);
+        $this->assertEquals($expectedScoreCondition, $scoreBuilder->build());
         $this->assertEquals($expectedSql, $resultSelect->assemble());
     }
+
+    /**
+     * @return array
+     */
+    public function buildQueryProvider()
+    {
+        return [
+            [Bool::QUERY_CONDITION_MUST, '+'],
+            [Bool::QUERY_CONDITION_SHOULD, ''],
+            [Bool::QUERY_CONDITION_NOT, '-']
+        ];
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Request/Config/ConverterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Request/Config/ConverterTest.php
index 836b89dbfd1..cbea9989331 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/Request/Config/ConverterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Request/Config/ConverterTest.php
@@ -40,8 +40,6 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
         $document->load(__DIR__ . '../../../_files/search_request.xml');
         $result = $this->object->convert($document);
         $expected = include __DIR__ . '/../../_files/search_request_config.php';
-        sort($expected);
-        sort($result);
         $this->assertEquals($expected, $result);
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/products.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/products.php
index 00802d2848e..93da5cc95ca 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/products.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/products.php
@@ -30,11 +30,11 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
     ->setId(1)
     ->setAttributeSetId(4)
     ->setWebsiteIds(array(1))
-    ->setName('Green socks')
+    ->setName('Unisex green socks')
     ->setSku('green_socks')
     ->setPrice(10)
     ->setWeight(1)
-    ->setShortDescription("Unisex green socks for some good peoples")
+    ->setShortDescription("Unisex green socks for some good peoples at one")
     ->setTaxClassId(0)
     ->setTierPrice(
         array(
@@ -58,7 +58,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
             ),
         )
     )
-    ->setDescription('Unisex <b>green socks</b> for some good peoples')
+    ->setDescription('Unisex <b>green socks</b> for some good peoples at one')
     ->setMetaTitle('green socks metadata')
     ->setMetaKeyword('green,socks,unisex')
     ->setMetaDescription('green socks metadata description')
@@ -303,7 +303,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
     ->setSku('grey_shorts')
     ->setPrice(14)
     ->setWeight(3)
-    ->setShortDescription("Grey shorts for all peoples")
+    ->setShortDescription("Grey or green shorts for all peoples at one")
     ->setTaxClassId(0)
     ->setTierPrice(
         array(
@@ -327,7 +327,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
             ),
         )
     )
-    ->setDescription('Grey shorts for <b>peoples</b>')
+    ->setDescription('Grey or green shorts for peoples at <b>one</b>')
     ->setMetaTitle('Grey shorts meta title')
     ->setMetaKeyword('grey,shorts,meta,men')
     ->setMetaDescription('Grey shorts meta description')
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
index 24391d4c77f..c8660552f63 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml
@@ -26,196 +26,284 @@
 <requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <request query="one_match" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="one_match" boost="2">
-                <queryReference clause="must" ref="fulltext_search_query" />
+                <queryReference clause="must" ref="fulltext_search_query"/>
             </query>
 
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="data_index" value="%request.title%" boost="2" />
+            <query xsi:type="matchQuery" name="fulltext_search_query" value="$fulltext_search_query$" boost="5">
+                <match field="data_index" boost="2"/>
             </query>
         </queries>
         <from>10</from>
         <size>10</size>
     </request>
+    <request query="one_wildcard" index="catalogsearch_fulltext">
+        <dimensions>
+            <dimension name="scope" value="default"/>
+        </dimensions>
+        <queries>
+            <query xsi:type="filteredQuery" name="one_wildcard" boost="2">
+                <filterReference clause="must" ref="wildcard_filter"/>
+            </query>
+        </queries>
+        <filters>
+            <filter xsi:type="wildcardFilter" name="wildcard_filter" value="$wildcard_filter$" field="data_index"/>
+        </filters>
+        <from>10</from>
+        <size>10</size>
+    </request>
     <request query="one_match_filters" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="one_match_filters" boost="2">
-                <queryReference clause="must" ref="fulltext_search_query" />
-                <queryReference clause="must" ref="fulltext_search_query2" />
+                <queryReference clause="must" ref="fulltext_search_query"/>
+                <queryReference clause="must" ref="filtered_query"/>
+                <queryReference clause="must" ref="filtered_query_rm"/>
+                <queryReference clause="must" ref="filtered_query_filter_rm"/>
             </query>
-
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="data_index" value="%request.title%" boost="2" />
+            <query xsi:type="matchQuery" name="fulltext_search_query" value="$fulltext_search_query$" boost="5">
+                <match field="data_index" boost="2"/>
             </query>
-
-            <query xsi:type="filteredQuery" name="fulltext_search_query2">
-                <filterReference ref="pid" />
+            <query xsi:type="filteredQuery" name="filtered_query">
+                <filterReference ref="pid"/>
+            </query>
+            <query xsi:type="filteredQuery" name="filtered_query_rm">
+                <queryReference ref="fulltext_search_query_rm"/>
+            </query>
+            <query xsi:type="filteredQuery" name="filtered_query_filter_rm">
+                <filterReference ref="bool_filter_rm"/>
+            </query>
+            <query xsi:type="matchQuery" value="$not_bind$" name="fulltext_search_query_rm">
+                <match field="some"/>
             </query>
         </queries>
         <filters>
+            <filter xsi:type="boolFilter" name="bool_filter_rm">
+                <filterReference clause="must" ref="term_rm"/>
+                <filterReference clause="must" ref="range_rm"/>
+            </filter>
+            <filter name="range_rm" xsi:type="rangeFilter" field="product_id" from="$not_bind$" to="$not_bind$"/>
+            <filter name="term_rm" xsi:type="termFilter" field="product_id" value="$not_bind$"/>
             <filter xsi:type="boolFilter" name="pid">
-                <filterReference clause="should" ref="pidm" />
-                <filterReference clause="should" ref="pidsh" />
+                <filterReference clause="should" ref="pidm"/>
+                <filterReference clause="should" ref="pidsh"/>
             </filter>
-            <filter name="pidm" xsi:type="rangeFilter" field="product_id" from="%pidm_from%" to="%pidm_to%" />
-            <filter name="pidsh" xsi:type="termFilter" field="product_id" value="%pidsh%" />
+            <filter name="pidm" xsi:type="rangeFilter" field="product_id" from="$pidm_from$" to="$pidm_to$"/>
+            <filter name="pidsh" xsi:type="termFilter" field="product_id" value="$pidsh$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="range_filter" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="filteredQuery" name="range_filter">
-                <filterReference ref="range_filter" />
+                <filterReference ref="range_filter"/>
             </query>
         </queries>
         <filters>
             <filter name="range_filter"
                     xsi:type="rangeFilter"
                     field="product_id"
-                    from="%request.product_id.from%"
-                    to="%request.product_id.to%" />
+                    from="$range_filter_from$"
+                    to="$range_filter_to$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="range_filter_without_from_field" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="filteredQuery" name="range_filter_without_from_field">
-                <filterReference ref="range_filter_without_from_field" />
+                <filterReference ref="range_filter_without_from_field"/>
             </query>
         </queries>
         <filters>
             <filter name="range_filter_without_from_field"
                     xsi:type="rangeFilter"
                     field="product_id"
-                    to="%request.product_id.to%" />
+                    to="$range_filter_to$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="range_filter_without_to_field" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="filteredQuery" name="range_filter_without_to_field">
-                <filterReference ref="range_filter_without_to_field" />
+                <filterReference ref="range_filter_without_to_field"/>
             </query>
         </queries>
         <filters>
             <filter name="range_filter_without_to_field"
                     xsi:type="rangeFilter"
                     field="product_id"
-                    from="%request.product_id.from%" />
+                    from="$range_filter_from$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="term_filter" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="filteredQuery" name="term_filter">
-                <filterReference ref="term_filter" />
+                <filterReference ref="term_filter"/>
             </query>
         </queries>
         <filters>
-            <filter name="term_filter" xsi:type="termFilter" field="product_id" value="%request.product_id%" />
+            <filter name="term_filter" xsi:type="termFilter" field="product_id" value="$request.product_id$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="bool_filter" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="filteredQuery" name="bool_filter">
-                <filterReference ref="bool_filter" />
+                <filterReference ref="bool_filter"/>
             </query>
         </queries>
         <filters>
             <filter xsi:type="boolFilter" name="bool_filter">
-                <filterReference clause="must" ref="must_range_filter1" />
-                <filterReference clause="should" ref="should_term_filter1" />
-                <filterReference clause="should" ref="should_term_filter2" />
-                <filterReference clause="not" ref="not_term_filter1" />
-                <filterReference clause="not" ref="not_term_filter2" />
+                <filterReference clause="must" ref="must_range_filter1"/>
+                <filterReference clause="should" ref="should_term_filter1"/>
+                <filterReference clause="should" ref="should_term_filter2"/>
+                <filterReference clause="should" ref="should_term_filter3"/>
+                <filterReference clause="should" ref="should_term_filter4"/>
+                <filterReference clause="not" ref="not_term_filter1"/>
+                <filterReference clause="not" ref="not_term_filter2"/>
             </filter>
             <filter name="must_range_filter1"
                     xsi:type="rangeFilter"
                     field="product_id"
-                    from="%request.must.range_filter1.from%"
-                    to="%request.must.range_filter1.to%" />
+                    from="$must_range_filter1_from$"
+                    to="$must_range_filter1_to$"/>
             <filter name="should_term_filter1"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.should.term_filter1%" />
+                    value="$should_term_filter1$"/>
             <filter name="should_term_filter2"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.should.term_filter2%" />
+                    value="$should_term_filter2$"/>
             <filter name="should_term_filter3"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.should.term_filter3%" />
+                    value="$should_term_filter3$"/>
             <filter name="should_term_filter4"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.should.term_filter4%" />
+                    value="$should_term_filter4$"/>
             <filter name="not_term_filter1"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.not.term_filter1%" />
+                    value="$not_term_filter1$"/>
             <filter name="not_term_filter2"
                     xsi:type="termFilter"
                     field="product_id"
-                    value="%request.not.term_filter2%" />
+                    value="$not_term_filter2$"/>
+        </filters>
+        <from>10</from>
+        <size>10</size>
+    </request>
+    <request query="bool_filter_with_nested_bool_filter" index="catalogsearch_fulltext">
+        <dimensions>
+            <dimension name="scope" value="default"/>
+        </dimensions>
+        <queries>
+            <query xsi:type="filteredQuery" name="bool_filter_with_nested_bool_filter">
+                <filterReference ref="bool_filter_with_nested_bool_filter"/>
+            </query>
+        </queries>
+        <filters>
+            <filter xsi:type="boolFilter" name="bool_filter_with_nested_bool_filter">
+                <filterReference clause="not" ref="not_range_filter"/>
+                <filterReference clause="not" ref="not_bool_filter"/>
+            </filter>
+            <filter xsi:type="boolFilter" name="not_bool_filter">
+                <filterReference clause="not" ref="nested_not_term_filter"/>
+            </filter>
+            <filter name="not_range_filter"
+                    xsi:type="rangeFilter"
+                    field="product_id"
+                    from="$not_range_filter_from$"
+                    to="$not_range_filter_to$"/>
+            <filter name="nested_not_term_filter"
+                    xsi:type="termFilter"
+                    field="product_id"
+                    value="$nested_not_term_filter$"/>
+        </filters>
+        <from>10</from>
+        <size>10</size>
+    </request>
+    <request query="bool_filter_with_range_in_nested_negative_filter" index="catalogsearch_fulltext">
+        <dimensions>
+            <dimension name="scope" value="default"/>
+        </dimensions>
+        <queries>
+            <query xsi:type="filteredQuery" name="bool_filter_with_range_in_nested_negative_filter">
+                <filterReference ref="bool_filter_with_range_in_nested_negative_filter"/>
+            </query>
+        </queries>
+        <filters>
+            <filter xsi:type="boolFilter" name="bool_filter_with_range_in_nested_negative_filter">
+                <filterReference clause="not" ref="not_bool_filter"/>
+            </filter>
+            <filter xsi:type="boolFilter" name="not_bool_filter">
+                <filterReference clause="must" ref="nested_must_range_filter"/>
+            </filter>
+            <filter name="nested_must_range_filter"
+                    xsi:type="rangeFilter"
+                    field="product_id"
+                    from="$nested_must_range_filter_from$"
+                    to="$nested_must_range_filter_to$"/>
         </filters>
         <from>10</from>
         <size>10</size>
     </request>
     <request query="advanced_search_test" index="catalogsearch_fulltext">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="advanced_search_test" boost="1">
-                <queryReference clause="should" ref="name_query" />
-                <queryReference clause="should" ref="description_query" />
-                <queryReference clause="should" ref="query_filter" />
+                <queryReference clause="should" ref="name_query"/>
+                <queryReference clause="should" ref="description_query"/>
+                <queryReference clause="should" ref="query_filter"/>
             </query>
-            <query xsi:type="matchQuery" name="name_query">
-                <match field="data_index" value="%request.name%" boost="1" />
+            <query xsi:type="matchQuery" name="name_query" value="$name_query$">
+                <match field="data_index" boost="1"/>
             </query>
-            <query xsi:type="matchQuery" name="description_query">
-                <match field="data_index" value="%request.description%" boost="1" />
+            <query xsi:type="matchQuery" name="description_query" value="$description$">
+                <match field="data_index" boost="1"/>
             </query>
             <query xsi:type="filteredQuery" name="query_filter">
-                <filterReference ref="filter" />
+                <filterReference ref="filter"/>
             </query>
         </queries>
         <filters>
             <filter xsi:type="boolFilter" name="filter">
-                <filterReference clause="must" ref="store_filter" />
-                <filterReference clause="must" ref="product_id_filter" />
+                <filterReference clause="must" ref="store_filter"/>
+                <filterReference clause="must" ref="product_id_filter"/>
             </filter>
-            <filter name="store_filter" xsi:type="termFilter" field="store_id" value="%request.store_id%" />
-            <filter name="product_id_filter" xsi:type="rangeFilter" field="product_id" from="%request.from_product_id%" to="%request.to_product_id%" />
+            <filter name="store_filter" xsi:type="termFilter" field="store_id" value="$store_filter$"/>
+            <filter name="product_id_filter" xsi:type="rangeFilter" field="product_id" from="$request.from_product_id$"
+                    to="$request.to_product_id$"/>
         </filters>
         <from>10</from>
         <size>10</size>
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request.xml b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request.xml
index 7d7125a42d5..bd707210acd 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request.xml
@@ -34,9 +34,9 @@
                 <queryReference clause="should" ref="fulltext_search_query2" />
             </query>
 
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="title" value="$request.title" boost="2" />
-                <match field="description" value="%request.description%" />
+            <query xsi:type="matchQuery" name="fulltext_search_query" value="default_value" boost="5">
+                <match field="title" boost="2" />
+                <match field="description" />
             </query>
 
             <query xsi:type="filteredQuery" name="fulltext_search_query2">
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request_config.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request_config.php
index 06a33a142c9..52f89b75fbe 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request_config.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_request_config.php
@@ -48,15 +48,14 @@ return [
             "fulltext_search_query" => [
                 "name" => "fulltext_search_query",
                 "boost" => "5",
+                "value" => "default_value",
                 "match" => [
                     [
                         "field" => "title",
-                        "value" => "\$request.title",
                         "boost" => "2"
                     ],
                     [
-                        "field" => "description",
-                        "value" => "%request.description%"
+                        "field" => "description"
                     ]
                 ],
                 "type" => "matchQuery"
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieDomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieDomainValidatorTest.php
new file mode 100644
index 00000000000..b9bf3ed03e0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieDomainValidatorTest.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Integration test for Magento\Framework\Session\Config\Validator\CookieDomainValidator
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Session\Config\Validator;
+
+class CookieDomainValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\Framework\Session\Config\Validator\CookieDomainValidator   */
+    private $model;
+
+    public function setUp()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->model = $objectManager->create('Magento\Framework\Session\Config\Validator\CookieDomainValidator');
+    }
+
+    public function testEmptyString()
+    {
+        $this->assertTrue($this->model->isValid(''));
+    }
+
+    public function testInvalidHostname()
+    {
+        $this->assertFalse($this->model->isValid('http://'));
+    }
+
+    public function testNotString()
+    {
+        $this->assertFalse($this->model->isValid(1));
+    }
+
+    public function testNonemptyValid()
+    {
+        $this->assertTrue($this->model->isValid('domain.com'));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieLifetimeValidatorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieLifetimeValidatorTest.php
new file mode 100644
index 00000000000..bccabd1cfab
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookieLifetimeValidatorTest.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Integration test for  Magento\Framework\Session\Config\Validator\CookieLifetimeValidator
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Session\Config\Validator;
+
+class CookieLifetimeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\Framework\Session\Config\Validator\CookieLifetimeValidator   */
+    private $model;
+
+    public function setUp()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->model = $objectManager->create('Magento\Framework\Session\Config\Validator\CookieLifetimeValidator');
+    }
+
+    public function testNonNumeric()
+    {
+        $this->assertFalse($this->model->isValid('non-numeric value'));
+    }
+
+    public function testNegative()
+    {
+        $this->assertFalse($this->model->isValid(-1));
+    }
+
+    public function testPositive()
+    {
+        $this->assertTrue($this->model->isValid(1));
+    }
+
+    public function testZero()
+    {
+        $this->assertTrue($this->model->isValid(0));
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Rss/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookiePathValidatorTest.php
similarity index 50%
rename from dev/tests/integration/testsuite/Magento/Rss/Controller/IndexTest.php
rename to dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookiePathValidatorTest.php
index a8294d1f698..e318b084bcf 100644
--- a/dev/tests/integration/testsuite/Magento/Rss/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/Config/Validator/CookiePathValidatorTest.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Integration test for Magento\Framework\Session\Config\Validator\CookiePathValidator
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,30 +23,34 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller;
+namespace Magento\Framework\Session\Config\Validator;
 
-class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
+class CookiePathValidatorTest extends \PHPUnit_Framework_TestCase
 {
-    public function testIndexActionDisabled()
+    /** @var  \Magento\Framework\Session\Config\Validator\CookiePathValidator   */
+    private $model;
+
+    public function setUp()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->model = $objectManager->create('Magento\Framework\Session\Config\Validator\CookiePathValidator');
+    }
+
+    public function testNoLeadingSlash()
     {
-        $this->dispatch('rss/index/index');
-        $this->assert404NotFound();
+        $path = 'path';
+        $this->assertFalse($this->model->isValid($path));
     }
 
-    /**
-     * @magentoConfigFixture current_store rss/config/active 1
-     * @magentoConfigFixture current_store rss/catalog/new 1
-     */
-    public function testIndexAction()
+    public function testInvalidPath()
     {
-        $this->dispatch('rss/index/index');
-        $this->assertContains('/rss/catalog/new/', $this->getResponse()->getBody());
+        $path = '/path?query=query';
+        $this->assertFalse($this->model->isValid($path));
     }
 
-    public function testNofeedAction()
+    public function testValidPath()
     {
-        $this->dispatch('rss/index/nofeed');
-        $this->assertHeaderPcre('Status', '/404/');
-        $this->assertHeaderPcre('Content-Type', '/text\/plain/');
+        $path = '/';
+        $this->assertTrue($this->model->isValid($path));
     }
-}
+} 
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php
index af90e50f940..ed805f46072 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php
@@ -23,6 +23,9 @@
  */
 namespace Magento\Framework\Session;
 
+/**
+ * @magentoAppIsolation enabled
+ */
 class ConfigTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -44,7 +47,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     {
         $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         /** @var $sessionManager \Magento\Framework\Session\SessionManager */
-        $sessionManager = $this->_objectManager->get('Magento\Framework\Session\SessionManager');
+        $sessionManager = $this->_objectManager->create('Magento\Framework\Session\SessionManager');
         if ($sessionManager->isSessionExists()) {
             $sessionManager->writeClose();
         }
@@ -84,9 +87,6 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->_model->getSavePath(), $this->_model->getOption('save_path'));
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     */
     public function testGetSessionSaveMethod()
     {
         $this->assertEquals('files', $this->_model->getSaveHandler());
@@ -101,4 +101,189 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     {
 
     }
+
+    public function testSetOptionsInvalidValue()
+    {
+        $preValue = $this->_model->getOptions();
+        $this->_model->setOptions('');
+        $this->assertEquals($preValue, $this->_model->getOptions());
+    }
+
+    /**
+     * @dataProvider optionsProvider
+     */
+    public function testSetOptions($option, $getter, $value)
+    {
+        $options = array($option => $value);
+        $this->_model->setOptions($options);
+        $this->assertSame($value, $this->_model->{$getter}());
+    }
+
+    public function optionsProvider()
+    {
+        return array(
+            array('save_path', 'getSavePath', __DIR__),
+            array('name', 'getName', 'FOOBAR'),
+            array('save_handler', 'getSaveHandler', 'user'),
+            array('gc_probability', 'getGcProbability', 42),
+            array('gc_divisor', 'getGcDivisor', 3),
+            array('gc_maxlifetime', 'getGcMaxlifetime', 180),
+            array('serialize_handler', 'getSerializeHandler', 'php_binary'),
+            array('cookie_lifetime', 'getCookieLifetime', 180),
+            array('cookie_path', 'getCookiePath', '/foo/bar'),
+            array('cookie_domain', 'getCookieDomain', 'framework.zend.com'),
+            array('cookie_secure', 'getCookieSecure', true),
+            array('cookie_httponly', 'getCookieHttpOnly', true),
+            array('use_cookies', 'getUseCookies', false),
+            array('use_only_cookies', 'getUseOnlyCookies', true),
+            array('referer_check', 'getRefererCheck', 'foobar'),
+            array('entropy_file', 'getEntropyFile', __FILE__),
+            array('entropy_length', 'getEntropyLength', 42),
+            array('cache_limiter', 'getCacheLimiter', 'private'),
+            array('cache_expire', 'getCacheExpire', 42),
+            array('use_trans_sid', 'getUseTransSid', true),
+            array('hash_function', 'getHashFunction', 'md5'),
+            array('hash_bits_per_character', 'getHashBitsPerCharacter', 5),
+            array('url_rewriter_tags', 'getUrlRewriterTags', 'a=href')
+        );
+    }
+
+    public function testNameIsMutable()
+    {
+        $this->_model->setName('FOOBAR');
+        $this->assertEquals('FOOBAR', $this->_model->getName());
+    }
+
+    public function testSaveHandlerIsMutable()
+    {
+        $this->_model->setSaveHandler('user');
+        $this->assertEquals('user', $this->_model->getSaveHandler());
+    }
+
+    public function testCookieLifetimeIsMutable()
+    {
+        $this->_model->setCookieLifetime(20);
+        $this->assertEquals(20, $this->_model->getCookieLifetime());
+    }
+
+    public function testCookieLifetimeCanBeZero()
+    {
+        $this->_model->setCookieLifetime(0);
+        $this->assertEquals(0, $this->_model->getCookieLifetime());
+    }
+
+    public function testSettingInvalidCookieLifetime()
+    {
+        $preVal = $this->_model->getCookieLifetime();
+        $this->_model->setCookieLifetime('foobar_bogus');
+        $this->assertEquals($preVal, $this->_model->getCookieLifetime());
+    }
+
+    public function testSettingInvalidCookieLifetime2()
+    {
+        $preVal = $this->_model->getCookieLifetime();
+        $this->_model->setCookieLifetime(-1);
+        $this->assertEquals($preVal, $this->_model->getCookieLifetime());
+    }
+
+    public function testWrongMethodCall()
+    {
+        $this->setExpectedException(
+            '\BadMethodCallException',
+            'Method "methodThatNotExist" does not exist in Magento\Framework\Session\Config'
+        );
+        $this->_model->methodThatNotExist();
+    }
+
+    public function testCookieSecureDefaultsToIniSettings()
+    {
+        $this->assertSame((bool)ini_get('session.cookie_secure'), $this->_model->getCookieSecure());
+    }
+
+    public function testCookieSecureIsMutable()
+    {
+        $value = ini_get('session.cookie_secure') ? false : true;
+        $this->_model->setCookieSecure($value);
+        $this->assertEquals($value, $this->_model->getCookieSecure());
+    }
+
+    public function testCookieDomainIsMutable()
+    {
+        $this->_model->setCookieDomain('example.com');
+        $this->assertEquals('example.com', $this->_model->getCookieDomain());
+    }
+
+    public function testCookieDomainCanBeEmpty()
+    {
+        $this->_model->setCookieDomain('');
+        $this->assertEquals('', $this->_model->getCookieDomain());
+    }
+
+    public function testSettingInvalidCookieDomain()
+    {
+        $preVal = $this->_model->getCookieDomain();
+        $this->_model->setCookieDomain(24);
+        $this->assertEquals($preVal, $this->_model->getCookieDomain());
+    }
+
+    public function testSettingInvalidCookieDomain2()
+    {
+        $preVal = $this->_model->getCookieDomain();
+        $this->_model->setCookieDomain('D:\\WINDOWS\\System32\\drivers\\etc\\hosts');
+        $this->assertEquals($preVal, $this->_model->getCookieDomain());
+    }
+
+    public function testCookieHttpOnlyIsMutable()
+    {
+        $value = ini_get('session.cookie_httponly') ? false : true;
+        $this->_model->setCookieHttpOnly($value);
+        $this->assertEquals($value, $this->_model->getCookieHttpOnly());
+    }
+
+    public function testUseCookiesDefaultsToIniSettings()
+    {
+        $this->assertSame((bool)ini_get('session.use_cookies'), $this->_model->getUseCookies());
+    }
+
+    public function testUseCookiesIsMutable()
+    {
+        $value = ini_get('session.use_cookies') ? false : true;
+        $this->_model->setUseCookies($value);
+        $this->assertEquals($value, (bool)$this->_model->getUseCookies());
+    }
+
+    public function testUseOnlyCookiesDefaultsToIniSettings()
+    {
+        $this->assertSame((bool)ini_get('session.use_only_cookies'), $this->_model->getUseOnlyCookies());
+    }
+
+    public function testUseOnlyCookiesIsMutable()
+    {
+        $value = ini_get('session.use_only_cookies') ? false : true;
+        $this->_model->setOption('use_only_cookies', $value);
+        $this->assertEquals($value, (bool)$this->_model->getOption('use_only_cookies'));
+    }
+
+    public function testRefererCheckDefaultsToIniSettings()
+    {
+        $this->assertSame(ini_get('session.referer_check'), $this->_model->getRefererCheck());
+    }
+
+    public function testRefererCheckIsMutable()
+    {
+        $this->_model->setOption('referer_check', 'FOOBAR');
+        $this->assertEquals('FOOBAR', $this->_model->getOption('referer_check'));
+    }
+
+    public function testRefererCheckMayBeEmpty()
+    {
+        $this->_model->setOption('referer_check', '');
+        $this->assertEquals('', $this->_model->getOption('referer_check'));
+    }
+
+    public function testSetSavePath()
+    {
+        $this->_model->setSavePath('some_save_path');
+        $this->assertEquals($this->_model->getOption('save_path'), 'some_save_path');
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Rss/Block/Order/StatusTest.php b/dev/tests/integration/testsuite/Magento/Framework/ValidatorFactoryTest.php
similarity index 57%
rename from dev/tests/integration/testsuite/Magento/Rss/Block/Order/StatusTest.php
rename to dev/tests/integration/testsuite/Magento/Framework/ValidatorFactoryTest.php
index 2749c04c074..414b045361c 100644
--- a/dev/tests/integration/testsuite/Magento/Rss/Block/Order/StatusTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/ValidatorFactoryTest.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Integration test for Magento\Framework\ValidatorFactory
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,24 +23,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Block\Order;
+namespace Magento\Framework;
 
-class StatusTest extends \PHPUnit_Framework_TestCase
+class ValidatorFactoryTest extends \PHPUnit_Framework_TestCase
 {
-    public function testToHtml()
-    {
-        $block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\LayoutInterface'
-        )->createBlock(
-            'Magento\Rss\Block\Order\Status'
-        );
-        $this->assertEmpty($block->toHtml());
+    /** @var  \Magento\Framework\ValidatorFactory */
+    private $model;
 
-        $uniqid = uniqid();
-        $order = $this->getMock('Magento\Framework\Object', array('formatPrice'), array(array('id' => $uniqid)));
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+    public function setUp()
+    {
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $objectManager->get('Magento\Framework\Registry')->register('current_order', $order);
-        $this->assertContains($uniqid, $block->toHtml());
+        $this->model = $objectManager->create('Magento\Framework\ValidatorFactory');
+    }
+
+    public function testCreateWithInstanceName()
+    {
+        $setName = 'Magento\Framework\Object';
+        $this->assertInstanceOf($setName, $this->model->create([], $setName));
+    }
+
+    public function testCreateDefault()
+    {
+        $default = 'Magento\Framework\Validator';
+        $this->assertInstanceOf($default, $this->model->create());
     }
-}
+}
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Layout/ElementTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Layout/ElementTest.php
index fcd819cc574..417f1f6788a 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/View/Layout/ElementTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/Layout/ElementTest.php
@@ -28,7 +28,7 @@ class ElementTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Framework\View\Layout\Element
      */
-    protected $_model;
+    protected $model;
 
     public function testPrepare()
     {
@@ -36,18 +36,18 @@ class ElementTest extends \PHPUnit_Framework_TestCase
          * @TODO: Need to use ObjectManager instead 'new'.
          * On this moment we have next bug MAGETWO-4274 which blocker for this key.
          */
-        $this->_model = new \Magento\Framework\View\Layout\Element(__DIR__ . '/_files/_layout_update.xml', 0, true);
+        $this->model = new \Magento\Framework\View\Layout\Element(__DIR__ . '/_files/_layout_update.xml', 0, true);
 
-        list($blockNode) = $this->_model->xpath('//block[@name="head"]');
-        list($actionNode) = $this->_model->xpath('//action[@method="setTitle"]');
+        list($blockNode) = $this->model->xpath('//block[@name="nodeForTesting"]');
+        list($actionNode) = $this->model->xpath('//action[@method="setSomething"]');
 
         $this->assertEmpty($blockNode->attributes()->parent);
         $this->assertEmpty($actionNode->attributes()->block);
 
-        $this->_model->prepare();
+        $this->model->prepare();
 
         $this->assertEquals('root', (string)$blockNode->attributes()->parent);
-        $this->assertEquals('Magento\Backend\Block\Page\Head', (string)$blockNode->attributes()->class);
-        $this->assertEquals('head', (string)$actionNode->attributes()->block);
+        $this->assertEquals('Magento\Backend\Block\Page', (string)$blockNode->attributes()->class);
+        $this->assertEquals('nodeForTesting', (string)$actionNode->attributes()->block);
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Layout/_files/_layout_update.xml b/dev/tests/integration/testsuite/Magento/Framework/View/Layout/_files/_layout_update.xml
index 0d13209e928..35d6f97a2e3 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/View/Layout/_files/_layout_update.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/Layout/_files/_layout_update.xml
@@ -23,28 +23,16 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../app/code/Magento/Core/etc/layout_single.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <head>
+        <title>Magento Admin</title>
+        <script src="prototype/prototype.js"/>
+        <script src="prototype/window.js"/>
+        <script src="prototype/deprecation.js"/>
+    </head>
     <block class="Magento\Backend\Block\Page" name="root" output="1" template="page.phtml">
-        <block class="Magento\Backend\Block\Page\Head" name="head" as="head" template="page/head.phtml">
-            <action method="setTitle">
-                <argument translate="true" name="title" xsi:type="string">Magento Admin</argument>
-            </action>
-            <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-prototype-js">
-                <arguments>
-                    <argument name="file" xsi:type="string">prototype/prototype.js</argument>
-                </arguments>
-            </block>
-            <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-window-js">
-                <arguments>
-                    <argument name="file" xsi:type="string">prototype/window.js</argument>
-                </arguments>
-            </block>
-            <block class="Magento\Theme\Block\Html\Head\Script" name="prototype-deprecation-js" ifconfig="dev/js/deprecation">
-                <arguments>
-                    <argument name="file" xsi:type="string">prototype/deprecation.js</argument>
-                </arguments>
-            </block>
-            <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
+        <block class="Magento\Backend\Block\Page" name="nodeForTesting">
+            <action method="setSomething"/>
         </block>
         <block class="Magento\Backend\Block\Page\Header" name="header" as="header"/>
         <block class="Magento\Backend\Block\Menu" name="menu" as="menu"/>
@@ -67,4 +55,7 @@
     <referenceBlock name="test.nonexisting.block">
         <action method="getSomething"/>
     </referenceBlock>
-</layout>
+    <referenceBlock name="after.body.start">
+        <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
+    </referenceBlock>
+</page>
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Utility/Layout.php b/dev/tests/integration/testsuite/Magento/Framework/View/Utility/Layout.php
index 0573aefe251..0f33340b155 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/View/Utility/Layout.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/Utility/Layout.php
@@ -27,6 +27,9 @@
  */
 namespace Magento\Framework\View\Utility;
 
+/**
+ * Class Layout
+ */
 class Layout
 {
     /**
@@ -34,6 +37,9 @@ class Layout
      */
     protected $_testCase;
 
+    /**
+     * @param \PHPUnit_Framework_TestCase $testCase
+     */
     public function __construct(\PHPUnit_Framework_TestCase $testCase)
     {
         $this->_testCase = $testCase;
@@ -50,7 +56,7 @@ class Layout
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         /** @var \Magento\Framework\View\File\Factory $fileFactory */
         $fileFactory = $objectManager->get('Magento\Framework\View\File\Factory');
-        $files = array();
+        $files = [];
         foreach ((array)$layoutUpdatesFile as $filename) {
             $files[] = $fileFactory->create($filename, 'Magento_View');
         }
@@ -65,7 +71,7 @@ class Layout
         $cache = $this->_testCase->getMockForAbstractClass('Magento\Framework\Cache\FrontendInterface');
         return $objectManager->create(
             'Magento\Framework\View\Layout\ProcessorInterface',
-            array('fileSource' => $fileSource, 'cache' => $cache)
+            ['fileSource' => $fileSource, 'cache' => $cache]
         );
     }
 
@@ -76,9 +82,9 @@ class Layout
      * @param array $args
      * @return \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
      */
-    public function getLayoutFromFixture($layoutUpdatesFile, array $args = array())
+    public function getLayoutFromFixture($layoutUpdatesFile, array $args = [])
     {
-        $layout = $this->_testCase->getMock('Magento\Framework\View\Layout', array('getUpdate'), $args);
+        $layout = $this->_testCase->getMock('Magento\Framework\View\Layout', ['getUpdate'], $args);
         $layoutUpdate = $this->getLayoutUpdateFromFixture($layoutUpdatesFile);
         $layoutUpdate->asSimplexml();
         $layout->expects(
@@ -99,21 +105,24 @@ class Layout
     public function getLayoutDependencies()
     {
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        return array(
+        return [
             'processorFactory' => $objectManager->get('Magento\Framework\View\Layout\ProcessorFactory'),
             'logger' => $objectManager->get('Magento\Framework\Logger'),
             'eventManager' => $objectManager->get('Magento\Framework\Event\ManagerInterface'),
-            'blockFactory' => $objectManager->create('Magento\Framework\View\Element\BlockFactory', array()),
-            'structure' => $objectManager->create('Magento\Framework\Data\Structure', array()),
+            'uiComponentFactory' => $objectManager->get('Magento\Framework\View\Element\UiComponentFactory'),
+            'blockFactory' => $objectManager->create('Magento\Framework\View\Element\BlockFactory', []),
+            'structure' => $objectManager->create('Magento\Framework\Data\Structure', []),
             'argumentParser' => $objectManager->get('Magento\Framework\View\Layout\Argument\Parser'),
             'argumentInterpreter' => $objectManager->get('layoutArgumentInterpreter'),
-            'scheduledStructure' => $objectManager->create('Magento\Framework\View\Layout\ScheduledStructure', array()),
+            'scheduledStructure' => $objectManager->create('Magento\Framework\View\Layout\ScheduledStructure', []),
             'scopeConfig' => $objectManager->create('Magento\Framework\App\Config\ScopeConfigInterface'),
             'appState' => $objectManager->get('Magento\Framework\App\State'),
             'messageManager' => $objectManager->get('Magento\Framework\Message\ManagerInterface'),
             'themeResolver' => $objectManager->get('Magento\Framework\View\Design\Theme\ResolverInterface'),
             'scopeResolver' => $objectManager->get('Magento\Framework\App\ScopeResolverInterface'),
+            'pageConfigReader' => $objectManager->get('Magento\Framework\View\Page\Config\Reader'),
+            'pageConfigGenerator' => $objectManager->get('Magento\Framework\View\Page\Config\Generator'),
             'scopeType' => \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-        );
+        ];
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml b/dev/tests/integration/testsuite/Magento/Framework/View/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
index 2527584dfef..daac0d65c2a 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/View/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/design/frontend/test_default/Magento_Core/layout_test_handle_sample.xml
@@ -23,26 +23,20 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../../../app/code/Magento/Core/etc/layout_single.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <head>
+        <title>Magento Admin</title>
+        <script src="prototype/prototype.js"/>
+        <script src="prototype/window.js"/>
+        <script src="prototype/deprecation.js"/>
+    </head>
+    <referenceBlock name="after.body.start">
+        <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
+    </referenceBlock>
     <block class="Magento\Backend\Block\Page" name="root" output="1" template="page.phtml">
-        <block class="Magento\Backend\Block\Page\Head" name="head" as="head" template="page/head.phtml">
-            <action method="setTitle">
-                <argument translate="true" name="title" xsi:type="string">Magento Admin</argument>
-            </action>
-            <action method="addJs">
-                <argument name="file" xsi:type="string">prototype/prototype.js</argument>
-            </action>
-            <action method="addJs">
-                <argument name="file" xsi:type="string">prototype/window.js</argument>
-            </action>
-            <action method="addJs" ifconfig="dev/js/deprecation">
-                <argument name="file" xsi:type="string">prototype/deprecation.js</argument>
-            </action>
-            <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml"/>
-        </block>
         <block class="Magento\Backend\Block\Page\Header" name="header" as="header"/>
         <block class="Magento\Backend\Block\Menu" name="menu" as="menu"/>
         <block class="Magento\Framework\View\Element\Messages" name="messages" as="messages"/>
         <block class="Magento\Framework\View\Element\Text" as="no_name"/>
     </block>
-</layout>
+</page>
diff --git a/dev/tests/integration/testsuite/Magento/Index/Model/Process/FileTest.php b/dev/tests/integration/testsuite/Magento/Index/Model/Process/FileTest.php
deleted file mode 100644
index 9e20056f333..00000000000
--- a/dev/tests/integration/testsuite/Magento/Index/Model/Process/FileTest.php
+++ /dev/null
@@ -1,186 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Test class for \Magento\Index\Model\Process\File
- */
-namespace Magento\Index\Model\Process;
-
-class FileTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Test lock name
-     */
-    const FILE_PATH = 'locks/index_test.lock';
-
-    /**
-     * @var \Magento\TestFramework\ObjectManager
-     */
-    protected $_objectManager;
-
-    /**
-     * @var resource
-     */
-    protected $_testFileHandler;
-
-    /**
-     * @var \Magento\Index\Model\Process\File
-     */
-    protected $_model;
-
-    /**
-     * @var \Magento\Framework\Filesystem\Directory\WriteInterface
-     */
-    protected $_varDirectory;
-
-    protected function setUp()
-    {
-        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
-        $filesystem = $this->_objectManager->create('Magento\Framework\App\Filesystem');
-        $this->_varDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::VAR_DIR);
-
-        $fullFileName = $this->_varDirectory->getAbsolutePath(self::FILE_PATH);
-        $this->_testFileHandler = fopen($fullFileName, 'w');
-    }
-
-    protected function tearDown()
-    {
-        unset($this->_objectManager);
-        unset($this->_model);
-        unset($this->_varDirectory);
-        fclose($this->_testFileHandler);
-        unset($this->_testFileHandler);
-    }
-
-    /**
-     * Open test file
-     */
-    protected function _openFile()
-    {
-        $this->_model = $this->_objectManager->create(
-            'Magento\Index\Model\Process\File',
-            array('streamHandler' => $this->_varDirectory->openFile(self::FILE_PATH, 'w+'))
-        );
-    }
-
-    /**
-     * Get shared lock for test file handler
-     *
-     * @return bool
-     */
-    protected function _tryGetSharedLock()
-    {
-        return flock($this->_testFileHandler, LOCK_SH | LOCK_NB);
-    }
-
-    /**
-     * Unlock test file handler
-     */
-    protected function _unlock()
-    {
-        flock($this->_testFileHandler, LOCK_UN);
-    }
-
-    /**
-     * This test can't check non blocking lock case because its required two parallel test processes
-     */
-    public function testProcessLockSuccessfulLock()
-    {
-        $this->_openFile();
-
-        // can't take shared lock if file has exclusive lock
-        $this->_model->processLock();
-        $this->assertFalse($this->_model->isProcessLocked());
-        $this->assertFalse($this->_tryGetSharedLock(), 'File must be locked');
-        $this->assertAttributeSame(true, '_streamLocked', $this->_model);
-        $this->assertAttributeSame(false, '_processLocked', $this->_model);
-
-        $this->_model->processUnlock();
-    }
-
-    public function testProcessFailedLock()
-    {
-        $this->_openFile();
-
-        // can't take exclusive lock if file has shared lock
-        $this->assertTrue($this->_tryGetSharedLock(), 'File must not be locked');
-        $this->_model->processLock();
-        $this->assertTrue($this->_model->isProcessLocked());
-        $this->assertAttributeSame(false, '_streamLocked', $this->_model);
-        $this->assertAttributeSame(true, '_processLocked', $this->_model);
-
-        $this->_unlock();
-    }
-
-    public function testProcessUnlock()
-    {
-        $this->_openFile();
-        $this->_model->processLock();
-        $this->_model->processUnlock();
-        $this->assertFalse($this->_model->isProcessLocked());
-        $this->assertAttributeSame(false, '_streamLocked', $this->_model);
-        $this->assertAttributeSame(null, '_processLocked', $this->_model);
-    }
-
-    public function testIsProcessLockedStoredFlag()
-    {
-        $this->_openFile();
-        $this->_model->processLock();
-        $this->assertFalse($this->_model->isProcessLocked());
-        $this->_model->processUnlock();
-    }
-
-    public function testIsProcessLockedTrue()
-    {
-        $this->_openFile();
-
-        $this->assertTrue($this->_tryGetSharedLock(), 'File must not be locked');
-        $this->assertTrue($this->_model->isProcessLocked());
-
-        $this->_unlock();
-    }
-
-    public function testIsProcessLockedFalseWithUnlock()
-    {
-        $this->_openFile();
-
-        $this->assertFalse($this->_model->isProcessLocked(true));
-        $this->assertTrue($this->_tryGetSharedLock(), 'File must not be locked');
-        $this->assertAttributeSame(false, '_streamLocked', $this->_model);
-
-        $this->_unlock();
-    }
-
-    public function testIsProcessLockedFalseWithoutUnlock()
-    {
-        $this->_openFile();
-
-        $this->assertFalse($this->_model->isProcessLocked(false));
-        $this->assertFalse($this->_tryGetSharedLock(), 'File must be locked');
-        $this->assertAttributeSame(true, '_streamLocked', $this->_model);
-
-        $this->_model->processUnlock();
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Index/Model/ProcessTest.php b/dev/tests/integration/testsuite/Magento/Index/Model/ProcessTest.php
deleted file mode 100644
index 698b8bba589..00000000000
--- a/dev/tests/integration/testsuite/Magento/Index/Model/ProcessTest.php
+++ /dev/null
@@ -1,175 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-class ProcessTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Test exception message
-     */
-    const EXCEPTION_MESSAGE = 'Test exception message';
-
-    /**
-     * Indexer used for test
-     */
-    const INDEXER_CODE = 'catalog_url';
-
-    /**
-     * @var array
-     */
-    protected $_indexerMatchData = array(
-        'new_data' => array(\Magento\Catalog\Model\Indexer\Url::EVENT_MATCH_RESULT_KEY => true)
-    );
-
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
-
-    /**
-     * @var \Magento\Index\Model\Process
-     */
-    protected $_model;
-
-    /**
-     * @var \Magento\Index\Model\Process\File
-     */
-    protected $_processFile;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_resourceMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_eventRepositoryMock;
-
-    protected function setUp()
-    {
-        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
-        $this->_eventRepositoryMock = $this->getMock(
-            'Magento\Index\Model\EventRepository',
-            array(),
-            array(),
-            '',
-            false
-        );
-
-        // get existing indexer process
-        $this->_model = $this->_objectManager->create(
-            'Magento\Index\Model\Process',
-            array('eventRepository' => $this->_eventRepositoryMock)
-        );
-        $this->_model->load(self::INDEXER_CODE, 'indexer_code');
-        if ($this->_model->isObjectNew()) {
-            $this->markTestIncomplete('Can\'t run test without ' . self::INDEXER_CODE . ' indexer.');
-        }
-
-        // get new process file instance for current indexer
-        /** @var $lockStorage \Magento\Index\Model\Lock\Storage */
-        $lockStorage = $this->_objectManager->create('Magento\Index\Model\Lock\Storage');
-        $this->_processFile = $lockStorage->getFile($this->_model->getId());
-    }
-
-    /**
-     * @return array
-     */
-    public function safeProcessEventDataProvider()
-    {
-        return array(
-            'not_matched' => array('$eventData' => array()),
-            'locked' => array('$eventData' => $this->_indexerMatchData, '$needLock' => true),
-            'matched' => array('$eventData' => $this->_indexerMatchData)
-        );
-    }
-
-    /**
-     * @param array $eventData
-     * @param bool $needLock
-     *
-     * @dataProvider safeProcessEventDataProvider
-     */
-    public function testSafeProcessEvent(array $eventData, $needLock = false)
-    {
-        if ($needLock) {
-            $this->_processFile->processLock();
-        }
-
-        $event = $this->_objectManager->create('Magento\Index\Model\Event', array('data' => $eventData));
-        $this->assertEquals($this->_model, $this->_model->safeProcessEvent($event));
-
-        if ($needLock) {
-            $this->_processFile->processUnlock();
-        }
-
-        $this->assertFalse($this->_processFile->isProcessLocked(true));
-    }
-
-    public function testSafeProcessEventException()
-    {
-        // prepare mock that throws exception
-        /** @var $eventMock \Magento\Index\Model\Event */
-        $eventMock = $this->getMock('Magento\Index\Model\Event', array('setProcess'), array(), '', false);
-        $eventMock->setData($this->_indexerMatchData);
-        $exceptionMessage = self::EXCEPTION_MESSAGE;
-        $eventMock->expects($this->any())->method('setProcess')->will(
-            $this->returnCallback(
-                function () use ($exceptionMessage) {
-                    throw new \Exception($exceptionMessage);
-                }
-            )
-        );
-
-        // can't use @expectedException because we need to assert indexer lock status
-        try {
-            $this->_model->safeProcessEvent($eventMock);
-        } catch (\Exception $e) {
-            $this->assertEquals(self::EXCEPTION_MESSAGE, $e->getMessage());
-        }
-
-        $this->assertFalse($this->_processFile->isProcessLocked(true));
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testReindexAllDoesntTriggerUnprocessedEventFetchingInManualMode()
-    {
-        $collection = $this->_objectManager->create('Magento\Index\Model\Resource\Event\Collection');
-        $this->_model->setMode(\Magento\Index\Model\Process::MODE_REAL_TIME);
-        $this->_model->setStatus(\Magento\Index\Model\Process::STATUS_PENDING);
-        $this->_eventRepositoryMock->expects(
-            $this->once()
-        )->method(
-            'getUnprocessed'
-        )->will(
-            $this->returnValue($collection)
-        );
-        $this->_eventRepositoryMock->expects($this->never())->method('hasUnprocessed');
-        $this->_model->reindexAll();
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Index/Model/ShellTest.php b/dev/tests/integration/testsuite/Magento/Index/Model/ShellTest.php
deleted file mode 100644
index 1b871f3fd67..00000000000
--- a/dev/tests/integration/testsuite/Magento/Index/Model/ShellTest.php
+++ /dev/null
@@ -1,107 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-class ShellTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Returns prepared model
-     *
-     * @param string $entryPoint
-     * @return \Magento\Index\Model\Shell
-     */
-    protected function _getModel($entryPoint = 'fake.php')
-    {
-        return \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Index\Model\Shell',
-            array('entryPoint' => $entryPoint)
-        );
-    }
-
-    /**
-     * Returns result of running model - can be real model or mocked one
-     *
-     * @param \Magento\Index\Model\Shell $model Can be mock
-     * @return string
-     */
-    protected function _run($model)
-    {
-        ob_start();
-        $model->run();
-        $result = ob_get_contents();
-        ob_end_clean();
-        return $result;
-    }
-
-    public function testGetUsageHelp()
-    {
-        $model = $this->_getModel('testme.php');
-        $this->assertContains('testme.php', $model->getUsageHelp());
-    }
-
-    public function testRunWithoutParams()
-    {
-        $model = $this->_getModel('testme.php');
-        $result = $this->_run($model);
-        $this->assertContains('testme.php', $result);
-        $this->assertContains('index', $result); // Something about indexes
-    }
-
-    public function testRunIndexList()
-    {
-        $model = $this->_getModel('testme.php');
-        $model->setRawArgs(array('testme.php', '--', 'status'));
-        $result = $this->_run($model);
-
-        $this->assertNotContains('testme.php', $result);
-        $this->assertNotContains('Usage:', $result);
-        $this->assertNotEmpty($result);
-    }
-
-    /**
-     * @param string $indexCode
-     * @param bool $expectedHasErrors
-     *
-     * @dataProvider hasErrorsDataProvider
-     */
-    public function testHasErrors($param, $expectedHasErrors)
-    {
-        $model = $this->_getModel('testme.php');
-        $model->setRawArgs(array('testme.php', '--', $param));
-        $this->_run($model);
-
-        $this->assertEquals($expectedHasErrors, $model->hasErrors());
-    }
-
-    /**
-     * @return array
-     */
-    public function hasErrorsDataProvider()
-    {
-        return array(
-            'execution without issues' => array('info', false),
-            'issue with wrong index' => array('--reindex=wrong_index_code', true)
-        );
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php
index 0890d7d0823..ead14bd9cfb 100644
--- a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php
+++ b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php
@@ -126,7 +126,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase
         /** @var \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder */
         $customerDetailsBuilder = $objectManager->get('Magento\Customer\Service\V1\Data\CustomerDetailsBuilder');
         $customerDetailsBuilder->setCustomer($customerBuilder->create());
-        $this->accountService->updateCustomer($customerDetailsBuilder->create());
+        $this->accountService->updateCustomer(1, $customerDetailsBuilder->create());
 
         $subscriber->loadByEmail('new@example.com');
         $this->assertTrue($subscriber->isSubscribed());
diff --git a/dev/tests/integration/testsuite/Magento/PayPalRecurringPayment/_files/recurring_payment.php b/dev/tests/integration/testsuite/Magento/PayPalRecurringPayment/_files/recurring_payment.php
index a9a1c379437..52e9ca0c5f3 100644
--- a/dev/tests/integration/testsuite/Magento/PayPalRecurringPayment/_files/recurring_payment.php
+++ b/dev/tests/integration/testsuite/Magento/PayPalRecurringPayment/_files/recurring_payment.php
@@ -52,7 +52,7 @@ $recurringPayment->addData(
             'street' => 'Street',
             'city' => 'City',
             'customer_email' => 'co@co.co',
-            'telephone' => 'Telephone',
+            'telephone' => 'Phone Number',
             'country_id' => 'Country',
             'firstname' => 'Co',
             'address_type' => 'billing'
@@ -63,7 +63,7 @@ $recurringPayment->addData(
             'street' => 'Street',
             'city' => 'City',
             'customer_email' => 'co@co.co',
-            'telephone' => 'Telephone',
+            'telephone' => 'Phone Number',
             'country_id' => 'Country',
             'firstname' => 'Co',
             'address_type' => 'shipping'
diff --git a/dev/tests/integration/testsuite/Magento/Rss/Controller/CatalogTest.php b/dev/tests/integration/testsuite/Magento/Rss/Controller/CatalogTest.php
deleted file mode 100644
index 56f1ffeaf38..00000000000
--- a/dev/tests/integration/testsuite/Magento/Rss/Controller/CatalogTest.php
+++ /dev/null
@@ -1,182 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Controller;
-
-class CatalogTest extends \Magento\TestFramework\TestCase\AbstractController
-{
-    /**
-     * @param string $action
-     * @dataProvider actionNoFeedDataProvider
-     */
-    public function testActionsNoFeed($action)
-    {
-        $this->dispatch("rss/catalog/{$action}");
-        $this->assertHeaderPcre('Http/1.1', '/^404 Not Found$/');
-        $this->assertEquals('There was no RSS feed enabled.', $this->getResponse()->getBody());
-    }
-
-    /**
-     * @return array
-     */
-    public function actionNoFeedDataProvider()
-    {
-        return array(array('new'), array('special'), array('salesrule'), array('category'));
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/products_new.php
-     * @magentoConfigFixture current_store rss/catalog/new 1
-     */
-    public function testNewAction()
-    {
-        $this->dispatch('rss/catalog/new');
-        $this->assertContains('New Product', $this->getResponse()->getBody());
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/product_special_price.php
-     * @magentoConfigFixture current_store rss/catalog/special 1
-     */
-    public function testSpecialAction()
-    {
-        $this->dispatch('rss/catalog/special');
-        $body = $this->getResponse()->getBody();
-        $this->assertContains('$10.00', $body);
-        $this->assertContains('$5.99', $body);
-    }
-
-    /**
-     * @magentoConfigFixture current_store rss/catalog/salesrule 1
-     */
-    public function testSalesruleAction()
-    {
-        $this->dispatch('rss/catalog/salesrule');
-        $this->assertHeaderPcre('Content-Type', '/text\/xml/');
-        // to improve accuracy of the test, implement a fixture of a shopping cart price rule with a coupon
-        $this->assertContains(
-            '<link>http://localhost/index.php/rss/catalog/salesrule/</link>',
-            $this->getResponse()->getBody()
-        );
-    }
-
-    /**
-     * @dataProvider authorizationFailedDataProvider
-     * @magentoAppArea adminhtml
-     */
-    public function testAuthorizationFailed($action)
-    {
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Backend\Model\UrlInterface'
-        )->turnOffSecretKey();
-        $this->dispatch("backend/rss/catalog/{$action}");
-        $this->assertHeaderPcre('Http/1.1', '/^401 Unauthorized$/');
-    }
-
-    /**
-     * @return array
-     */
-    public function authorizationFailedDataProvider()
-    {
-        return array(array('notifystock'), array('review'));
-    }
-
-    /**
-     * @magentoDataFixture Magento/Catalog/_files/multiple_products.php
-     * @magentoConfigFixture admin_store cataloginventory/item_options/notify_stock_qty 75
-     * @magentoConfigFixture current_store cataloginventory/item_options/notify_stock_qty 75
-     */
-    public function testNotifyStockAction()
-    {
-        // workaround: trigger updating "low stock date", because RSS collection requires it to be not null
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\CatalogInventory\Model\Resource\Stock'
-        )->updateLowStockDate();
-        $this->_loginAdmin();
-        $this->dispatch('backend/rss/catalog/notifystock');
-
-        $this->assertHeaderPcre('Content-Type', '/text\/xml/');
-
-        // assert that among 2 products in fixture, there is only one with 50 qty
-        $body = $this->getResponse()->getBody();
-        $this->assertNotContains('<![CDATA[Simple Product]]>', $body);
-        // this one was supposed to have qty 100 ( > 75)
-        $this->assertContains('<![CDATA[Simple Product2]]>', $body);
-        // 50 < 75
-        // this one was supposed to have qty 140 ( > 75)
-        $this->assertNotContains('<![CDATA[Simple Product 3]]>', $body);
-    }
-
-    /**
-     * @magentoDataFixture Magento/Review/_files/reviews.php
-     */
-    public function testReviewAction()
-    {
-        $this->_loginAdmin();
-        $this->dispatch('backend/rss/catalog/review');
-        $this->assertHeaderPcre('Content-Type', '/text\/xml/');
-        $body = $this->getResponse()->getBody();
-        $this->assertContains('"Simple Product 3"', $body);
-        $this->assertContains('Review text', $body);
-    }
-
-    /**
-     * @magentoConfigFixture current_store rss/catalog/category 1
-     */
-    public function testCategoryAction()
-    {
-        $this->getRequest()->setParam(
-            'cid',
-            \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-                'Magento\Framework\StoreManagerInterface'
-            )->getStore()->getRootCategoryId()
-        );
-        $this->dispatch('rss/catalog/category');
-        $this->assertStringMatchesFormat(
-            '%A<link>http://localhost/index.php/catalog/category/view/%A/id/2/</link>%A',
-            $this->getResponse()->getBody()
-        );
-    }
-
-    /**
-     * Emulate administrator logging in
-     */
-    protected function _loginAdmin()
-    {
-        \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea(
-            \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE
-        );
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\DesignInterface'
-        )->setDefaultDesignTheme();
-        $this->getRequest()->setServer(
-            array(
-                'PHP_AUTH_USER' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
-                'PHP_AUTH_PW' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD
-            )
-        );
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Backend\Model\UrlInterface'
-        )->turnOffSecretKey();
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Rss/Controller/OrderTest.php b/dev/tests/integration/testsuite/Magento/Rss/Controller/OrderTest.php
deleted file mode 100644
index b691922e240..00000000000
--- a/dev/tests/integration/testsuite/Magento/Rss/Controller/OrderTest.php
+++ /dev/null
@@ -1,89 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Rss\Controller;
-
-/**
- * @magentoAppArea adminhtml
- */
-class OrderTest extends \Magento\TestFramework\TestCase\AbstractController
-{
-    /**
-     * Reuse URI for "new" action
-     */
-    const NEW_ORDER_URI = 'backend/rss/order/new';
-
-    public function testNewActionAuthorizationFailed()
-    {
-        $this->dispatch(self::NEW_ORDER_URI);
-        $this->assertHeaderPcre('Http/1.1', '/^401 Unauthorized$/');
-    }
-
-    /**
-     * @magentoDataFixture Magento/Sales/_files/order.php
-     */
-    public function testNewAction()
-    {
-        $this->getRequest()->setServer(
-            array(
-                'PHP_AUTH_USER' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
-                'PHP_AUTH_PW' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD
-            )
-        );
-        $this->dispatch(self::NEW_ORDER_URI);
-        $this->assertHeaderPcre('Content-Type', '/text\/xml/');
-        $this->assertContains('#100000001', $this->getResponse()->getBody());
-    }
-
-    public function testNotLoggedIn()
-    {
-        $this->dispatch(self::NEW_ORDER_URI);
-        $this->assertHeaderPcre('Http/1.1', '/^401 Unauthorized$/');
-    }
-
-    /**
-     * @param string $login
-     * @param string $password
-     * @dataProvider invalidAccessDataProvider
-     * @magentoDataFixture Magento/User/_files/dummy_user.php
-     */
-    public function testInvalidAccess($login, $password)
-    {
-        $this->getRequest()->setServer(array('PHP_AUTH_USER' => $login, 'PHP_AUTH_PW' => $password));
-        $this->dispatch(self::NEW_ORDER_URI);
-        $this->assertHeaderPcre('Http/1.1', '/^401 Unauthorized$/');
-    }
-
-    /**
-     * @return array
-     */
-    public function invalidAccessDataProvider()
-    {
-        return array(
-            'no login' => array('', \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD),
-            'no password' => array(\Magento\TestFramework\Bootstrap::ADMIN_NAME, ''),
-            'no login and password' => array('', ''),
-            'user with inappropriate ACL' => array('dummy_username', 'dummy_password1')
-        );
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Report/Filter/Form/CouponTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Report/Filter/Form/CouponTest.php
index dc7d5bbcf43..2283fd67e47 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Report/Filter/Form/CouponTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Report/Filter/Form/CouponTest.php
@@ -22,9 +22,6 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * Test for \Magento\Index\Model\Lock\Storage
- */
 namespace Magento\Sales\Block\Adminhtml\Report\Filter\Form;
 
 /**
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
index 0b0247dbb6d..968720cc7a5 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
@@ -501,7 +501,7 @@ class SetupUtil
             ->setCode('custom_group')
             ->setTaxClassId($customerTaxClassId);
         $customerGroup = new \Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder);
-        $customerGroupId = $customerGroupService->saveGroup($customerGroup);
+        $customerGroupId = $customerGroupService->createGroup($customerGroup);
         return $customerGroupId;
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
index 2c4621007df..abb943ece0f 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
@@ -56,7 +56,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
         $customerGroupService = $this->_objectManager->create('\Magento\Customer\Service\V1\CustomerGroupService');
         $group = $builder->setId(null)->setCode(self::GROUP_CODE)->setTaxClassId($taxClassId)
             ->create();
-        $customerGroupService->saveGroup($group);
+        $customerGroupService->createGroup($group);
 
         /** @var $model \Magento\Tax\Model\TaxClass\Type\Customer */
         $model = $this->_objectManager->create('Magento\Tax\Model\TaxClass\Type\Customer');
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/IndexerConfigFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/IndexerConfigFilesTest.php
index 3c7f7b6bcc5..b790bacf408 100644
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/IndexerConfigFilesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/IndexerConfigFilesTest.php
@@ -26,36 +26,60 @@ namespace Magento\Test\Integrity\Modular;
 class IndexerConfigFilesTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Index\Model\Indexer\Config\Reader
+     * Configuration acl file list
+     *
+     * @var array
      */
-    protected $_model;
+    protected $fileList = array();
 
-    public function setUp()
-    {
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        /** @var $filesystem \Magento\Framework\App\Filesystem */
-        $filesystem = $objectManager->get('Magento\Framework\App\Filesystem');
-        $modulesDirectory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MODULES_DIR);
-        $fileIteratorFactory = $objectManager->get('Magento\Framework\Config\FileIteratorFactory');
-        $xmlFiles = $fileIteratorFactory->create(
-            $modulesDirectory,
-            $modulesDirectory->search('/*/*/etc/{*/indexers.xml,indexers.xml}')
-        );
+    /**
+     * Path to scheme file
+     *
+     * @var string
+     */
+    protected $schemeFile;
 
-        $validationStateMock = $this->getMock('Magento\Framework\Config\ValidationStateInterface');
-        $validationStateMock->expects($this->any())->method('isValidated')->will($this->returnValue(true));
-        $fileResolverMock = $this->getMock('Magento\Framework\Config\FileResolverInterface');
-        $fileResolverMock->expects($this->any())->method('get')->will($this->returnValue($xmlFiles));
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    protected function setUp()
+    {
+        $this->schemeFile = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\App\Filesystem'
+        )->getPath(
+            \Magento\Framework\App\Filesystem::APP_DIR
+        ) . '/code/Magento/Indexer/etc/indexer.xsd';
+    }
 
-        $this->_model = $objectManager->create(
-            'Magento\Index\Model\Indexer\Config\Reader',
-            array('fileResolver' => $fileResolverMock, 'validationState' => $validationStateMock)
-        );
+    /**
+     * Test each acl configuration file
+     * @param string $file
+     * @dataProvider indexerConfigFileDataProvider
+     */
+    public function testIndexerConfigFile($file)
+    {
+        $domConfig = new \Magento\Framework\Config\Dom(file_get_contents($file));
+        $result = $domConfig->validate($this->schemeFile, $errors);
+        $message = "Invalid XML-file: {$file}\n";
+        foreach ($errors as $error) {
+            $message .= "{$error}\n";
+        }
+        $this->assertTrue($result, $message);
     }
 
-    public function testImportXmlFiles()
+    /**
+     * @return array
+     */
+    public function indexerConfigFileDataProvider()
     {
-        $this->_model->read('global');
+        $fileList = glob(
+            \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+                'Magento\Framework\App\Filesystem'
+            )->getPath(
+                \Magento\Framework\App\Filesystem::APP_DIR
+            ) . '/*/*/*/etc/indexer.xml'
+        );
+        $dataProviderResult = array();
+        foreach ($fileList as $file) {
+            $dataProviderResult[$file] = array($file);
+        }
+        return $dataProviderResult;
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/NewIndexerConfigFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/NewIndexerConfigFilesTest.php
deleted file mode 100644
index 960def7e804..00000000000
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/NewIndexerConfigFilesTest.php
+++ /dev/null
@@ -1,74 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Test\Integrity\Modular;
-
-class NewIndexerConfigFilesTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Configuration acl file list
-     *
-     * @var array
-     */
-    protected $fileList = array();
-
-    /**
-     * Path to scheme file
-     *
-     * @var string
-     */
-    protected $schemeFile;
-
-    protected function setUp()
-    {
-        $this->schemeFile = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\App\Filesystem'
-        )->getPath(
-            \Magento\Framework\App\Filesystem::APP_DIR
-        ) . '/code/Magento/Indexer/etc/indexer.xsd';
-    }
-
-    /**
-     * Test each acl configuration file
-     * @param string $file
-     * @dataProvider indexerConfigFileDataProvider
-     */
-    public function testIndexerConfigFile($file)
-    {
-        $domConfig = new \Magento\Framework\Config\Dom(file_get_contents($file));
-        $result = $domConfig->validate($this->schemeFile, $errors);
-        $message = "Invalid XML-file: {$file}\n";
-        foreach ($errors as $error) {
-            $message .= "{$error}\n";
-        }
-        $this->assertTrue($result, $message);
-    }
-
-    /**
-     * @return array
-     */
-    public function indexerConfigFileDataProvider()
-    {
-        return \Magento\TestFramework\Utility\Files::init()->getConfigFiles('indexer.xml');
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/TemplateFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/TemplateFilesTest.php
index 309a216fa2c..c184bf9384d 100644
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/TemplateFilesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/TemplateFilesTest.php
@@ -50,7 +50,8 @@ class TemplateFilesTest extends \Magento\TestFramework\TestCase\AbstractIntegrit
                     $template,
                     $params
                 );
-                $this->assertFileExists($file, "Block class: {$class}");
+                $this->assertInternalType('string', $file);
+                $this->assertFileExists($file);
             },
             $this->allTemplatesDataProvider()
         );
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/StaticFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/StaticFilesTest.php
index 0fd84acaeb0..e138ef625e1 100644
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/StaticFilesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/StaticFilesTest.php
@@ -297,11 +297,7 @@ class StaticFilesTest extends \PHPUnit_Framework_TestCase
     private function collectFileIdsFromLayout($file)
     {
         $xml = simplexml_load_file($file);
-        // Collect "addCss" and "addJs" from theme layout
-        $elements = $xml->xpath(
-            '//block[@class="Magento\Theme\Block\Html\Head\Css" or @class="Magento\Theme\Block\Html\Head\Script"]' .
-            '/arguments/argument[@name="file"]'
-        );
+        $elements = $xml->xpath('//head/css|link|script');
         $result = array();
         if ($elements) {
             foreach ($elements as $node) {
diff --git a/dev/tests/integration/testsuite/Magento/Theme/Block/Html/HeadTest.php b/dev/tests/integration/testsuite/Magento/Theme/Block/Html/HeadTest.php
deleted file mode 100644
index 64b0fe1772e..00000000000
--- a/dev/tests/integration/testsuite/Magento/Theme/Block/Html/HeadTest.php
+++ /dev/null
@@ -1,191 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Theme\Block\Html;
-
-class HeadTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Theme\Block\Html\Head
-     */
-    private $_block;
-
-    protected function setUp()
-    {
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\App\State')
-            ->setAreaCode('frontend');
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\DesignInterface'
-        )->setDesignTheme(
-            'Magento/blank'
-        );
-        $this->_block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\LayoutInterface'
-        )->createBlock(
-            'Magento\Theme\Block\Html\Head'
-        );
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     * @magentoConfigFixture current_store dev/js/merge_files 0
-     * @magentoConfigFixture current_store dev/js/minify_files 0
-     */
-    public function testGetCssJsHtml()
-    {
-        $this->_block->addChild(
-            'zero.js',
-            'Magento\Theme\Block\Html\Head\Script',
-            array('file' => 'zero.js', 'properties' => array('flag_name' => 'nonexisting_condition'))
-        );
-        $this->_block->addChild(
-            'varien/js.js',
-            'Magento\Theme\Block\Html\Head\Script',
-            array('file' => 'varien/js.js')
-        );
-        $this->_block->addChild(
-            'Magento_Bundle::bundle.js',
-            'Magento\Theme\Block\Html\Head\Script',
-            array('file' => 'Magento_Bundle::bundle.js')
-        );
-        $this->_block->addChild(
-            'ui.css',
-            'Magento\Theme\Block\Html\Head\Css',
-            array('file' => 'tiny_mce/themes/advanced/skins/default/ui.css')
-        );
-        $this->_block->addChild(
-            'styles.css',
-            'Magento\Theme\Block\Html\Head\Css',
-            array('file' => 'css/styles.css', 'properties' => array('attributes' => 'media="print"'))
-        );
-        $this->_block->addRss('RSS Feed', 'http://example.com/feed.xml');
-
-        $this->_block->addChild(
-            'magento-page-head-canonical-link',
-            'Magento\Theme\Block\Html\Head\Link',
-            array(
-                'url' => 'http://localhost/index.php/category.html',
-                'properties' => array('attributes' => array('rel' => 'next'))
-            )
-        );
-
-        $this->_block->addChild(
-            'varien/form.js',
-            'Magento\Theme\Block\Html\Head\Script',
-            array('file' => 'varien/form.js', 'properties' => array('ie_condition' => 'lt IE 7'))
-        );
-        $this->assertEquals(
-            '<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://example.com/feed.xml" />'
-            . "\n"
-            . '<script type="text/javascript"'
-            . ' src="http://localhost/pub/static/frontend/Magento/blank/en_US/varien/js.js"></script>' . "\n"
-            . '<script type="text/javascript"'
-            . ' src="http://localhost/pub/static/frontend/Magento/blank/en_US/Magento_Bundle/bundle.js">'
-            . '</script>' . "\n"
-            . '<link rel="stylesheet" type="text/css" media="all"'
-            . ' href="http://localhost/pub/static/frontend/Magento/blank/en_US/'
-            . 'tiny_mce/themes/advanced/skins/default/ui.css" />' . "\n"
-            . '<link rel="stylesheet" type="text/css" media="print" '
-                . 'href="http://localhost/pub/static/frontend/Magento/blank/en_US/css/styles.css" />'
-                . "\n"
-            . '<link rel="next" href="http://localhost/index.php/category.html" />' . "\n"
-            . '<!--[if lt IE 7]>' . "\n"
-            . '<script type="text/javascript"'
-            . ' src="http://localhost/pub/static/frontend/Magento/blank/en_US/varien/form.js"></script>' . "\n"
-            . '<![endif]-->' . "\n",
-            $this->_block->getCssJsHtml()
-        );
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     * @magentoConfigFixture current_store dev/js/minify_files 1
-     */
-    public function testGetCssJsHtmlJsMinified()
-    {
-        $this->_block->addChild('jjs', 'Magento\Theme\Block\Html\Head\Script', array('file' => 'varien/js.js'));
-        $this->assertStringMatchesFormat(
-            '<script type="text/javascript" src="http://localhost/pub/static/_cache/minified/%s_js.min.js"></script>',
-            $this->_block->getCssJsHtml()
-        );
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     * @magentoConfigFixture current_store dev/js/minify_files 0
-     */
-    public function testGetCssJsHtmlJsNotMinified()
-    {
-        $this->_block->addChild('jjs', 'Magento\Theme\Block\Html\Head\Script', array('file' => 'varien/js.js'));
-        $this->assertSame(
-            '<script type="text/javascript"'
-                . ' src="http://localhost/pub/static/frontend/Magento/blank/en_US/varien/js.js"></script>' . "\n",
-            $this->_block->getCssJsHtml()
-        );
-    }
-
-    /**
-     * Head link with several attributes
-     * @magentoAppIsolation enabled
-     */
-    public function testGetCssJsHtmlSeveralAttributes()
-    {
-        $this->_block->addChild(
-            'magento-page-head-test-link',
-            'Magento\Theme\Block\Html\Head\Link',
-            array(
-                'url' => 'http://localhost/index.php/category.html',
-                'properties' => array(
-                    'attributes' => array('rel' => 'next', 'attr' => 'value', 'some_other_attr' => 'value2')
-                )
-            )
-        );
-
-        $this->assertSame(
-            '<link rel="next" attr="value" some_other_attr="value2" ' .
-            'href="http://localhost/index.php/category.html" />' .
-            "\n",
-            $this->_block->getCssJsHtml()
-        );
-    }
-
-    /**
-     * Test getRobots default value
-     * @magentoAppIsolation enabled
-     */
-    public function testGetRobotsDefaultValue()
-    {
-        $this->assertEquals('INDEX,FOLLOW', $this->_block->getRobots());
-    }
-
-    /**
-     * Test getRobots
-     *
-     * @magentoConfigFixture default_store design/search_engine_robots/default_robots INDEX,NOFOLLOW
-     * @magentoAppIsolation enabled
-     */
-    public function testGetRobots()
-    {
-        $this->assertEquals('INDEX,NOFOLLOW', $this->_block->getRobots());
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Theme/Block/HtmlTest.php b/dev/tests/integration/testsuite/Magento/Theme/Block/HtmlTest.php
deleted file mode 100644
index 5e39f9fe90c..00000000000
--- a/dev/tests/integration/testsuite/Magento/Theme/Block/HtmlTest.php
+++ /dev/null
@@ -1,116 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Theme\Block;
-
-class HtmlTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @dataProvider getConfigValuesDataProvider
-     * @magentoAppArea frontend
-     */
-    public function testGetPrintLogoUrl($configData, $returnValue)
-    {
-        $scopeConfig = $this->getMockBuilder(
-            'Magento\Framework\App\Config\ScopeConfigInterface'
-        )->disableOriginalConstructor()->getMock();
-        $scopeConfig->expects($this->atLeastOnce())->method('getValue')->will($this->returnValueMap($configData));
-
-        $securityInfoMock = $this->getMock('Magento\Framework\Url\SecurityInfoInterface');
-        $codeData = $this->getMock('Magento\Core\Helper\Data', array(), array(), '', false);
-        $urlBuilder = $this->getMock(
-            'Magento\Framework\Url',
-            array('getBaseUrl'),
-            array(
-                $this->getMock('Magento\Framework\App\Route\ConfigInterface'),
-                $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false),
-                $securityInfoMock,
-                $this->getMock('Magento\Framework\Url\ScopeResolverInterface', array(), array(), '', false),
-                $this->getMock('Magento\Framework\Session\Generic', array(), array(), '', false),
-                $this->getMock('Magento\Framework\Session\SidResolverInterface', array(), array(), '', false),
-                $this->getMock('Magento\Framework\Url\RouteParamsResolverFactory', array(), array(), '', false),
-                $this->getMock('Magento\Framework\Url\QueryParamsResolver', array(), array(), '', false),
-                $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface', array(), array(), '', false),
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                array()
-            )
-        );
-        $urlBuilder->expects(
-            $this->any()
-        )->method(
-            'getBaseUrl'
-        )->will(
-            $this->returnValue('http://localhost/pub/media/')
-        );
-
-        $context = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Element\Template\Context',
-            array('scopeConfig' => $scopeConfig, 'urlBuilder' => $urlBuilder)
-        );
-        $storeManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\StoreManagerInterface'
-        );
-        $block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Theme\Block\Html',
-            array('storeManager' => $storeManager, 'urlHelperMock' => $codeData, 'context' => $context)
-        );
-
-        $this->assertEquals($returnValue, $block->getPrintLogoUrl());
-    }
-
-    public function getConfigValuesDataProvider()
-    {
-        return array(
-            'sales_identity_logo_html' => array(
-                array(
-                    array(
-                        'sales/identity/logo_html',
-                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                        null,
-                        'image.gif'
-                    )
-                ),
-                'http://localhost/pub/media/sales/store/logo_html/image.gif'
-            ),
-            'sales_identity_logo' => array(
-                array(
-                    array('sales/identity/logo', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, null, 'image.gif')
-                ),
-                'http://localhost/pub/media/sales/store/logo/image.gif'
-            ),
-            'sales_identity_logoTif' => array(
-                array(
-                    array('sales/identity/logo', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, null, 'image.tif')
-                ),
-                ''
-            ),
-            'sales_identity_logoTiff' => array(
-                array(
-                    array('sales/identity/logo', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, null, 'image.tiff')
-                ),
-                ''
-            ),
-            'no_logo' => array(array(), '')
-        );
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/EditTest.php
similarity index 83%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/EditTest.php
index fa773d7b14f..4ca9162c017 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/EditTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Category;
+namespace Magento\UrlRewrite\Block\Catalog\Category;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit
+ * Test for \Magento\UrlRewrite\Block\Catalog\Category\Edit
  * @magentoAppArea adminhtml
  */
 class EditTest extends \PHPUnit_Framework_TestCase
@@ -46,9 +46,9 @@ class EditTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\View\LayoutInterface'
         );
 
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit */
+        /** @var $block \Magento\UrlRewrite\Block\Catalog\Category\Edit */
         $block = $layout->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit',
+            'Magento\UrlRewrite\Block\Catalog\Category\Edit',
             '',
             array('data' => $blockAttributes)
         );
@@ -63,7 +63,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check selector
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Category\Edit $block
      * @param array $expected
      */
     private function _checkSelector($block, $expected)
@@ -71,12 +71,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $selectorBlock \Magento\Backend\Block\Urlrewrite\Selector|bool */
+        /** @var $selectorBlock \Magento\UrlRewrite\Block\Selector|bool */
         $selectorBlock = $layout->getChildBlock($blockName, 'selector');
 
         if ($expected['selector']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Selector',
+                'Magento\UrlRewrite\Block\Selector',
                 $selectorBlock,
                 'Child block with entity selector is invalid'
             );
@@ -88,7 +88,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check links
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Category\Edit $block
      * @param array $expected
      */
     private function _checkLinks($block, $expected)
@@ -96,12 +96,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $categoryBlock \Magento\Backend\Block\Urlrewrite\Link|bool */
+        /** @var $categoryBlock \Magento\UrlRewrite\Block\Link|bool */
         $categoryBlock = $layout->getChildBlock($blockName, 'category_link');
 
         if ($expected['category_link']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Link',
+                'Magento\UrlRewrite\Block\Link',
                 $categoryBlock,
                 'Child block with category link is invalid'
             );
@@ -131,36 +131,38 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check buttons
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Category\Edit $block
      * @param array $expected
      */
     private function _checkButtons($block, $expected)
     {
         $buttonsHtml = $block->getButtonsHtml();
 
-        if ($expected['back_button']) {
-            if ($block->getCategory()->getId()) {
-                $this->assertSelectCount(
-                    'button.back[onclick~="\/category"]',
-                    1,
-                    $buttonsHtml,
-                    'Back button is not present in category URL rewrite edit block'
-                );
+        if (isset($expected['back_button'])) {
+            if ($expected['back_button']) {
+                if ($block->getCategory()->getId()) {
+                    $this->assertSelectCount(
+                        'button.back[onclick~="\/category"]',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in category URL rewrite edit block'
+                    );
+                } else {
+                    $this->assertSelectCount(
+                        'button.back',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in category URL rewrite edit block'
+                    );
+                }
             } else {
                 $this->assertSelectCount(
                     'button.back',
-                    1,
+                    0,
                     $buttonsHtml,
-                    'Back button is not present in category URL rewrite edit block'
+                    'Back button should not present in category URL rewrite edit block'
                 );
             }
-        } else {
-            $this->assertSelectCount(
-                'button.back',
-                0,
-                $buttonsHtml,
-                'Back button should not present in category URL rewrite edit block'
-            );
         }
 
         if ($expected['save_button']) {
@@ -215,7 +217,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check form
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Category\Edit $block
      * @param array $expected
      */
     private function _checkForm($block, $expected)
@@ -223,12 +225,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $formBlock \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form|bool */
+        /** @var $formBlock \Magento\UrlRewrite\Block\Catalog\Edit\Form|bool */
         $formBlock = $layout->getChildBlock($blockName, 'form');
 
         if ($expected['form']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form',
+                'Magento\UrlRewrite\Block\Catalog\Edit\Form',
                 $formBlock,
                 'Child block with form is invalid'
             );
@@ -252,7 +254,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check categories tree
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Category\Edit $block
      * @param array $expected
      */
     private function _checkCategoriesTree($block, $expected)
@@ -260,12 +262,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $categoriesTreeBlock \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree|bool  */
+        /** @var $categoriesTreeBlock \Magento\UrlRewrite\Block\Catalog\Category\Tree|bool */
         $categoriesTreeBlock = $layout->getChildBlock($blockName, 'categories_tree');
 
         if ($expected['categories_tree']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree',
+                'Magento\UrlRewrite\Block\Catalog\Category\Tree',
                 $categoriesTreeBlock,
                 'Child block with categories tree is invalid'
             );
@@ -331,7 +333,6 @@ class EditTest extends \PHPUnit_Framework_TestCase
                 array(
                     'selector' => false,
                     'category_link' => array('name' => $category->getName()),
-                    'back_button' => true,
                     'save_button' => true,
                     'reset_button' => true,
                     'delete_button' => true,
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/TreeTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/TreeTest.php
similarity index 82%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/TreeTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/TreeTest.php
index ed5f30b17c0..750c8a63c84 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/TreeTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Category/TreeTest.php
@@ -21,17 +21,17 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Category;
+namespace Magento\UrlRewrite\Block\Catalog\Category;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree
+ * Test for \Magento\UrlRewrite\Block\Catalog\Category\Tree
  *
  * @magentoAppArea adminhtml
  */
 class TreeTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree
+     * @var \Magento\UrlRewrite\Block\Catalog\Category\Tree
      */
     private $_treeBlock;
 
@@ -41,16 +41,15 @@ class TreeTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         parent::setUp();
-
         $this->_treeBlock = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         )->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree'
+            'Magento\UrlRewrite\Block\Catalog\Category\Tree'
         );
     }
 
     /**
-     * Test for method \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree::getTreeArray()
+     * Test for method \Magento\UrlRewrite\Block\Catalog\Category\Tree::getTreeArray()
      */
     public function testGetTreeArray()
     {
@@ -65,14 +64,15 @@ class TreeTest extends \PHPUnit_Framework_TestCase
             'children' => array(
                 array(
                     'id' => 2,
-                    'parent_id' => 1,
+                    'parent_id' => \Magento\Catalog\Model\Category::TREE_ROOT_ID,
                     'children_count' => 0,
                     'is_active' => true,
                     'name' => 'Default Category',
                     'level' => 1,
                     'product_count' => 0,
                     'cls' => 'active-category',
-                    'expanded' => false
+                    'expanded' => false,
+                    'disabled' => true,
                 )
             ),
             'cls' => 'no-active-category',
@@ -96,7 +96,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for method \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree::getCategoryCollection()
+     * Test for method \Magento\UrlRewrite\Block\Catalog\Category\Tree::getCategoryCollection()
      */
     public function testGetCategoryCollection()
     {
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php
similarity index 79%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Edit/FormTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php
index 720fa4b7d0a..81ce14cbdd9 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php
@@ -21,14 +21,24 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Edit;
+namespace Magento\UrlRewrite\Block\Catalog\Edit;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Catalog\Edit\FormTest
+ * Test for \Magento\UrlRewrite\Block\Catalog\Edit\Form
  * @magentoAppArea adminhtml
  */
 class FormTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
     /**
      * Get form instance
      *
@@ -38,12 +48,12 @@ class FormTest extends \PHPUnit_Framework_TestCase
     protected function _getFormInstance($args = array())
     {
         /** @var $layout \Magento\Framework\View\Layout */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+        $layout = $this->objectManager->get(
             'Magento\Framework\View\LayoutInterface'
         );
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form */
+        /** @var $block \Magento\UrlRewrite\Block\Catalog\Edit\Form */
         $block = $layout->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form',
+            'Magento\UrlRewrite\Block\Catalog\Edit\Form',
             'block',
             array('data' => $args)
         );
@@ -55,36 +65,39 @@ class FormTest extends \PHPUnit_Framework_TestCase
     /**
      * Check _formPostInit set expected fields values
      *
-     * @covers \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form::_formPostInit
+     * @covers \Magento\UrlRewrite\Block\Catalog\Edit\Form::_formPostInit
      *
      * @dataProvider formPostInitDataProvider
      *
      * @param array $productData
      * @param array $categoryData
      * @param string $action
-     * @param string $idPath
      * @param string $requestPath
      * @param string $targetPath
      * @magentoConfigFixture current_store general/single_store_mode/enabled 1
      * @magentoAppIsolation enabled
      */
-    public function testFormPostInitNew($productData, $categoryData, $action, $idPath, $requestPath, $targetPath)
+    public function testFormPostInitNew($productData, $categoryData, $action, $requestPath, $targetPath)
     {
         $args = array();
         if ($productData) {
-            $args['product'] = new \Magento\Framework\Object($productData);
+            $args['product'] = $this->objectManager->create(
+                'Magento\Catalog\Model\Product',
+                array('data' => $productData)
+            );
         }
         if ($categoryData) {
-            $args['category'] = new \Magento\Framework\Object($categoryData);
+            $args['category'] = $this->objectManager->create(
+                'Magento\Catalog\Model\Category',
+                array('data' => $categoryData)
+            );
         }
         $form = $this->_getFormInstance($args);
         $this->assertContains($action, $form->getAction());
 
-        $this->assertEquals($idPath, $form->getElement('id_path')->getValue());
         $this->assertEquals($requestPath, $form->getElement('request_path')->getValue());
         $this->assertEquals($targetPath, $form->getElement('target_path')->getValue());
 
-        $this->assertTrue($form->getElement('id_path')->getData('disabled'));
         $this->assertTrue($form->getElement('target_path')->getData('disabled'));
     }
 
@@ -103,10 +116,16 @@ class FormTest extends \PHPUnit_Framework_TestCase
     {
         $args = array();
         if ($productData) {
-            $args['product'] = new \Magento\Framework\Object($productData);
+            $args['product'] = $this->objectManager->create(
+                'Magento\Catalog\Model\Product',
+                array('data' => $productData)
+            );
         }
         if ($categoryData) {
-            $args['category'] = new \Magento\Framework\Object($categoryData);
+            $args['category'] = $this->objectManager->create(
+                'Magento\Catalog\Model\Category',
+                array('data' => $categoryData)
+            );
         }
         $form = $this->_getFormInstance($args);
         $this->assertEquals($expectedStores, $form->getElement('store_id')->getValues());
@@ -174,25 +193,22 @@ class FormTest extends \PHPUnit_Framework_TestCase
         return array(
             array(
                 null,
-                array('id' => 3, 'level' => 2, 'url_key' => 'category'),
-                'category/3',
+                array('entity_id' => 3, 'level' => 2, 'url_key' => 'category', 'store_id' => 1),
                 'category/3',
                 'category.html',
                 'catalog/category/view/id/3'
             ),
             array(
-                array('id' => 2, 'url_key' => 'product'),
+                array('entity_id' => 2, 'level' => 2,  'url_key' => 'product', 'store_id' => 1),
                 null,
                 'product/2',
-                'product/2',
                 'product.html',
                 'catalog/product/view/id/2'
             ),
             array(
-                array('id' => 2, 'name' => 'product'),
-                array('id' => 3, 'level' => 2, 'url_key' => 'category'),
+                array('entity_id' => 2, 'name' => 'product', 'store_id' => 1),
+                array('entity_id' => 3, 'level' => 2, 'url_key' => 'category', 'store_id' => 1),
                 'product/2/category/3',
-                'product/2/3',
                 'category/product.html',
                 'catalog/product/view/id/2/category/3'
             )
@@ -213,7 +229,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
         return array(
             array(
                 null,
-                array('id' => 3, 'store_ids' => array(1)),
+                array('entity_id' => 3, 'store_ids' => array(1)),
                 array(
                     array('label' => 'Main Website', 'value' => array()),
                     array(
@@ -223,7 +239,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
                 )
             ),
             array(
-                array('id' => 2, 'store_ids' => array(1)),
+                array('entity_id' => 2, 'store_ids' => array(1)),
                 null,
                 array(
                     array('label' => 'Main Website', 'value' => array()),
@@ -234,8 +250,8 @@ class FormTest extends \PHPUnit_Framework_TestCase
                 )
             ),
             array(
-                array('id' => 2, 'store_ids' => array(1)),
-                array('id' => 3, 'store_ids' => array(1)),
+                array('entity_id' => 2, 'store_ids' => array(1)),
+                array('entity_id' => 3, 'store_ids' => array(1)),
                 array(
                     array('label' => 'Main Website', 'value' => array()),
                     array(
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/EditTest.php
similarity index 86%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/EditTest.php
index e458d8bc2ae..1d954edf93c 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/EditTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Product;
+namespace Magento\UrlRewrite\Block\Catalog\Product;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit
+ * Test for \Magento\UrlRewrite\Block\Catalog\Product\Edit
  * @magentoAppArea adminhtml
  */
 class EditTest extends \PHPUnit_Framework_TestCase
@@ -46,9 +46,9 @@ class EditTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\View\LayoutInterface'
         );
 
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit */
+        /** @var $block \Magento\UrlRewrite\Block\Catalog\Product\Edit */
         $block = $layout->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit',
+            'Magento\UrlRewrite\Block\Catalog\Product\Edit',
             '',
             array('data' => $blockAttributes)
         );
@@ -64,7 +64,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check selector
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkSelector($block, $expected)
@@ -72,12 +72,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $selectorBlock \Magento\Backend\Block\Urlrewrite\Selector|bool */
+        /** @var $selectorBlock \Magento\UrlRewrite\Block\Selector|bool */
         $selectorBlock = $layout->getChildBlock($blockName, 'selector');
 
         if ($expected['selector']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Selector',
+                'Magento\UrlRewrite\Block\Selector',
                 $selectorBlock,
                 'Child block with entity selector is invalid'
             );
@@ -89,7 +89,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check links
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkLinks($block, $expected)
@@ -97,12 +97,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $productLinkBlock \Magento\Backend\Block\Urlrewrite\Link|bool */
+        /** @var $productLinkBlock \Magento\UrlRewrite\Block\Link|bool */
         $productLinkBlock = $layout->getChildBlock($blockName, 'product_link');
 
         if ($expected['product_link']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Link',
+                'Magento\UrlRewrite\Block\Link',
                 $productLinkBlock,
                 'Child block with product link is invalid'
             );
@@ -128,12 +128,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
             $this->assertFalse($productLinkBlock, 'Child block with product link should not present in block');
         }
 
-        /** @var $categoryLinkBlock \Magento\Backend\Block\Urlrewrite\Link|bool */
+        /** @var $categoryLinkBlock \Magento\UrlRewrite\Block\Link|bool */
         $categoryLinkBlock = $layout->getChildBlock($blockName, 'category_link');
 
         if ($expected['category_link']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Link',
+                'Magento\UrlRewrite\Block\Link',
                 $categoryLinkBlock,
                 'Child block with category link is invalid'
             );
@@ -163,36 +163,38 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check buttons
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkButtons($block, $expected)
     {
         $buttonsHtml = $block->getButtonsHtml();
 
-        if ($expected['back_button']) {
-            if ($block->getProduct()->getId()) {
-                $this->assertSelectCount(
-                    'button.back[onclick~="\/product"]',
-                    1,
-                    $buttonsHtml,
-                    'Back button is not present in product URL rewrite edit block'
-                );
+        if (isset($expected['back_button'])) {
+            if ($expected['back_button']) {
+                if ($block->getProduct()->getId()) {
+                    $this->assertSelectCount(
+                        'button.back[onclick~="\/product"]',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in product URL rewrite edit block'
+                    );
+                } else {
+                    $this->assertSelectCount(
+                        'button.back',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in product URL rewrite edit block'
+                    );
+                }
             } else {
                 $this->assertSelectCount(
                     'button.back',
-                    1,
+                    0,
                     $buttonsHtml,
-                    'Back button is not present in product URL rewrite edit block'
+                    'Back button should not present in product URL rewrite edit block'
                 );
             }
-        } else {
-            $this->assertSelectCount(
-                'button.back',
-                0,
-                $buttonsHtml,
-                'Back button should not present in product URL rewrite edit block'
-            );
         }
 
         if ($expected['save_button']) {
@@ -247,7 +249,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check form
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkForm($block, $expected)
@@ -255,12 +257,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $formBlock \Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form|bool */
+        /** @var $formBlock \Magento\UrlRewrite\Block\Catalog\Edit\Form|bool */
         $formBlock = $layout->getChildBlock($blockName, 'form');
 
         if ($expected['form']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Edit\Form',
+                'Magento\UrlRewrite\Block\Catalog\Edit\Form',
                 $formBlock,
                 'Child block with form is invalid'
             );
@@ -292,7 +294,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check grid
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkGrid($block, $expected)
@@ -300,12 +302,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $gridBlock \Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid|bool */
+        /** @var $gridBlock \Magento\UrlRewrite\Block\Catalog\Product\Grid|bool */
         $gridBlock = $layout->getChildBlock($blockName, 'products_grid');
 
         if ($expected['products_grid']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid',
+                'Magento\UrlRewrite\Block\Catalog\Product\Grid',
                 $gridBlock,
                 'Child block with product grid is invalid'
             );
@@ -317,7 +319,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check categories
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit $block
+     * @param \Magento\UrlRewrite\Block\Catalog\Product\Edit $block
      * @param array $expected
      */
     private function _checkCategories($block, $expected)
@@ -325,12 +327,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $categoriesTreeBlock \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree|bool */
+        /** @var $categoriesTreeBlock \Magento\UrlRewrite\Block\Catalog\Category\Tree|bool */
         $categoriesTreeBlock = $layout->getChildBlock($blockName, 'categories_tree');
 
         if ($expected['categories_tree']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree',
+                'Magento\UrlRewrite\Block\Catalog\Category\Tree',
                 $categoriesTreeBlock,
                 'Child block with categories tree is invalid'
             );
@@ -450,7 +452,6 @@ class EditTest extends \PHPUnit_Framework_TestCase
                     'selector' => false,
                     'product_link' => array('name' => $product->getName()),
                     'category_link' => array('name' => $category->getName()),
-                    'back_button' => true,
                     'reset_button' => true,
                     'delete_button' => true,
                     'save_button' => true,
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/GridTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/GridTest.php
similarity index 89%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/GridTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/GridTest.php
index 809774e3378..748c94b7328 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/GridTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Product/GridTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Catalog\Product;
+namespace Magento\UrlRewrite\Block\Catalog\Product;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid
+ * Test for \Magento\UrlRewrite\Block\Catalog\Product\Grid
  * @magentoAppArea adminhtml
  */
 class GridTest extends \PHPUnit_Framework_TestCase
@@ -34,11 +34,11 @@ class GridTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareGrid()
     {
-        /** @var $gridBlock \Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid */
+        /** @var $gridBlock \Magento\UrlRewrite\Block\Catalog\Product\Grid */
         $gridBlock = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         )->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid'
+            'Magento\UrlRewrite\Block\Catalog\Product\Grid'
         );
         $gridBlock->toHtml();
 
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php
similarity index 86%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/FormTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php
index 5620a13d839..0611ba5f1c0 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page\Edit;
+namespace Magento\UrlRewrite\Block\Cms\Page\Edit;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\FormTest
+ * Test for \Magento\UrlRewrite\Block\Cms\Page\Edit\FormTest
  * @magentoAppArea adminhtml
  */
 class FormTest extends \PHPUnit_Framework_TestCase
@@ -41,9 +41,9 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         );
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form */
+        /** @var $block \Magento\UrlRewrite\Block\Cms\Page\Edit\Form */
         $block = $layout->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form',
+            'Magento\UrlRewrite\Block\Cms\Page\Edit\Form',
             'block',
             array('data' => $args)
         );
@@ -55,19 +55,18 @@ class FormTest extends \PHPUnit_Framework_TestCase
     /**
      * Check _formPostInit set expected fields values
      *
-     * @covers \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form::_formPostInit
+     * @covers \Magento\UrlRewrite\Block\Cms\Page\Edit\Form::_formPostInit
      *
      * @dataProvider formPostInitDataProvider
      *
      * @param array $cmsPageData
      * @param string $action
-     * @param string $idPath
      * @param string $requestPath
      * @param string $targetPath
      * @magentoConfigFixture current_store general/single_store_mode/enabled 1
      * @magentoAppIsolation enabled
      */
-    public function testFormPostInit($cmsPageData, $action, $idPath, $requestPath, $targetPath)
+    public function testFormPostInit($cmsPageData, $action, $requestPath, $targetPath)
     {
         $args = array();
         if ($cmsPageData) {
@@ -79,11 +78,9 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $form = $this->_getFormInstance($args);
         $this->assertContains($action, $form->getAction());
 
-        $this->assertEquals($idPath, $form->getElement('id_path')->getValue());
         $this->assertEquals($requestPath, $form->getElement('request_path')->getValue());
         $this->assertEquals($targetPath, $form->getElement('target_path')->getValue());
 
-        $this->assertTrue($form->getElement('id_path')->getData('disabled'));
         $this->assertTrue($form->getElement('target_path')->getData('disabled'));
     }
 
@@ -114,8 +111,8 @@ class FormTest extends \PHPUnit_Framework_TestCase
      * @magentoAppIsolation enabled
      * @magentoDataFixture Magento/Core/_files/store.php
      *
-     * @expectedException \Magento\Framework\Model\Exception
-     * @expectedExceptionMessage Chosen cms page is not associated with any website.
+     * @expectedException \Magento\Framework\App\InitException
+     * @expectedExceptionMessage Chosen cms page does not associated with any website.
      */
     public function testGetEntityStoresProductStoresException()
     {
@@ -136,7 +133,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
             array(
                 array('page_id' => 3, 'identifier' => 'cms-page'),
                 'cms_page/3',
-                'cms_page/3',
                 'cms-page',
                 'cms/page/view/page_id/3'
             )
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/EditTest.php
similarity index 83%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/EditTest.php
index 91ad9c95ba1..74f8bea2c7a 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/EditTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page;
+namespace Magento\UrlRewrite\Block\Cms\Page;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit
+ * Test for \Magento\UrlRewrite\Block\Cms\Page\Edit
  * @magentoAppArea adminhtml
  */
 class EditTest extends \PHPUnit_Framework_TestCase
@@ -46,9 +46,9 @@ class EditTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\View\LayoutInterface'
         );
 
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit */
+        /** @var $block \Magento\UrlRewrite\Block\Cms\Page\Edit */
         $block = $layout->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit',
+            'Magento\UrlRewrite\Block\Cms\Page\Edit',
             '',
             array('data' => $blockAttributes)
         );
@@ -63,7 +63,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check selector
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit $block
+     * @param \Magento\UrlRewrite\Block\Cms\Page\Edit $block
      * @param array $expected
      */
     private function _checkSelector($block, $expected)
@@ -71,12 +71,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $selectorBlock \Magento\Backend\Block\Urlrewrite\Selector|bool */
+        /** @var $selectorBlock \Magento\UrlRewrite\Block\Selector|bool */
         $selectorBlock = $layout->getChildBlock($blockName, 'selector');
 
         if ($expected['selector']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Selector',
+                'Magento\UrlRewrite\Block\Selector',
                 $selectorBlock,
                 'Child block with entity selector is invalid'
             );
@@ -88,7 +88,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check links
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit $block
+     * @param \Magento\UrlRewrite\Block\Cms\Page\Edit $block
      * @param array $expected
      */
     private function _checkLinks($block, $expected)
@@ -96,12 +96,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $cmsPageLinkBlock \Magento\Backend\Block\Urlrewrite\Link|bool */
+        /** @var $cmsPageLinkBlock \Magento\UrlRewrite\Block\Link|bool */
         $cmsPageLinkBlock = $layout->getChildBlock($blockName, 'cms_page_link');
 
         if ($expected['cms_page_link']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Link',
+                'Magento\UrlRewrite\Block\Link',
                 $cmsPageLinkBlock,
                 'Child block with CMS page link is invalid'
             );
@@ -131,36 +131,38 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check buttons
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit $block
+     * @param \Magento\UrlRewrite\Block\Cms\Page\Edit $block
      * @param array $expected
      */
     private function _checkButtons($block, $expected)
     {
         $buttonsHtml = $block->getButtonsHtml();
 
-        if ($expected['back_button']) {
-            if ($block->getCmsPage()->getId()) {
-                $this->assertSelectCount(
-                    'button.back[onclick~="\/cms_page"]',
-                    1,
-                    $buttonsHtml,
-                    'Back button is not present in CMS page URL rewrite edit block'
-                );
+        if (isset($expected['back_button'])) {
+            if ($expected['back_button']) {
+                if ($block->getCmsPage()->getId()) {
+                    $this->assertSelectCount(
+                        'button.back[onclick~="\/cms_page"]',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in CMS page URL rewrite edit block'
+                    );
+                } else {
+                    $this->assertSelectCount(
+                        'button.back',
+                        1,
+                        $buttonsHtml,
+                        'Back button is not present in CMS page URL rewrite edit block'
+                    );
+                }
             } else {
                 $this->assertSelectCount(
                     'button.back',
-                    1,
+                    0,
                     $buttonsHtml,
-                    'Back button is not present in CMS page URL rewrite edit block'
+                    'Back button should not present in CMS page URL rewrite edit block'
                 );
             }
-        } else {
-            $this->assertSelectCount(
-                'button.back',
-                0,
-                $buttonsHtml,
-                'Back button should not present in CMS page URL rewrite edit block'
-            );
         }
 
         if ($expected['save_button']) {
@@ -215,7 +217,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check form
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit $block
+     * @param \Magento\UrlRewrite\Block\Cms\Page\Edit $block
      * @param array $expected
      */
     private function _checkForm($block, $expected)
@@ -223,12 +225,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $formBlock \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form|bool */
+        /** @var $formBlock \Magento\UrlRewrite\Block\Cms\Page\Edit\Form|bool */
         $formBlock = $layout->getChildBlock($blockName, 'form');
 
         if ($expected['form']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit\Form',
+                'Magento\UrlRewrite\Block\Cms\Page\Edit\Form',
                 $formBlock,
                 'Child block with form is invalid'
             );
@@ -252,7 +254,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check grid
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit $block
+     * @param \Magento\UrlRewrite\Block\Cms\Page\Edit $block
      * @param array $expected
      */
     private function _checkGrid($block, $expected)
@@ -260,12 +262,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $gridBlock \Magento\Backend\Block\Urlrewrite\Cms\Page\Grid|bool */
+        /** @var $gridBlock \Magento\UrlRewrite\Block\Cms\Page\Grid|bool */
         $gridBlock = $layout->getChildBlock($blockName, 'cms_pages_grid');
 
         if ($expected['cms_pages_grid']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Cms\Page\Grid',
+                'Magento\UrlRewrite\Block\Cms\Page\Grid',
                 $gridBlock,
                 'Child block with CMS pages grid is invalid'
             );
@@ -331,7 +333,6 @@ class EditTest extends \PHPUnit_Framework_TestCase
                 array(
                     'selector' => false,
                     'cms_page_link' => array('name' => $cmsPage->getTitle()),
-                    'back_button' => true,
                     'save_button' => true,
                     'reset_button' => true,
                     'delete_button' => true,
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/GridTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/GridTest.php
similarity index 87%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/GridTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/GridTest.php
index 7603e0ec3b5..ce62b9e0a91 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/GridTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/GridTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Cms\Page;
+namespace Magento\UrlRewrite\Block\Cms\Page;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Cms\Page\Grid
+ * Test for \Magento\UrlRewrite\Block\Cms\Page\Grid
  * @magentoAppArea adminhtml
  */
 class GridTest extends \PHPUnit_Framework_TestCase
@@ -34,11 +34,11 @@ class GridTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareGrid()
     {
-        /** @var \Magento\Backend\Block\Urlrewrite\Cms\Page\Grid $gridBlock */
+        /** @var \Magento\UrlRewrite\Block\Cms\Page\Grid $gridBlock */
         $gridBlock = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         )->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Cms\Page\Grid'
+            'Magento\UrlRewrite\Block\Cms\Page\Grid'
         );
         $gridBlock->toHtml();
 
@@ -70,11 +70,11 @@ class GridTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareGridForMultipleStores()
     {
-        /** @var \Magento\Backend\Block\Urlrewrite\Cms\Page\Grid $gridBlock */
+        /** @var \Magento\UrlRewrite\Block\Cms\Page\Grid $gridBlock */
         $gridBlock = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         )->createBlock(
-            'Magento\Backend\Block\Urlrewrite\Cms\Page\Grid'
+            'Magento\UrlRewrite\Block\Cms\Page\Grid'
         );
         $gridBlock->toHtml();
         $this->assertInstanceOf(
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Edit/FormTest.php
similarity index 84%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Edit/FormTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Edit/FormTest.php
index c0d0354f2bf..f4c058b5b83 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Edit/FormTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite\Edit;
+namespace Magento\UrlRewrite\Block\Edit;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Edit\FormTest
+ * Test for \Magento\UrlRewrite\Block\Edit\FormTest
  * @magentoAppArea adminhtml
  */
 class FormTest extends \PHPUnit_Framework_TestCase
@@ -41,8 +41,8 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         );
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Edit\Form */
-        $block = $layout->createBlock('Magento\Backend\Block\Urlrewrite\Edit\Form', 'block', array('data' => $args));
+        /** @var $block \Magento\UrlRewrite\Block\Edit\Form */
+        $block = $layout->createBlock('Magento\UrlRewrite\Block\Edit\Form', 'block', array('data' => $args));
         $block->setTemplate(null);
         $block->toHtml();
         return $block->getForm();
@@ -65,13 +65,13 @@ class FormTest extends \PHPUnit_Framework_TestCase
 
         // Check all expected form elements are present
         $expectedElements = array(
-            'is_system',
-            'id_path',
+            'store_id',
+            'entity_type',
+            'entity_id',
             'request_path',
             'target_path',
-            'options',
-            'description',
-            'store_id'
+            'redirect_type',
+            'description'
         );
         foreach ($expectedElements as $expectedElement) {
             $this->assertNotNull($form->getElement($expectedElement));
@@ -87,15 +87,16 @@ class FormTest extends \PHPUnit_Framework_TestCase
         // Set urlrewrite data to session
         $sessionValues = array(
             'store_id' => 1,
-            'id_path' => 'id_path',
+            'entity_type' => 'entity_type',
+            'entity_id' => 'entity_id',
             'request_path' => 'request_path',
             'target_path' => 'target_path',
-            'options' => 'options',
+            'redirect_type' => 'redirect_type',
             'description' => 'description'
         );
         \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             'Magento\Backend\Model\Session'
-        )->setUrlrewriteData(
+        )->setUrlRewriteData(
             $sessionValues
         );
         // Re-init form to use newly set session data
@@ -164,11 +165,11 @@ class FormTest extends \PHPUnit_Framework_TestCase
      * @dataProvider fieldsStateDataProvider
      * @magentoAppIsolation enabled
      */
-    public function testDisabledFields($urlRewrite, $fields)
+    public function testReadonlyFields($urlRewrite, $fields)
     {
         $form = $this->_getFormInstance(array('url_rewrite' => $urlRewrite));
         foreach ($fields as $fieldKey => $expected) {
-            $this->assertEquals($expected, $form->getElement($fieldKey)->getDisabled());
+            $this->assertEquals($expected, $form->getElement($fieldKey)->getReadonly());
         }
     }
 
@@ -181,23 +182,13 @@ class FormTest extends \PHPUnit_Framework_TestCase
             array(
                 new \Magento\Framework\Object(),
                 array(
-                    'is_system' => true,
-                    'id_path' => false,
-                    'request_path' => false,
-                    'target_path' => false,
-                    'options' => false,
-                    'description' => false
+                    'store_id' => false,
                 )
             ),
             array(
-                new \Magento\Framework\Object(array('id' => 3)),
+                new \Magento\Framework\Object(array('id' => 3, 'is_autogenerated' => true)),
                 array(
-                    'is_system' => true,
-                    'id_path' => false,
-                    'request_path' => false,
-                    'target_path' => false,
-                    'options' => false,
-                    'description' => false
+                    'store_id' => true,
                 )
             )
         );
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/EditTest.php
similarity index 89%
rename from dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php
rename to dev/tests/integration/testsuite/Magento/UrlRewrite/Block/EditTest.php
index 20ab0578ec2..e2fde05e9ee 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/EditTest.php
@@ -21,10 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Block\Urlrewrite;
+namespace Magento\UrlRewrite\Block;
 
 /**
- * Test for \Magento\Backend\Block\Urlrewrite\Edit
+ * Test for \Magento\UrlRewrite\Block\Edit
  * @magentoAppArea adminhtml
  */
 class EditTest extends \PHPUnit_Framework_TestCase
@@ -41,14 +41,13 @@ class EditTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareLayout($blockAttributes, $expected)
     {
-
         /** @var $layout \Magento\Framework\View\LayoutInterface */
         $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Framework\View\LayoutInterface'
         );
 
-        /** @var $block \Magento\Backend\Block\Urlrewrite\Edit */
-        $block = $layout->createBlock('Magento\Backend\Block\Urlrewrite\Edit', '', array('data' => $blockAttributes));
+        /** @var $block \Magento\UrlRewrite\Block\Edit */
+        $block = $layout->createBlock('Magento\UrlRewrite\Block\Edit', '', array('data' => $blockAttributes));
 
         $this->_checkSelector($block, $expected);
         $this->_checkButtons($block, $expected);
@@ -58,19 +57,19 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check entity selector
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Edit $block
+     * @param \Magento\UrlRewrite\Block\Edit $block
      * @param array $expected
      */
     private function _checkSelector($block, $expected)
     {
         $layout = $block->getLayout();
 
-        /** @var $selectorBlock \Magento\Backend\Block\Urlrewrite\Selector|bool */
+        /** @var $selectorBlock \Magento\UrlRewrite\Block\Selector|bool */
         $selectorBlock = $layout->getChildBlock($block->getNameInLayout(), 'selector');
 
         if ($expected['selector']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Selector',
+                'Magento\UrlRewrite\Block\Selector',
                 $selectorBlock,
                 'Child block with entity selector is invalid'
             );
@@ -82,7 +81,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check form
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Edit $block
+     * @param \Magento\UrlRewrite\Block\Edit $block
      * @param array $expected
      */
     private function _checkForm($block, $expected)
@@ -90,12 +89,12 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layout = $block->getLayout();
         $blockName = $block->getNameInLayout();
 
-        /** @var $formBlock \Magento\Backend\Block\Urlrewrite\Edit\Form|bool */
+        /** @var $formBlock \Magento\UrlRewrite\Block\Edit\Form|bool */
         $formBlock = $layout->getChildBlock($blockName, 'form');
 
         if ($expected['form']) {
             $this->assertInstanceOf(
-                'Magento\Backend\Block\Urlrewrite\Edit\Form',
+                'Magento\UrlRewrite\Block\Edit\Form',
                 $formBlock,
                 'Child block with form is invalid'
             );
@@ -113,7 +112,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     /**
      * Check buttons
      *
-     * @param \Magento\Backend\Block\Urlrewrite\Edit $block
+     * @param \Magento\UrlRewrite\Block\Edit $block
      * @param array $expected
      */
     private function _checkButtons($block, $expected)
diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
deleted file mode 100644
index 28202ea56bc..00000000000
--- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
+++ /dev/null
@@ -1,90 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\Helper;
-
-class UrlRewriteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\UrlRewrite\Helper\UrlRewrite
-     */
-    protected $_helper;
-
-    protected function setUp()
-    {
-        $this->_helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\UrlRewrite\Helper\UrlRewrite'
-        );
-    }
-
-    /**
-     * @dataProvider requestPathDataProvider
-     */
-    public function testValidateRequestPath($requestPath)
-    {
-        $this->assertTrue($this->_helper->validateRequestPath($requestPath));
-    }
-
-    /**
-     * @dataProvider requestPathExceptionDataProvider
-     * @expectedException \Magento\Framework\Model\Exception
-     */
-    public function testValidateRequestPathException($requestPath)
-    {
-        $this->_helper->validateRequestPath($requestPath);
-    }
-
-    /**
-     * @dataProvider requestPathDataProvider
-     */
-    public function testValidateSuffix($suffix)
-    {
-        $this->assertTrue($this->_helper->validateSuffix($suffix));
-    }
-
-    /**
-     * @dataProvider requestPathExceptionDataProvider
-     * @expectedException \Magento\Framework\Model\Exception
-     */
-    public function testValidateSuffixException($suffix)
-    {
-        $this->_helper->validateSuffix($suffix);
-    }
-
-    public function requestPathDataProvider()
-    {
-        return array(
-            'no leading slash' => array('correct/request/path'),
-            'leading slash' => array('another/good/request/path/')
-        );
-    }
-
-    public function requestPathExceptionDataProvider()
-    {
-        return array(
-            'two slashes' => array('request/path/with/two//slashes'),
-            'three slashes' => array('request/path/with/three///slashes'),
-            'anchor' => array('request/path/with#anchor')
-        );
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
deleted file mode 100644
index 72055d052de..00000000000
--- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
+++ /dev/null
@@ -1,307 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\Model;
-use \Magento\TestFramework\Helper\Bootstrap;
-
-class UrlRewriteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    protected $model;
-
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $objectManager;
-
-    protected function setUp()
-    {
-        $this->objectManager = Bootstrap::getObjectManager();
-
-        $this->model = $this->objectManager->create(
-            'Magento\UrlRewrite\Model\UrlRewrite'
-        );
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     *
-     * @throws \Exception
-     */
-    public function testLoadByRequestPath()
-    {
-        $this->model->setStoreId(
-            $this->objectManager->get(
-                'Magento\Framework\StoreManagerInterface'
-            )->getDefaultStoreView()->getId()
-        )->setRequestPath(
-            'fancy/url.html'
-        )->setTargetPath(
-            'catalog/product/view'
-        )->setIsSystem(
-            1
-        )->setOptions(
-            'RP'
-        )->save();
-
-        try {
-            $read = $this->objectManager->create(
-                'Magento\UrlRewrite\Model\UrlRewrite'
-            );
-            $read->setStoreId(
-                $this->objectManager->get(
-                    'Magento\Framework\StoreManagerInterface'
-                )->getDefaultStoreView()->getId()
-            )->loadByRequestPath(
-                'fancy/url.html'
-            );
-
-            $this->assertEquals($this->model->getStoreId(), $read->getStoreId());
-            $this->assertEquals($this->model->getRequestPath(), $read->getRequestPath());
-            $this->assertEquals($this->model->getTargetPath(), $read->getTargetPath());
-            $this->assertEquals($this->model->getIsSystem(), $read->getIsSystem());
-            $this->assertEquals($this->model->getOptions(), $read->getOptions());
-            $this->model->delete();
-        } catch (\Exception $e) {
-            $this->model->delete();
-            throw $e;
-        }
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     * @throws \Exception
-     */
-    public function testLoadByIdPath()
-    {
-        $this->model->setStoreId(
-            $this->objectManager->get(
-                'Magento\Framework\StoreManagerInterface'
-            )->getDefaultStoreView()->getId()
-        )->setRequestPath(
-            'product1.html'
-        )->setTargetPath(
-            'catalog/product/view/id/1'
-        )->setIdPath(
-            'product/1'
-        )->setIsSystem(
-            1
-        )->setOptions(
-            'RP'
-        )->save();
-
-        try {
-            $read = $this->objectManager->create(
-                'Magento\UrlRewrite\Model\UrlRewrite'
-            );
-            $read->setStoreId(
-                $this->objectManager->get(
-                    'Magento\Framework\StoreManagerInterface'
-                )->getDefaultStoreView()->getId()
-            )->loadByIdPath(
-                'product/1'
-            );
-            $this->assertEquals($this->model->getStoreId(), $read->getStoreId());
-            $this->assertEquals($this->model->getRequestPath(), $read->getRequestPath());
-            $this->assertEquals($this->model->getTargetPath(), $read->getTargetPath());
-            $this->assertEquals($this->model->getIdPath(), $read->getIdPath());
-            $this->assertEquals($this->model->getIsSystem(), $read->getIsSystem());
-            $this->assertEquals($this->model->getOptions(), $read->getOptions());
-            $this->model->delete();
-        } catch (\Exception $e) {
-            $this->model->delete();
-            throw $e;
-        }
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testHasOption()
-    {
-        $this->model->setOptions('RP');
-        $this->assertTrue($this->model->hasOption('RP'));
-    }
-
-    /**
-     *
-     * @magentoDbIsolation enabled
-     * @throws \Exception
-     */
-    public function testRewrite()
-    {
-        $request = $this->objectManager->create(
-            'Magento\Framework\App\RequestInterface'
-        )->setPathInfo(
-            'fancy/url.html'
-        );
-        $_SERVER['QUERY_STRING'] = 'foo=bar&___fooo=bar';
-
-        $this->model->setRequestPath(
-            'fancy/url.html'
-        )->setTargetPath(
-            'another/fancy/url.html'
-        )->setIsSystem(
-            1
-        )->save();
-
-        try {
-            $this->assertTrue($this->model->rewrite($request));
-            $this->assertEquals('/another/fancy/url.html?foo=bar', $request->getRequestUri());
-            $this->assertEquals('another/fancy/url.html', $request->getPathInfo());
-            $this->model->delete();
-        } catch (\Exception $e) {
-            $this->model->delete();
-            throw $e;
-        }
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testRewriteSetCookie()
-    {
-        $_SERVER['QUERY_STRING'] = 'foo=bar';
-
-        $context = $this->objectManager->create(
-            '\Magento\Framework\Model\Context'
-        );
-        $registry = $this->objectManager->create(
-            '\Magento\Framework\Registry'
-        );
-        $scopeConfig = $this->objectManager->create(
-            '\Magento\Framework\App\Config\ScopeConfigInterface'
-        );
-        $storeManager = $this->objectManager->create(
-            '\Magento\Framework\StoreManagerInterface'
-        );
-        $httpContext = $this->objectManager->create(
-            '\Magento\Framework\App\Http\Context'
-        );
-
-        $constructorArgs = [
-            'context' => $context,
-            'registry' => $registry,
-            'scopeConfig' => $scopeConfig,
-            'storeManager' => $storeManager,
-            'httpContext' => $httpContext,
-        ];
-
-        //SUT must be mocked out for this test to prevent headers from being sent,
-        //causing errors.
-
-        /** @var \PHPUnit_Framework_MockObject_MockObject /\Magento\UrlRewrite\Model\UrlRewrite $modelMock */
-        $modelMock = $this->getMock('\Magento\UrlRewrite\Model\UrlRewrite',
-            ['_sendRedirectHeaders'],
-            $constructorArgs
-        );
-
-        $modelMock->setRequestPath('http://fancy/url.html')
-            ->setTargetPath('http://another/fancy/url.html')
-            ->setIsSystem(1)
-            ->setOptions('R')
-            ->save();
-
-        $modelMock->expects($this->exactly(2))
-            ->method('_sendRedirectHeaders');
-
-        $request = $this->objectManager
-            ->create('Magento\Framework\App\RequestInterface')
-            ->setPathInfo('http://fancy/url.html');
-
-        $this->assertTrue($modelMock->rewrite($request));
-        $this->assertEquals('admin', $_COOKIE[\Magento\Store\Model\Store::COOKIE_NAME]);
-
-        $modelMock->delete();
-
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testRewriteNonExistingRecord()
-    {
-        $request = $this->objectManager
-            ->create('Magento\Framework\App\RequestInterface');
-        $this->assertFalse($this->model->rewrite($request));
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testRewriteWrongStore()
-    {
-        $request = $this->objectManager
-            ->create('Magento\Framework\App\RequestInterface');
-        $_GET['___from_store'] = uniqid('store');
-        $this->assertFalse($this->model->rewrite($request));
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testRewriteNonExistingRecordCorrectStore()
-    {
-        $request = $this->objectManager
-            ->create('Magento\Framework\App\RequestInterface');
-        $_GET['___from_store'] = $this->objectManager->get(
-            'Magento\Framework\StoreManagerInterface'
-        )->getDefaultStoreView()->getCode();
-        $this->assertFalse($this->model->rewrite($request));
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     */
-    public function testGetStoreId()
-    {
-        $this->model->setStoreId(10);
-        $this->assertEquals(10, $this->model->getStoreId());
-    }
-
-    /**
-     * @magentoDbIsolation enabled
-     *
-     * @throws \Exception
-     */
-    public function testCRUD()
-    {
-        $this->model->setStoreId(
-            $this->objectManager->get(
-                'Magento\Framework\StoreManagerInterface'
-            )->getDefaultStoreView()->getId()
-        )->setRequestPath(
-            'fancy/url.html'
-        )->setTargetPath(
-            'catalog/product/view'
-        )->setIsSystem(
-            1
-        )->setOptions(
-            'RP'
-        );
-        $crud = new \Magento\TestFramework\Entity($this->model, ['request_path' => 'fancy/url2.html']);
-        $crud->testCrud();
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/User/Block/User/Edit/Tab/MainTest.php b/dev/tests/integration/testsuite/Magento/User/Block/User/Edit/Tab/MainTest.php
index 3cfeb5ec7c8..8f12355386c 100644
--- a/dev/tests/integration/testsuite/Magento/User/Block/User/Edit/Tab/MainTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Block/User/Edit/Tab/MainTest.php
@@ -67,9 +67,9 @@ class MainTest extends \Magento\Backend\Utility\Controller
         $actualHtml = $this->_block->toHtml();
         $this->assertSelectCount(
             'input.required-entry[type="password"]',
-            0,
+            1,
             $actualHtml,
-            'All password fields have to be optional.'
+            'There should be 1 required password entry: current user password.'
         );
         $this->assertSelectCount('input.validate-admin-password[type="password"][name="password"]', 1, $actualHtml);
         $this->assertSelectCount(
@@ -77,6 +77,11 @@ class MainTest extends \Magento\Backend\Utility\Controller
             1,
             $actualHtml
         );
+        $this->assertSelectCount(
+            'input.validate-current-password[type="password"][name="' . Main::CURRENT_USER_PASSWORD_FIELD . '"]',
+            1,
+            $actualHtml
+        );
     }
 
     public function testToHtmlPasswordFieldsNewEntry()
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
index 4e4df501ce7..2359accb3c1 100644
--- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\User\Controller\Adminhtml;
 
+use Magento\TestFramework\Bootstrap;
+
 /**
  * @magentoAppArea adminhtml
  */
@@ -68,20 +70,28 @@ class UserTest extends \Magento\Backend\Utility\Controller
     /**
      * @magentoDbIsolation enabled
      */
-    public function testSaveAction()
+    public function testSaveActionMissingCurrentAdminPassword()
     {
-        $this->_createNew();
-        $this->assertSessionMessages(
-            $this->equalTo(array('You saved the user.')),
-            \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+        $fixture = uniqid();
+        $this->getRequest()->setPost(
+            array(
+                'username' => $fixture,
+                'email' => "{$fixture}@example.com",
+                'firstname' => 'First',
+                'lastname' => 'Last',
+                'password' => 'password_with_1_number',
+                'password_confirmation' => 'password_with_1_number'
+            )
         );
-        $this->assertRedirect($this->stringContains('backend/admin/user/index/'));
+        $this->dispatch('backend/admin/user/save');
+        $this->assertSessionMessages($this->equalTo(array('You have entered an invalid password for current user.')));
+        $this->assertRedirect($this->stringContains('backend/admin/user/edit'));
     }
 
     /**
-     * Create new user through dispatching save action
+     * @magentoDbIsolation enabled
      */
-    private function _createNew()
+    public function testSaveAction()
     {
         $fixture = uniqid();
         $this->getRequest()->setPost(
@@ -91,10 +101,16 @@ class UserTest extends \Magento\Backend\Utility\Controller
                 'firstname' => 'First',
                 'lastname' => 'Last',
                 'password' => 'password_with_1_number',
-                'password_confirmation' => 'password_with_1_number'
+                'password_confirmation' => 'password_with_1_number',
+                \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD => Bootstrap::ADMIN_PASSWORD
             )
         );
         $this->dispatch('backend/admin/user/save');
+        $this->assertSessionMessages(
+            $this->equalTo(array('You saved the user.')),
+            \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+        );
+        $this->assertRedirect($this->stringContains('backend/admin/user/index/'));
     }
 
     /**
@@ -143,7 +159,8 @@ class UserTest extends \Magento\Backend\Utility\Controller
                 'firstname' => 'First',
                 'lastname' => 'Last',
                 'password' => $passwordPair['password'],
-                'password_confirmation' => $passwordPair['password_confirmation']
+                'password_confirmation' => $passwordPair['password_confirmation'],
+                \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD => Bootstrap::ADMIN_PASSWORD
             );
             $data[] = array($postData, $passwordPair['is_correct']);
         }
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/Config/_files/webapi.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
index 6664082c8d6..af0bdefddc0 100644
--- a/dev/tests/integration/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
@@ -26,17 +26,13 @@ return [
         'Magento\TestModule1\Service\V1\AllSoapAndRestInterface' => [
             'item' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1'
-                    ]
+                    'Magento_Test1::resource1'
                 ],
                 'secure' => false,
             ],
             'create' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1'
-                    ]
+                    'Magento_Test1::resource1'
                 ],
                 'secure' => false,
             ],
@@ -44,37 +40,29 @@ return [
         'Magento\TestModule1\Service\V2\AllSoapAndRestInterface' => [
             'item' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1',
-                        'Magento_Test1::resource2'
-                    ]
+                    'Magento_Test1::resource1',
+                    'Magento_Test1::resource2'
                 ],
                 'secure' => false,
             ],
             'create' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1',
-                        'Magento_Test1::resource2'
-                    ]
+                    'Magento_Test1::resource1',
+                    'Magento_Test1::resource2'
                 ],
                 'secure' => false,
             ],
             'delete' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1',
-                        'Magento_Test1::resource2'
-                    ]
+                    'Magento_Test1::resource1',
+                    'Magento_Test1::resource2'
                 ],
                 'secure' => false,
             ],
             'update' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Test1::resource1',
-                        'Magento_Test1::resource2'
-                    ]
+                    'Magento_Test1::resource1',
+                    'Magento_Test1::resource2'
                 ],
                 'secure' => false,
             ],
diff --git a/dev/tests/integration/testsuite/Magento/Weee/Model/TaxTest.php b/dev/tests/integration/testsuite/Magento/Weee/Model/TaxTest.php
index 087e0b19131..64cb2bf4934 100644
--- a/dev/tests/integration/testsuite/Magento/Weee/Model/TaxTest.php
+++ b/dev/tests/integration/testsuite/Magento/Weee/Model/TaxTest.php
@@ -93,7 +93,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
             'country' => 'US',
             'value' => '12.4',
             'state' => '0',
-            'attribute_id' => '75',
+            'attribute_id' => '73',
             'entity_type_id' => '0'
         );
         $weeeTax->setData($weeeTaxData);
diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Block/RssTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Block/RssTest.php
deleted file mode 100644
index db434525c81..00000000000
--- a/dev/tests/integration/testsuite/Magento/Wishlist/Block/RssTest.php
+++ /dev/null
@@ -1,107 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Wishlist\Block;
-
-class RssTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $_customerSession;
-
-    /**
-     * Core data
-     *
-     * @var \Magento\Core\Helper\Data
-     */
-    protected $_coreData;
-
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
-
-    protected function setUp()
-    {
-        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $this->_customerSession = $this->_objectManager->create('Magento\Customer\Model\Session');
-        $this->_coreData = $this->_objectManager->create('Magento\Core\Helper\Data');
-
-    }
-
-    /**
-     * @magentoDataFixture Magento/Customer/_files/customer.php
-     * @magentoDataFixture Magento/Wishlist/_files/wishlist_with_product_qty_increments.php
-     * @magentoAppArea frontend
-     */
-    public function testCustomerTitle()
-    {
-        $fixtureCustomerId = 1;
-        $this->_customerSession->loginById($fixtureCustomerId);
-
-        /** @var \Magento\Wishlist\Model\Wishlist $wishlist */
-        $wishlist = $this->_objectManager->create('Magento\Wishlist\Model\Wishlist')
-            ->loadByCustomerId($fixtureCustomerId);
-
-        /** @var \Magento\Framework\App\Helper\Context $contextHelper */
-        $contextHelper = $this->_objectManager->create('Magento\Framework\App\Helper\Context');
-
-        $wishlistHelper = $this->_objectManager->create('Magento\Wishlist\Helper\Rss',
-            [
-                'context' => $contextHelper,
-                'customerSession' => $this->_customerSession
-            ]
-        );
-
-        /** @var \Magento\Catalog\Block\Product\Context $context */
-        $contextBlock = $this->_objectManager->create(
-            'Magento\Wishlist\Block\Context',
-            [
-                'request' => $contextHelper->getRequest(),
-                'wishlistHelper' => $wishlistHelper
-            ]
-        );
-        /** @var \Magento\Framework\App\Request\Http $request */
-        $request = $contextHelper->getRequest();
-        $request->setParam('wishlist_id', $wishlist->getId());
-        $request->setParam('data', $this->_coreData->urlEncode($fixtureCustomerId));
-
-        /** @var \Magento\Wishlist\Block\Rss $block */
-        $block = $this->_objectManager->create('Magento\Wishlist\Block\Rss',
-            [
-                'context' => $contextBlock
-            ]
-        );
-
-        /** @var \Magento\Framework\Escaper $escaper */
-        $escaper = $this->_objectManager->create('Magento\Framework\Escaper');
-
-        $expectedSting = '%A' . __("<title><![CDATA[%1 %2's Wishlist]]></title>",
-                $escaper->escapeHtml($this->_customerSession->getCustomerDataObject()->getFirstname()),
-                $escaper->escapeHtml($this->_customerSession->getCustomerDataObject()->getLastname())
-            ) . '%A';
-        $this->assertStringMatchesFormat($expectedSting, $block->toHtml());
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
index 652b3935e03..4076938f01c 100644
--- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
@@ -129,29 +129,6 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
         );
     }
 
-    /**
-     * @magentoConfigFixture current_store rss/wishlist/active 1
-     * @magentoDataFixture Magento/Wishlist/_files/wishlist.php
-     * @magentoAppIsolation enabled
-     */
-    public function testRssAction()
-    {
-        $wishlist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Wishlist\Model\Wishlist'
-        );
-        $wishlist->load('fixture_unique_code', 'sharing_code');
-        $this->getRequest()->setParam('wishlist_id', $wishlist->getId())->setParam('data', base64_encode('1'));
-        $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Customer\Model\Session');
-        $service = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Customer\Service\V1\CustomerAccountService'
-        );
-        $customer = $service->authenticate('customer@example.com', 'password');
-        $session->setCustomerDataAsLoggedIn($customer);
-
-        $this->dispatch('wishlist/index/rss');
-        $this->assertContains('<![CDATA[Simple Product]]>', $this->getResponse()->getBody());
-    }
-
     /**
      * @magentoDataFixture Magento/Wishlist/_files/wishlist.php
      */
diff --git a/dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js b/dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js
new file mode 100644
index 00000000000..88093491a67
--- /dev/null
+++ b/dev/tests/js/testsuite/lib/ko/datepicker/datepicker.js
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+test('DatepickerBinding', function () {
+    expect(1);
+
+    var element    = $('#datepicker'),
+        observable = ko.observable(),
+        openBtn,
+        todayBtn,
+        todayDate,
+        dateFormat,
+        result;
+
+    ko.applyBindingsToNode(element, {
+        datepicker: observable
+    });
+
+    dateFormat = $(element).datepicker('option', 'dateFormat');
+    todayDate = moment().format(dateFormat);
+
+    btn      = $('img.ui-datepicker-trigger');
+    todayBtn = $('[data-handler="today"]');
+
+    btn.click();
+    todayBtn.click();
+
+    result = moment(observable()).format(dateFormat);
+
+    equal(todayDate, result);
+});
\ No newline at end of file
diff --git a/app/code/Magento/Index/etc/acl.xml b/dev/tests/js/testsuite/lib/ko/datepicker/index.html
similarity index 57%
rename from app/code/Magento/Index/etc/acl.xml
rename to dev/tests/js/testsuite/lib/ko/datepicker/index.html
index 915fc10d066..d3f8762c1f0 100644
--- a/app/code/Magento/Index/etc/acl.xml
+++ b/dev/tests/js/testsuite/lib/ko/datepicker/index.html
@@ -1,4 +1,3 @@
-<?xml version="1.0"?>
 <!--
 /**
  * Magento
@@ -19,20 +18,30 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
+ * @category    storage
+ * @package     test
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
-    <acl>
-        <resources>
-            <resource id="Magento_Adminhtml::admin">
-                <resource id="Magento_Adminhtml::system">
-                    <resource id="Magento_Adminhtml::tools">
-                        <resource id="Magento_Index::index" title="Index Management" sortOrder="20" />
-                    </resource>
-                </resource>
-            </resource>
-        </resources>
-    </acl>
-</config>
+
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Unit test</title>
+    <base href="../../../"/>
+    <link type="text/css" rel="stylesheet" href="framework/qunit/qunit-1.14.0.css"/>
+    <script type="text/javascript" src="framework/qunit/qunit-1.14.0.js"></script>
+    <script src="../../../pub/lib/jquery/jquery.js"></script>
+    <script src="../../../pub/moment.js"></script>
+    <script src="../../../pub/lib/ko/ko.js"></script>
+    <script type="text/javascript" src="testsuite/lib/ko/datepicker/datepicker.js"></script>
+</head>
+<body>
+<div id="qunit"></div>
+<div id="qunit-fixture">
+    <input type="text" id="datepicker">
+</div>
+</body>
+</html>
+
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Application.php b/dev/tests/performance/framework/Magento/TestFramework/Application.php
index 5bd1efb2243..9f59a6b7bc2 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Application.php
@@ -144,10 +144,6 @@ class Application
         $this->_shell->execute(
             'php -f ' . $this->_config->getApplicationBaseDir() . '/dev/shell/indexer.php -- reindexall'
         );
-        // TODO: remove once Magento\Index module is completely removed (MAGETWO-18168)
-        $this->_shell->execute(
-            'php -f ' . $this->_config->getApplicationBaseDir() . '/dev/shell/newindexer.php -- reindexall'
-        );
         return $this;
     }
 
diff --git a/dev/tests/performance/framework/tests/unit/phpunit.xml.dist b/dev/tests/performance/framework/tests/unit/phpunit.xml.dist
index 6814c5bde95..274d40f64e6 100644
--- a/dev/tests/performance/framework/tests/unit/phpunit.xml.dist
+++ b/dev/tests/performance/framework/tests/unit/phpunit.xml.dist
@@ -23,7 +23,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <testsuites>
         <testsuite name="Unit Tests for Performance Testing Framework">
             <directory suffix="Test.php">testsuite</directory>
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
index d72682dbfcd..c01af6805d8 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
@@ -225,7 +225,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
     public function testApplyFixturesSuperSetNoInstallation()
     {
         // Initial uninstall/install only
-        $this->_shell->expects($this->exactly(8))->method('execute');
+        $this->_shell->expects($this->exactly(5))->method('execute');
 
         $fixture1 = $this->_getFixtureFiles(array('fixture1'));
         $this->_object->applyFixtures($fixture1);
@@ -256,24 +256,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
             $this->contains($this->_installerScript)
         );
 
-        $this->_shell->expects(
-            $this->at(6)
-        )->method(
-            'execute'
-        )->with(
-            $this->anything(),
-            $this->contains($this->_uninstallScript)
-        );
-
-        $this->_shell->expects(
-            $this->at(7)
-        )->method(
-            'execute'
-        )->with(
-            $this->anything(),
-            $this->contains($this->_installerScript)
-        );
-
         $fixtures = $this->_getFixtureFiles(array('fixture1', 'fixture2'));
         $this->_object->applyFixtures($fixtures);
         $incompatibleSet = $this->_getFixtureFiles(array('fixture1'));
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/ComplexGeneratorTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/ComplexGeneratorTest.php
index 79e899a0757..dda5a938aaf 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/ComplexGeneratorTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/ComplexGeneratorTest.php
@@ -47,14 +47,9 @@ class ComplexGeneratorTest extends \PHPUnit_Framework_TestCase
             $patternData = array(array(
                 'id' => '%s',
                 'name' => 'Static',
-                // @codingStandardsIgnoreStart
-                /**
-                 * PHP_CodeSniffer bug - http://pear.php.net/bugs/bug.php?id=19290 (fixed in 1.4.0)
-                 */
                 'calculated' => function ($index) {
                     return $index * 10;
                 }
-                // @codingStandardsIgnoreEnd
             ),array('name' => 'xxx %s'), array('name' => 'yyy %s'));
             $this->_pattern = new \Magento\TestFramework\ImportExport\Fixture\Complex\Pattern();
             $this->_pattern->setHeaders(array_keys($patternData[0]));
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/PatternTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/PatternTest.php
index 81b2ed2d745..c98b8ec1fa1 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/PatternTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/Complex/PatternTest.php
@@ -54,14 +54,9 @@ class PatternTest extends \PHPUnit_Framework_TestCase
         $result = array(0 => array(array(array(
             'id' => '%s',
             'name' => 'Static',
-            // @codingStandardsIgnoreStart
-            /**
-             * PHP_CodeSniffer bug - http://pear.php.net/bugs/bug.php?id=19290 (fixed in 1.4.0)
-             */
             'calculated' => function ($index) {
                 return $index * 10;
             }
-            // @codingStandardsIgnoreEnd
         ),
             array('name' => 'xxx %s'),
             array('name' => 'yyy %s')
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/GeneratorTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/GeneratorTest.php
index 55cf0d322b2..4a4504ead88 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/GeneratorTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ImportExport/Fixture/GeneratorTest.php
@@ -30,14 +30,9 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
         $pattern = array(
             'id' => '%s',
             'name' => 'Static',
-            // @codingStandardsIgnoreStart
-            /**
-             * PHP_CodeSniffer bug - http://pear.php.net/bugs/bug.php?id=19290 (fixed in 1.4.0)
-             */
             'calculated' => function ($index) {
                 return $index * 10;
             }
-            // @codingStandardsIgnoreEnd
         );
         $model = new \Magento\TestFramework\ImportExport\Fixture\Generator($pattern, 2);
         $rows = array();
diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/Classes.php b/dev/tests/static/framework/Magento/TestFramework/Utility/Classes.php
index 5fcbd70f894..d5c4afe316a 100644
--- a/dev/tests/static/framework/Magento/TestFramework/Utility/Classes.php
+++ b/dev/tests/static/framework/Magento/TestFramework/Utility/Classes.php
@@ -293,7 +293,7 @@ class Classes
     public static function isAutogenerated($className)
     {
         if (preg_match('/.*\\\\[a-zA-Z0-9]{1,}(Factory|Proxy|SearchResults)$/', $className)
-            || preg_match('/^Magento\\[\w]+\\(Test\\Page)\\/', $className)
+            || preg_match('/^Magento\\\\[\w]+\\\\(Test\\\\Page)\\\\/', $className)
         ) {
             return true;
         }
diff --git a/dev/tests/static/framework/tests/unit/phpunit.xml.dist b/dev/tests/static/framework/tests/unit/phpunit.xml.dist
index 9d512001dbd..877e717a86a 100644
--- a/dev/tests/static/framework/tests/unit/phpunit.xml.dist
+++ b/dev/tests/static/framework/tests/unit/phpunit.xml.dist
@@ -23,7 +23,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="../../bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="../../bootstrap.php"
+>
     <testsuites>
         <testsuite name="Magento Unit Tests for Static Code Analysis Framework">
             <directory suffix="Test.php">testsuite/Magento/TestFramework</directory>
diff --git a/dev/tests/static/phpunit-all.xml.dist b/dev/tests/static/phpunit-all.xml.dist
index 68cffbbe743..633c35fe3c3 100644
--- a/dev/tests/static/phpunit-all.xml.dist
+++ b/dev/tests/static/phpunit-all.xml.dist
@@ -25,7 +25,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <testsuites>
         <testsuite name="All Static Code Analysis Tests">
             <directory>testsuite/Magento/Test/</directory>
diff --git a/dev/tests/static/phpunit.xml.dist b/dev/tests/static/phpunit.xml.dist
index 6a58c9aaf01..a1f5bb13e73 100644
--- a/dev/tests/static/phpunit.xml.dist
+++ b/dev/tests/static/phpunit.xml.dist
@@ -25,7 +25,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <testsuites>
         <testsuite name="Javascript Static Code Analysis">
             <file>testsuite/Magento/Test/Js/LiveCodeTest.php</file>
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
index 6ed35e3e3b9..843536894a9 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
@@ -311,20 +311,6 @@ class CompilerTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    /**
-     * Test consistency of plugin interfaces
-     */
-    public function testPluginInterfaces()
-    {
-        $invoker = new \Magento\TestFramework\Utility\AggregateInvoker($this);
-        $invoker(
-            function ($plugin, $type) {
-                $this->validatePlugins($plugin, $type);
-            },
-            $this->pluginDataProvider()
-        );
-    }
-
     /**
      * Validate constructor integrity
      */
@@ -369,6 +355,20 @@ class CompilerTest extends \PHPUnit_Framework_TestCase
         spl_autoload_unregister(array($autoloader, 'load'));
     }
 
+    /**
+     * Test consistency of plugin interfaces
+     */
+    public function testPluginInterfaces()
+    {
+        $invoker = new \Magento\TestFramework\Utility\AggregateInvoker($this);
+        $invoker(
+            function ($plugin, $type) {
+                $this->validatePlugins($plugin, $type);
+            },
+            $this->pluginDataProvider()
+        );
+    }
+
     /**
      * Validate plugin interface
      *
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php
index 57c8c1af5f6..4d9be87a5a7 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/HandlesTest.php
@@ -91,4 +91,25 @@ class HandlesTest extends \PHPUnit_Framework_TestCase
             \Magento\TestFramework\Utility\Files::init()->getLayoutFiles()
         );
     }
+
+    public function testHeadBlockUsage()
+    {
+        $invoker = new \Magento\TestFramework\Utility\AggregateInvoker($this);
+        $invoker(
+        /**
+         * Test validate that head block doesn't exist in layout
+         *
+         * @param string $layoutFile
+         */
+            function ($layoutFile) {
+                $dom = new \DOMDocument();
+                $dom->load($layoutFile);
+                $xpath = new \DOMXpath($dom);
+                if ($xpath->query("//*[@name='head']")->length) {
+                    $this->fail('Following file contains deprecated head block. File Path:' . "\n" . $layoutFile);
+                }
+            },
+            \Magento\TestFramework\Utility\Files::init()->getLayoutFiles()
+        );
+    }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
index b122b0c2721..09ce6a9c8f3 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
@@ -52,45 +52,37 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
         return array('Magento');
     }
 
-    /**
-     * Test check dependencies in library from application
-     *
-     * @test
-     * @dataProvider libraryDataProvider
-     */
-    public function testCheckDependencies($file)
+    public function testCheckDependencies()
     {
-        $fileReflection = new FileReflection($file);
-        $tokens = new Tokens($fileReflection->getContents(), new ParserFactory());
-        $tokens->parseContent();
+        $invoker = new \Magento\TestFramework\Utility\AggregateInvoker($this);
+        $invoker(
+            /**
+             * @param string $file
+             */
+            function ($file) {
+                $fileReflection = new FileReflection($file);
+                $tokens = new Tokens($fileReflection->getContents(), new ParserFactory());
+                $tokens->parseContent();
 
-        $dependencies = array_merge((new Injectable())->getDependencies($fileReflection), $tokens->getDependencies());
-
-        foreach ($dependencies as $dependency) {
-            if (preg_match(
-                '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#',
-                $dependency
-            ) && !file_exists(
-                BP . '/lib/internal/' . str_replace('\\', '/', $dependency) . '.php'
-            )
-            ) {
-                $this->errors[$fileReflection->getFileName()][] = $dependency;
-            }
-        }
+                $dependencies = array_merge(
+                    (new Injectable())->getDependencies($fileReflection),
+                    $tokens->getDependencies()
+                );
 
-        if ($this->hasErrors()) {
-            $this->fail($this->getFailMessage());
-        }
-    }
+                $pattern = '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#';
+                foreach ($dependencies as $dependency) {
+                    $filePath = BP . '/lib/internal/' . str_replace('\\', '/', $dependency) . '.php';
+                    if (preg_match($pattern, $dependency) && !file_exists($filePath)) {
+                        $this->errors[$fileReflection->getFileName()][] = $dependency;
+                    }
+                }
 
-    /**
-     * Check if error not empty
-     *
-     * @return bool
-     */
-    protected function hasErrors()
-    {
-        return !empty($this->errors);
+                if (!empty($this->errors)) {
+                    $this->fail($this->getFailMessage());
+                }
+            },
+            $this->libraryDataProvider()
+        );
     }
 
     /**
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/_files/blacklist.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/_files/blacklist.txt
index 1f5fbbaec50..d704850fcfe 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/_files/blacklist.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/_files/blacklist.txt
@@ -67,6 +67,7 @@ lib/internal/Magento/Framework/App/Helper/AbstractHelper.php
 lib/internal/Magento/Framework/App/Helper/Context.php
 
 lib/internal/Magento/Framework/View/DesignLoader.php
+lib/internal/Magento/Framework/View/Page/Config.php
 lib/internal/Magento/Framework/Session/SidResolverInterface.php
 
 lib/internal/Magento/Framework/App/Filesystem/DirectoryList/Configuration.php
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/ConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/ConfigTest.php
index d8d1ec63cae..d2176f56aeb 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/ConfigTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/ConfigTest.php
@@ -107,9 +107,6 @@ Element 'dimensions': Missing child element(s). Expected is ( dimension )
 Element 'queryReference': The attribute 'ref' is required but missing.
 Element 'filterReference': The attribute 'ref' is required but missing.
 Element 'filter': The attribute 'field' is required but missing.
-Element 'filter': The attribute 'value' is required but missing.
-Element 'filterReference': The attribute 'clause' is required but missing.
-Element 'filterReference': The attribute 'ref' is required but missing.
 Element 'bucket': Missing child element(s). Expected is ( metrics ).
 Element 'metric', attribute 'type': [facet 'enumeration'] " .
                 "The value 'sumasdasd' is not an element of the set {'sum', 'count', 'min', 'max'}.
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/invalid_partial.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/invalid_partial.xml
index 82b5fb547aa..e32e8fd4058 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/invalid_partial.xml
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/invalid_partial.xml
@@ -29,46 +29,41 @@
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="sugested_search_container" boost="2">
-                <queryReference clause="not" ref="fulltext_search_query" />
+                <queryReference clause="not" ref="fulltext_search_query"/>
             </query>
-
             <query xsi:type="boolQuery" name="suggested_search_container_dd" boost="2">
-                <queryReference clause="not" ref="fulltext_search_query" />
+                <queryReference clause="not" ref="fulltext_search_query"/>
             </query>
-
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="title" value="%request.title%" boost="2" />
-                <match field="description" value="%request.description%" />
+            <query xsi:type="matchQuery" value="$fulltext_search_query$" name="fulltext_search_query" boost="5">
+                <match field="title" boost="2"/>
+                <match field="description"/>
             </query>
-
             <query xsi:type="filteredQuery" name="promoted_documents_boost">
-                <queryReference />
+                <queryReference/>
             </query>
-
             <query xsi:type="filteredQuery" name="promoted_documents_boost2">
-                <filterReference  />
+                <filterReference/>
             </query>
         </queries>
         <filters>
-            <filter xsi:type="termFilter" name="promoted_documents_boost"  />
-            <filter xsi:type="rangeFilter" field="promoted" name="price_name" from="10" to="100" />
+            <filter xsi:type="termFilter" name="promoted_documents_boost" value="$promoted_documents_boost$"/>
+            <filter xsi:type="rangeFilter" field="promoted" name="price_name" from="10" to="100"/>
             <filter xsi:type="boolFilter" name="price_name1">
-                <filterReference clause="must" ref="price_name" />
-                <filterReference />
-                <filterReference clause="must" ref="price_name" />
+                <filterReference clause="must" ref="price_name"/>
+                <filterReference clause="must" ref="price_name"/>
             </filter>
-            <filter xsi:type="termFilter" name="promoted_boost" field="promoted" value="1" />
-            <filter xsi:type="rangeFilter" field="promoted" name="price" from="10" to="100" />
+            <filter xsi:type="termFilter" name="promoted_boost" field="promoted" value="1"/>
+            <filter xsi:type="rangeFilter" field="promoted" name="price" from="10" to="100"/>
         </filters>
         <aggregation>
-             <bucket xsi:type="termBucket" name="category_bucket" field="category">
+            <bucket xsi:type="termBucket" name="category_bucket" field="category">
 
-             </bucket>
-             <bucket xsi:type="rangeBucket" name="price_bucket" field="price">
+            </bucket>
+            <bucket xsi:type="rangeBucket" name="price_bucket" field="price">
                 <metrics>
-                    <metric type="sumasdasd" />
+                    <metric type="sumasdasd"/>
                 </metrics>
-             </bucket>
+            </bucket>
         </aggregation>
     </request>
 </requests>
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid.xml
index 5f42427c890..b7bffe1d036 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid.xml
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid.xml
@@ -26,61 +26,61 @@
 <requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <request query="sugegsted_search_container_1" index="product_1">
         <dimensions>
-            <dimension name="scope" value="default" />
+            <dimension name="scope" value="default"/>
         </dimensions>
         <queries>
             <query xsi:type="boolQuery" name="sugegsted_search_container_1" boost="2">
-                <queryReference clause="must" ref="fulltext_search_query" />
-                <queryReference clause="should" ref="promoted_documents_boost" />
-                <queryReference clause="not" ref="query_reference" />
+                <queryReference clause="must" ref="fulltext_search_query"/>
+                <queryReference clause="should" ref="promoted_documents_boost"/>
+                <queryReference clause="not" ref="query_reference"/>
             </query>
 
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="title" value="%request.title%" boost="2" />
-                <match field="description" value="%request.description%" />
+            <query xsi:type="matchQuery" name="fulltext_search_query" value="$fulltext_search_query$" boost="5">
+                <match field="title" boost="2"/>
+                <match field="description"/>
             </query>
 
             <query xsi:type="filteredQuery" name="promoted_documents_boost">
-                <queryReference ref="fulltext_search_query" />
+                <queryReference ref="fulltext_search_query"/>
             </query>
 
             <query xsi:type="filteredQuery" name="query_reference">
-                <filterReference ref="price" />
+                <filterReference ref="price"/>
             </query>
         </queries>
         <filters>
-            <filter xsi:type="termFilter" name="promoted_documents_boost" field="promoted" value="1" />
-            <filter xsi:type="rangeFilter" field="promoted" name="price_name" from="10" to="100" />
+            <filter xsi:type="termFilter" name="promoted_documents_boost" field="promoted" value="1"/>
+            <filter xsi:type="rangeFilter" field="promoted" name="price_name" from="10" to="100"/>
             <filter xsi:type="boolFilter" name="price_name_bool">
-                <filterReference clause="must" ref="promoted_boost" />
-                <filterReference clause="should" ref="promoted_documents_boost" />
-                <filterReference clause="not" ref="price_name" />
+                <filterReference clause="must" ref="promoted_boost"/>
+                <filterReference clause="should" ref="promoted_documents_boost"/>
+                <filterReference clause="not" ref="price_name"/>
             </filter>
-            <filter xsi:type="termFilter" name="promoted_boost" field="promoted" value="1" />
-            <filter xsi:type="rangeFilter" field="promoted" name="price" from="10" to="100" />
+            <filter xsi:type="termFilter" name="promoted_boost" field="promoted" value="1"/>
+            <filter xsi:type="rangeFilter" field="promoted" name="price" from="10" to="100"/>
         </filters>
         <aggregation>
-             <bucket xsi:type="termBucket" name="category_bucket" field="category">
+            <bucket xsi:type="termBucket" name="category_bucket" field="category">
                 <metrics>
-                    <metric type="sum" />
-                    <metric type="count" />
-                    <metric type="min" />
-                    <metric type="max" />
+                    <metric type="sum"/>
+                    <metric type="count"/>
+                    <metric type="min"/>
+                    <metric type="max"/>
                 </metrics>
-             </bucket>
-             <bucket xsi:type="rangeBucket" name="price_bucket" field="price">
+            </bucket>
+            <bucket xsi:type="rangeBucket" name="price_bucket" field="price">
                 <metrics>
-                    <metric type="sum" />
-                    <metric type="count" />
-                    <metric type="min" />
-                    <metric type="max" />
+                    <metric type="sum"/>
+                    <metric type="count"/>
+                    <metric type="min"/>
+                    <metric type="max"/>
                 </metrics>
-                 <ranges>
-                    <range from="" to="50" />
-                    <range from="50" to="100" />
-                    <range from="100" to="" />
+                <ranges>
+                    <range from="" to="50"/>
+                    <range from="50" to="100"/>
+                    <range from="100" to=""/>
                 </ranges>
-             </bucket>
+            </bucket>
         </aggregation>
         <from>10</from>
         <size>10</size>
@@ -88,28 +88,28 @@
     <request query="sugegsted_search_container_2" index="product_2">
         <queries>
             <query xsi:type="boolQuery" name="sugegsted_search_container_2" boost="2">
-                <queryReference clause="not" ref="fulltext_search_query_c_2" />
+                <queryReference clause="not" ref="fulltext_search_query_c_2"/>
             </query>
-            <query xsi:type="matchQuery" name="fulltext_search_query_c_2" boost="5">
-                <match field="title" value="%request.title%" boost="2" />
-                <match field="description" value="%request.description%" />
+            <query xsi:type="matchQuery" value="$fulltext_search$" name="fulltext_search_query_c_2" boost="5">
+                <match field="title" boost="2"/>
+                <match field="description"/>
             </query>
         </queries>
         <filters>
-            <filter xsi:type="rangeFilter" field="promoted" name="price_filter" from="10" to="100" />
+            <filter xsi:type="rangeFilter" field="promoted" name="price_filter" from="10" to="100"/>
         </filters>
         <aggregation>
             <bucket xsi:type="termBucket" name="category_bucket" field="category">
                 <metrics>
-                    <metric type="sum" />
+                    <metric type="sum"/>
                 </metrics>
             </bucket>
             <bucket xsi:type="rangeBucket" name="price_bucket" field="price">
                 <metrics>
-                    <metric type="sum" />
+                    <metric type="sum"/>
                 </metrics>
                 <ranges>
-                    <range from="" to="50" />
+                    <range from="" to="50"/>
                 </ranges>
             </bucket>
         </aggregation>
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid_partial.xml b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid_partial.xml
index 1f5530a779c..79e56d6079f 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid_partial.xml
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/_files/valid_partial.xml
@@ -35,9 +35,9 @@
                 <queryReference clause="not" ref="fulltext_search_query" />
             </query>
 
-            <query xsi:type="matchQuery" name="fulltext_search_query" boost="5">
-                <match field="title" value="%request.title%" boost="2" />
-                <match field="description" value="%request.description%" />
+            <query xsi:type="matchQuery" value="$fulltext_search_query$" name="fulltext_search_query" boost="5">
+                <match field="title" boost="2" />
+                <match field="description" />
             </query>
 
             <query xsi:type="filteredQuery" name="promoted_documents_boost">
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php
index 5a8c02cf277..3b239cbee08 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php
@@ -26,38 +26,44 @@ namespace Magento\Test\Integrity\Xml;
 
 class SchemaTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @param $filename
-     * @dataProvider getXmlFiles
-     */
-    public function testXmlFiles($filename)
+    public function testXmlFiles()
     {
-        $dom = new \DOMDocument();
-        $xmlFile = file_get_contents($filename);
-        $dom->loadXML($xmlFile);
-        $errors = libxml_get_errors();
-        $this->assertEmpty($errors, print_r($errors, true));
+        $invoker = new \Magento\TestFramework\Utility\AggregateInvoker($this);
+        $invoker(
+            /**
+             * @param string $filename
+             */
+            function ($filename) {
+                $dom = new \DOMDocument();
+                $xmlFile = file_get_contents($filename);
+                $dom->loadXML($xmlFile);
+                $errors = libxml_get_errors();
+                $this->assertEmpty($errors, print_r($errors, true));
 
-        $schemaLocations = [];
-        preg_match('/xsi:noNamespaceSchemaLocation=\s*"([^"]+)"/s', $xmlFile, $schemaLocations);
-        $this->assertEquals(
-            2,
-            count($schemaLocations),
-            'The XML file at ' . $filename . ' does not have a schema properly defined.  It should
-have a xsi:noNamespaceSchemaLocation attribute defined with a relative path.  E.g.
-xsi:noNamespaceSchemaLocation="../../../lib/internal/Magento/Framework/etc/something.xsd"
-            '
-        );
+                $schemaLocations = [];
+                preg_match('/xsi:noNamespaceSchemaLocation=\s*"([^"]+)"/s', $xmlFile, $schemaLocations);
+                $this->assertEquals(
+                    2,
+                    count($schemaLocations),
+                    'The XML file at ' . $filename . ' does not have a schema properly defined.  It should '
+                    . 'have a xsi:noNamespaceSchemaLocation attribute defined with a relative path.  E.g. '
+                    . 'xsi:noNamespaceSchemaLocation="../../../lib/internal/Magento/Framework/etc/something.xsd"'
+                );
 
-        $schemaFile = dirname($filename).'/'.$schemaLocations[1];
+                $schemaFile = dirname($filename).'/'.$schemaLocations[1];
 
-        $this->assertTrue(file_exists($schemaFile), "$filename refers to an invalid schema $schemaFile.");
+                $this->assertFileExists($schemaFile, "$filename refers to an invalid schema $schemaFile.");
 
-        $errors = \Magento\TestFramework\Utility\Validator::validateXml($dom, $schemaFile);
-        $this->assertEmpty($errors, "Error validating $filename against $schemaFile\n" . print_r($errors, true));
+                $errors = \Magento\TestFramework\Utility\Validator::validateXml($dom, $schemaFile);
+                $this->assertEmpty(
+                    $errors,
+                    "Error validating $filename against $schemaFile\n" . print_r($errors, true)
+                );
+            },
+            $this->getXmlFiles()
+        );
     }
 
-
     public function getSchemas()
     {
         $codeSchemas = $this->_getFiles(BP . '/app/code/Magento', '*.xsd');
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/composer.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/composer.txt
new file mode 100644
index 00000000000..e1aebd12715
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/composer.txt
@@ -0,0 +1 @@
+/app/code/Magento/RequireJs
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
index 7f88901174c..6f8558945e1 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
@@ -20,9 +20,6 @@ dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Code/Dictionary/_files/s
 dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Code/Dictionary/_files/source/app/code/Magento/SecondModule/Model/Model.php
 dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Code/Dictionary/_files/source/not_magento_dir/Model.php
 dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Code/Dictionary/_files/source/app/code/Magento/FirstModule/Helper/Helper.php
-dev/tests/static/framework/PHP/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php
-dev/tests/static/framework/PHP/CodeSniffer/Standards/Zend/Sniffs/Files/ClosingTagSniff.php
-dev/tests/static/framework/PHP/CodeSniffer/Standards/Zend/Sniffs/NamingConventions/ValidVariableNameSniff.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/coupling.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/cyclomatic_complexity.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/descendant_count.php
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
index 3a875897abe..259e7cbf6ed 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php
@@ -138,8 +138,6 @@ return array(
     'core_layout_update' => 'Magento_Core',
     'core_resource' => 'Magento_Core',
     'core_translate' => 'Magento_Core',
-    'core_url_rewrite' => 'Magento_Core',
-    'core_url_rewrite_tag' => 'Magento_Core',
     'core_variable' => 'Magento_Core',
     'core_variable_value' => 'Magento_Core',
     'core_session' => 'Magento_Core',
@@ -211,9 +209,6 @@ return array(
     'googleshopping_types' => 'Magento_GoogleShopping',
     'importexport_importdata' => 'Magento_ImportExport',
     'integration' => 'Magento_Integration',
-    'index_event' => 'Magento_Index',
-    'index_process' => 'Magento_Index',
-    'index_process_event' => 'Magento_Index',
     'log_customer' => 'Magento_Log',
     'log_quote' => 'Magento_Log',
     'log_summary' => 'Magento_Log',
@@ -344,7 +339,6 @@ return array(
     'wishlist_item_option' => 'Magento_Wishlist',
     'wishlist' => 'Magento_Wishlist',
     'admin_system_messages' => 'Magento_AdminNotification',
-    'cms_url_rewrite' => 'Magento_Cms',
     'core_theme' => 'Magento_Core',
     'core_theme_files' => 'Magento_Core',
     'core_theme_files_link' => 'Magento_Core',
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index ee13cdcbc81..ef28f155927 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -364,7 +364,6 @@ return array(
     ),
     array(
         'Mage_Adminhtml_Model_System_Config_Backend_Seo_Product',
-        'Magento\Catalog\Model\Config\Backend\Seo\Product'
     ),
     array(
         'Mage_Adminhtml_Model_System_Config_Backend_Serialized_Array',
@@ -1632,8 +1631,6 @@ return array(
         'Magento\GroupedProduct\Block\Cart\Item\Renderer\Grouped'
     ),
     array('Magento\Log\Model\EntryPoint\Shell', 'Magento\Log\App\Shell'),
-    array('Magento\Index\Model\EntryPoint\Shell', 'Magento\Index\App\Shell'),
-    array('Magento\Index\Model\EntryPoint\Indexer', 'Magento\Index\App\Indexer'),
     array('Magento\Core\Model\Config\Modules\Reader', 'Magento\Framework\Module\Dir\Reader'),
     array('Magento\Framework\Data\Form\Factory', 'Magento\Framework\Data\FormFactory'),
     array('Magento\Framework\App\Cache\Config', 'Magento\Framework\Cache\Config'),
@@ -2271,7 +2268,7 @@ return array(
     array('Magento\Backend\Helper\Media\Js'),
     array(
         'Magento\Core\Model\Resource\Url\Rewrite\Collection',
-        'Magento\UrlRewrite\Model\Resource\UrlRewrite\Collection'
+        'Magento\UrlRewrite\Model\Resource\UrlRewriteCollection'
     ),
     array(
         'Magento\Core\Model\Resource\Url\Rewrite',
@@ -2340,7 +2337,7 @@ return array(
     ['Magento\Core\Model\Store\Storage\DefaultStorage', 'Magento\Store\Model\Storage\DefaultStorage'],
     ['Magento\Core\Model\Store\StorageFactory', 'Magento\Store\Model\StorageFactory'],
     ['Magento\Core\Model\StoreManager', 'Magento\Store\Model\StoreManager'],
-    ['Magento\Core\Model\StoreManagerInterface', 'Magento\Framework\StoreManagerInterface'],
+    ['Magento\Store\Model\StoreManagerInterface', 'Magento\Framework\StoreManagerInterface'],
     ['Magento\Core\Model\System\Store', 'Magento\Store\Model\System\Store'],
     ['Magento\Core\Model\Website', 'Magento\Store\Model\Website'],
     ['Magento\Core\Model\Website\Factory', 'Magento\Store\Model\WebsiteFactory'],
@@ -2796,6 +2793,8 @@ return array(
     ['Magento\Framework\App\State\MaintenanceMode', 'Magento\Framework\App\MaintenanceMode'],
     ['Magento\Framework\Error\Handler', 'Magento\Framework\App\ErrorHandler'],
     ['Magento\Framework\Error\HandlerInterface', 'Magento\Framework\App\ErrorHandler'],
+    ['Magento\Index'],
+    ['Magento\Catalog\Model\Resource\Product\Indexer\Eav'],
     ['\Magento\Framework\Service\Data\Eav\AbstractObject', 'Magento\Framework\Service\Data\AbstractExtensibleObject'],
     ['\Magento\Framework\Service\Data\AbstractObject', 'Magento\Framework\Service\Data\AbstractSimpleObject'],
     [
@@ -2809,5 +2808,28 @@ return array(
     ['Magento\Catalog\Block\Product'],
     ['\Magento\Sales\Model\Observer'],
     ['\Magento\Checkout\Service\V1\QuoteLoader', '\Magento\Sales\Model\QuoteRepository'],
-    ['Magento\PageCache\Model\Observer']
+    ['Magento\PageCache\Model\Observer'],
+    ['Magento\Rss\Block\Order\Info\Buttons\Rss'],
+    ['Magento\Rss\Block\Order\NewOrder'],
+    ['Magento\Rss\Block\Order\Status'],
+    ['Magento\Rss\Controller\Adminhtml\Order\NewAction'],
+    ['Magento\Rss\Controller\Order\Status'],
+    ['Magento\Rss\Helper\Order'],
+    ['Magento\Rss\Block\Order\Details', 'Magento\Sales\Block\Order\Details'],
+    ['Magento\Rss\Model\Resource\Order', 'Magento\Sales\Model\Resource\Order\Rss\OrderStatus'],
+    ['Magento\Rss\Block\Catalog\AbstractCatalog'],
+    ['Magento\Rss\Block\Catalog\NewCatalog'],
+    ['Magento\Rss\Block\Catalog\Review'],
+    ['Magento\Rss\Block\AbstractBlock'],
+    ['Magento\Rss\Block\ListBlock'],
+    ['Magento\Rss\Controller\Adminhtml\Catalog\Notifystock'],
+    ['Magento\Rss\Controller\Adminhtml\Catalog\Review'],
+    ['Magento\Rss\Controller\Catalog\Category'],
+    ['Magento\Rss\Controller\Catalog\NewAction'],
+    ['Magento\Rss\Controller\Catalog\Salesrule'],
+    ['Magento\Rss\Controller\Catalog\Special'],
+    ['Magento\Rss\Controller\Index\Nofeed'],
+    ['Magento\Rss\Controller\Catalog'],
+    ['Magento\Wishlist\Block\Rss'],
+    ['Magento\Wishlist\Controller\Index\Rss'],
 );
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
index ff0aea14ebb..ab3d8f307ae 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
@@ -115,5 +115,6 @@ return array(
     '/config/global/helpers' => 'Was replaced using di',
     '/config/global/external_cache' => 'Was replaced using di',
     '/config/global/currency/import/services' => 'Configurations moved to DI file settings',
-    '/config/global/template' => 'Use /config/template of email_templates.xml'
+    '/config/global/template' => 'Use /config/template of email_templates.xml',
+    '/config/default/general/file/sitemap_generate_valid_paths' => '/config/default/sitemap/file/valid_paths',
 );
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
index d709e0ff8cc..7f8f8694513 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
@@ -195,7 +195,6 @@ return array(
         'Magento\Framework\Locale',
         'Magento_Core_Model_LocaleInterface::XML_PATH_DEFAULT_TIMEZONE'
     ),
-    array('XML_PATH_INDEXER_DATA', 'Magento\Index\Model\Process'),
     array('XML_PATH_INSTALL_DATE', 'Mage_Core_Model_App', 'Mage_Core_Model_Config_Primary::XML_PATH_INSTALL_DATE'),
     array('XML_PATH_LOCALE_INHERITANCE', 'Mage_Core_Model_Translate'),
     array('XML_PATH_PRODUCT_ATTRIBUTES', 'Magento\Wishlist\Model\Config'),
@@ -379,6 +378,16 @@ return array(
         '\Magento\Core\Helper\Data',
         '\Magento\Catalog\Helper\Catalog::XML_PATH_PUBLIC_FILES_VALID_PATHS'
     ),
+    array(
+        'XML_PATH_PUBLIC_FILES_VALID_PATHS',
+        'Magento\Catalog\Helper\Catalog',
+        '\Magento\Sitemap\Helper\Data::XML_PATH_PUBLIC_FILES_VALID_PATHS'
+    ),
+    array(
+        'XML_PATH_SITEMAP_VALID_PATHS',
+        '\Magento\Catalog\Helper\Catalog',
+        '\Magento\Sitemap\Helper\Data::XML_PATH_SITEMAP_VALID_PATHS'
+    ),
     array('TYPE_PHYSICAL', '\Magento\Core\Model\Theme', '\Magento\Framework\View\Design\ThemeInterface::TYPE_PHYSICAL'),
     array('TYPE_VIRTUAL', '\Magento\Core\Model\Theme', '\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL'),
     array('TYPE_STAGING', '\Magento\Core\Model\Theme', '\Magento\Framework\View\Design\ThemeInterface::TYPE_STAGING'),
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 09e6a7709ec..5dc587b191c 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -322,7 +322,6 @@ return array(
         '',
         '\Magento\Framework\App\Filesystem::getDirectoryRead(\Magento\Framework\App\Filesystem::VAR_DIR)::search())'
     ),
-    array('cloneIndexTable', 'Magento\Index\Model\Resource\AbstractResource'),
     array('collectRoutes', 'Magento\Backend\App\Router'),
     array('collectRoutes', 'Magento\Core\App\Router\Base'),
     array('composeLocaleHierarchy', 'Magento\Translation\Helper\Data'),
@@ -659,16 +658,6 @@ return array(
     array('getTrackingPopUpUrlByShipId', '', 'getTrackingPopupUrlBySalesModel'),
     array('getTrackingPopUpUrlByTrackId', '', 'getTrackingPopupUrlBySalesModel'),
     array('getUnixProcessMemoryUsage', 'Magento\TestFramework\Helper\Memory', 'getRealMemoryUsage'),
-    array(
-        'getUnprocessedEvents',
-        'Magento\Index\Model\Resource\Event',
-        'Magento_Index_Model_EventRepository::getUnprocessed()'
-    ),
-    array(
-        'getUnprocessedEventsCollection',
-        'Magento\Index\Model\Process',
-        'Magento_Index_Model_EventRepository::getUnprocessed()'
-    ),
     array('getUploadMaxSize', 'Magento\Backend\Block\Media\Uploader', 'Magento_File_Size::getUploadMaxSize()'),
     array('getUrlForReferer', 'Magento\Backend\Block\Page\Footer'),
     array('getValidator', 'Magento\SalesRule\Model\Observer'),
@@ -1010,7 +999,6 @@ return array(
     array('getCatalogHelper', 'Magento\Backend\Block\Catalog\Category\Tabs'),
     array('_getSession', 'Magento\Centinel\Model\Service'),
     array('_getValidationStateModel', 'Magento\Centinel\Model\Service'),
-    array('_getIndexer', 'Magento\Index\Model\Shell'),
     array('_getApi', 'Magento\Ogone\Block\Placeform'),
     array(
         '_getResource',
@@ -1102,6 +1090,7 @@ return array(
     array('getPublicFilesValidPath', '\Magento\Core\Helper\Data'),
     array('getViewConfig', '\Magento\Core\Model\View\Config', 'get'),
     array('_getSession', '\Magento\Catalog\Helper\Product\Compare', '$this->_catalogSession'),
+    array('getSitemapValidPaths', '\Magento\Catalog\Helper\Catalog', '\Magento\Sitemap\Helper\Data::getValidPaths'),
     array('getEnginePool', '\Magento\Framework\View\Element\Template\Context', 'getEngineFactory'),
     array('getHtml', 'Magento\Framework\View\Element\Messages'),
     array('is_dir_writeable'),
@@ -1916,10 +1905,15 @@ return array(
     ['removeTag', 'Magento\UrlRewrite\Model\UrlRewrite'],
     ['addTag', 'Magento\UrlRewrite\Model\UrlRewrite'],
     ['loadByTags', 'Magento\UrlRewrite\Model\UrlRewrite'],
+    ['canApplyMsrp', 'Magento\Checkout\Block\Cart\AbstractCart', 'Magento\Msrp\Block\Total'],
+    ['createController', 'Magento\Framework\App\ActionFactory', 'Magento\Framework\App\ActionFactory::create'],
     ['getMethodFormBlock', 'Magento\Centinel\Helper\Data'],
     ['login', 'Magento\Customer\Model\Session'],
     ['roundPrice', 'Magento\Store\Model\Store', 'Magento\Framework\Pricing\PriceCurrencyInterface::round'],
     ['formatPrice', 'Magento\Store\Model\Store', 'Magento\Framework\Pricing\PriceCurrencyInterface::format'],
     ['convertPrice', 'Magento\Store\Model\Store', 'Magento\Framework\Pricing\PriceCurrencyInterface::convert'],
     ['getPriceFilter', 'Magento\Store\Model\Store'],
+    ['_addHeader', 'Magento\Rss\Model\Rss'],
+    ['_addEntries', 'Magento\Rss\Model\Rss'],
+    ['_addEntry', 'Magento\Rss\Model\Rss'],
 );
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
index 5b203315d30..69c7b1d5af9 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
@@ -44,7 +44,6 @@ return array(
     array('_config', 'Magento\Framework\Logger', '_dirs'),
     array('_config', 'Magento\Core\Model\Resource\Setup'),
     array('_configModel', 'Magento\Backend\Model\Menu\AbstractDirector'),
-    array('_configuration', 'Magento\Index\Model\Lock\Storage', '_dirs'),
     array('_connectionConfig', 'Magento\Core\Model\Resource\Setup'),
     array('_connectionTypes', 'Magento\Framework\App\Resource'),
     array('_currencyNameTable'),
@@ -201,8 +200,6 @@ return array(
     array('_filesystem', 'Magento\GiftWrapping\Model\Wrapping'),
     array('_customer', 'Magento\Backend\Model\Session\Quote'),
     array('_customerFactory', 'Magento\Backend\Model\Session\Quote'),
-    array('_dirs', 'Magento\Index\Model\Lock\Storage'),
-    array('_filesystem', 'Magento\Index\Model\Lock\Storage'),
     array('_coreDir', 'Magento\Sales\Model\Order\Pdf\AbstractPdf'),
     array('_coreDir', 'Magento\ScheduledImportExport\Model\Scheduled\Operation'),
     array('_dirs', 'Magento\Core\Block\Template'),
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt
index 9db36d76f0a..482c01bdee0 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/blacklist/common.txt
@@ -11,12 +11,14 @@ app/code/Magento/ConfigurableProduct/view
 app/code/Magento/DesignEditor/view
 app/code/Magento/Email/view
 app/code/Magento/Integration/view
+app/code/Magento/Msrp/view
 app/code/Magento/Theme/view
 app/code/Magento/User/view
 app/code/Magento/Webapi/view
 app/code/Magento/GroupedProduct/view
+app/code/Magento/Rss/view
 app/code/Magento/RecurringPayment/view
-app/code/Magento/UrlRedirect/view
+app/code/Magento/UrlRewrite/view
 dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php
 dev/tests/integration/framework/Magento/TestFramework/Db/Adapter/Mysql.php
 dev/tests/integration/framework/Magento/TestFramework/Db/ConnectionAdapter.php
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
index 81e78ef60f1..a7e453c4e08 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
@@ -59,7 +59,6 @@ Magento/DesignEditor/Model/Url
 Magento/Directory/Model
 Magento/GiftMessage/Block/Adminhtml/Sales/Order
 Magento/ImportExport/Model
-Magento/Index/Model/Process
 Magento/Integration/Controller/Adminhtml
 Magento/Install/Block/Db
 Magento/Newsletter/Block/Adminhtml/Template/Preview
@@ -87,6 +86,7 @@ Magento/Shipping/Model/Carrier
 Magento/Sitemap/Block/Adminhtml/Edit
 Magento/Sitemap/Model/
 Magento/CatalogRule/Model
+Magento/Rss/Controller/Adminhtml/Feed
 Magento/Tax/Block/Checkout
 Magento/Tax/Model/Sales/Pdf
 Magento/Tax/Model/Config/Price
@@ -122,7 +122,7 @@ Magento/Usps/Model/Carrier
 Magento/Dhl/Model
 Magento/Shipping/Model
 Magento/Catalog/Service/V1/Category
-Magento/UrlRedirect/Model
+Magento/Ui
 setup
 Magento/Sales/Service/V1
-Magento/Shipping/Controller/Adminhtml/Order/Shipment
\ No newline at end of file
+Magento/Shipping/Controller/Adminhtml/Order/Shipment
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
index e232e29d865..1c128f4d65f 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
@@ -5,8 +5,6 @@ app/bootstrap.php
 app/code/Magento/Backend/Block/Page/System/Config/Robots/Reset.php
 app/code/Magento/Backend/Block/System/Store/Edit
 app/code/Magento/Backend/Block/System/Store/Edit.php
-app/code/Magento/Backend/Block/Urlrewrite
-app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
 app/code/Magento/Backend/Model/Observer.php
 app/code/Magento/Bundle/Model/Plugin
 app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/NewCategory.php
@@ -83,18 +81,12 @@ app/code/Magento/ImportExport/Model/Import/Config
 app/code/Magento/ImportExport/Model/Import/Config.php
 app/code/Magento/ImportExport/Model/Import/ConfigInterface.php
 app/code/Magento/ImportExport/Controller/Adminhtml/Import.php
-app/code/Magento/Index/Model/Indexer/Config
-app/code/Magento/Index/Model/Indexer/Config.php
-app/code/Magento/Index/Model/Indexer/ConfigInterface.php
-app/code/Magento/Index/Model/Indexer/Factory.php
-app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
-app/code/Magento/Index/Model/Shell.php
 app/code/Magento/Integration
 app/code/Magento/Log/Model/Resource/Helper.php
 app/code/Magento/Log/Model/Resource/Shell.php
 app/code/Magento/Log/Model/Shell.php
 app/code/Magento/Log/Model/Shell
-app/code/Magento/Theme/Block/Html/Head
+app/code/Magento/Msrp
 app/code/Magento/ProductAlert/Block/Product/View
 app/code/Magento/RecurringPayment
 app/code/Magento/Reports/Block/Adminhtml/Customer
@@ -107,11 +99,17 @@ app/code/Magento/Reports/Model/Resource/Customer
 app/code/Magento/Reports/Model/Resource/Report/Collection.php
 app/code/Magento/Sales/Block/Guest/Link.php
 app/code/Magento/Sales/Block/Order/Link.php
+app/code/Magento/Sales/Block/Order/Info/Buttons/Rss.php
+app/code/Magento/Sales/Block/Adminhtml/Order/Details.php
 app/code/Magento/Sales/Model/Order/Pdf/Config
 app/code/Magento/Sales/Model/Order/Pdf/Config.php
 app/code/Magento/Sales/Model/Order/Pdf/Total/Factory.php
 app/code/Magento/Sales/Model/Observer
 app/code/Magento/Sales/Model/Quote/Address/*Interface.php
+app/code/Magento/Sales/Model/Quote/Address/*Interface.php
+app/code/Magento/Sales/Model/Resource/Order/Rss/OrderStatus.php
+app/code/Magento/Sales/Model/Rss/NewOrder.php
+app/code/Magento/Sales/Model/Rss/OrderStatus.php
 app/code/Magento/SalesRule/Model/Plugin
 app/code/Magento/Sendfriend/Block/Plugin/Catalog/Product/View.php
 app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/Invoice.php
@@ -122,8 +120,13 @@ app/code/Magento/Shipping/Model/Resource/Order
 app/code/Magento/Theme
 app/code/Magento/Webapi
 app/code/Magento/GroupedProduct
-app/code/Magento/UrlRedirect
+app/code/Magento/Rss
+app/code/Magento/CatalogUrlRewrite
+app/code/Magento/CmsUrlRewrite
+app/code/Magento/UrlRewrite
 app/code/Magento/Wishlist/Block/Link.php
+app/code/Magento/Wishlist/Block/Rss
+app/code/Magento/Wishlist/Model/Rss/Wishlist.php
 dev/shell
 dev/tests/functional
 dev/tests/integration/*
diff --git a/dev/tests/unit/filename b/dev/tests/unit/filename
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/dev/tests/unit/filename.csv b/dev/tests/unit/filename.csv
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/dev/tests/unit/filename.invalid_type b/dev/tests/unit/filename.invalid_type
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/dev/tests/unit/framework/Magento/Test/BaseTestCase.php b/dev/tests/unit/framework/Magento/Test/BaseTestCase.php
new file mode 100644
index 00000000000..502d94e0f6b
--- /dev/null
+++ b/dev/tests/unit/framework/Magento/Test/BaseTestCase.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Framework for unit tests containing helper methods
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ *
+ * Number of fields is necessary because of the number of fields used by multiple layers
+ * of parent classes.
+ *
+ */
+namespace Magento\Test;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class BaseTestCase extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+    }
+    
+    /**
+     * Build a basic mock object
+     *
+     * @param string $className
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function basicMock($className)
+    {
+        return $this->getMockBuilder($className)
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    public function booleanDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/framework/tests/unit/phpunit.xml.dist b/dev/tests/unit/framework/tests/unit/phpunit.xml.dist
index 631d457f475..605ac25c926 100644
--- a/dev/tests/unit/framework/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/framework/tests/unit/phpunit.xml.dist
@@ -23,7 +23,11 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <testsuites>
         <testsuite name="Unit Tests for Unit Tests Framework">
             <directory suffix="Test.php">testsuite</directory>
diff --git a/dev/tests/unit/phpunit.xml.dist b/dev/tests/unit/phpunit.xml.dist
index 14e25a73567..9f9822b2e47 100644
--- a/dev/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/phpunit.xml.dist
@@ -23,16 +23,17 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit bootstrap="./framework/bootstrap.php">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
     <testsuite name="Magento Unit Tests">
         <directory suffix="Test.php">testsuite</directory>
     </testsuite>
     <php>
         <ini name="date.timezone" value="America/Los_Angeles"/>
     </php>
-    <listeners>
-        <listener class="Magento\TestFramework\Listener\GarbageCleanup" file="framework/Magento/TestFramework/Listener/GarbageCleanup.php"/>
-    </listeners>
     <filter>
         <whitelist addUncoveredFilesFromWhiteList="true">
             <directory suffix=".php">../../../app/code/Magento</directory>
diff --git a/dev/tests/unit/testsuite/Magento/AdminNotification/Model/FeedTest.php b/dev/tests/unit/testsuite/Magento/AdminNotification/Model/FeedTest.php
new file mode 100644
index 00000000000..0dd602e7641
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/AdminNotification/Model/FeedTest.php
@@ -0,0 +1,179 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\AdminNotification\Model;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class FeedTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\AdminNotification\Model\Feed */
+    protected $feed;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $inboxFactory;
+
+    /** @var \Magento\AdminNotification\Model\Inbox|\PHPUnit_Framework_MockObject_MockObject */
+    protected $inboxModel;
+
+    /** @var \Magento\Framework\HTTP\Adapter\CurlFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $curlFactory;
+
+    /** @var \Magento\Framework\HTTP\Adapter\Curl|\PHPUnit_Framework_MockObject_MockObject */
+    protected $curl;
+
+    /** @var \Magento\Backend\App\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $backendConfig;
+
+    /** @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $cacheManager;
+
+    /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */
+    protected $appState;
+
+    protected function setUp()
+    {
+        $this->inboxFactory = $this->getMock('Magento\AdminNotification\Model\InboxFactory', ['create']);
+        $this->curlFactory = $this->getMock('\Magento\Framework\HTTP\Adapter\CurlFactory', ['create']);
+        $this->curl = $this->getMock('\Magento\Framework\HTTP\Adapter\Curl', ['read']);
+        $this->appState = $this->getMock('\Magento\Framework\App\State', ['getInstallDate'], [], '', false);
+        $this->inboxModel = $this->getMock(
+            '\Magento\AdminNotification\Model\Inbox',
+            [
+                '__wakeup',
+                'parse'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->backendConfig = $this->getMock(
+            'Magento\Backend\App\ConfigInterface',
+            [
+                'getValue',
+                'setValue',
+                'isSetFlag'
+            ]
+        );
+        $this->cacheManager = $this->getMock(
+            '\Magento\Framework\App\CacheInterface',
+            [
+                'load',
+                'getFrontend',
+                'remove',
+                'save',
+                'clean'
+            ]
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->feed = $this->objectManagerHelper->getObject(
+            'Magento\AdminNotification\Model\Feed',
+            [
+                'backendConfig' => $this->backendConfig,
+                'cacheManager' => $this->cacheManager,
+                'inboxFactory' => $this->inboxFactory,
+                'appState' => $this->appState,
+                'curlFactory' => $this->curlFactory
+            ]
+        );
+    }
+
+    /**
+     * @dataProvider checkUpdateDataProvider
+     * @param bool $callInbox
+     * @param string $curlRequest
+     */
+    public function testCheckUpdate($callInbox, $curlRequest)
+    {
+        $lastUpdate = 1410121748;
+        $this->curlFactory->expects($this->at(0))->method('create')->will($this->returnValue($this->curl));
+        $this->curl->expects($this->any())->method('read')->will($this->returnValue($curlRequest));
+        $this->backendConfig->expects($this->at(0))->method('getValue')->will($this->returnValue('1'));
+        $this->backendConfig->expects($this->once())->method('isSetFlag')->will($this->returnValue(false));
+        $this->backendConfig->expects($this->at(1))->method('getValue')
+            ->will($this->returnValue('http://feed.magento.com'));
+        $this->cacheManager->expects($this->once())->method('load')->will(($this->returnValue($lastUpdate)));
+        $this->appState->expects($this->once())->method('getInstallDate')->will(($this->returnValue($lastUpdate)));
+        if ($callInbox) {
+            $this->inboxFactory->expects($this->once())->method('create')
+                ->will(($this->returnValue($this->inboxModel)));
+            $this->inboxModel->expects($this->once())->method('parse')->will($this->returnSelf());
+        } else {
+            $this->inboxFactory->expects($this->never())->method('create');
+            $this->inboxModel->expects($this->never())->method('parse');
+        }
+
+        $this->feed->checkUpdate();
+    }
+
+    /**
+     * @return array
+     */
+    public function checkUpdateDataProvider()
+    {
+        return [
+            [
+                true,
+                'HEADER
+
+                <?xml version="1.0" encoding="utf-8" ?>
+                        <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+                            <channel>
+                                <title>MagentoCommerce</title>
+                                <item>
+                                    <title><![CDATA[Test Title]]></title>
+                                    <link><![CDATA[http://magento.com/feed_url]]></link>
+                                    <severity>4</severity>
+                                    <description><![CDATA[Test Description]]></description>
+                                    <pubDate>Tue, 9 Sep 2014 16:46:11 UTC</pubDate>
+                                </item>
+                            </channel>
+                        </rss>'
+            ],
+            [
+                false,
+                'HEADER
+
+                <?xml version="1.0" encoding="utf-8" ?>
+                        <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+                            <channel>
+                                <title>MagentoCommerce</title>
+                                <item>
+                                    <title><![CDATA[Test Title]]></title>
+                                    <link><![CDATA[http://magento.com/feed_url]]></link>
+                                    <severity>4</severity>
+                                    <description><![CDATA[Test Description]]></description>
+                                    <pubDate>Tue, 1 Sep 2014 16:46:11 UTC</pubDate>
+                                </item>
+                            </channel>
+                        </rss>'
+            ]
+        ];
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/UrlrewriteTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/UrlrewriteTest.php
deleted file mode 100644
index 0c75ff35e50..00000000000
--- a/dev/tests/unit/testsuite/Magento/Backend/Block/UrlrewriteTest.php
+++ /dev/null
@@ -1,109 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Backend\Block;
-
-class UrlrewriteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @param array $modes
-     * @param string $expectedUrl
-     * @dataProvider getCreateUrlData
-     */
-    public function testGetCreateUrl(array $modes, $expectedUrl)
-    {
-        /** @var $selectorBlock \Magento\Backend\Block\Urlrewrite\Selector */
-        $selectorBlock = $modes ? $this->getMock(
-            'Magento\Backend\Block\Urlrewrite\Selector',
-            array('getModes'),
-            array(),
-            '',
-            false
-        ) : false;
-        if ($selectorBlock) {
-            $selectorBlock->expects($this->once())->method('getModes')->with()->will($this->returnValue($modes));
-        }
-
-        $testedBlock = $this->getMock('Magento\Backend\Block\Urlrewrite', array('getUrl'), array(), '', false);
-        $testedBlock->setSelectorBlock($selectorBlock);
-        $testedBlock->expects(
-            $this->once()
-        )->method(
-            'getUrl'
-        )->with(
-            'adminhtml/*/edit'
-        )->will(
-            $this->returnValue('http://localhost/admin/urlrewrite/edit/')
-        );
-
-        $this->assertEquals($expectedUrl, $testedBlock->getCreateUrl());
-    }
-
-    /**
-     * Data for testGetCreateUrl
-     * @static
-     * @return array
-     */
-    public static function getCreateUrlData()
-    {
-        return array(
-            array(array(), 'http://localhost/admin/urlrewrite/edit/'),
-            array(
-                array(
-                    'category' => 'For category',
-                    'product' => 'For product',
-                    'id' => 'Custom',
-                    'cms_page' => 'For CMS page'
-                ),
-                'http://localhost/admin/urlrewrite/edit/category'
-            ),
-            array(
-                array(
-                    'product' => 'For product',
-                    'category' => 'For category',
-                    'id' => 'Custom',
-                    'cms_page' => 'For CMS page'
-                ),
-                'http://localhost/admin/urlrewrite/edit/product'
-            ),
-            array(
-                array(
-                    'id' => 'Custom',
-                    'product' => 'For product',
-                    'category' => 'For category',
-                    'cms_page' => 'For CMS page'
-                ),
-                'http://localhost/admin/urlrewrite/edit/id'
-            ),
-            array(
-                array(
-                    'cms_page' => 'For CMS page',
-                    'product' => 'For product',
-                    'category' => 'For category',
-                    'id' => 'Custom'
-                ),
-                'http://localhost/admin/urlrewrite/edit/cms_page'
-            )
-        );
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/Grid/Column/Renderer/ConcatTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/Grid/Column/Renderer/ConcatTest.php
new file mode 100644
index 00000000000..7832ec46409
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/Grid/Column/Renderer/ConcatTest.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Block\Widget\Grid\Column\Renderer;
+
+use Magento\Framework\Object;
+
+class ConcatTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManagerHelper;
+    /** @var \Magento\Backend\Block\Widget\Grid\Column\Renderer\Concat */
+    protected $renderer;
+
+    public function setUp()
+    {
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->renderer = $this->objectManagerHelper->getObject(
+            'Magento\\Backend\\Block\\Widget\\Grid\\Column\\Renderer\\Concat'
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function typeProvider()
+    {
+        return [
+            ['getGetter', ['getTest', 'getBest']],
+            ['getIndex', ['test', 'best', 'nothing']],
+        ];
+    }
+
+    /**
+     * @dataProvider typeProvider
+     */
+    public function testRender($method, $getters)
+    {
+        $object = new Object(['test' => 'a', 'best' => 'b']);
+        $column = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
+            ->disableOriginalConstructor()
+            ->setMethods([$method, 'getSeparator'])
+            ->getMock();
+        $column->expects($this->any())
+            ->method('getSeparator')
+            ->willReturn('-');
+        $column->expects($this->any())
+            ->method($method)
+            ->willReturn($getters);
+        $column->expects($this->any())
+            ->method('getGetter')
+            ->willReturn(['getTest', 'getBest']);
+        $this->renderer->setColumn($column);
+        $this->assertEquals('a-b', $this->renderer->render($object));
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/GridTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/GridTest.php
deleted file mode 100644
index b29d9875538..00000000000
--- a/dev/tests/unit/testsuite/Magento/Backend/Block/Widget/GridTest.php
+++ /dev/null
@@ -1,87 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Test class for \Magento\Backend\Model\Url
- */
-namespace Magento\Backend\Block\Widget;
-
-class GridTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\TestFramework\Helper\ObjectManager
-     */
-    protected $_objectManager;
-
-    protected function setUp()
-    {
-        $this->_objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-    }
-
-    /**
-     * @covers \Magento\Backend\Block\Widget\Grid::addRssList
-     * @covers \Magento\Backend\Block\Widget\Grid::clearRss
-     * @covers \Magento\Backend\Block\Widget\Grid::getRssLists
-     * @dataProvider addGetClearRssDataProvider
-     */
-    public function testAddGetClearRss($isUseStoreInUrl)
-    {
-        $urlMock = $this->getMock('Magento\Framework\Url', array(), array(), '', false);
-
-        $storeMock = $this->getMock('Magento\Store\Model\Store', array(), array(), '', false);
-        $storeMock->expects($this->any())->method('isUseStoreInUrl')->will($this->returnValue($isUseStoreInUrl));
-
-        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', array(), array(), '', false);
-
-        $urlBuilderMock = $this->getMock('Magento\Backend\Model\Url', array(), array(), '', false);
-
-
-        $urlBuilderMock->expects($this->any())->method('getUrl')->will($this->returnValue('some_url'));
-
-        $block = $this->_objectManager->getObject(
-            'Magento\Backend\Block\Widget\Grid',
-            array('storeManager' => $storeManagerMock, 'urlModel' => $urlMock, 'urlBuilder' => $urlBuilderMock)
-        );
-
-        $this->assertFalse($block->getRssLists());
-
-        $block->addRssList('some_url', 'some_label');
-        $elements = $block->getRssLists();
-        $element = reset($elements);
-        $this->assertEquals('some_url', $element->getUrl());
-        $this->assertEquals('some_label', $element->getLabel());
-
-        $block->clearRss();
-        $this->assertFalse($block->getRssLists());
-    }
-
-    /**
-     * @see self::testAddGetClearRss()
-     * @return array
-     */
-    public function addGetClearRssDataProvider()
-    {
-        return array(array(true), array(false));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
index d1d8ca92222..62061bbf18f 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
@@ -250,18 +250,8 @@ class TunnelTest extends \PHPUnit_Framework_TestCase
             $response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
             $response->headersSentThrowsException = false;
         }
-        $rewriteFactory = $this->getMock(
-            'Magento\UrlRewrite\Model\UrlRewriteFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $varienFront = $helper->getObject(
-            'Magento\Framework\App\FrontController',
-            array('rewriteFactory' => $rewriteFactory)
-        );
+        $varienFront = $helper->getObject('Magento\Framework\App\FrontController');
 
         $arguments = array(
             'request' => $request,
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
index fc8a971c2e5..34cdc68745d 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
@@ -101,7 +101,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $this->_userMock = $this->getMockBuilder(
             'Magento\User\Model\User'
         )->disableOriginalConstructor()->setMethods(
-            array('load', 'save', 'sendPasswordResetNotificationEmail', '__sleep', '__wakeup')
+            array('load', 'save', 'sendPasswordResetNotificationEmail', 'verifyIdentity', '__sleep', '__wakeup')
         )->getMock();
 
         $this->_validatorMock = $this->getMockBuilder(
@@ -164,7 +164,8 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             'username' => 'Foo',
             'firstname' => 'Bar',
             'lastname' => 'Dummy',
-            'email' => 'test@example.com'
+            'email' => 'test@example.com',
+            \Magento\Backend\Block\System\Account\Edit\Form::IDENTITY_VERIFICATION_PASSWORD_FIELD => 'current_password'
         );
 
         $testedMessage = 'The account has been saved.';
@@ -223,6 +224,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $this->_userMock->setUserId($userId);
 
         $this->_userMock->expects($this->once())->method('save');
+        $this->_userMock->expects($this->once())->method('verifyIdentity')->will($this->returnValue(true));
         $this->_userMock->expects($this->once())->method('sendPasswordResetNotificationEmail');
 
         $this->_requestMock->setParams($requestParams);
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
similarity index 65%
rename from dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php
rename to dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
index ea89dbef4eb..3df96729bd1 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/DomainTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/DomainTest.php
@@ -21,21 +21,27 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Model\Config\Backend;
+namespace Magento\Backend\Model\Config\Backend\Cookie;
 
 use Magento\Framework\Model\Exception;
+use Magento\Framework\Session\Config\Validator\CookieDomainValidator;
 
 /**
- * Test \Magento\Backend\Model\Config\Backend\Domain
+ * Test \Magento\Backend\Model\Config\Backend\Cookie\Domain
  */
 class DomainTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\Framework\Model\Resource\AbstractResource | \PHPUnit_Framework_MockObject_MockObject */
     protected $resourceMock;
 
-    /** @var \Magento\Backend\Model\Config\Backend\Domain */
+    /** @var \Magento\Backend\Model\Config\Backend\Cookie\Domain */
     protected $domain;
 
+    /**
+     * @var  CookieDomainValidator | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $validatorMock;
+
     protected function setUp()
     {
         $eventDispatcherMock = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false);
@@ -66,38 +72,50 @@ class DomainTest extends \PHPUnit_Framework_TestCase
             false
         );
 
+        $this->validatorMock = $this->getMockBuilder(
+            'Magento\Framework\Session\Config\Validator\CookieDomainValidator'
+        )->disableOriginalConstructor()
+            ->getMock();
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->domain = $helper->getObject(
-            'Magento\Backend\Model\Config\Backend\Domain',
+            'Magento\Backend\Model\Config\Backend\Cookie\Domain',
             [
                 'context' => $contextMock,
                 'resource' => $this->resourceMock,
+                'configValidator' => $this->validatorMock,
             ]
         );
     }
 
     /**
-     * @covers \Magento\Backend\Model\Config\Backend\Domain::_beforeSave
+     * @covers \Magento\Backend\Model\Config\Backend\Cookie\Domain::_beforeSave
      * @dataProvider beforeSaveDataProvider
      *
      * @param string $value
-     * @param string $exceptionMessage
+     * @param bool $isValid
+     * @param int $callNum
+     * @param int $callGetMessages
      */
-    public function testBeforeSave($value, $exceptionMessage = null)
+    public function testBeforeSave($value, $isValid, $callNum, $callGetMessages = 0)
     {
         $this->resourceMock->expects($this->any())->method('addCommitCallback')->will($this->returnSelf());
         $this->resourceMock->expects($this->any())->method('commit')->will($this->returnSelf());
         $this->resourceMock->expects($this->any())->method('rollBack')->will($this->returnSelf());
 
+        $this->validatorMock->expects($this->exactly($callNum))
+            ->method('isValid')
+            ->will($this->returnValue($isValid));
+        $this->validatorMock->expects($this->exactly($callGetMessages))
+            ->method('getMessages')
+            ->will($this->returnValue(['message']));
         $this->domain->setValue($value);
         try {
             $this->domain->save();
-            if ($exceptionMessage ) {
+            if ($callGetMessages ) {
                 $this->fail('Failed to throw exception');
             }
         } catch (Exception $e) {
-            $this->assertContains('Invalid domain name: ', $e->getMessage());
-            $this->assertContains($exceptionMessage, $e->getMessage());
+            $this->assertEquals('Invalid domain name: message', $e->getMessage());
         }
     }
 
@@ -107,15 +125,10 @@ class DomainTest extends \PHPUnit_Framework_TestCase
     public function beforeSaveDataProvider()
     {
         return [
-            'not string' => [['array'], 'Invalid type given. String expected'],
-            'invalid hostname' => [
-                'http://',
-                'The input does not match the expected structure for a DNS hostname; '
-                . 'The input does not appear to be a valid URI hostname; '
-                . 'The input does not appear to be a valid local network name'
-            ],
-            'valid hostname' => ['hostname.com'],
-            'empty string' => [''],
+            'not string' => [['array'], false, 1, 1],
+            'invalid hostname' => ['http://', false, 1, 1],
+            'valid hostname' => ['hostname.com', true, 1, 0],
+            'empty string' => ['', false, 0, 0],
         ];
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
new file mode 100644
index 00000000000..81ef3022fc2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/LifetimeTest.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Unit test for Magento\Backend\Model\Config\Backend\Cookie\Lifetime
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+use \Magento\TestFramework\Helper\ObjectManager;
+use \Magento\Framework\Session\Config\Validator\CookieLifetimeValidator;
+
+class LifetimeTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject | CookieLifetimeValidator */
+    private $validatorMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Install\Model\Resource\Resource */
+    private $resourceMock;
+
+    /** @var \Magento\Backend\Model\Config\Backend\Cookie\Lifetime */
+    private $model;
+
+    public function setUp()
+    {
+        $this->validatorMock = $this->getMockBuilder(
+            'Magento\Framework\Session\Config\Validator\CookieLifetimeValidator'
+        )->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock = $this->getMockBuilder('Magento\Install\Model\Resource\Resource')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManager = new ObjectManager($this);
+        $this->model = $objectManager->getObject('Magento\Backend\Model\Config\Backend\Cookie\Lifetime',
+            [
+                'configValidator' => $this->validatorMock,
+                'resource' => $this->resourceMock
+            ]
+        );
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Invalid cookie lifetime: must be numeric
+     */
+    public function testBeforeSaveException()
+    {
+        $invalidCookieLifetime = 'invalid lifetime';
+        $messages = ['must be numeric'];
+        $this->validatorMock->expects($this->once())
+            ->method('getMessages')
+            ->willReturn($messages);
+        $this->validatorMock->expects($this->once())
+            ->method('isValid')
+            ->with($invalidCookieLifetime)
+            ->willReturn(false);
+
+        // Test
+        $this->model->setValue($invalidCookieLifetime)->save();
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * No assertions exist because the purpose of the test is to make sure that no
+     * exception gets thrown
+     */
+    public function testBeforeSaveNoException()
+    {
+        $validCookieLifetime = 1;
+        $this->validatorMock->expects($this->once())
+            ->method('isValid')
+            ->with($validCookieLifetime)
+            ->willReturn(true);
+        $this->resourceMock->expects($this->once())->method('addCommitCallback')->willReturnSelf();
+
+        // Test
+        $this->model->setValue($validCookieLifetime)->save();
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * No assertions exist because the purpose of the test is to make sure that no
+     * exception gets thrown
+     */
+    public function testBeforeEmptyString()
+    {
+        $validCookieLifetime = '';
+        $this->validatorMock->expects($this->never())
+            ->method('isValid');
+
+        $this->resourceMock->expects($this->once())->method('addCommitCallback')->willReturnSelf();
+
+        // Test
+        $this->model->setValue($validCookieLifetime)->save();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
new file mode 100644
index 00000000000..9bd316ad23c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/Cookie/PathTest.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Unit test for Magento\Backend\Model\Config\Backend\Cookie\Path
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Model\Config\Backend\Cookie;
+
+use \Magento\TestFramework\Helper\ObjectManager;
+use \Magento\Framework\Session\Config\Validator\CookiePathValidator;
+
+class PathTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject | CookiePathValidator */
+    private $validatorMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Install\Model\Resource\Resource */
+    private $resourceMock;
+
+    /** @var \Magento\Backend\Model\Config\Backend\Cookie\Path */
+    private $model;
+
+    public function setUp()
+    {
+        $this->validatorMock = $this->getMockBuilder('Magento\Framework\Session\Config\Validator\CookiePathValidator')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock = $this->getMockBuilder('Magento\Install\Model\Resource\Resource')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManager = new ObjectManager($this);
+        $this->model = $objectManager->getObject('Magento\Backend\Model\Config\Backend\Cookie\Path',
+            [
+                'configValidator' => $this->validatorMock,
+                'resource' => $this->resourceMock
+            ]
+        );
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Invalid cookie path
+     */
+    public function testBeforeSaveException()
+    {
+        $invalidCookiePath = 'invalid path';
+        $this->validatorMock->expects($this->once())
+            ->method('isValid')
+            ->with($invalidCookiePath)
+            ->willReturn(false);
+
+        // Must throw exception
+        $this->model->setValue($invalidCookiePath)->save();
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * No assertions exist because the purpose of the test is to make sure that no
+     * exception gets thrown
+     */
+    public function testBeforeSaveNoException()
+    {
+        $validCookiePath = 1;
+        $this->validatorMock->expects($this->once())
+            ->method('isValid')
+            ->with($validCookiePath)
+            ->willReturn(true);
+        $this->resourceMock->expects($this->any())->method('addCommitCallback')->willReturnSelf();
+
+        // Must not throw exception
+        $this->model->setValue($validCookiePath)->save();
+    }
+
+    /**
+     * Method is not publicly accessible, so it must be called through parent
+     *
+     * Empty string should not be sent to validator
+     */
+    public function testBeforeSaveEmptyString()
+    {
+        $validCookiePath = '';
+        $this->validatorMock->expects($this->never())
+            ->method('isValid');
+
+        $this->resourceMock->expects($this->any())->method('addCommitCallback')->willReturnSelf();
+
+        // Must not throw exception
+        $this->model->setValue($validCookiePath)->save();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Backend/AdminConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
similarity index 60%
rename from dev/tests/unit/testsuite/Magento/Backend/AdminConfigTest.php
rename to dev/tests/unit/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
index aa990ca1064..254530b975c 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/AdminConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Session/AdminConfigTest.php
@@ -22,21 +22,25 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Backend;
+/**
+ * Test class for \Magento\Backend\Model\Session\AdminConfig
+ */
+namespace Magento\Backend\Model\Session;
 
 use Magento\TestFramework\ObjectManager;
 
-/**
- * Test class for \Magento\Backend\AdminConfig
- *
- */
 class AdminConfigTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\App\RequestInterface
+     * @var \Magento\Framework\App\RequestInterface | \PHPUnit_Framework_MockObject_MockObject
      */
     private $requestMock;
 
+    /**
+     * @var \Magento\Framework\ValidatorFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validatorFactory;
+
     /**
      * @var \Magento\TestFramework\Helper\ObjectManager
      */
@@ -62,6 +66,10 @@ class AdminConfigTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('init.host')
         );
         $this->objectManager =  new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->validatorFactory = $this->getMockBuilder('Magento\Framework\ValidatorFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        
     }
 
     public function testSetCookiePathNonDefault()
@@ -74,9 +82,22 @@ class AdminConfigTest extends \PHPUnit_Framework_TestCase
             ->method('getFrontName')
             ->will($this->returnValue('backend'));
 
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(true);
+        $this->validatorFactory->expects($this->any())
+            ->method('setInstanceName')
+            ->willReturnSelf();
+        $this->validatorFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($validatorMock);
         $adminConfig = $this->objectManager->getObject(
-            'Magento\Backend\AdminConfig',
+            'Magento\Backend\Model\Session\AdminConfig',
             [
+                'validatorFactory' => $this->validatorFactory,
                 'request' => $this->requestMock,
                 'frontNameResolver' => $mockFrontNameResolver,
             ]
@@ -92,11 +113,26 @@ class AdminConfigTest extends \PHPUnit_Framework_TestCase
     public function testSetSessionNameByConstructor()
     {
         $sessionName = 'admin';
+
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(true);
+        $this->validatorFactory->expects($this->any())
+            ->method('setInstanceName')
+            ->willReturnSelf();
+        $this->validatorFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($validatorMock);
+
         $adminConfig = $this->objectManager->getObject(
-            'Magento\Backend\AdminConfig',
+            'Magento\Backend\Model\Session\AdminConfig',
             [
+                'validatorFactory' => $this->validatorFactory,
                 'request' => $this->requestMock,
-                'sessionName' => $sessionName
+                'sessionName' => $sessionName,
             ]
         );
         $this->assertSame($sessionName, $adminConfig->getName());
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Widget/Grid/Row/UrlGeneratorTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Widget/Grid/Row/UrlGeneratorTest.php
index 89012b4cf1f..0e0084f4f3f 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Widget/Grid/Row/UrlGeneratorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Widget/Grid/Row/UrlGeneratorTest.php
@@ -27,7 +27,6 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
 {
     public function testGetUrl()
     {
-        $this->markTestIncomplete('Bug with phpunit 3.7: PHPUnit_Framework_Exception: Class "%s" already exists');
         $itemId = 3;
         $urlPath = 'mng/item/edit';
 
@@ -38,7 +37,7 @@ class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
             'Magento\Backend\Model\Url',
             array(),
             array(),
-            'Magento\Backend\Model\UrlProxy',
+            '',
             false
         );
         $urlModelMock->expects(
diff --git a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
index 7bd62bd4ec6..6bd995785c4 100644
--- a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
@@ -38,45 +38,17 @@ class DataTest extends \PHPUnit_Framework_TestCase
      */
     protected $filesystem;
 
-    /**
-     * @var \Magento\Index\Model\Resource\Process\CollectionFactory | \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $processFactory;
-
     public function setUp()
     {
         $this->filesystem = $this->getMockBuilder('Magento\Framework\App\Filesystem')->disableOriginalConstructor()
             ->getMock();
-        $this->processFactory = $this->getMockBuilder('Magento\Index\Model\Resource\Process\CollectionFactory')
-            ->setMethods(['create'])->disableOriginalConstructor()->getMock();
 
         $this->helper = (new \Magento\TestFramework\Helper\ObjectManager($this))
             ->getObject('Magento\Backup\Helper\Data', [
                 'filesystem' => $this->filesystem,
-                'processFactory' => $this->processFactory
             ]);
     }
 
-    public function testInvalidateIndexer()
-    {
-        $process = $this->getMockBuilder('Magento\Index\Model\Process')->disableOriginalConstructor()->getMock();
-        $process->expects(
-            $this->once()
-        )->method(
-                'changeStatus'
-            )->with(
-                \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX
-            );
-        $iterator = $this->returnValue(new \ArrayIterator([$process]));
-        $collection = $this->getMockBuilder(
-            'Magento\Index\Model\Resource\Process\Collection'
-        )->disableOriginalConstructor()->getMock();
-        $collection->expects($this->at(0))->method('getIterator')->will($iterator);
-        $this->processFactory->expects($this->any())->method('create')->will($this->returnValue($collection));
-
-        $this->helper->invalidateIndexer();
-    }
-
     public function testGetBackupIgnorePaths()
     {
         $this->filesystem->expects($this->any())->method('getPath')
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/Grid/LinkTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/Grid/LinkTest.php
new file mode 100644
index 00000000000..7f67bb01e38
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/Grid/LinkTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Adminhtml\Rss\Grid;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class LinkTest
+ * @package Magento\Catalog\Block\Adminhtml\Rss\Grid
+ */
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Adminhtml\Rss\Grid\Link
+     */
+    protected $link;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    protected function setUp()
+    {
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->link = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Adminhtml\Rss\Grid\Link',
+            [
+                'rssUrlBuilder' => $this->urlBuilderInterface
+            ]
+        );
+    }
+
+    public function testGetLink()
+    {
+        $rssUrl = 'http://rss.magento.com';
+        $this->urlBuilderInterface->expects($this->once())->method('getUrl')->will($this->returnValue($rssUrl));
+        $this->assertEquals($rssUrl, $this->link->getLink());
+    }
+
+    public function testGetLabel()
+    {
+        $this->assertEquals('Notify Low Stock RSS', $this->link->getLabel());
+    }
+
+    public function testIsRssAllowed()
+    {
+        $this->assertEquals(true, $this->link->isRssAllowed());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/NotifyStockTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/NotifyStockTest.php
new file mode 100644
index 00000000000..71fad7e6491
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Rss/NotifyStockTest.php
@@ -0,0 +1,133 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Adminhtml\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class NotifyStockTest
+ * @package Magento\Catalog\Block\Adminhtml\Rss
+ */
+class NotifyStockTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Adminhtml\Rss\NotifyStock
+     */
+    protected $block;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Backend\Block\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NotifyStock|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var array
+     */
+    protected $rssFeed = array(
+        'title' => 'Low Stock Products',
+        'description' => 'Low Stock Products',
+        'link' => 'http://magento.com/rss/feeds/index/type/notifystock',
+        'charset' => 'UTF-8',
+        'entries' => array(
+            array(
+                'title' => 'Low Stock Product',
+                'description' => 'Low Stock Product has reached a quantity of 1.',
+                'link' => 'http://magento.com/catalog/product/edit/id/1',
+            )
+        )
+    );
+
+    protected function setUp()
+    {
+        $this->rssModel = $this->getMockBuilder('Magento\Catalog\Model\Rss\Product\NotifyStock')
+            ->setMethods(['getProductsCollection', '__wakeup'])
+            ->disableOriginalConstructor()->getMock();
+        $this->rssUrlBuilder = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->urlBuilder = $this->getMock('Magento\Framework\UrlInterface');
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Adminhtml\Rss\NotifyStock',
+            [
+                'urlBuilder' => $this->urlBuilder,
+                'rssModel' => $this->rssModel,
+                'rssUrlBuilder' => $this->rssUrlBuilder
+            ]
+        );
+    }
+
+    public function testGetRssData()
+    {
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->will($this->returnValue('http://magento.com/rss/feeds/index/type/notifystock'));
+        $item = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->setMethods(array('__sleep', '__wakeup', 'getId', 'getQty', 'getName'))
+            ->disableOriginalConstructor()
+            ->getMock();
+        $item->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $item->expects($this->once())->method('getQty')->will($this->returnValue(1));
+        $item->expects($this->any())->method('getName')->will($this->returnValue('Low Stock Product'));
+
+        $this->rssModel->expects($this->once())->method('getProductsCollection')
+            ->will($this->returnValue(array($item)));
+        $this->urlBuilder->expects($this->once())->method('getUrl')
+            ->with('catalog/product/edit', array('id' => 1, '_secure' => true, '_nosecret' => true))
+            ->will($this->returnValue('http://magento.com/catalog/product/edit/id/1'));
+        $this->assertEquals($this->rssFeed, $this->block->getRssData());
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(600, $this->block->getCacheLifetime());
+    }
+
+    public function testIsAllowed()
+    {
+        $this->assertTrue($this->block->isAllowed());
+    }
+
+    public function testGetFeeds()
+    {
+        $this->assertEmpty($this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/Rss/LinkTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/Rss/LinkTest.php
new file mode 100644
index 00000000000..334cd74e710
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/Rss/LinkTest.php
@@ -0,0 +1,143 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Category\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class LinkTest
+ * @package Magento\Catalog\Block\Category\Rss
+ */
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Category\Rss\Link
+     */
+    protected $link;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerInterface;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registry;
+
+    protected function setUp()
+    {
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->storeManagerInterface = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->registry = $this->getMock('Magento\Framework\Registry');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->link = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Category\Rss\Link',
+            [
+                'rssUrlBuilder' => $this->urlBuilderInterface,
+                'registry' => $this->registry,
+                'scopeConfig' => $this->scopeConfigInterface,
+                'storeManager' => $this->storeManagerInterface
+            ]
+        );
+    }
+
+    /**
+     * @dataProvider isRssAllowedDataProvider
+     * @param bool $isAllowed
+     */
+    public function testIsRssAllowed($isAllowed)
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')->will($this->returnValue($isAllowed));
+        $this->assertEquals($isAllowed, $this->link->isRssAllowed());
+    }
+
+    public function isRssAllowedDataProvider()
+    {
+        return array(
+            array(true),
+            array(false)
+        );
+    }
+
+    public function testGetLabel()
+    {
+        $this->assertEquals('Subscribe to RSS Feed', $this->link->getLabel());
+    }
+
+    /**
+     * @dataProvider isTopCategoryDataProvider
+     * @param bool $isTop
+     * @param string $categoryLevel
+     */
+    public function testIsTopCategory($isTop, $categoryLevel)
+    {
+        $categoryModel = $this->getMock('\Magento\Catalog\Model\Category', ['__wakeup', 'getLevel'], [], '', false);
+        $this->registry->expects($this->once())->method('registry')->will($this->returnValue($categoryModel));
+        $categoryModel->expects($this->any())->method('getLevel')->will($this->returnValue($categoryLevel));
+        $this->assertEquals($isTop, $this->link->isTopCategory());
+    }
+
+    public function isTopCategoryDataProvider()
+    {
+        return array(
+            array(true, '2'),
+            array(false, '1')
+        );
+    }
+
+    public function testGetLink()
+    {
+        $rssUrl = 'http://rss.magento.com';
+        $this->urlBuilderInterface->expects($this->once())->method('getUrl')->will($this->returnValue($rssUrl));
+
+        $categoryModel = $this->getMock('\Magento\Catalog\Model\Category', ['__wakeup', 'getId'], [], '', false);
+        $this->registry->expects($this->once())->method('registry')->will($this->returnValue($categoryModel));
+        $categoryModel->expects($this->any())->method('getId')->will($this->returnValue('1'));
+
+        $storeModel = $this->getMock('\Magento\Store\Model\Category', ['__wakeup', 'getId'], [], '', false);
+        $this->storeManagerInterface->expects($this->any())->method('getStore')->will($this->returnValue($storeModel));
+        $storeModel->expects($this->any())->method('getId')->will($this->returnValue('1'));
+
+        $this->assertEquals($rssUrl, $this->link->getLink());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/ViewTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/ViewTest.php
index 889873846e4..f8522427598 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/ViewTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Category/ViewTest.php
@@ -30,10 +30,15 @@ class ViewTest extends \PHPUnit_Framework_TestCase
      */
     protected $block;
 
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
     protected function setUp()
     {
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $objectManager->getObject('Magento\Catalog\Block\Category\View');
+        $this->block = $objectManager->getObject('Magento\Catalog\Block\Category\View', []);
     }
 
     protected function tearDown()
@@ -50,3 +55,4 @@ class ViewTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($categoryTag, $this->block->getIdentities());
     }
 }
+
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/CategoryTest.php
new file mode 100644
index 00000000000..1301243af68
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/CategoryTest.php
@@ -0,0 +1,268 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class CategoryTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CategoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Rss\Category
+     */
+    protected $block;
+
+    /**
+     * @var \Magento\Framework\App\Http\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $httpContext;
+
+    /**
+     * @var \Magento\Catalog\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $catalogHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $categoryFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Category|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    /**
+     * @var array
+     */
+    protected $rssFeed = array(
+        'title' => 'Category Name',
+        'description' => 'Category Name',
+        'link' => 'http://magento.com/category-name.html',
+        'charset' => 'UTF-8',
+        'entries' => array(
+            array(
+                'title' => 'Product Name',
+                'link' => 'http://magento.com/product.html',
+            )
+        )
+    );
+
+    protected function setUp()
+    {
+        $this->request = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->request->expects($this->at(0))->method('getParam')->with('cid')->will($this->returnValue(1));
+        $this->request->expects($this->at(1))->method('getParam')->with('store_id')->will($this->returnValue(null));
+
+        $this->httpContext = $this->getMock('Magento\Framework\App\Http\Context');
+        $this->catalogHelper = $this->getMock('Magento\Catalog\Helper\Data', [], [], '', false);
+        $this->categoryFactory = $this->getMockBuilder('Magento\Catalog\Model\CategoryFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()->getMock();
+        $this->rssModel = $this->getMock('Magento\Catalog\Model\Rss\Category', ['getProductCollection'], [], '', false);
+        $this->rssUrlBuilder = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->imageHelper = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
+        $this->customerSession = $this->getMock('Magento\Customer\Model\Session', ['getId'], [], '', false);
+        $this->customerSession->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $store = $this->getMockBuilder('\Magento\Store\Model\Store')
+            ->setMethods(['getId', '__wakeup'])->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $this->scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Rss\Category',
+            [
+                'request' => $this->request,
+                'scopeConfig' => $this->scopeConfig,
+                'httpContext' => $this->httpContext,
+                'catalogData' => $this->catalogHelper,
+                'categoryFactory' => $this->categoryFactory,
+                'rssModel' => $this->rssModel,
+                'rssUrlBuilder' => $this->rssUrlBuilder,
+                'imageHelper' => $this->imageHelper,
+                'customerSession' => $this->customerSession,
+                'storeManager' => $this->storeManager
+            ]
+        );
+    }
+
+    public function testGetRssData()
+    {
+        $category = $this->getMockBuilder('\Magento\Catalog\Model\Category')
+            ->setMethods(['__sleep', '__wakeup', 'load', 'getId', 'getUrl', 'getName'])
+            ->disableOriginalConstructor()->getMock();
+        $category->expects($this->once())->method('load')->will($this->returnSelf());
+        $category->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $category->expects($this->once())->method('getName')->will($this->returnValue('Category Name'));
+        $category->expects($this->once())->method('getUrl')
+            ->will($this->returnValue('http://magento.com/category-name.html'));
+
+        $this->categoryFactory->expects($this->any())->method('create')->will($this->returnValue($category));
+
+        $product = $this->getMockBuilder('\Magento\catalog\Model\Product')
+            ->setMethods([
+                '__sleep',
+                '__wakeup',
+                'getName',
+                'getAllowedInRss',
+                'getProductUrl',
+                'getDescription',
+                'getAllowedPriceInRss'
+            ])->disableOriginalConstructor()->getMock();
+        $product->expects($this->once())->method('getName')->will($this->returnValue('Product Name'));
+        $product->expects($this->once())->method('getAllowedInRss')->will($this->returnValue(true));
+        $product->expects($this->exactly(2))->method('getProductUrl')
+            ->will($this->returnValue('http://magento.com/product.html'));
+        $product->expects($this->once())->method('getDescription')
+            ->will($this->returnValue('Product Description'));
+        $product->expects($this->once())->method('getAllowedPriceInRss')->will($this->returnValue(true));
+
+        $this->rssModel->expects($this->once())->method('getProductCollection')
+            ->will($this->returnValue(array($product)));
+        $this->imageHelper->expects($this->once())->method('init')
+            ->with($product, 'thumbnail')
+            ->will($this->returnSelf());
+        $this->imageHelper->expects($this->once())->method('resize')->with(75, 75)
+            ->will($this->returnValue('image_link'));
+
+        $data = $this->block->getRssData();
+        $this->assertEquals($this->rssFeed['link'], $data['link']);
+        $this->assertEquals($this->rssFeed['title'], $data['title']);
+        $this->assertEquals($this->rssFeed['description'], $data['description']);
+        $this->assertEquals($this->rssFeed['entries'][0]['title'], $data['entries'][0]['title']);
+        $this->assertEquals($this->rssFeed['entries'][0]['link'], $data['entries'][0]['link']);
+        $this->assertContains('<a href="http://magento.com/product.html">', $data['entries'][0]['description']);
+        $this->assertContains(
+            '<img src="image_link" border="0" align="left" height="75" width="75">',
+            $data['entries'][0]['description']
+        );
+
+        $this->assertContains(
+            '<td  style="text-decoration:none;">Product Description </td>',
+            $data['entries'][0]['description']
+        );
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(600, $this->block->getCacheLifetime());
+    }
+
+    public function testIsAllowed()
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')
+            ->with('rss/catalog/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertEquals(true, $this->block->isAllowed());
+    }
+
+    public function testGetFeeds()
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')
+            ->with('rss/catalog/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+
+        $category = $this->getMockBuilder('\Magento\Catalog\Model\Category')
+            ->setMethods(['__sleep', '__wakeup', 'getTreeModel', 'getResourceCollection', 'getId', 'getName'])
+            ->disableOriginalConstructor()->getMock();
+
+        $collection = $this->getMockBuilder('\Magento\Catalog\Model\Resource\Category\Collection')
+            ->setMethods([
+                'addIdFilter',
+                'addAttributeToSelect',
+                'addAttributeToSort',
+                'load',
+                'addAttributeToFilter',
+                'getIterator'
+            ])->disableOriginalConstructor()->getMock();
+        $collection->expects($this->once())->method('addIdFilter')->will($this->returnSelf());
+        $collection->expects($this->exactly(3))->method('addAttributeToSelect')->will($this->returnSelf());
+        $collection->expects($this->once())->method('addAttributeToSort')->will($this->returnSelf());
+        $collection->expects($this->once())->method('addAttributeToFilter')->will($this->returnSelf());
+        $collection->expects($this->once())->method('load')->will($this->returnSelf());
+        $collection->expects($this->once())->method('getIterator')->will($this->returnValue(
+            new \ArrayIterator(array($category))
+        ));
+
+        $category->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $category->expects($this->once())->method('getName')->will($this->returnValue('Category Name'));
+        $category->expects($this->once())->method('getResourceCollection')->will($this->returnValue($collection));
+        $this->categoryFactory->expects($this->once())->method('create')->will($this->returnValue($category));
+
+        $node = new \Magento\Framework\Object(array('id' => 1));
+        $nodes = $this->getMockBuilder('Magento\Framework\Data\Tree\Node')
+            ->setMethods(['getChildren'])->disableOriginalConstructor()->getMock();
+        $nodes->expects($this->once())->method('getChildren')->will($this->returnValue(array($node)));
+
+        $tree = $this->getMockBuilder('\Magento\Catalog\Model\Resource\Category\Tree')
+            ->setMethods(['loadChildren', 'loadNode'])->disableOriginalConstructor()->getMock();
+        $tree->expects($this->once())->method('loadNode')->will($this->returnSelf());
+        $tree->expects($this->once())->method('loadChildren')->will($this->returnValue($nodes));
+
+        $category->expects($this->once())->method('getTreeModel')->will($this->returnValue($tree));
+        $category->expects($this->once())->method('getResourceCollection')->will($this->returnValue(''));
+
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->will($this->returnValue('http://magento.com/category-name.html'));
+        $feeds = array('group' => 'Categories', 'feeds' => array(
+            array('label' => 'Category Name', 'link' => 'http://magento.com/category-name.html')
+        ));
+        $this->assertEquals($feeds, $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/NewProductsTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/NewProductsTest.php
new file mode 100644
index 00000000000..3c43f17cf83
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/NewProductsTest.php
@@ -0,0 +1,204 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss\Product;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class NewProductsTest
+ * @package Magento\Catalog\Block\Rss\Product
+ */
+class NewProductsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Rss\Product\NewProducts
+     */
+    protected $block;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NewProducts|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $newProducts;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    protected function setUp()
+    {
+        $this->request = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->request->expects($this->any())->method('getParam')->with('store_id')->will($this->returnValue(null));
+
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->imageHelper = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
+        $this->newProducts = $this->getMock('Magento\Catalog\Model\Rss\Product\NewProducts', [], [], '', false);
+        $this->rssUrlBuilder = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $this->storeManager = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $store = $this->getMockBuilder('\Magento\Store\Model\Store')
+            ->setMethods(['getId', 'getFrontendName', '__wakeup'])->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $store->expects($this->any())->method('getFrontendName')->will($this->returnValue('Store 1'));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Rss\Product\NewProducts',
+            [
+                'request' => $this->request,
+                'imageHelper' => $this->imageHelper,
+                'rssModel' => $this->newProducts,
+                'rssUrlBuilder' => $this->rssUrlBuilder,
+                'storeManager' => $this->storeManager,
+                'scopeConfig' => $this->scopeConfig,
+            ]
+        );
+    }
+
+    public function isAllowedDataProvider()
+    {
+        return array(
+            array(1, true),
+            array(0, false)
+        );
+    }
+    /**
+     * @dataProvider isAllowedDataProvider
+     */
+    public function testIsAllowed($configValue, $expectedResult)
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')->will($this->returnValue($configValue));
+        $this->assertEquals($expectedResult, $this->block->isAllowed());
+    }
+
+    protected function getItemMock()
+    {
+        $methods = [
+            'setAllowedInRss',
+            'setAllowedPriceInRss',
+            'getAllowedPriceInRss',
+            'getAllowedInRss',
+            'getProductUrl',
+            'getDescription',
+            'getName',
+            '__wakeup'
+        ];
+        $item = $this->getMock('\Magento\Catalog\Model\Product', $methods, [], '', false);
+        $item->expects($this->once())->method('setAllowedInRss')->with(true);
+        $item->expects($this->once())->method('setAllowedPriceInRss')->with(true);
+        $item->expects($this->once())->method('getAllowedPriceInRss')->will($this->returnValue(true));
+        $item->expects($this->once())->method('getAllowedInRss')->will($this->returnValue(true));
+        $item->expects($this->once())->method('getDescription')->will($this->returnValue('Product Description'));
+        $item->expects($this->once())->method('getName')->will($this->returnValue('Product Name'));
+        $item->expects($this->any())->method('getProductUrl')->will(
+            $this->returnValue('http://magento.com/product-name.html')
+        );
+        return $item;
+    }
+
+    public function testGetRssData()
+    {
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->with(array('type' => 'new_products', 'store_id' => 1))
+            ->will($this->returnValue('http://magento.com/rss/feed/index/type/new_products/store_id/1'));
+        $item = $this->getItemMock();
+        $this->newProducts->expects($this->once())->method('getProductsCollection')
+            ->will($this->returnValue([$item]));
+        $this->imageHelper->expects($this->once())->method('init')->with($item, 'thumbnail')
+            ->will($this->returnSelf());
+        $this->imageHelper->expects($this->once())->method('resize')->with(75, 75)
+            ->will($this->returnValue('image_link'));
+        $data = array(
+            'title' => 'New Products from Store 1',
+            'description' => 'New Products from Store 1',
+            'link' => 'http://magento.com/rss/feed/index/type/new_products/store_id/1',
+            'charset' => 'UTF-8',
+            'language' => null,
+            'entries' => array(
+                array(
+                    'title' => 'Product Name',
+                    'link' => 'http://magento.com/product-name.html',
+                )
+            )
+        );
+        $rssData = $this->block->getRssData();
+        $description = $rssData['entries'][0]['description'];
+        unset($rssData['entries'][0]['description']);
+        $this->assertEquals($data, $rssData);
+        $this->assertContains('<a href="http://magento.com/product-name.html">', $description);
+        $this->assertContains('<img src="image_link" border="0" align="left" height="75" width="75">', $description);
+        $this->assertContains('<td style="text-decoration:none;">Product Description </td>', $description);
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(600, $this->block->getCacheLifetime());
+    }
+
+    public function testGetFeeds()
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')->will($this->returnValue(true));
+        $rssUrl ='http://magento.com/rss/feed/index/type/new_products/store_id/1';
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->with(array('type' => 'new_products'))
+            ->will($this->returnValue($rssUrl));
+        $expected = array(
+            'label' => 'New Products',
+            'link' => $rssUrl
+        );
+        $this->assertEquals($expected, $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/SpecialTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/SpecialTest.php
new file mode 100644
index 00000000000..0b04d798631
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Rss/Product/SpecialTest.php
@@ -0,0 +1,246 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Rss\Product;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class SpecialTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class SpecialTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Block\Rss\Product\Special
+     */
+    protected $block;
+
+    /**
+     * @var \Magento\Framework\App\Http\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $httpContext;
+
+    /**
+     * @var \Magento\Catalog\Helper\Image|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $imageHelper;
+
+    /**
+     * @var \Magento\Catalog\Helper\Output|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $outputHelper;
+
+    /**
+     * @var \Magento\Catalog\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $catalogHelper;
+
+    /**
+     * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceCurrency;
+
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\Special|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssUrlBuilder;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeDate;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    protected function setUp()
+    {
+        $this->request = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->request->expects($this->at(0))->method('getParam')->with('store_id')->will($this->returnValue(null));
+        $this->request->expects($this->at(1))->method('getParam')->with('cid')->will($this->returnValue(null));
+
+        $this->httpContext = $this->getMockBuilder('Magento\Framework\App\Http\Context')
+            ->setMethods(['getValue'])->disableOriginalConstructor()->getMock();
+        $this->httpContext->expects($this->any())->method('getValue')->will($this->returnValue(1));
+
+        $this->imageHelper = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
+        $this->outputHelper = $this->getMock('Magento\Catalog\Helper\Output', ['productAttribute'], [], '', false);
+        $this->catalogHelper = $this->getMock('Magento\Catalog\Helper\Data', ['canApplyMsrp'], [], '', false);
+        $this->priceCurrency = $this->getMock('Magento\Framework\Pricing\PriceCurrencyInterface');
+        $this->rssModel = $this->getMock('Magento\Catalog\Model\Rss\Product\Special', [], [], '', false);
+        $this->rssUrlBuilder = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $store = $this->getMockBuilder('\Magento\Store\Model\Store')
+            ->setMethods(['getId', 'getFrontendName', '__wakeup'])->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $store->expects($this->any())->method('getFrontendName')->will($this->returnValue('Store 1'));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+
+        $this->scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->scopeConfig->expects($this->any())->method('getValue')->will($this->returnValue('en_US'));
+
+        $this->localeDate = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Rss\Product\Special',
+            [
+                'request' => $this->request,
+                'httpContext' => $this->httpContext,
+                'imageHelper' => $this->imageHelper,
+                'outputHelper' => $this->outputHelper,
+                'catalogHelper' => $this->catalogHelper,
+                'priceCurrency' => $this->priceCurrency,
+                'rssModel' => $this->rssModel,
+                'rssUrlBuilder' => $this->rssUrlBuilder,
+                'storeManager' => $this->storeManager,
+                'scopeConfig' => $this->scopeConfig,
+                'localeDate' => $this->localeDate
+            ]
+        );
+    }
+
+    public function testGetRssData()
+    {
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->with(array('type' => 'special_products', 'store_id' => 1))
+            ->will($this->returnValue('http://magento.com/rss/feed/index/type/special_products/store_id/1'));
+        $item = $this->getItemMock();
+        $this->rssModel->expects($this->once())->method('getProductsCollection')
+            ->will($this->returnValue(array($item)));
+        $this->catalogHelper->expects($this->once())->method('canApplyMsrp')->will($this->returnValue(false));
+        $this->localeDate->expects($this->once())->method('formatDate')->will($this->returnValue(date('Y-m-d')));
+
+        $this->priceCurrency->expects($this->any())->method('convertAndFormat')->will($this->returnArgument(0));
+
+        $this->imageHelper->expects($this->once())->method('init')->with($item, 'thumbnail')
+            ->will($this->returnSelf());
+        $this->imageHelper->expects($this->once())->method('resize')->with(75, 75)
+            ->will($this->returnValue('image_link'));
+        $this->outputHelper->expects($this->once())->method('productAttribute')->will($this->returnValue(''));
+        $data = array(
+            'title' => 'Store 1 - Special Products',
+            'description' => 'Store 1 - Special Products',
+            'link' => 'http://magento.com/rss/feed/index/type/special_products/store_id/1',
+            'charset' => 'UTF-8',
+            'language' => 'en_US',
+            'entries' => array(
+                array(
+                    'title' => 'Product Name',
+                    'link' => 'http://magento.com/product-name.html'
+                )
+            )
+        );
+        $rssData = $this->block->getRssData();
+        $description = $rssData['entries'][0]['description'];
+        unset($rssData['entries'][0]['description']);
+        $this->assertEquals($data, $rssData);
+        $this->assertContains('<a href="http://magento.com/product-name.html"><', $description);
+        $this->assertContains(
+            sprintf('<p>Price:  Special Price: 10<br />Special Expires On: %s</p>', date('Y-m-d')),
+            $description
+        );
+        $this->assertContains(
+            '<img src="image_link" alt="" border="0" align="left" height="75" width="75" />',
+            $description
+        );
+    }
+
+    protected function getItemMock()
+    {
+        $item = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->setMethods([
+                '__wakeup',
+                '__sleep',
+                'getName',
+                'getProductUrl',
+                'getDescription',
+                'getAllowedInRss',
+                'getAllowedPriceInRss',
+                'getSpecialToDate',
+                'getSpecialPrice',
+                'getFinalPrice',
+                'getPrice',
+                'getUseSpecial'
+            ])->disableOriginalConstructor()->getMock();
+        $item->expects($this->once())->method('getAllowedInRss')->will($this->returnValue(true));
+        $item->expects($this->exactly(3))->method('getSpecialToDate')->will($this->returnValue(date('Y-m-d')));
+        $item->expects($this->exactly(2))->method('getFinalPrice')->will($this->returnValue(10));
+        $item->expects($this->once())->method('getSpecialPrice')->will($this->returnValue(15));
+        $item->expects($this->exactly(2))->method('getAllowedPriceInRss')->will($this->returnValue(true));
+        $item->expects($this->once())->method('getUseSpecial')->will($this->returnValue(true));
+        $item->expects($this->once())->method('getDescription')->will($this->returnValue('Product Description'));
+        $item->expects($this->once())->method('getName')->will($this->returnValue('Product Name'));
+        $item->expects($this->exactly(2))->method('getProductUrl')
+            ->will($this->returnValue('http://magento.com/product-name.html'));
+
+        return $item;
+    }
+
+    public function testIsAllowed()
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')
+            ->with('rss/catalog/special', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertEquals(true, $this->block->isAllowed());
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(600, $this->block->getCacheLifetime());
+    }
+
+    public function testGetFeeds()
+    {
+        $this->scopeConfig->expects($this->once())->method('isSetFlag')
+            ->with('rss/catalog/special', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->rssUrlBuilder->expects($this->once())->method('getUrl')
+            ->with(array('type' => 'special_products'))
+            ->will($this->returnValue('http://magento.com/rss/feed/index/type/special_products/store_id/1'));
+        $expected = array(
+            'label' => 'Special Products',
+            'link' => 'http://magento.com/rss/feed/index/type/special_products/store_id/1'
+        );
+        $this->assertEquals($expected, $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Widget/LinkTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Widget/LinkTest.php
new file mode 100644
index 00000000000..84b58dcd75e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Widget/LinkTest.php
@@ -0,0 +1,196 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Block\Widget;
+
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\UrlRewrite\Model\UrlFinderInterface
+     */
+    protected $urlFinder;
+
+    /**
+     * @var \Magento\Catalog\Block\Widget\Link
+     */
+    protected $block;
+
+    protected function setUp()
+    {
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->urlFinder = $this->getMock('Magento\UrlRewrite\Model\UrlFinderInterface');
+
+        $context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $context->expects($this->any())
+            ->method('getStoreManager')
+            ->will($this->returnValue($this->storeManager));
+
+        $this->block = (new ObjectManager($this))->getObject('Magento\Catalog\Block\Widget\Link', [
+            'context' => $context,
+            'urlFinder' => $this->urlFinder,
+        ]);
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     * @expectedExceptionMessage Parameter id_path is not set.
+     */
+    public function testGetHrefWithoutSetIdPath()
+    {
+        $this->block->getHref();
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     * @expectedExceptionMessage Wrong id_path structure.
+     */
+    public function testGetHrefIfSetWrongIdPath()
+    {
+        $this->block->setData('id_path', 'wrong_id_path');
+        $this->block->getHref();
+    }
+
+    public function testGetHrefWithSetStoreId()
+    {
+        $this->block->setData('id_path', 'type/id');
+        $this->block->setData('store_id', 'store_id');
+
+        $this->storeManager->expects($this->once())
+            ->method('getStore')->with('store_id')
+            // interrupt test execution
+            ->will($this->throwException(new \Exception()));
+
+        try {
+            $this->block->getHref();
+        } catch (\Exception $e) {
+        }
+    }
+
+    public function testGetHrefIfRewriteIsNotFound()
+    {
+        $this->block->setData('id_path', 'entity_type/entity_id');
+
+        $store = $this->getMock('Magento\Store\Model\Store', ['getId', '__wakeUp'], [], '', false);
+        $store->expects($this->any())
+            ->method('getId');
+
+        $this->storeManager->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
+        $this->urlFinder->expects($this->once())->method('findOneByData')
+            ->will($this->returnValue(false));
+
+        $this->assertFalse($this->block->getHref());
+    }
+
+    /**
+     * @param string $url
+     * @param string $separator
+     * @dataProvider dataProviderForTestGetHrefWithoutUrlStoreSuffix
+     */
+    public function testGetHrefWithoutUrlStoreSuffix($url, $separator)
+    {
+        $storeId = 15;
+        $storeCode = 'store-code';
+        $requestPath = 'request-path';
+        $this->block->setData('id_path', 'entity_type/entity_id');
+
+        $rewrite = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewrite', [], [], '', false);
+        $rewrite->expects($this->once())
+            ->method('getRequestPath')
+            ->will($this->returnValue($requestPath));
+
+        $store = $this->getMock('Magento\Store\Model\Store', ['getId', 'getUrl', 'getCode', '__wakeUp'], [], '', false);
+        $store->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+        $store->expects($this->once())
+            ->method('getUrl')
+            ->with('', ['_direct' => $requestPath])
+            ->will($this->returnValue($url));
+        $store->expects($this->once())
+            ->method('getCode')
+            ->will($this->returnValue($storeCode));
+
+        $this->storeManager->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
+        $this->urlFinder->expects($this->once())->method('findOneByData')
+            ->with([
+                    UrlRewrite::ENTITY_ID => 'entity_id',
+                    UrlRewrite::ENTITY_TYPE => 'entity_type',
+                    UrlRewrite::STORE_ID => $storeId,
+                ])
+            ->will($this->returnValue($rewrite));
+
+        $this->assertEquals($url . $separator . '___store=' . $storeCode, $this->block->getHref());
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderForTestGetHrefWithoutUrlStoreSuffix()
+    {
+        return [
+            ['url', '?'],
+            ['url?some_parameter', '&'],
+        ];
+    }
+
+    public function testGetHrefWithForProductWithCategoryIdParameter()
+    {
+        $storeId = 15;
+        $this->block->setData('id_path', ProductUrlRewriteGenerator::ENTITY_TYPE . '/entity_id/category_id');
+
+        $store = $this->getMock('Magento\Store\Model\Store', ['getId', '__wakeUp'], [], '', false);
+        $store->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+
+        $this->storeManager->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
+        $this->urlFinder->expects($this->once())->method('findOneByData')
+            ->with([
+                UrlRewrite::ENTITY_ID => 'entity_id',
+                UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+                UrlRewrite::STORE_ID => $storeId,
+                UrlRewrite::METADATA => ['category_id' => 'category_id'],
+            ])
+            ->will($this->returnValue(false));
+
+        $this->block->getHref();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
index 4079abca16e..b16bb19a0cc 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
@@ -150,7 +150,6 @@ class HelperTest extends \PHPUnit_Framework_TestCase
 
         $productData = array(
             'stock_data' => array('stock_data'),
-            'url_key_create_redirect' => true,
             'options' => array('option1', 'option2')
         );
 
@@ -209,26 +208,10 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             ->method('addData')
             ->with($productData);
 
-        $this->productMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue(true));
-
         $this->productMock->expects($this->once())
             ->method('setWebsiteIds')
             ->with(array($this->websiteId));
 
-        $this->productMock->expects($this->at(6))
-            ->method('setData')
-            ->with('save_rewrites_history', true);
-
-        $this->productMock->expects($this->at(7))
-            ->method('setData')
-            ->with('attributeCode1', false);
-
-        $this->productMock->expects($this->at(8))
-            ->method('setData')
-            ->with('attributeCode2', false);
-
         $this->productMock->expects($this->any())
             ->method('getOptionsReadOnly')
             ->will($this->returnValue(false));
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/CategoryTest.php
index 301a1ecc68e..d1b23374eed 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/CategoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/CategoryTest.php
@@ -40,11 +40,29 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $filter;
 
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Category\Flat\State|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $flatState;
+
     protected function setUp()
     {
         $this->filter = $this->getMock('Magento\Framework\Filter\FilterManager', ['translitUrl'], [], '', false);
+        $this->flatState = $this->getMock(
+            'Magento\Catalog\Model\Indexer\Category\Flat\State',
+            ['isAvailable'],
+            [],
+            '',
+            false
+        );
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $this->objectManager->getObject('Magento\Catalog\Model\Category', ['filter' => $this->filter]);
+        $this->model = $this->objectManager->getObject(
+            'Magento\Catalog\Model\Category',
+            [
+                'filter' => $this->filter,
+                'flatState' => $this->flatState,
+            ]
+        );
     }
 
     /**
@@ -112,4 +130,26 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($resultString, $this->model->formatUrlKey($strIn));
     }
+
+    public function testGetUseFlatResourceFalse()
+    {
+        $this->assertEquals(false, $this->model->getUseFlatResource());
+    }
+
+    public function testGetUseFlatResourceTrue()
+    {
+        $this->flatState->expects($this->any())
+            ->method('isAvailable')
+            ->will($this->returnValue(true));
+
+        $this->model = $this->objectManager->getObject(
+            'Magento\Catalog\Model\Category',
+            [
+                'filter' => $this->filter,
+                'flatState' => $this->flatState,
+            ]
+        );
+
+        $this->assertEquals(true, $this->model->getUseFlatResource());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
index 1598fd47fa1..9dc1cf35202 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
@@ -69,8 +69,13 @@ class CustomerGroupTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('return_value', $this->_model->afterDeleteGroup($this->_subjectMock, 'return_value'));
     }
 
-    public function testAroundSave()
+    public function testAroundCreate()
     {
-        $this->assertEquals('return_value', $this->_model->afterSaveGroup($this->_subjectMock, 'return_value'));
+        $this->assertEquals('return_value', $this->_model->afterCreateGroup($this->_subjectMock, 'return_value'));
+    }
+
+    public function testAroundUpdate()
+    {
+        $this->assertEquals('return_value', $this->_model->afterUpdateGroup($this->_subjectMock, 'return_value'));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
new file mode 100644
index 00000000000..4856d5b8fa9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
@@ -0,0 +1,196 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Model;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Observer
+     */
+    protected $_observer;
+
+    /**
+     * @var \Magento\Catalog\Helper\Category
+     */
+    protected $_catalogCategory;
+
+    /**
+     * @var \Magento\Catalog\Model\Category
+     */
+    protected $_category;
+
+    /**
+     * @var \Magento\Catalog\Model\Category
+     */
+    protected $_childrenCategory;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Category\Flat\State
+     */
+    protected $_categoryFlatState;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $_storeManager;
+
+    public function setUp()
+    {
+        $this->_catalogCategory = $this->getMock(
+            '\Magento\Catalog\Helper\Category',
+            ['getStoreCategories', 'getCategoryUrl'],
+            [],
+            '',
+            false
+        );
+
+        $this->_categoryFlatState = $this->getMock(
+            '\Magento\Catalog\Model\Indexer\Category\Flat\State',
+            ['isFlatEnabled'],
+            [],
+            '',
+            false
+        );
+
+        $this->_storeManager = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_observer = (new ObjectManager($this))->getObject('\Magento\Catalog\Model\Observer', [
+            'urlFactory' => $this->_getCleanMock('\Magento\Catalog\Model\UrlFactory'),
+            'categoryResource' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Category'),
+            'catalogProduct' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Product'),
+            'storeManager' => $this->_storeManager,
+            'catalogLayer' => $this->_getCleanMock('\Magento\Catalog\Model\Layer\Category'),
+            'indexIndexer' => $this->_getCleanMock('\Magento\Index\Model\Indexer'),
+            'catalogCategory' => $this->_catalogCategory,
+            'catalogData' => $this->_getCleanMock('\Magento\Catalog\Helper\Data'),
+            'categoryFlatState' => $this->_categoryFlatState,
+            'productResourceFactory' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\ProductFactory'),
+        ]);
+    }
+
+    /**
+     * Get clean mock by class name
+     *
+     * @param string $className
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getCleanMock($className)
+    {
+        return $this->getMock($className, [], [], '', false);
+    }
+
+    protected function _preparationData()
+    {
+        $this->_childrenCategory = $this->getMock(
+            '\Magento\Catalog\Model\Category',
+            ['getIsActive', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $this->_childrenCategory->expects($this->once())
+            ->method('getIsActive')
+            ->will($this->returnValue(false));
+
+        $this->_category = $this->getMock(
+            '\Magento\Catalog\Model\Category',
+            ['getIsActive', '__wakeup', 'getName', 'getChildren', 'getUseFlatResource', 'getChildrenNodes'],
+            [],
+            '',
+            false
+        );
+        $this->_category->expects($this->once())
+            ->method('getIsActive')
+            ->will($this->returnValue(true));
+        $this->_category->expects($this->once())
+            ->method('getName')
+            ->will($this->returnValue('Name'));
+
+        $this->_catalogCategory->expects($this->once())
+            ->method('getStoreCategories')
+            ->will($this->returnValue(array($this->_category)));
+        $this->_catalogCategory->expects($this->once())
+            ->method('getCategoryUrl')
+            ->will($this->returnValue('url'));
+
+        $blockMock = $this->_getCleanMock('\Magento\Theme\Block\Html\Topmenu');
+
+        $treeMock = $this->_getCleanMock('\Magento\Framework\Data\Tree');
+
+        $menuMock = $this->getMock('\Magento\Framework\Data\Tree\Node', ['getTree', 'addChild'], [], '', false);
+        $menuMock->expects($this->once())
+            ->method('getTree')
+            ->will($this->returnValue($treeMock));
+
+        $eventMock = $this->getMock('\Magento\Framework\Event', ['getBlock'], [], '', false);
+        $eventMock->expects($this->once())
+            ->method('getBlock')
+            ->will($this->returnValue($blockMock));
+
+        $observerMock = $this->getMock('\Magento\Framework\Event\Observer', ['getEvent', 'getMenu'], [], '', false);
+        $observerMock->expects($this->once())
+            ->method('getEvent')
+            ->will($this->returnValue($eventMock));
+        $observerMock->expects($this->once())
+            ->method('getMenu')
+            ->will($this->returnValue($menuMock));
+
+        return $observerMock;
+    }
+
+    public function testAddCatalogToTopMenuItemsWithoutFlat()
+    {
+        $observer = $this->_preparationData();
+
+        $this->_category->expects($this->once())
+            ->method('getChildren')
+            ->will($this->returnValue(array($this->_childrenCategory)));
+
+        $this->_observer->addCatalogToTopmenuItems($observer);
+    }
+
+    public function testAddCatalogToTopMenuItemsWithFlat()
+    {
+        $observer = $this->_preparationData();
+
+        $this->_category->expects($this->once())
+            ->method('getChildrenNodes')
+            ->will($this->returnValue(array($this->_childrenCategory)));
+
+        $this->_category->expects($this->once())
+            ->method('getUseFlatResource')
+            ->will($this->returnValue(true));
+
+        $this->_categoryFlatState->expects($this->once())
+            ->method('isFlatEnabled')
+            ->will($this->returnValue(true));
+
+        $this->_observer->addCatalogToTopmenuItems($observer);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
index b79481348a6..f7a42576989 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
@@ -45,11 +45,6 @@ class ActionTest extends \PHPUnit_Framework_TestCase
      */
     protected $productWebsite;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $indexIndexer;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -93,13 +88,6 @@ class ActionTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('create')
             ->will($this->returnValue($this->productWebsite));
-        $this->indexIndexer = $this->getMock(
-            '\Magento\Index\Model\Indexer',
-            ['processEntityAction', '__wakeup'],
-            [],
-            '',
-            false
-        );
         $this->categoryIndexer = $this->getMock(
             '\Magento\Indexer\Model\Indexer',
             ['getId', 'load', 'isScheduled', 'reindexList'],
@@ -128,7 +116,6 @@ class ActionTest extends \PHPUnit_Framework_TestCase
                 'eventDispatcher' => $eventManagerMock,
                 'resource' => $this->resource,
                 'productWebsiteFactory' => $this->productWebsiteFactory,
-                'indexIndexer' => $this->indexIndexer,
                 'categoryIndexer' => $this->categoryIndexer,
                 'eavConfig' => $this->eavConfig
             ]
@@ -146,10 +133,7 @@ class ActionTest extends \PHPUnit_Framework_TestCase
             ->method('updateAttributes')
             ->with($productIds, $attrData, $storeId)
             ->will($this->returnSelf());
-        $this->indexIndexer
-            ->expects($this->any())
-            ->method('processEntityAction')
-            ->with($this->model, 'catalog_product', 'mass_action');
+
         $this->categoryIndexer
             ->expects($this->any())
             ->method('getId')
@@ -196,10 +180,7 @@ class ActionTest extends \PHPUnit_Framework_TestCase
             ->method($methodName)
             ->with($websiteIds, $productIds)
             ->will($this->returnSelf());
-        $this->indexIndexer
-            ->expects($this->any())
-            ->method('processEntityAction')
-            ->with($this->model, 'catalog_product', 'mass_action');
+
         $this->categoryIndexer
             ->expects($this->any())
             ->method('getId')
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/UrlkeyTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/UrlkeyTest.php
deleted file mode 100644
index fb24ac7b9bb..00000000000
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/UrlkeyTest.php
+++ /dev/null
@@ -1,93 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Product\Attribute\Backend;
-
-use Magento\Framework\Object;
-use Magento\TestFramework\Helper\ObjectManager;
-
-class UrlkeyTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Model\Product\Attribute\Backend\Urlkey
-     */
-    private $model;
-
-    /**
-     * @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $attribute;
-
-    protected function setUp()
-    {
-
-        $this->attribute = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\AbstractAttribute')
-            ->setMethods(['__wakeup', 'getName'])
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
-        $helper = new ObjectManager($this);
-        $this->model = $helper->getObject('Magento\Catalog\Model\Product\Attribute\Backend\Urlkey');
-        $this->model->setAttribute($this->attribute);
-    }
-
-    /**
-     * @param bool|string $objData
-     * @dataProvider beforeSaveProvider
-     */
-    public function testBeforeSave($objData)
-    {
-        $attributeName = 'attr';
-        $this->attribute->expects($this->once())->method('getName')->will($this->returnValue($attributeName));
-
-        /** @var \Magento\Catalog\Model\Product\Url|\PHPUnit_Framework_MockObject_MockObject $object */
-        $object = $this->getMockBuilder('Magento\Catalog\Model\Product\Url')
-            ->setMethods(['getName', 'getData', 'setData', 'formatUrlKey'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $object->expects($this->once())->method('getData')->with($this->equalTo($attributeName))->will(
-            $this->returnValue($objData)
-        );
-        $object->expects($this->any())->method('getName')->will($this->returnValue('testData'));
-        $object->expects($this->any())->method('setData')->with(
-            $this->equalTo($attributeName),
-            $this->logicalOr($this->equalTo('testData'), $this->equalTo('someData'))
-        );
-        $object->expects($this->any())->method('formatUrlKey')->with(
-            $this->logicalOr($this->equalTo('testData'), $this->equalTo('someData'))
-        )->will(
-                $this->returnCallback(
-                    function ($data) {
-                        return $data;
-                    }
-                )
-            );
-
-        $this->model->beforeSave($object);
-    }
-
-    public function beforeSaveProvider()
-    {
-        return [[false], [''], ['someData']];
-    }
-} 
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php
deleted file mode 100644
index e0cf332202c..00000000000
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/EnabledTest.php
+++ /dev/null
@@ -1,69 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type;
-
-use Magento\TestFramework\Helper\ObjectManager;
-
-class EnabledTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled
-     */
-    protected $_model;
-
-    public function setUp()
-    {
-        $objectManager = new ObjectManager($this);
-        $this->_model = $objectManager->getObject('Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled');
-    }
-
-    public function testGetFlatColumns()
-    {
-        $abstractAttributeMock = $this->getMock(
-            '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
-            array('getAttributeCode', '__wakeup'),
-            array(),
-            '',
-            false
-        );
-
-        $abstractAttributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('code'));
-
-        $this->_model->setAttribute($abstractAttributeMock);
-
-        $flatColumns = $this->_model->getFlatColumns();
-
-        $this->assertTrue(is_array($flatColumns), 'FlatColumns must be an array value');
-        $this->assertTrue(!empty($flatColumns), 'FlatColumns must be not empty');
-        foreach ($flatColumns as $result) {
-            $this->assertArrayHasKey('unsigned', $result, 'FlatColumns must have "unsigned" column');
-            $this->assertArrayHasKey('default', $result, 'FlatColumns must have "default" column');
-            $this->assertArrayHasKey('extra', $result, 'FlatColumns must have "extra" column');
-            $this->assertArrayHasKey('type', $result, 'FlatColumns must have "type" column');
-            $this->assertArrayHasKey('nullable', $result, 'FlatColumns must have "nullable" column');
-            $this->assertArrayHasKey('comment', $result, 'FlatColumns must have "comment" column');
-            $this->assertArrayHasKey('length', $result, 'FlatColumns must have "length" column');
-        }
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/CopierTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/CopierTest.php
index 3462d0b4001..92fa476de80 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/CopierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/CopierTest.php
@@ -85,7 +85,9 @@ class CopierTest extends \PHPUnit_Framework_TestCase
                 'setId',
                 'setStoreId',
                 'getId',
-                'save'
+                'save',
+                'setUrlKey',
+                'getUrlKey',
             ),
             array(),
             '',
@@ -113,16 +115,14 @@ class CopierTest extends \PHPUnit_Framework_TestCase
             \Magento\Store\Model\Store::DEFAULT_STORE_ID
         );
         $duplicateMock->expects($this->once())->method('setData')->with('product data');
-
-
-
         $this->copyConstructorMock->expects($this->once())->method('build')->with($this->productMock, $duplicateMock);
-
+        $duplicateMock->expects($this->once())->method('getUrlKey')->willReturn('urk-key-1');
+        $duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2');
         $duplicateMock->expects($this->once())->method('save');
         $duplicateMock->expects($this->any())->method('getId')->will($this->returnValue(2));
-
         $optionMock->expects($this->once())->method('duplicate')->with(1, 2);
         $resourceMock->expects($this->once())->method('duplicate')->with(1, 2);
+
         $this->assertEquals($duplicateMock, $this->_model->copy($this->productMock));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/UrlTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/UrlTest.php
index 0e4140e5b1a..90c9906452e 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/UrlTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/UrlTest.php
@@ -36,9 +36,9 @@ class UrlTest extends \PHPUnit_Framework_TestCase
     protected $filter;
 
     /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\UrlRewrite\Model\UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $urlRewrite;
+    protected $urlFinder;
 
     /**
      * @var \Magento\Catalog\Helper\Category|\PHPUnit_Framework_MockObject_MockObject
@@ -63,18 +63,9 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             ['translitUrl']
         )->getMock();
 
-        $rewriteFactory = $this->getMockBuilder(
-            'Magento\UrlRewrite\Model\UrlRewriteFactory'
-        )->disableOriginalConstructor()->setMethods(
-            ['create']
-        )->getMock();
-
-        $this->urlRewrite = $this->getMockBuilder(
-            'Magento\UrlRewrite\Model\UrlRewrite'
-        )->disableOriginalConstructor()->setMethods(
-            ['setStoreId', 'getRequestPath', 'loadByIdPath', 'getId', '__wakeup']
-        )->getMock();
-        $rewriteFactory->expects($this->once())->method('create')->will($this->returnValue($this->urlRewrite));
+        $this->urlFinder = $this->getMockBuilder(
+            'Magento\UrlRewrite\Model\UrlFinderInterface'
+        )->disableOriginalConstructor()->getMock();
 
         $this->catalogCategory = $this->getMockBuilder(
             'Magento\Catalog\Helper\Category'
@@ -99,7 +90,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $this->model = $objectManager->getObject(
             'Magento\Catalog\Model\Product\Url',
             [
-                'urlRewriteFactory' => $rewriteFactory,
                 'filter' => $this->filter,
                 'catalogCategory' => $this->catalogCategory,
                 'storeManager' => $storeManager,
@@ -127,41 +117,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($resultString, $this->model->formatUrlKey($strIn));
     }
 
-    /**
-     * @expectedException \Magento\Framework\Model\Exception
-     * @expectedExceptionMessage Invalid category object supplied
-     */
-    public function testGetUrlPath()
-    {
-        $urlPathProduct = '/some/url/path';
-        $urlPathCategory = '/some/url/path/category';
-
-        $product = $this->getMockBuilder(
-            'Magento\Catalog\Model\Product'
-        )->disableOriginalConstructor()->setMethods(
-            ['getData', '__wakeup']
-        )->getMock();
-        $product->expects($this->atLeastOnce())
-            ->method('getData')
-            ->with('url_path')
-            ->will($this->returnValue($urlPathProduct));
-        $category = $this->getMockBuilder(
-            'Magento\Catalog\Model\Category'
-        )->disableOriginalConstructor()->setMethods(
-            ['getUrlPath', '__wakeup']
-        )->getMock();
-        $category->expects($this->atLeastOnce())->method('getUrlPath')->will($this->returnValue($urlPathCategory));
-        $this->catalogCategory
-            ->expects($this->atLeastOnce())
-            ->method('getCategoryUrlPath')
-            ->with($urlPathCategory)
-            ->will($this->returnValue($urlPathCategory));
-
-        $this->assertEquals($urlPathProduct, $this->model->getUrlPath($product));
-        $this->assertEquals($urlPathCategory . '/' . $urlPathProduct, $this->model->getUrlPath($product, $category));
-        $this->model->getUrlPath($product, 1);
-    }
-
     /**
      * @dataProvider getUrlDataProvider
      * @covers Magento\Catalog\Model\Product\Url::getUrl
@@ -175,9 +130,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
      * @param $categoryId
      * @param $routeParams
      * @param $routeParamsUrl
-     * @param $entityId
-     * @param $idPath
-     * @param $requestPathUrlRewrite
      * @param $productId
      * @param $productUrlKey
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -190,9 +142,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $categoryId,
         $routeParams,
         $routeParamsUrl,
-        $entityId,
-        $idPath,
-        $requestPathUrlRewrite,
         $productId,
         $productUrlKey
     ) {
@@ -205,10 +154,9 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $product->expects($this->any())->method('getStoreId')->will($this->returnValue($storeId));
         $product->expects($this->any())->method('getCategoryId')->will($this->returnValue($categoryId));
         $product->expects($this->any())->method('getRequestPath')->will($this->returnValue($requestPathProduct));
-        $product->expects($this->any())->method('getEntityId')->will($this->returnValue($entityId));
         $product->expects($this->any())
             ->method('setRequestPath')
-            ->with($requestPathUrlRewrite)
+            ->with(false)
             ->will($this->returnSelf());
         $product->expects($this->any())->method('getId')->will($this->returnValue($productId));
         $product->expects($this->any())->method('getUrlKey')->will($this->returnValue($productUrlKey));
@@ -217,13 +165,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
             ->method('getUrl')
             ->with($routePath, $routeParamsUrl)
             ->will($this->returnValue($requestPathProduct));
-        $this->urlRewrite->expects($this->any())->method('setStoreId')->with($storeId)->will($this->returnSelf());
-        $this->urlRewrite->expects($this->any())->method('loadByIdPath')->with($idPath)->will($this->returnSelf());
-        $this->urlRewrite->expects($this->any())->method('getId')->will($this->returnSelf());
-        $this->urlRewrite
-            ->expects($this->any())
-            ->method('getRequestPath')
-            ->will($this->returnValue($requestPathUrlRewrite));
+        $this->urlFinder->expects($this->any())->method('findOneByData')->will($this->returnValue(false));
 
         switch ($getUrlMethod) {
             case 'getUrl':
@@ -255,22 +197,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 ['_scope' => 1],
                 ['_scope' => 1, '_direct' => '/product/url/path', '_query' => []],
                 null,
-                '',
-                null,
-                null,
-                null,
-            ], [
-                'getUrl',
-                '',
-                null,
-                1,
-                1,
-                ['_scope' => 1],
-                ['_scope' => 1, '_direct' => '/product_url_rewrite/url/path', '_query' => []],
-                1,
-                'product/1/1',
-                '/product_url_rewrite/url/path',
-                null,
                 null,
             ], [
                 'getUrl',
@@ -280,9 +206,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 1,
                 ['_scope' => 1],
                 ['_scope' => 1, '_query' => [], 'id' => 1, 's' => 'urlKey', 'category' => 1],
-                null,
-                '',
-                null,
                 1,
                 'urlKey',
             ], [
@@ -294,9 +217,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 ['_scope' => 1],
                 ['_scope' => 1, '_direct' => '/product/url/path', '_query' => [], '_scope_to_url' => true],
                 null,
-                '',
-                null,
-                null,
                 null,
             ], [
                 'getProductUrl',
@@ -307,9 +227,6 @@ class UrlTest extends \PHPUnit_Framework_TestCase
                 [],
                 ['_direct' => '/product/url/path', '_query' => []],
                 null,
-                '',
-                null,
-                null,
                 null,
             ]
         ];
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/CategoryTest.php
new file mode 100644
index 00000000000..cfde970ec39
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/CategoryTest.php
@@ -0,0 +1,186 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class CategoryTest
+ * @package Magento\Catalog\Model\Rss
+ */
+class CategoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Rss\Category
+     */
+    protected $model;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Layer\Category|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $category;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Visibility|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $visibility;
+
+    protected function setUp()
+    {
+        $this->category = $this->getMock(
+            'Magento\Catalog\Model\Layer\Category',
+            ['setStore', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $this->collectionFactory = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->visibility = $this->getMock(
+            'Magento\Catalog\Model\Product\Visibility',
+            ['getVisibleInCatalogIds',
+                '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        /** @var \Magento\Catalog\Model\Rss\Category model */
+        $this->model = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Rss\Category',
+            [
+                'catalogLayer' => $this->category,
+                'collectionFactory' => $this->collectionFactory,
+                'visibility' => $this->visibility
+            ]
+        );
+    }
+
+    public function testGetProductCollection()
+    {
+        $storeId = 1;
+        $categoryChildren = 'children';
+        $visibleInCatalogIds = 1;
+
+        $this->visibility
+            ->expects($this->once())
+            ->method('getVisibleInCatalogIds')
+            ->will($this->returnValue($visibleInCatalogIds));
+        $products = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Collection',
+            [
+                'setStoreId',
+                'addAttributeToSort',
+                'setVisibility',
+                'setCurPage',
+                'setPageSize',
+                'addCountToCategories',
+            ],
+            [],
+            '',
+            false
+        );
+        $resourceCollection = $this->getMock(
+            'Magento\Catalog\Model\Resource\Collection\AbstractCollection',
+            [
+                'addAttributeToSelect',
+                'addAttributeToFilter',
+                'addIdFilter',
+                'load'
+            ],
+            [],
+            '',
+            false
+        );
+        $resourceCollection->expects($this->exactly(3))->method('addAttributeToSelect')->will($this->returnSelf());
+        $resourceCollection->expects($this->once())->method('addAttributeToFilter')->will($this->returnSelf());
+        $resourceCollection->expects($this->once())
+            ->method('addIdFilter')
+            ->with($categoryChildren)
+            ->will($this->returnSelf());
+        $resourceCollection->expects($this->once())->method('load')->will($this->returnSelf());
+        $products->expects($this->once())->method('addCountToCategories')->with($resourceCollection);
+        $products->expects($this->once())
+            ->method('addAttributeToSort')
+            ->with('updated_at', 'desc')
+            ->will($this->returnSelf());
+        $products->expects($this->once())
+            ->method('setVisibility')
+            ->with($visibleInCatalogIds)
+            ->will($this->returnSelf());
+        $products->expects($this->once())->method('setCurPage')->with(1)->will($this->returnSelf());
+        $products->expects($this->once())->method('setPageSize')->with(50)->will($this->returnSelf());
+        $products->expects($this->once())->method('setStoreId')->with($storeId);
+        $this->collectionFactory->expects($this->once())->method('create')->will($this->returnValue($products));
+        $category = $this->getMock(
+            'Magento\Catalog\Model\Category',
+            [
+                'getResourceCollection',
+                'getChildren',
+                'getProductCollection',
+                '__wakeup'
+            ],
+            [],
+            '',
+            false
+        );
+        $category->expects($this->once())
+            ->method('getResourceCollection')
+            ->will($this->returnValue($resourceCollection));
+        $category->expects($this->once())->method('getChildren')->will($this->returnValue($categoryChildren));
+        $category->expects($this->once())->method('getProductCollection')->will($this->returnValue($products));
+        $layer = $this->getMock(
+            'Magento\Catalog\Model\Layer',
+            [
+                'setCurrentCategory',
+                'prepareProductCollection',
+                'getProductCollection',
+                '__wakeup',
+            ],
+            [],
+            '',
+            false
+        );
+        $layer->expects($this->once())->method('setCurrentCategory')->with($category)->will($this->returnSelf());
+        $layer->expects($this->once())->method('getProductCollection')->will($this->returnValue($products));
+        $this->category->expects($this->once())->method('setStore')->with($storeId)->will($this->returnValue($layer));
+        $this->assertEquals($products, $this->model->getProductCollection($category, $storeId));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NewProductsTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NewProductsTest.php
new file mode 100644
index 00000000000..010474e76d3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NewProductsTest.php
@@ -0,0 +1,117 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class NewProductsTest
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class NewProductsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NewProducts
+     */
+    protected $newProducts;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product
+     */
+    protected $product;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Visibility|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $visibility;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezone;
+
+    protected function setUp()
+    {
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+        $this->productFactory = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create']);
+        $this->productFactory->expects($this->any())->method('create')->will($this->returnValue($this->product));
+        $this->visibility = $this->getMock('Magento\Catalog\Model\Product\Visibility', [], [], '', false);
+        $this->timezone = $this->getMock('Magento\Framework\Stdlib\DateTime\Timezone', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->newProducts = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Rss\Product\NewProducts',
+            [
+                'productFactory' => $this->productFactory,
+                'visibility' => $this->visibility,
+                'localeDate' => $this->timezone
+            ]
+        );
+    }
+
+    public function testGetProductsCollection()
+    {
+        /** @var \Magento\Framework\Stdlib\DateTime\Date|\PHPUnit_Framework_MockObject_MockObject $dateObject */
+        $dateObject = $this->getMock('Magento\Framework\Stdlib\DateTime\Date');
+        $dateObject->expects($this->any())->method('setTime')->will($this->returnSelf());
+        $dateObject->expects($this->any())->method('toString')->will(
+            $this->returnValue(date(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT))
+        );
+        $this->timezone->expects($this->exactly(2))->method('date')->will($this->returnValue($dateObject));
+
+        /** @var \Magento\Catalog\Model\Resource\Product\Collection $productCollection */
+        $productCollection = $this->getMock('Magento\Catalog\Model\Resource\Product\Collection', [], [], '', false);
+        $this->product->expects($this->once())->method('getResourceCollection')->will(
+            $this->returnValue($productCollection)
+        );
+        $storeId = 1;
+        $productCollection->expects($this->once())->method('setStoreId')->with($storeId);
+        $productCollection->expects($this->once())->method('addStoreFilter')->will($this->returnSelf());
+        $productCollection->expects($this->any())->method('addAttributeToFilter')->will($this->returnSelf());
+        $productCollection->expects($this->any())->method('addAttributeToSelect')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('addAttributeToSort')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('applyFrontendPriceLimitations')->will($this->returnSelf());
+        $visibleIds = [1, 3];
+        $this->visibility->expects($this->once())->method('getVisibleInCatalogIds')->will(
+            $this->returnValue($visibleIds)
+        );
+        $productCollection->expects($this->once())->method('setVisibility')->with($visibleIds)->will(
+            $this->returnSelf()
+        );
+
+        $products = $this->newProducts->getProductsCollection($storeId);
+        $this->assertEquals($productCollection, $products);
+    }
+}
+
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NotifyStockTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NotifyStockTest.php
new file mode 100644
index 00000000000..b01373be658
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/NotifyStockTest.php
@@ -0,0 +1,118 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class NotifyStockTest
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class NotifyStockTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\NotifyStock
+     */
+    protected $notifyStock;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+
+    protected $productFactory;
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product
+     */
+    protected $product;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Model\Resource\StockFactory
+     */
+    protected $stockFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Model\Resource\Stock
+     */
+    protected $stock;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Attribute\Source\Status|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $status;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManager;
+
+    protected function setUp()
+    {
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+        $this->productFactory = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create']);
+        $this->productFactory->expects($this->any())->method('create')->will($this->returnValue($this->product));
+
+        $this->stock = $this->getMock('Magento\CatalogInventory\Model\Resource\Stock', [], [], '', false);
+        $this->stockFactory = $this->getMock('Magento\CatalogInventory\Model\Resource\StockFactory', ['create']);
+        $this->stockFactory->expects($this->any())->method('create')->will($this->returnValue($this->stock));
+
+        $this->status = $this->getMock('Magento\Catalog\Model\Product\Attribute\Source\Status');
+        $this->eventManager = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->notifyStock = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Rss\Product\NotifyStock',
+            [
+                'productFactory' => $this->productFactory,
+                'stockFactory' => $this->stockFactory,
+                'productStatus' => $this->status,
+                'eventManager' => $this->eventManager
+            ]
+        );
+    }
+
+    public function testGetProductsCollection()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Product\Collection $productCollection */
+        $productCollection = $this->getMock('Magento\Catalog\Model\Resource\Product\Collection', [], [], '', false);
+        $this->product->expects($this->once())->method('getCollection')->will($this->returnValue($productCollection));
+
+        $productCollection->expects($this->once())->method('addAttributeToSelect')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('addAttributeToFilter')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('setOrder')->will($this->returnSelf());
+
+        $this->eventManager->expects($this->once())->method('dispatch')->with(
+            'rss_catalog_notify_stock_collection_select'
+        );
+        $this->stock->expects($this->once())->method('addLowStockFilter')->with($productCollection);
+
+        $products = $this->notifyStock->getProductsCollection();
+        $this->assertEquals($productCollection, $products);
+
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/SpecialTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/SpecialTest.php
new file mode 100644
index 00000000000..b8bb906951d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Rss/Product/SpecialTest.php
@@ -0,0 +1,103 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Rss\Product;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class SpecialTest
+ * @package Magento\Catalog\Model\Rss\Product
+ */
+class SpecialTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Rss\Product\Special
+     */
+    protected $special;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product
+     */
+    protected $product;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    protected function setUp()
+    {
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+        $this->productFactory = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create']);
+        $this->productFactory->expects($this->any())->method('create')->will($this->returnValue($this->product));
+        $this->storeManager = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->special = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Rss\Product\Special',
+            [
+                'productFactory' => $this->productFactory,
+                'storeManager' => $this->storeManager
+            ]
+        );
+    }
+
+    public function testGetProductsCollection()
+    {
+        $storeId = 1;
+        $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $this->storeManager->expects($this->once())->method('getStore')->with($storeId)->will(
+            $this->returnValue($store)
+        );
+        $websiteId = 1;
+        $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId));
+
+        /** @var \Magento\Catalog\Model\Resource\Product\Collection $productCollection */
+        $productCollection = $this->getMock('Magento\Catalog\Model\Resource\Product\Collection', [], [], '', false);
+        $this->product->expects($this->once())->method('getResourceCollection')->will(
+            $this->returnValue($productCollection)
+        );
+        $customerGroupId = 1;
+        $productCollection->expects($this->once())->method('addPriceDataFieldFilter')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('addPriceData')->with($storeId, $customerGroupId)->will(
+            $this->returnSelf()
+        );
+        $productCollection->expects($this->once())->method('addAttributeToSelect')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('addAttributeToSort')->will($this->returnSelf());
+
+        $products = $this->special->getProductsCollection($storeId, $customerGroupId);
+        $this->assertEquals($productCollection, $products);
+
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php
deleted file mode 100644
index 332aac74feb..00000000000
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php
+++ /dev/null
@@ -1,313 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model;
-
-class UrlTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $_model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_resourceModel;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_urlFactory;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_storeModel;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_productModel;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_categoryModel;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_categoryFactory;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_categoryHelper;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_rewriteModel;
-
-    /**
-     * @var \Magento\TestFramework\Helper\ObjectManager
-     */
-    protected $_objectManager;
-
-    /**
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    protected function setUp()
-    {
-        $this->_resourceModel = $this->getMock(
-            '\Magento\Catalog\Model\Resource\Url',
-            array(
-                '__wakeup',
-                'getStores',
-                'clearStoreInvalidRewrites',
-                'getProductsByStore',
-                'prepareRewrites',
-                'getCategories',
-                'getCategory',
-                'getCategoryModel',
-                'loadCategoryChilds',
-                'checkRequestPaths',
-                'saveRewrite',
-                'clearCategoryProduct',
-                'getCategoryParentPath',
-                'findFinalTargetPath',
-                'deleteRewriteRecord',
-                'saveCategoryAttribute',
-                'getProductsByCategory',
-                'deleteCategoryProductStoreRewrites'
-            ),
-            array(),
-            '',
-            false
-        );
-        $this->_urlFactory = $this->getMock(
-            '\Magento\Catalog\Model\Resource\UrlFactory',
-            array(
-                'create',
-                'formatUrlKey',
-                'getUrlPath'
-            )
-        );
-        $this->_storeModel = $this->getMock(
-            '\Magento\Store\Model\Store',
-            array(
-                '__wakeup',
-                'getId',
-                'getRootCategoryId'
-            ),
-            array(),
-            '',
-            false
-        );
-        $this->_productModel = $this->getMock(
-            'Magento\Catalog\Model\Product',
-            array(
-                '__wakeup',
-                'getCategoryIds',
-                'getId',
-                'getResource',
-                'getUrlPath'
-            ),
-            array(),
-            '',
-            false
-        );
-        $this->_categoryModel = $this->getMock(
-            'Magento\Catalog\Model\Category',
-            array(
-                '__wakeup',
-                'getId',
-                'getStoreId',
-                'getChilds',
-                'getAllChilds',
-                'formatUrlKey',
-                'getUrlKey',
-                'getCategoryUrlPath',
-                'getName'
-            ),
-            array(),
-            '',
-            false
-        );
-        $this->_categoryFactory = $this->getMock('\Magento\Catalog\Model\CategoryFactory');
-        $this->_categoryHelper = $this->getMock(
-            'Magento\Catalog\Helper\Category',
-            array(
-                'getCategoryUrlPath',
-                'getCategoryUrlSuffix'
-            ),
-            array(),
-            '',
-            false
-        );
-        $this->_rewriteModel = $this->getMock(
-            'Magento\UrlRewrite\Model\UrlRewrite',
-            array(
-                '__wakeup',
-                'getRequestPath'
-            ),
-            array(),
-            '',
-            false
-        );
-
-        $this->_objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_model = $this->_objectManager->getObject(
-            'Magento\Catalog\Model\Url',
-            array(
-                'urlFactory' => $this->_urlFactory,
-                'catalogCategoryFactory' => $this->_categoryFactory,
-                'catalogCategory' => $this->_categoryHelper
-            )
-        );
-
-        $this->_urlFactory->expects($this->any())->method('create')
-            ->will($this->returnValue($this->_resourceModel));
-        $this->_resourceModel->expects($this->any())->method('getCategory')
-            ->will($this->returnValue($this->_categoryModel));
-        $this->_resourceModel->expects($this->any())->method('loadCategoryChilds')
-            ->will($this->returnValue($this->_categoryModel));
-        $this->_resourceModel->expects($this->any())->method('saveRewrite')
-            ->will($this->returnSelf());
-        $this->_categoryModel->expects($this->any())->method('getId')
-            ->will($this->returnValue(1));
-        $this->_categoryModel->expects($this->any())->method('getStoreId')
-            ->will($this->returnValue(1));
-        $this->_categoryModel->expects($this->any())->method('getChilds')
-            ->will($this->returnSelf());
-        $this->_storeModel->expects($this->any())->method('getId')
-            ->will($this->returnValue(1));
-    }
-
-    public function testGenerateUniqueIdPath()
-    {
-        $path = $this->_model->generateUniqueIdPath();
-        $this->assertNotContains('.', $path);
-        $this->assertContains('_', $path);
-        $this->assertNotEquals($path, $this->_model->generateUniqueIdPath());
-    }
-
-    public function testRefreshRewrites()
-    {
-        $rewrite = array('category/1' => $this->_rewriteModel);
-        $validatedPath = 'validated_path.html';
-
-        $this->_urlFactory->expects($this->any())->method('formatUrlKey')
-            ->will($this->returnValue('url_formatted'));
-        $this->_urlFactory->expects($this->any())->method('getUrlPath')
-            ->will($this->returnValue($validatedPath));
-        $this->_resourceModel->expects($this->any())->method('prepareRewrites')
-            ->will($this->returnValue($rewrite));
-        $this->_resourceModel->expects($this->at(0))->method('getStores')
-            ->will($this->returnValue(array($this->_storeModel)));
-        $this->_resourceModel->expects($this->any())->method('getStores')
-            ->will($this->returnValue($this->_storeModel));
-        $this->_resourceModel->expects($this->once())->method('clearStoreInvalidRewrites')
-            ->will($this->returnSelf());
-        $this->_resourceModel->expects($this->at(14))->method('getProductsByStore')
-            ->will($this->returnValue(null));
-        $this->_resourceModel->expects($this->any())->method('getProductsByStore')
-            ->will($this->returnValue(array($this->_productModel)));
-        $this->_resourceModel->expects($this->any())->method('getCategories')
-            ->will($this->returnValue(array($this->_categoryModel)));
-        $this->_resourceModel->expects($this->once())->method('checkRequestPaths')
-            ->will($this->returnValue($validatedPath));
-        $this->_resourceModel->expects($this->once())->method('clearCategoryProduct')
-            ->will($this->returnSelf());
-        $this->_productModel->expects($this->any())->method('getCategoryIds')
-            ->will($this->returnValue(array(1)));
-        $this->_productModel->expects($this->any())->method('getId')
-            ->will($this->returnValue(1));
-        $this->_productModel->expects($this->any())->method('getResource')
-            ->will($this->returnValue($this->_resourceModel));
-        $this->_productModel->expects($this->once())->method('getUrlPath')
-            ->will($this->returnValue($validatedPath));
-        $this->_storeModel->expects($this->any())->method('getRootCategoryId')
-            ->will($this->returnValue(1));
-
-        $this->_model->refreshRewrites();
-    }
-
-    /**
-     * @param string $targetPathExecute
-     * @param bool $changeRequestPath
-     *
-     * @dataProvider refreshcategoryRewriteDataProvider
-     */
-    public function testRefreshCategoryRewrite($targetPathExecute, $changeRequestPath)
-    {
-        $categoryId = 1;
-        $rewrite = array('category/1' => $this->_rewriteModel);
-
-        $this->_resourceModel->expects($this->once())->method('prepareRewrites')
-            ->will($this->returnValue($rewrite));
-        $this->_resourceModel->expects($this->at(0))->method('getStores')
-            ->will($this->returnValue(array($this->_storeModel)));
-        $this->_resourceModel->expects($this->once())->method('getStores')
-            ->will($this->returnValue($this->_storeModel));
-        $this->_resourceModel->expects($this->any())->method('getCategoryModel')
-            ->will($this->returnValue($this->_categoryModel));
-        $this->_resourceModel->expects($this->once())->method('getCategoryParentPath')
-            ->will($this->returnValue('parent_path'));
-        $this->_resourceModel->expects($this->any())->method('deleteRewriteRecord')
-            ->will($this->returnSelf());
-        $this->_resourceModel->expects($this->any())->method('saveCategoryAttribute')
-            ->will($this->returnSelf());
-        $this->_resourceModel->expects($this->any())->method('getProductsByCategory')
-            ->will($this->returnValue(null));
-        $this->_resourceModel->expects($this->any())->method('deleteCategoryProductStoreRewrites')
-            ->will($this->returnSelf());
-        $this->_resourceModel->expects($this->$targetPathExecute())->method('findFinalTargetPath')
-            ->will($this->returnValue('category/1'));
-        $this->_categoryModel->expects($this->any())->method('getAllChilds')
-            ->will($this->returnValue(array($this->_categoryModel)));
-        $this->_categoryModel->expects($this->any())->method('formatUrlKey')
-            ->will($this->returnValue('url_formatted'));
-        $this->_categoryModel->expects($this->any())->method('getUrlKey')
-            ->will($this->returnValue('url_key'));
-        $this->_categoryModel->expects($this->any())->method('getCategoryUrlPath')
-            ->will($this->returnValue('category_parent_path'));
-        $this->_categoryHelper->expects($this->once())->method('getCategoryUrlPath')
-            ->will($this->returnValue('category_parent_path'));
-        $this->_categoryHelper->expects($this->once())->method('getCategoryUrlSuffix')
-            ->will($this->returnValue('suffics'));
-        $this->_rewriteModel->expects($this->once())->method('getRequestPath')
-            ->will($this->returnValue('category_parent_pathurl_formatted-1suffics'));
-
-        $this->_model->refreshCategoryRewrite($categoryId, '', true, $changeRequestPath);
-    }
-
-    public function refreshcategoryRewriteDataProvider()
-    {
-        return array(
-            array('once', true),
-            array('never', false)
-        );
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
index a452910afa8..576e9fa344a 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
@@ -134,7 +134,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderMsrpDisabled()
     {
-        $priceType = $this->getMock('Magento\Catalog\Pricing\Price\MsrpPrice', [], [], '', false);
+        $priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
         $this->priceInfo->expects($this->once())
             ->method('getPrice')
             ->with($this->equalTo('msrp_price'))
@@ -155,7 +155,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderMsrpEnabled()
     {
-        $priceType = $this->getMock('Magento\Catalog\Pricing\Price\MsrpPrice', [], [], '', false);
+        $priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
         $this->priceInfo->expects($this->once())
             ->method('getPrice')
             ->with($this->equalTo('msrp_price'))
@@ -166,6 +166,11 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($this->product))
             ->will($this->returnValue(true));
 
+        $priceType->expects($this->any())
+            ->method('isMinimalPriceLessMsrp')
+            ->with($this->equalTo($this->product))
+            ->will($this->returnValue(true));
+
         $priceBoxRender = $this->getMockBuilder('Magento\Framework\Pricing\Render\PriceBox')
             ->disableOriginalConstructor()
             ->getMock();
@@ -211,7 +216,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
         $this->object->setData('price_id', $priceId);
 
         $arguments = [
-            'display_label'     => __('As low as:'),
+            'display_label'     => 'As low as',
             'price_id'          => $priceId,
             'include_container' => false,
             'skip_adjustments' => true
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/TierPriceServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/TierPriceServiceTest.php
index 8fd0c94936d..5ee05fcb1f7 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/TierPriceServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/TierPriceServiceTest.php
@@ -244,14 +244,6 @@ class TierPriceServiceTest extends \PHPUnit_Framework_TestCase
             )
         );
         $price = new \Magento\Catalog\Service\V1\Data\Product\TierPrice($priceBuilder);
-        $groupBuilder = $this->getMock(
-            '\Magento\Customer\Service\V1\Data\CustomerGroupBuilder',
-            array(),
-            array(),
-            '',
-            false
-        );
-
         $websiteMock = $this->getMockBuilder('Magento\Store\Model\Website')
             ->setMethods(['getId', '__wakeup'])
             ->disableOriginalConstructor()
@@ -260,9 +252,6 @@ class TierPriceServiceTest extends \PHPUnit_Framework_TestCase
 
         $this->storeManagerMock->expects($this->once())->method('getWebsite')->will($this->returnValue($websiteMock));
 
-        $groupBuilder->expects($this->any())->method('getData')->will($this->returnValue(array('id' => 1)));
-        $group = new \Magento\Customer\Service\V1\Data\CustomerGroup($groupBuilder);
-        $this->groupServiceMock->expects($this->once())->method('getGroup')->will($this->returnValue($group));
         $this->productMock
             ->expects($this->once())
             ->method('getData')
@@ -367,16 +356,6 @@ class TierPriceServiceTest extends \PHPUnit_Framework_TestCase
             )
         );
         $price = new \Magento\Catalog\Service\V1\Data\Product\TierPrice($priceBuilder);
-        $groupBuilder = $this->getMock(
-            '\Magento\Customer\Service\V1\Data\CustomerGroupBuilder',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $groupBuilder->expects($this->any())->method('getData')->will($this->returnValue(array('id' => 1)));
-        $group = new \Magento\Customer\Service\V1\Data\CustomerGroup($groupBuilder);
-        $this->groupServiceMock->expects($this->once())->method('getGroup')->will($this->returnValue($group));
         $this->productMock
             ->expects($this->once())
             ->method('getData')
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/_files/eav_attributes_data.php b/dev/tests/unit/testsuite/Magento/Catalog/_files/eav_attributes_data.php
deleted file mode 100644
index f5d201a2d93..00000000000
--- a/dev/tests/unit/testsuite/Magento/Catalog/_files/eav_attributes_data.php
+++ /dev/null
@@ -1,468 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-return array(
-    //empty attribute case
-    array(
-        false,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        false
-    ), //Event Type, result
-    //attribute exists, but shouldn't be matched
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        false
-    ), //Event Type, result
-    //Next cases describe situation that one valuable argument exists
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 1),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 1),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        false
-    ),//Event Type, result
-    array(
-        true,
-        true, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 1),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 1),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 1),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 1),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 1)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_DELETE,
-        true
-    ), //Event Type, result
-    //\Magento\Index\Model\Event::TYPE_SAVE cases
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        false
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        true, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        false
-    ), //Event Type, result
-    array(
-        true,
-        true, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 1),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        true, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 1),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 1),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 1),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 1),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false,
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 1),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ),
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 1)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 0)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ), //Event Type, result
-    array(
-        true,
-        false, //Attribute, isAddFilterable
-        //Original attribute data
-        array(
-            array('backend_type', 'not_static'),
-            array('is_filterable', 0),
-            array('used_in_product_listing', 0),
-            array('is_used_for_promo_rules', 0),
-            array('used_for_sort_by', 0)
-        ),
-        //Attribute data
-        array(
-            array('backend_type', null, 'not_static'),
-            array('is_filterable', null, 0),
-            array('used_in_product_listing', null, 0),
-            array('is_used_for_promo_rules', null, 0),
-            array('used_for_sort_by', null, 1)
-        ),
-        \Magento\Index\Model\Event::TYPE_SAVE,
-        true
-    ) //Event Type, result
-);
diff --git a/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/FullTest.php b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/FullTest.php
new file mode 100644
index 00000000000..7b40da2041f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/FullTest.php
@@ -0,0 +1,135 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Action;
+
+class FullTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resource;
+    /** @var \Magento\Catalog\Model\Product\Type|\PHPUnit_Framework_MockObject_MockObject */
+    protected $catalogProductType;
+    /** @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $eavConfig;
+    /** @var \Magento\Framework\Search\Request\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $searchRequestConfig;
+    /** @var \Magento\Catalog\Model\Product\Attribute\Source\Status|\PHPUnit_Framework_MockObject_MockObject */
+    protected $catalogProductStatus;
+    /** @var \Magento\CatalogSearch\Model\Resource\EngineProvider|\PHPUnit_Framework_MockObject_MockObject */
+    protected $engineProvider;
+    /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $eventManager;
+    /** @var \Magento\CatalogSearch\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $catalogSearchData;
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+    /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+    /** @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject */
+    protected $dateTime;
+    /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $localeResolver;
+    /** @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $localeDate;
+    /** @var \Magento\CatalogSearch\Model\Resource\Fulltext|\PHPUnit_Framework_MockObject_MockObject */
+    protected $fulltextResource;
+    /** @var \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManagerHelper;
+    /** @var \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\Full */
+    protected $object;
+
+    public function setUp()
+    {
+        $this->resource = $this->getMockBuilder('Magento\\Framework\\App\\Resource')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->catalogProductType = $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Type')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->eavConfig = $this->getMockBuilder('Magento\\Eav\\Model\\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->searchRequestConfig = $this->getMockBuilder('Magento\\Framework\\Search\\Request\\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->catalogProductStatus =
+            $this->getMockBuilder('Magento\\Catalog\\Model\\Product\\Attribute\\Source\\Status')
+                ->disableOriginalConstructor()
+                ->getMock();
+        $this->engineProvider = $this->getMockBuilder('Magento\\CatalogSearch\\Model\\Resource\\EngineProvider')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->eventManager = $this->getMockBuilder('Magento\\Framework\\Event\\ManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->catalogSearchData = $this->getMockBuilder('Magento\\CatalogSearch\\Helper\\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->scopeConfig = $this->getMockBuilder('Magento\\Framework\\App\\Config\\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManager = $this->getMockBuilder('Magento\\Framework\\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dateTime = $this->getMockBuilder('Magento\\Framework\\Stdlib\\DateTime')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->localeResolver = $this->getMockBuilder('Magento\\Framework\\Locale\\ResolverInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->localeDate = $this->getMockBuilder('Magento\\Framework\\Stdlib\\DateTime\\TimezoneInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fulltextResource = $this->getMockBuilder('Magento\\CatalogSearch\\Model\\Resource\\Fulltext')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->object = $this->objectManagerHelper->getObject(
+            'Magento\\CatalogSearch\\Model\\Indexer\\Fulltext\\Action\\Full',
+            array(
+                'resource' => $this->resource,
+                'catalogProductType' => $this->catalogProductType,
+                'eavConfig' => $this->eavConfig,
+                'searchRequestConfig' => $this->searchRequestConfig,
+                'catalogProductStatus' => $this->catalogProductStatus,
+                'engineProvider' => $this->engineProvider,
+                'eventManager' => $this->eventManager,
+                'catalogSearchData' => $this->catalogSearchData,
+                'scopeConfig' => $this->scopeConfig,
+                'storeManager' => $this->storeManager,
+                'dateTime' => $this->dateTime,
+                'localeResolver' => $this->localeResolver,
+                'localeDate' => $this->localeDate,
+                'fulltextResource' => $this->fulltextResource
+            )
+        );
+    }
+
+    public function testReindexAll()
+    {
+        $this->storeManager->expects($this->once())->method('getStores')->willReturn([]);
+        $this->searchRequestConfig->expects($this->once())->method('reset');
+        $this->object->reindexAll();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/ReaderPluginTest.php b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/ReaderPluginTest.php
new file mode 100644
index 00000000000..fa05cbd4f0a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/ReaderPluginTest.php
@@ -0,0 +1,63 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogSearch\Model\Search;
+
+class ReaderPluginTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogSearch\Model\Search\RequestGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $requestGenerator;
+    /** @var \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManagerHelper;
+    /** @var \Magento\CatalogSearch\Model\Search\ReaderPlugin */
+    protected $object;
+
+    public function setUp()
+    {
+        $this->requestGenerator = $this->getMockBuilder('Magento\\CatalogSearch\\Model\\Search\\RequestGenerator')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->object = $this->objectManagerHelper->getObject(
+            'Magento\\CatalogSearch\\Model\\Search\\ReaderPlugin',
+            array('requestGenerator' => $this->requestGenerator)
+        );
+    }
+
+    public function testAroundRead()
+    {
+        $this->requestGenerator->expects($this->once())
+            ->method('generate')
+            ->will($this->returnValue(['test' => 'a']));
+
+        $result = $this->object->aroundRead(
+            $this->getMockBuilder('Magento\Framework\Config\ReaderInterface')->disableOriginalConstructor()->getMock(),
+            function () {
+                return ['test' => 'b', 'd' => 'e'];
+            }
+        );
+
+        $this->assertEquals(['test' => ['b', 'a'], 'd' => 'e'], $result);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/RequestGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/RequestGeneratorTest.php
new file mode 100644
index 00000000000..62e269492ad
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogSearch/Model/Search/RequestGeneratorTest.php
@@ -0,0 +1,135 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogSearch\Model\Search;
+
+use Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory;
+
+class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\CatalogSearch\Model\Search\RequestGenerator */
+    protected $object;
+
+    /** @var  CollectionFactory | \PHPUnit_Framework_MockObject_MockObject */
+    protected $productAttributeCollectionFactory;
+
+    public function setUp()
+    {
+        $this->productAttributeCollectionFactory =
+            $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory')
+                ->setMethods(['create'])
+                ->disableOriginalConstructor()
+                ->getMock();
+
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->object = $this->objectManagerHelper->getObject(
+            'Magento\\CatalogSearch\\Model\\Search\\RequestGenerator',
+            ['productAttributeCollectionFactory' => $this->productAttributeCollectionFactory]
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function attributesProvider()
+    {
+        return [
+            [[0, 0, 0], 'sku', 'static'],
+            [[0, 0, 0], 'price', 'static'],
+            [[1, 2, 0], 'name', 'text'],
+            [[1, 0, 0], 'name2', 'text', false],
+            [[1, 2, 1], 'date', 'decimal'],
+            [[1, 2, 1], 'attr_int', 'int'],
+        ];
+    }
+
+    /**
+     * @param array $countResult
+     * @param string $code
+     * @param string $type
+     * @param bool $visibleInAdvanced
+     * @dataProvider attributesProvider
+     */
+    public function testGenerate($countResult, $code, $type, $visibleInAdvanced = true)
+    {
+        $collection = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Attribute\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $collection->expects($this->any())
+            ->method('getIterator')
+            ->willReturn(
+                new \ArrayIterator(
+                    [
+                        $this->createAttributeMock($code, $type, $visibleInAdvanced),
+                    ]
+                )
+            );
+        $this->productAttributeCollectionFactory->expects($this->any())
+            ->method('create')
+            ->willReturn($collection);
+        $result = $this->object->generate();
+
+        $this->assertEquals($countResult[0], $this->countVal($result['quick_search_container']['queries']));
+        $this->assertEquals($countResult[1], $this->countVal($result['advanced_search_container']['queries']));
+        $this->assertEquals($countResult[2], $this->countVal($result['advanced_search_container']['filters']));
+    }
+
+    /**
+     * Create attribute mock
+     *
+     * @param string $code
+     * @param string $type
+     * @param bool $visibleInAdvanced
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    private function createAttributeMock($code, $type, $visibleInAdvanced = true)
+    {
+        $attribute = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributeCode', 'getBackendType', 'getIsVisibleInAdvancedSearch', 'getSearchWeight'])
+            ->getMock();
+        $attribute->expects($this->any())
+            ->method('getAttributeCode')
+            ->willReturn($code);
+        $attribute->expects($this->any())
+            ->method('getBackendType')
+            ->willReturn($type);
+
+        $attribute->expects($this->any())
+            ->method('getSearchWeight')
+            ->willReturn(1);
+
+        $attribute->expects($this->any())
+            ->method('getIsVisibleInAdvancedSearch')
+            ->willReturn($visibleInAdvanced);
+        return $attribute;
+    }
+
+    private function countVal(&$value)
+    {
+        return !empty($value) ? count($value) : 0;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..c0f52504c58
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGeneratorTest.php
@@ -0,0 +1,94 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
+class CanonicalUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewrite;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoryUrlPathGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->canonicalUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator',
+            [
+                'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator,
+                'urlRewriteBuilder' => $this->urlRewriteBuilder
+            ]
+        );
+    }
+
+    public function testGenerate()
+    {
+        $requestPath = 'category.html';
+        $targetPath = 'target-path';
+        $storeId = 'store_id';
+        $categoryId = 'category_id';
+
+        $this->category->expects($this->any())->method('getId')->will($this->returnValue($categoryId));
+        $this->categoryUrlPathGenerator->expects($this->any())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($requestPath));
+        $this->categoryUrlPathGenerator->expects($this->any())->method('getCanonicalUrlPath')
+            ->will($this->returnValue($targetPath));
+        $this->urlRewriteBuilder->expects($this->any())->method('setStoreId')->with($storeId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityId')->with($categoryId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityType')
+            ->with(CategoryUrlRewriteGenerator::ENTITY_TYPE)->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRequestPath')->with($requestPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setTargetPath')->with($targetPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->canonicalUrlRewriteGenerator->generate($storeId, $this->category)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProviderTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProviderTest.php
new file mode 100644
index 00000000000..d2238966e96
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenCategoriesProviderTest.php
@@ -0,0 +1,90 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ChildrenCategoriesProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $select;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $connection;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider */
+    protected $childrenCategoriesProvider;
+
+    protected function setUp()
+    {
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()
+            ->setMethods(['getPath', 'getResourceCollection', 'getResource', 'getLevel', '__wakeup'])->getMock();
+        $categoryCollection = $this->getMockBuilder(
+            'Magento\Catalog\Model\Resource\Collection\AbstractCollection'
+        )->disableOriginalConstructor()->setMethods(['addAttributeToSelect', 'addIdFilter'])->getMock();
+        $this->category->expects($this->once())->method('getPath')->willReturn('category-path');
+        $this->category->expects($this->once())->method('getResourceCollection')->willReturn($categoryCollection);
+        $categoryCollection->expects($this->any())->method('addAttributeToSelect')->willReturnSelf();
+        $categoryCollection->expects($this->any())->method('addIdFilter')->with(['id'])->willReturnSelf();
+        $this->select = $this->getMockBuilder('Magento\Framework\DB\Selecty')
+            ->disableOriginalConstructor()->setMethods(['from', 'where', 'deleteFromSelect'])->getMock();
+        $this->connection = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface');
+        $categoryResource = $this->getMockBuilder('Magento\Catalog\Model\Resource\Category')
+            ->disableOriginalConstructor()->getMock();
+        $this->category->expects($this->any())->method('getResource')->willReturn($categoryResource);
+        $categoryResource->expects($this->any())->method('getReadConnection')->willReturn($this->connection);
+        $this->connection->expects($this->any())->method('select')->willReturn($this->select);
+        $this->connection->expects($this->any())->method('quoteIdentifier')->willReturnArgument(0);
+        $this->select->expects($this->any())->method('from')->willReturnSelf();
+
+        $this->childrenCategoriesProvider = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider'
+        );
+    }
+
+    public function testGetChildrenRecursive()
+    {
+        $bind = ['c_path' => 'category-path/%'];
+        $this->select->expects($this->any())->method('where')->with('path LIKE :c_path')->willReturnSelf();
+        $this->connection->expects($this->any())->method('fetchCol')->with($this->select, $bind)->willReturn(['id']);
+        $this->childrenCategoriesProvider->getChildren($this->category, true);
+    }
+
+    public function testGetChildren()
+    {
+        $categoryLevel = 3;
+        $this->select->expects($this->at(1))->method('where')->with('path LIKE :c_path')->willReturnSelf();
+        $this->select->expects($this->at(2))->method('where')->with('level <= :c_level')->willReturnSelf();
+        $this->category->expects($this->once())->method('getLevel')->willReturn($categoryLevel);
+        $bind = ['c_path' => 'category-path/%', 'c_level' => $categoryLevel + 1];
+        $this->connection->expects($this->any())->method('fetchCol')->with($this->select, $bind)->willReturn(['id']);
+
+        $this->childrenCategoriesProvider->getChildren($this->category, false);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..d5425b773b7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGeneratorTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ChildrenUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator */
+    protected $childrenUrlRewriteGenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $childrenCategoriesProvider;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryUrlRewriteGeneratorFactory;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryUrlRewriteGenerator;
+
+    protected function setUp()
+    {
+        $this->childrenCategoriesProvider = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider'
+        )->disableOriginalConstructor()->getMock();
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoryUrlRewriteGeneratorFactory = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory'
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
+        $this->categoryUrlRewriteGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->childrenUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator',
+            [
+                'childrenCategoriesProvider' => $this->childrenCategoriesProvider,
+                'categoryUrlRewriteGeneratorFactory' => $this->categoryUrlRewriteGeneratorFactory
+            ]
+        );
+    }
+
+    public function testNoChildrenCategories()
+    {
+        $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, false)
+            ->will($this->returnValue([]));
+
+        $this->assertEquals([], $this->childrenUrlRewriteGenerator->generate('store_id', $this->category));
+    }
+
+    public function testGenerate()
+    {
+        $storeId = 'store_id';
+        $saveRewritesHistory = 'flag';
+
+        $childCategory = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()->getMock();
+        $childCategory->expects($this->once())->method('setStoreId')->with($storeId);
+        $childCategory->expects($this->once())->method('setData')
+            ->with('save_rewrites_history', $saveRewritesHistory);
+        $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, false)
+            ->will($this->returnValue([$childCategory]));
+        $this->category->expects($this->any())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue($saveRewritesHistory));
+        $this->categoryUrlRewriteGeneratorFactory->expects($this->once())->method('create')
+            ->will($this->returnValue($this->categoryUrlRewriteGenerator));
+        $this->categoryUrlRewriteGenerator->expects($this->once())->method('generate')->with($childCategory)
+            ->will($this->returnValue([['url-1', 'url-2']]));
+
+        $this->assertEquals(
+            [['url-1', 'url-2']],
+            $this->childrenUrlRewriteGenerator->generate($storeId, $this->category)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegeneratorTest.php
new file mode 100644
index 00000000000..8fbfb2a0c65
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegeneratorTest.php
@@ -0,0 +1,298 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Category;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
+class CurrentUrlRewritesRegeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $filter;
+
+    /** @var \Magento\UrlRewrite\Model\UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlFinder;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewrite;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()->getMock();
+        $this->filter = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\Filter')
+            ->disableOriginalConstructor()->getMock();
+        $this->filter->expects($this->any())->method('setStoreId')->will($this->returnSelf());
+        $this->filter->expects($this->any())->method('setEntityId')->will($this->returnSelf());
+        $this->urlFinder = $this->getMockBuilder('Magento\UrlRewrite\Model\UrlFinderInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoryUrlPathGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->currentUrlRewritesRegenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator',
+            [
+                'urlFinder' => $this->urlFinder,
+                'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator,
+                'urlRewriteBuilder' => $this->urlRewriteBuilder
+            ]
+        );
+    }
+
+    public function testIsAutogeneratedWithoutSaveRewriteHistory()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([[UrlRewrite::IS_AUTOGENERATED => 1]])));
+        $this->category->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(false));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->category)
+        );
+    }
+
+    public function testSkipGenerationForAutogenerated()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will(
+                $this->returnValue(
+                    $this->getCurrentRewritesMocks(
+                        [
+                            [UrlRewrite::IS_AUTOGENERATED => 1, UrlRewrite::REQUEST_PATH => 'same-path']
+                        ]
+                    )
+                )
+            );
+        $this->category->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(true));
+        $this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue('same-path'));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->category)
+        );
+    }
+
+    public function testIsAutogenerated()
+    {
+        $requestPath = 'autogenerated.html';
+        $targetPath = 'some-path.html';
+        $storeId = 2;
+        $categoryId = 12;
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will(
+                $this->returnValue(
+                    $this->getCurrentRewritesMocks(
+                        [
+                            [
+                                UrlRewrite::REQUEST_PATH => $requestPath,
+                                UrlRewrite::TARGET_PATH => 'custom-target-path',
+                                UrlRewrite::STORE_ID => $storeId,
+                                UrlRewrite::IS_AUTOGENERATED => 1,
+                                UrlRewrite::METADATA => [],
+                            ],
+                        ]
+                    )
+                )
+            );
+        $this->category->expects($this->any())->method('getId')->will($this->returnValue($categoryId));
+        $this->category->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(true));
+        $this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($targetPath));
+
+        $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, OptionProvider::PERMANENT);
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
+        );
+    }
+
+    public function testSkipGenerationForCustom()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will(
+                $this->returnValue(
+                    $this->getCurrentRewritesMocks(
+                        [
+                            [
+                                UrlRewrite::IS_AUTOGENERATED => 0,
+                                UrlRewrite::REQUEST_PATH => 'same-path',
+                                UrlRewrite::REDIRECT_TYPE => 1
+                            ]
+                        ]
+                    )
+                )
+            );
+        $this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue('same-path'));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->category)
+        );
+    }
+
+    public function testGenerationForCustomWithoutTargetPathGeneration()
+    {
+        $storeId = 12;
+        $categoryId = 123;
+        $requestPath = 'generate-for-custom-without-redirect-type.html';
+        $targetPath = 'custom-target-path.html';
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will(
+                $this->returnValue(
+                    $this->getCurrentRewritesMocks(
+                        [
+                            [
+                                UrlRewrite::REQUEST_PATH => $requestPath,
+                                UrlRewrite::TARGET_PATH => $targetPath,
+                                UrlRewrite::REDIRECT_TYPE => 0,
+                                UrlRewrite::IS_AUTOGENERATED => 0,
+                                UrlRewrite::DESCRIPTION => $description,
+                                UrlRewrite::METADATA => [],
+                            ]
+                        ]
+                    )
+                )
+            );
+        $this->categoryUrlPathGenerator->expects($this->never())->method('getUrlPathWithSuffix');
+        $this->category->expects($this->any())->method('getId')->will($this->returnValue($categoryId));
+        $this->urlRewriteBuilder->expects($this->once())->method('setDescription')->with($description)
+            ->will($this->returnSelf());
+        $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, 0);
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
+        );
+    }
+
+    public function testGenerationForCustomWithTargetPathGeneration()
+    {
+        $storeId = 12;
+        $categoryId = 123;
+        $requestPath = 'generate-for-custom-without-redirect-type.html';
+        $targetPath = 'generated-target-path.html';
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will(
+                $this->returnValue(
+                    $this->getCurrentRewritesMocks(
+                        [
+                            [
+                                UrlRewrite::REQUEST_PATH => $requestPath,
+                                UrlRewrite::TARGET_PATH => 'custom-target-path.html',
+                                UrlRewrite::REDIRECT_TYPE => 'code',
+                                UrlRewrite::IS_AUTOGENERATED => 0,
+                                UrlRewrite::DESCRIPTION => $description,
+                                UrlRewrite::METADATA => [],
+                            ]
+                        ]
+                    )
+                )
+            );
+        $this->categoryUrlPathGenerator->expects($this->any())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($targetPath));
+        $this->category->expects($this->any())->method('getId')->will($this->returnValue($categoryId));
+        $this->urlRewriteBuilder->expects($this->once())->method('setDescription')->with($description)
+            ->will($this->returnSelf());
+        $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, 'code');
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
+        );
+    }
+
+    /**
+     * @param array $currentRewrites
+     * @return array
+     */
+    protected function getCurrentRewritesMocks($currentRewrites)
+    {
+        $rewrites = [];
+        foreach ($currentRewrites as $urlRewrite) {
+            /** @var \PHPUnit_Framework_MockObject_MockObject */
+            $url = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+                ->disableOriginalConstructor()->getMock();
+            foreach ($urlRewrite as $key => $value) {
+                $url->expects($this->any())
+                    ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))))
+                    ->will($this->returnValue($value));
+            }
+            $rewrites[] = $url;
+        }
+        return $rewrites;
+    }
+
+    /**
+     * @param mixed $storeId
+     * @param mixed $categoryId
+     * @param mixed $requestPath
+     * @param mixed $targetPath
+     * @param mixed $redirectType
+     */
+    protected function prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, $redirectType)
+    {
+        $this->urlRewriteBuilder->expects($this->any())->method('setStoreId')->with($storeId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityId')->with($categoryId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityType')
+            ->with(CategoryUrlRewriteGenerator::ENTITY_TYPE)->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRequestPath')->with($requestPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setTargetPath')->with($targetPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setIsAutogenerated')->with(0)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRedirectType')->with($redirectType)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setMetadata')->with([])->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGeneratorTest.php
new file mode 100644
index 00000000000..c887e65bfd3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGeneratorTest.php
@@ -0,0 +1,264 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Catalog\Model\Category;
+
+class CategoryUrlPathGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryFactory;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    protected function setUp()
+    {
+        $categoryMethods = [
+            '__wakeup',
+            'getUrlPath',
+            'getParentId',
+            'getLevel',
+            'dataHasChangedFor',
+            'getUrlKey',
+            'getStoreId',
+            'getId',
+            'formatUrlKey',
+            'getName',
+        ];
+        $this->category = $this->getMock('Magento\Catalog\Model\Category', $categoryMethods, [], '', false);
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->categoryFactory = $this->getMock('Magento\Catalog\Model\CategoryFactory', ['create']);
+
+        $this->categoryUrlPathGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator',
+            [
+                'storeManager' => $this->storeManager,
+                'scopeConfig' => $this->scopeConfig,
+                'categoryFactory' => $this->categoryFactory
+            ]
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function getUrlPathDataProvider()
+    {
+        $noGenerationLevel = CategoryUrlPathGenerator::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING - 1;
+        $requireGenerationLevel = CategoryUrlPathGenerator::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING;
+        return [
+            [Category::TREE_ROOT_ID, 'url-path', $noGenerationLevel, '', false, false, ''],
+            ['parent_id', 'url-path', $noGenerationLevel, '', false, false, 'url-path'],
+            ['parent_id', 'url-path', $noGenerationLevel, 'url-key', true, false, 'url-key'],
+            ['parent_id', 'url-path', $noGenerationLevel, 'url-key', false, true, 'url-key'],
+            [null, 'url-path', $requireGenerationLevel, 'url-key', false, true, 'url-key'],
+        ];
+    }
+
+    /**
+     * @dataProvider getUrlPathDataProvider
+     * @param int $parentId
+     * @param string $urlPath
+     * @param int $level
+     * @param string $urlKey
+     * @param bool $dataChangedForUrlKey
+     * @param bool $dataChangedForPathIds
+     * @param string $result
+     */
+    public function testGetUrlPath(
+        $parentId,
+        $urlPath,
+        $level,
+        $urlKey,
+        $dataChangedForUrlKey,
+        $dataChangedForPathIds,
+        $result
+    ) {
+        $this->category->expects($this->any())->method('getParentId')->will($this->returnValue($parentId));
+        $this->category->expects($this->any())->method('getLevel')->will($this->returnValue($level));
+        $this->category->expects($this->any())->method('getUrlPath')->will($this->returnValue($urlPath));
+        $this->category->expects($this->any())->method('getUrlKey')->will($this->returnValue($urlKey));
+        $this->category->expects($this->any())->method('dataHasChangedFor')
+            ->will($this->returnValueMap([['url_key', $dataChangedForUrlKey], ['path_ids', $dataChangedForPathIds]]));
+
+        $this->assertEquals($result, $this->categoryUrlPathGenerator->getUrlPath($this->category));
+    }
+
+    /**
+     * @return array
+     */
+    public function getUrlPathWithParentDataProvider()
+    {
+        return [
+            ['url-key', 'parent_id', 'parent-category-path', 'parent-category-path/url-key'],
+            ['url-key', Category::TREE_ROOT_ID, null, 'url-key'],
+        ];
+    }
+
+    /**
+     * @dataProvider getUrlPathWithParentDataProvider
+     * @param string $urlKey
+     * @param int $parentCategoryParentId
+     * @param string $parentUrlPath
+     * @param string $result
+     */
+    public function testGetUrlPathWithParent($urlKey, $parentCategoryParentId, $parentUrlPath, $result)
+    {
+        $urlPath = null;
+        $parentLevel = CategoryUrlPathGenerator::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING - 1;
+        $this->category->expects($this->any())->method('getParentId')
+            ->will($this->returnValue('parent_id'));
+        $this->category->expects($this->any())->method('getLevel')
+            ->will($this->returnValue(CategoryUrlPathGenerator::MINIMAL_CATEGORY_LEVEL_FOR_PROCESSING));
+        $this->category->expects($this->any())->method('getUrlPath')->will($this->returnValue($urlPath));
+        $this->category->expects($this->any())->method('getUrlKey')->will($this->returnValue($urlKey));
+        $methods = ['__wakeup', 'getUrlPath', 'getParentId', 'getLevel', 'dataHasChangedFor', 'load'];
+        $parentCategory = $this->getMock('Magento\Catalog\Model\Category', $methods, [], '', false);
+        $parentCategory->expects($this->any())->method('getParentId')
+            ->will($this->returnValue($parentCategoryParentId));
+        $parentCategory->expects($this->any())->method('getLevel')->will($this->returnValue($parentLevel));
+        $parentCategory->expects($this->any())->method('getUrlPath')->will($this->returnValue($parentUrlPath));
+        $parentCategory->expects($this->any())->method('load')->with('parent_id')->will($this->returnSelf());
+        $parentCategory->expects($this->any())->method('dataHasChangedFor')
+            ->will($this->returnValueMap([['url_key', false], ['path_ids', false]]));
+
+        $this->categoryFactory->expects($this->once())->method('create')
+            ->will($this->returnValue($parentCategory));
+
+        $this->assertEquals($result, $this->categoryUrlPathGenerator->getUrlPath($this->category));
+    }
+
+    /**
+     * @return array
+     */
+    public function getUrlPathWithSuffixDataProvider()
+    {
+        return [
+            ['url-path', 1, null, '.html', 'url-path.html'],
+            ['url-path', null, 1, '.html', 'url-path.html'],
+        ];
+    }
+
+    /**
+     * @dataProvider getUrlPathWithSuffixDataProvider
+     * @param string $urlPath
+     * @param int $storeId
+     * @param int $categoryStoreId
+     * @param string $suffix
+     * @param string $result
+     */
+    public function testGetUrlPathWithSuffixAndStore($urlPath, $storeId, $categoryStoreId, $suffix, $result)
+    {
+        $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue($categoryStoreId));
+        $this->category->expects($this->once())->method('getParentId')->will($this->returnValue(123));
+        $this->category->expects($this->once())->method('getUrlPath')->will($this->returnValue($urlPath));
+        $this->category->expects($this->exactly(2))->method('dataHasChangedFor')
+            ->will($this->returnValueMap([['url_key', false], ['path_ids', false]]));
+
+        $passedStoreId = $storeId ? $storeId : $categoryStoreId;
+        $this->scopeConfig->expects($this->once())->method('getValue')
+            ->with(CategoryUrlPathGenerator::XML_PATH_CATEGORY_URL_SUFFIX, ScopeInterface::SCOPE_STORE, $passedStoreId)
+            ->will($this->returnValue($suffix));
+
+        $this->assertEquals(
+            $result,
+            $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId)
+        );
+    }
+
+    public function testGetUrlPathWithSuffixWithoutStore()
+    {
+        $urlPath = 'url-path';
+        $storeId = null;
+        $currentStoreId = 1;
+        $suffix = '.html';
+        $result = 'url-path.html';
+
+        $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue($storeId));
+        $this->category->expects($this->once())->method('getParentId')->will($this->returnValue('parent_id'));
+        $this->category->expects($this->once())->method('getUrlPath')->will($this->returnValue($urlPath));
+        $this->category->expects($this->exactly(2))->method('dataHasChangedFor')
+            ->will($this->returnValueMap([['url_key', false], ['path_ids', false]]));
+
+        $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $store->expects($this->once())->method('getId')->will($this->returnValue($currentStoreId));
+        $this->storeManager->expects($this->once())->method('getStore')->will($this->returnValue($store));
+        $this->scopeConfig->expects($this->once())->method('getValue')
+            ->with(CategoryUrlPathGenerator::XML_PATH_CATEGORY_URL_SUFFIX, ScopeInterface::SCOPE_STORE, $currentStoreId)
+            ->will($this->returnValue($suffix));
+
+        $this->assertEquals(
+            $result,
+            $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId)
+        );
+    }
+
+    public function testGetCanonicalUrlPath()
+    {
+        $this->category->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $this->assertEquals(
+            'catalog/category/view/id/1',
+            $this->categoryUrlPathGenerator->getCanonicalUrlPath($this->category)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function generateUrlKeyDataProvider()
+    {
+        return [
+            ['url-key', null, 'url-key'],
+            ['', 'category-name', 'category-name'],
+        ];
+    }
+
+    /**
+     * @dataProvider generateUrlKeyDataProvider
+     * @param string $urlKey
+     * @param string $name
+     * @param string $result
+     */
+    public function testGenerateUrlKey($urlKey, $name, $result)
+    {
+        $this->category->expects($this->once())->method('getUrlKey')->will($this->returnValue($urlKey));
+        $this->category->expects($this->any())->method('getName')->will($this->returnValue($name));
+        $this->category->expects($this->once())->method('formatUrlKey')->will($this->returnArgument(0));
+
+        $this->assertEquals($result, $this->categoryUrlPathGenerator->generateUrlKey($this->category));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..93f78f770b2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\TestFramework\Helper\ObjectManager;
+
+class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $childrenUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator */
+    protected $categoryUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeViewService;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    protected function setUp()
+    {
+        $this->currentUrlRewritesRegenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Category\CurrentUrlRewritesRegenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->canonicalUrlRewriteGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Category\CanonicalUrlRewriteGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->childrenUrlRewriteGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Category\ChildrenUrlRewriteGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->storeViewService = $this->getMockBuilder('Magento\CatalogUrlRewrite\Service\V1\StoreViewService')
+            ->disableOriginalConstructor()->getMock();
+        $this->category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+
+        $this->categoryUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator',
+            [
+                'canonicalUrlRewriteGenerator' => $this->canonicalUrlRewriteGenerator,
+                'childrenUrlRewriteGenerator' => $this->childrenUrlRewriteGenerator,
+                'currentUrlRewritesRegenerator' => $this->currentUrlRewritesRegenerator,
+                'storeViewService' => $this->storeViewService,
+            ]
+        );
+    }
+
+    public function testGenerationForGlobalScope()
+    {
+        $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
+        $this->category->expects($this->any())->method('getStoreIds')->will($this->returnValue([1]));
+        $this->storeViewService->expects($this->once())->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(false));
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->childrenUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['children']));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['current']));
+
+        $this->assertEquals(
+            ['canonical', 'children', 'current'],
+            $this->categoryUrlRewriteGenerator->generate($this->category)
+        );
+    }
+
+    public function testGenerationForSpecificStore()
+    {
+        $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $this->category->expects($this->never())->method('getStoreIds');
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->childrenUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+
+        $this->assertEquals(['canonical'], $this->categoryUrlRewriteGenerator->generate($this->category));
+    }
+
+    public function testSkipGenerationForGlobalScope()
+    {
+        $this->category->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
+        $this->storeViewService->expects($this->exactly(2))->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(true));
+
+        $this->assertEquals([], $this->categoryUrlRewriteGenerator->generate($this->category));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ObjectRegistryTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ObjectRegistryTest.php
new file mode 100644
index 00000000000..30a03bc8b6d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ObjectRegistryTest.php
@@ -0,0 +1,70 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Framework\Object;
+
+class ObjectRegistryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry */
+    protected $objectRegistry;
+
+    /** @var \Magento\Framework\Object|\PHPUnit_Framework_MockObject_MockObject */
+    protected $object;
+
+    protected function setUp()
+    {
+        $this->object = $this->getMock('Magento\Framework\Object');
+        $this->object->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->objectRegistry = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\ObjectRegistry',
+            ['entities' => [$this->object]]
+        );
+    }
+
+    public function testGet()
+    {
+        $this->assertEquals($this->object, $this->objectRegistry->get(1));
+    }
+
+    public function testGetNotExistObject()
+    {
+        $this->assertEquals(null, $this->objectRegistry->get('no-id'));
+    }
+
+    public function testGetList()
+    {
+        $this->assertEquals([1 => $this->object], $this->objectRegistry->getList());
+    }
+
+    public function testGetEmptyList()
+    {
+        $objectRegistry = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\ObjectRegistry',
+            ['entities' => []]
+        );
+        $this->assertEquals([], $objectRegistry->getList());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..88644c24af1
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGeneratorTest.php
@@ -0,0 +1,103 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+
+class CanonicalUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $product;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryRegistry;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewrite;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoryRegistry = $this->getMockBuilder('\Magento\CatalogUrlRewrite\Model\ObjectRegistry')
+            ->disableOriginalConstructor()->getMock();
+        $this->productUrlPathGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->canonicalUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator',
+            [
+                'productUrlPathGenerator' => $this->productUrlPathGenerator,
+                'urlRewriteBuilder' => $this->urlRewriteBuilder
+            ]
+        );
+    }
+
+    public function testGenerate()
+    {
+        $requestPath = 'simple-product.html';
+        $storeId = 10;
+        $productId = 'product_id';
+        $targetPath = 'catalog/product/view/id/' . $productId;
+
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->productUrlPathGenerator->expects($this->any())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($requestPath));
+        $this->productUrlPathGenerator->expects($this->any())->method('getCanonicalUrlPath')
+            ->will($this->returnValue($targetPath));
+        $this->categoryRegistry->expects($this->any())->method('getList')->will($this->returnValue([]));
+
+        $this->urlRewriteBuilder->expects($this->any())->method('setStoreId')->with($storeId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityId')->with($productId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityType')
+            ->with(ProductUrlRewriteGenerator::ENTITY_TYPE)->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRequestPath')->with($requestPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setTargetPath')->with($targetPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
+        $this->assertEquals(
+            [
+                $this->urlRewrite,
+            ],
+            $this->canonicalUrlRewriteGenerator->generate($storeId, $this->product)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..5db087e85b4
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGeneratorTest.php
@@ -0,0 +1,121 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Catalog\Model\Category;
+
+class CategoriesUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator */
+    protected $categoriesUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $product;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryRegistry;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewrite;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoryRegistry = $this->getMockBuilder('\Magento\CatalogUrlRewrite\Model\ObjectRegistry')
+            ->disableOriginalConstructor()->getMock();
+        $this->productUrlPathGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->categoriesUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator',
+            [
+                'productUrlPathGenerator' => $this->productUrlPathGenerator,
+                'urlRewriteBuilder' => $this->urlRewriteBuilder
+            ]
+        );
+    }
+
+    public function testGenerateEmpty()
+    {
+        $this->categoryRegistry->expects($this->any())->method('getList')->will($this->returnValue([]));
+
+        $this->assertEquals(
+            [],
+            $this->categoriesUrlRewriteGenerator->generate(1, $this->product, $this->categoryRegistry)
+        );
+    }
+
+    public function testGenerateCategories()
+    {
+        $urlPathWithCategory = 'category/simple-product.html';
+        $storeId = 10;
+        $productId = 'product_id';
+        $canonicalUrlPathWithCategory = 'canonical-path-with-category';
+        $categoryId = 'category_id';
+
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->productUrlPathGenerator->expects($this->any())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($urlPathWithCategory));
+        $this->productUrlPathGenerator->expects($this->any())->method('getCanonicalUrlPath')
+            ->will($this->returnValue($canonicalUrlPathWithCategory));
+        $category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $category->expects($this->any())->method('getId')->will($this->returnValue($categoryId));
+        $this->categoryRegistry->expects($this->any())->method('getList')
+            ->will($this->returnValue([$category]));
+
+        $this->urlRewriteBuilder->expects($this->any())->method('setStoreId')->with($storeId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityId')->with($productId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityType')
+            ->with(ProductUrlRewriteGenerator::ENTITY_TYPE)->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRequestPath')->with($urlPathWithCategory)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setTargetPath')->with($canonicalUrlPathWithCategory)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setMetadata')
+            ->with(['category_id' => $categoryId])->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
+
+        $this->assertEquals(
+            [
+                $this->urlRewrite,
+            ],
+            $this->categoriesUrlRewriteGenerator->generate($storeId, $this->product, $this->categoryRegistry)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegeneratorTest.php
new file mode 100644
index 00000000000..aa370ad6a7e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegeneratorTest.php
@@ -0,0 +1,337 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model\Product;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+
+class CurrentUrlRewritesRegeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $filter;
+
+    /** @var \Magento\UrlRewrite\Model\UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlFinder;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $product;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $objectRegistry;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewriteBuilder;
+
+    /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlRewrite;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()->getMock();
+        $this->category = $this->getMockBuilder('Magento\Catalog\Model\Category')
+            ->disableOriginalConstructor()->getMock();
+        $this->objectRegistry = $this->getMockBuilder('\Magento\CatalogUrlRewrite\Model\ObjectRegistry')
+            ->disableOriginalConstructor()->getMock();
+        $this->filter = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\Filter')
+            ->disableOriginalConstructor()->getMock();
+        $this->filter->expects($this->any())->method('setStoreId')->will($this->returnSelf());
+        $this->filter->expects($this->any())->method('setEntityId')->will($this->returnSelf());
+        $this->urlFinder= $this->getMockBuilder('Magento\UrlRewrite\Model\UrlFinderInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->productUrlPathGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->currentUrlRewritesRegenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator',
+            [
+                'urlFinder' => $this->urlFinder,
+                'productUrlPathGenerator' => $this->productUrlPathGenerator,
+                'urlRewriteBuilder' => $this->urlRewriteBuilder
+            ]
+        );
+    }
+
+    public function testIsAutogeneratedWithoutSaveRewriteHistory()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([[UrlRewrite::IS_AUTOGENERATED => 1]])));
+        $this->product->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(false));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testSkipGenerationForAutogenerated()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [UrlRewrite::IS_AUTOGENERATED => 1, UrlRewrite::REQUEST_PATH => 'same-path']
+            ])));
+        $this->product->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(true));
+        $this->productUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue('same-path'));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testIsAutogeneratedWithoutCategory()
+    {
+        $requestPath = 'autogenerated.html';
+        $targetPath = 'some-path.html';
+        $storeId = 2;
+        $productId = 12;
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [
+                    UrlRewrite::REQUEST_PATH => $requestPath,
+                    UrlRewrite::TARGET_PATH => 'custom-target-path',
+                    UrlRewrite::STORE_ID => $storeId,
+                    UrlRewrite::IS_AUTOGENERATED => 1,
+                    UrlRewrite::METADATA => [],
+                    UrlRewrite::DESCRIPTION => $description,
+                ],
+            ])));
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->product->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(true));
+        $this->productUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($targetPath));
+
+        $this->prepareUrlRewriteMock(
+            $storeId,
+            $productId,
+            $requestPath,
+            $targetPath,
+            OptionProvider::PERMANENT,
+            [],
+            $description
+        );
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testIsAutogeneratedWithCategory()
+    {
+        $productId = 12;
+        $requestPath = 'autogenerated.html';
+        $targetPath = 'simple-product.html';
+        $storeId = 2;
+        $metadata = ['category_id' => 2, 'some_another_data' => 1];
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [
+                    UrlRewrite::REQUEST_PATH => $requestPath,
+                    UrlRewrite::TARGET_PATH => 'some-path.html',
+                    UrlRewrite::STORE_ID => $storeId,
+                    UrlRewrite::IS_AUTOGENERATED => 1,
+                    UrlRewrite::METADATA => $metadata,
+                    UrlRewrite::DESCRIPTION => $description,
+                ],
+            ])));
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->product->expects($this->once())->method('getData')->with('save_rewrites_history')
+            ->will($this->returnValue(true));
+        $this->productUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($targetPath));
+        $this->objectRegistry->expects($this->once())->method('get')->will($this->returnValue($this->category));
+        $this->prepareUrlRewriteMock(
+            $storeId,
+            $productId,
+            $requestPath,
+            $targetPath,
+            OptionProvider::PERMANENT,
+            $metadata,
+            $description
+        );
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testSkipGenerationForCustom()
+    {
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [
+                    UrlRewrite::IS_AUTOGENERATED => 0,
+                    UrlRewrite::REQUEST_PATH => 'same-path',
+                    UrlRewrite::REDIRECT_TYPE => 1
+                ]
+            ])));
+        $this->productUrlPathGenerator->expects($this->once())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue('same-path'));
+
+        $this->assertEquals(
+            [],
+            $this->currentUrlRewritesRegenerator->generate('store_id', $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testGenerationForCustomWithoutTargetPathGeneration()
+    {
+        $storeId = 12;
+        $productId = 123;
+        $requestPath = 'generate-for-custom-without-redirect-type.html';
+        $targetPath = 'custom-target-path.html';
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [
+                    UrlRewrite::REQUEST_PATH => $requestPath,
+                    UrlRewrite::TARGET_PATH => $targetPath,
+                    UrlRewrite::REDIRECT_TYPE => 0,
+                    UrlRewrite::IS_AUTOGENERATED => 0,
+                    UrlRewrite::DESCRIPTION => $description,
+                    UrlRewrite::METADATA => [],
+                ]
+            ])));
+        $this->productUrlPathGenerator->expects($this->never())->method('getUrlPathWithSuffix');
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->prepareUrlRewriteMock($storeId, $productId, $requestPath, $targetPath, 0, [], $description);
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->objectRegistry)
+        );
+    }
+
+    public function testGenerationForCustomWithTargetPathGeneration()
+    {
+        $storeId = 12;
+        $productId = 123;
+        $requestPath = 'generate-for-custom-without-redirect-type.html';
+        $targetPath = 'generated-target-path.html';
+        $description = 'description';
+        $this->urlFinder->expects($this->once())->method('findAllByData')
+            ->will($this->returnValue($this->getCurrentRewritesMocks([
+                [
+                    UrlRewrite::REQUEST_PATH => $requestPath,
+                    UrlRewrite::TARGET_PATH => 'custom-target-path.html',
+                    UrlRewrite::REDIRECT_TYPE => 'code',
+                    UrlRewrite::IS_AUTOGENERATED => 0,
+                    UrlRewrite::DESCRIPTION => $description,
+                    UrlRewrite::METADATA => [],
+                ]
+            ])));
+        $this->productUrlPathGenerator->expects($this->any())->method('getUrlPathWithSuffix')
+            ->will($this->returnValue($targetPath));
+        $this->product->expects($this->any())->method('getId')->will($this->returnValue($productId));
+        $this->prepareUrlRewriteMock($storeId, $productId, $requestPath, $targetPath, 'code', [], $description);
+
+        $this->assertEquals(
+            [$this->urlRewrite],
+            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->objectRegistry)
+        );
+    }
+
+    /**
+     * @param array $currentRewrites
+     * @return array
+     */
+    protected function getCurrentRewritesMocks($currentRewrites)
+    {
+        $rewrites = [];
+        foreach ($currentRewrites as $urlRewrite) {
+            /** @var \PHPUnit_Framework_MockObject_MockObject */
+            $url = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+                ->disableOriginalConstructor()->getMock();
+            foreach ($urlRewrite as $key => $value) {
+                $url->expects($this->any())
+                    ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))))
+                    ->will($this->returnValue($value));
+            }
+            $rewrites[] = $url;
+        }
+        return $rewrites;
+    }
+
+    /**
+     * @param mixed $storeId
+     * @param mixed $productId
+     * @param mixed $requestPath
+     * @param mixed $targetPath
+     * @param mixed $redirectType
+     * @param mixed $metadata
+     * @param mixed $description
+     */
+    protected function prepareUrlRewriteMock(
+        $storeId,
+        $productId,
+        $requestPath,
+        $targetPath,
+        $redirectType,
+        $metadata,
+        $description
+    ) {
+        $this->urlRewriteBuilder->expects($this->any())->method('setStoreId')->with($storeId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityId')->with($productId)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setEntityType')
+            ->with(ProductUrlRewriteGenerator::ENTITY_TYPE)->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRequestPath')->with($requestPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setTargetPath')->with($targetPath)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setIsAutogenerated')->with(0)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setRedirectType')->with($redirectType)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('setMetadata')->with($metadata)
+            ->will($this->returnSelf());
+        $this->urlRewriteBuilder->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
+        $this->urlRewriteBuilder->expects($this->once())->method('setDescription')->with($description)
+            ->will($this->returnSelf());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlPathGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlPathGeneratorTest.php
new file mode 100644
index 00000000000..5970d6aad28
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlPathGeneratorTest.php
@@ -0,0 +1,181 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use \Magento\Store\Model\ScopeInterface;
+
+class ProductUrlPathGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator */
+    protected $productUrlPathGenerator;
+
+    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoryUrlPathGenerator;
+
+    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $product;
+
+    /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
+    protected $category;
+
+    protected function setUp()
+    {
+        $this->category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $productMethods = ['__wakeup', 'getData', 'getUrlKey', 'getName', 'formatUrlKey', 'getId'];
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', $productMethods, [], '', false);
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->categoryUrlPathGenerator = $this->getMock(
+            'Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->productUrlPathGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator',
+            [
+                'storeManager' => $this->storeManager,
+                'scopeConfig' => $this->scopeConfig,
+                'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator
+            ]
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function getUrlPathDataProvider()
+    {
+        return [
+            'path based on url key' => ['url-key', null, 'url-key'],
+            'path based on product name 1' => ['', 'product-name', 'product-name'],
+            'path based on product name 2' => [null, 'product-name', 'product-name'],
+        ];
+    }
+
+    /**
+     * @dataProvider getUrlPathDataProvider
+     * @param $urlKey
+     * @param $productName
+     * @param $result
+     */
+    public function testGenerateUrlPath($urlKey, $productName, $result)
+    {
+        $this->product->expects($this->once())->method('getData')->with('url_path')
+            ->will($this->returnValue(null));
+        $this->product->expects($this->once())->method('getUrlKey')->will($this->returnValue($urlKey));
+        $this->product->expects($this->any())->method('getName')->will($this->returnValue($productName));
+        $this->product->expects($this->once())->method('formatUrlKey')->will($this->returnArgument(0));
+
+        $this->assertEquals($result, $this->productUrlPathGenerator->getUrlPath($this->product, null));
+    }
+
+    public function testGetUrlPath()
+    {
+        $this->product->expects($this->once())->method('getData')->with('url_path')
+            ->will($this->returnValue('url-path'));
+        $this->product->expects($this->never())->method('getUrlKey');
+
+        $this->assertEquals('url-path', $this->productUrlPathGenerator->getUrlPath($this->product, null));
+    }
+
+    public function testGetUrlPathWithCategory()
+    {
+        $this->product->expects($this->once())->method('getData')->with('url_path')
+            ->will($this->returnValue('product-path'));
+        $this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPath')
+            ->will($this->returnValue('category-url-path'));
+
+        $this->assertEquals(
+            'category-url-path/product-path',
+            $this->productUrlPathGenerator->getUrlPath($this->product, $this->category)
+        );
+    }
+
+    public function testGetUrlPathWithSuffix()
+    {
+        $storeId = 1;
+        $this->product->expects($this->once())->method('getData')->with('url_path')
+            ->will($this->returnValue('product-path'));
+        $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $store->expects($this->once())->method('getId')->will($this->returnValue($storeId));
+        $this->storeManager->expects($this->once())->method('getStore')->will($this->returnValue($store));
+        $this->scopeConfig->expects($this->once())->method('getValue')
+            ->with(ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, ScopeInterface::SCOPE_STORE, $storeId)
+            ->will($this->returnValue('.html'));
+
+        $this->assertEquals(
+            'product-path.html',
+            $this->productUrlPathGenerator->getUrlPathWithSuffix($this->product, null)
+        );
+    }
+
+    public function testGetUrlPathWithSuffixAndCategoryAnsStore()
+    {
+        $storeId = 1;
+        $this->product->expects($this->once())->method('getData')->with('url_path')
+            ->will($this->returnValue('product-path'));
+        $this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPath')
+            ->will($this->returnValue('category-url-path'));
+        $this->storeManager->expects($this->never())->method('getStore');
+        $this->scopeConfig->expects($this->once())->method('getValue')
+            ->with(ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, ScopeInterface::SCOPE_STORE, $storeId)
+            ->will($this->returnValue('.html'));
+
+        $this->assertEquals(
+            'category-url-path/product-path.html',
+            $this->productUrlPathGenerator->getUrlPathWithSuffix($this->product, $storeId, $this->category)
+        );
+    }
+
+    public function testGetCanonicalUrlPath()
+    {
+        $this->product->expects($this->once())->method('getId')->will($this->returnValue(1));
+
+        $this->assertEquals(
+            'catalog/product/view/id/1',
+            $this->productUrlPathGenerator->getCanonicalUrlPath($this->product)
+        );
+    }
+
+    public function testGetCanonicalUrlPathWithCategory()
+    {
+        $this->product->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $this->category->expects($this->once())->method('getId')->will($this->returnValue(1));
+
+        $this->assertEquals(
+            'catalog/product/view/id/1/category/1',
+            $this->productUrlPathGenerator->getCanonicalUrlPath($this->product, $this->category)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGeneratorTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGeneratorTest.php
new file mode 100644
index 00000000000..ccbd68f9549
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGeneratorTest.php
@@ -0,0 +1,210 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $canonicalUrlRewriteGenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $currentUrlRewritesRegenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $categoriesUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator */
+    protected $productUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeViewService;
+
+    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $product;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $objectRegistryFactory;
+
+    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Catalog\Model\Resource\Category\Collection|\PHPUnit_Framework_MockObject_MockObject */
+    protected $categoriesCollection;
+
+    protected function setUp()
+    {
+        $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+        $this->categoriesCollection = $this->getMockBuilder('Magento\Catalog\Model\Resource\Category\Collection')
+            ->disableOriginalConstructor()->getMock();
+        $this->product->expects($this->any())->method('getCategoryCollection')
+            ->will($this->returnValue($this->categoriesCollection));
+        $this->storeManager = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+            ->disableOriginalConstructor()->getMock();
+        $this->categoriesCollection->expects($this->exactly(2))->method('addAttributeToSelect')
+            ->will($this->returnSelf());
+        $this->currentUrlRewritesRegenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->canonicalUrlRewriteGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->categoriesUrlRewriteGenerator = $this->getMockBuilder(
+            'Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator'
+        )->disableOriginalConstructor()->getMock();
+        $this->objectRegistryFactory = $this->getMockBuilder('Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory')
+            ->disableOriginalConstructor()->setMethods(['create'])->getMock();
+        $this->storeViewService = $this->getMockBuilder('Magento\CatalogUrlRewrite\Service\V1\StoreViewService')
+            ->disableOriginalConstructor()->getMock();
+
+        $this->productUrlRewriteGenerator = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator',
+            [
+                'canonicalUrlRewriteGenerator' => $this->canonicalUrlRewriteGenerator,
+                'categoriesUrlRewriteGenerator' => $this->categoriesUrlRewriteGenerator,
+                'currentUrlRewritesRegenerator' => $this->currentUrlRewritesRegenerator,
+                'objectRegistryFactory' => $this->objectRegistryFactory,
+                'storeViewService' => $this->storeViewService,
+                'storeManager' => $this->storeManager,
+            ]
+        );
+    }
+
+    public function testGenerationForGlobalScope()
+    {
+        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
+        $this->product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1]));
+        $this->storeViewService->expects($this->once())->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(false));
+        $this->categoriesCollection->expects($this->any())->method('getIterator')
+            ->willReturn(new \ArrayIterator([]));
+        $this->initObjectRegistryFactory([]);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['categories']));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['current']));
+
+        $this->assertEquals(
+            ['canonical', 'categories', 'current'],
+            $this->productUrlRewriteGenerator->generate($this->product)
+        );
+    }
+
+    public function testGenerationForSpecificStore()
+    {
+        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $this->product->expects($this->never())->method('getStoreIds');
+        $storeRootCategoryId = 'root-for-store-id';
+        $category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $category->expects($this->any())->method('getParentIds')
+            ->will($this->returnValue(['root-id', $storeRootCategoryId]));
+        $category->expects($this->any())->method('getParentId')->will($this->returnValue('parent_id'));
+        $category->expects($this->any())->method('getId')->will($this->returnValue('category_id'));
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue($storeRootCategoryId));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $this->categoriesCollection->expects($this->any())->method('getIterator')
+            ->willReturn(new \ArrayIterator([$category]));
+        $this->initObjectRegistryFactory([$category]);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+
+        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+    }
+
+    public function testSkipRootCategoryForCategoriesGenerator()
+    {
+        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $this->product->expects($this->never())->method('getStoreIds');
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue('root-for-store-id'));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $rootCategory = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $rootCategory->expects($this->any())->method('getParentIds')->will($this->returnValue([1, 2]));
+        $rootCategory->expects($this->any())->method('getParentId')->will($this->returnValue(Category::TREE_ROOT_ID));
+        $this->categoriesCollection->expects($this->any())->method('getIterator')
+            ->willReturn(new \ArrayIterator([$rootCategory]));
+        $this->initObjectRegistryFactory([]);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+
+        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+    }
+
+    public function testSkipGenerationForNotStoreRootCategory()
+    {
+        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $this->product->expects($this->never())->method('getStoreIds');
+        $category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $category->expects($this->any())->method('getParentIds')
+            ->will($this->returnValue(['root-id', 'root-for-store-id']));
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue('not-root-id'));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $this->categoriesCollection->expects($this->any())->method('getIterator')
+            ->willReturn(new \ArrayIterator([$category]));
+        $this->initObjectRegistryFactory([]);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue(['canonical']));
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+
+        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+    }
+
+    public function testSkipGenerationForGlobalScope()
+    {
+        $this->product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
+        $this->storeViewService->expects($this->exactly(2))->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(true));
+
+        $this->assertEquals([], $this->productUrlRewriteGenerator->generate($this->product));
+    }
+
+    /**
+     * @param array $entities
+     */
+    protected function initObjectRegistryFactory($entities)
+    {
+        $objectRegistry = $this->getMockBuilder('Magento\CatalogUrlRewrite\Model\ObjectRegistry')
+            ->disableOriginalConstructor()->getMock();
+        $this->objectRegistryFactory->expects($this->any())->method('create')
+            ->with(['entities' => $entities])
+            ->will($this->returnValue($objectRegistry));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/_files/categoryUrlRewritesDataProvider.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/_files/categoryUrlRewritesDataProvider.php
new file mode 100644
index 00000000000..c7951b5422e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Model/_files/categoryUrlRewritesDataProvider.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+
+return [
+    [1, 1, 'test-category.html', null, [
+        [
+            'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            'entity_id' => 1,
+            'store_id' => 1,
+            'request_path' => 'test-category.html',
+            'target_path' => 'catalog/category/view/id/1',
+            'redirect_type' => 0,
+            'is_autogenerated' => true,
+            'metadata' => null
+        ]
+    ]],
+    [1, 1, 'test-category.html', [
+        [
+            UrlRewrite::REQUEST_PATH => 'generate-for-autogenerated.html',
+            UrlRewrite::TARGET_PATH => 'some-path.html',
+            UrlRewrite::STORE_ID => 2,
+            UrlRewrite::IS_AUTOGENERATED => 1,
+        ],
+        [
+            UrlRewrite::REQUEST_PATH => 'test-category.html',
+            UrlRewrite::TARGET_PATH => 'skip-generation-due-to-equals-request-and-generated-target-path.html',
+            UrlRewrite::IS_AUTOGENERATED => 1,
+        ],
+        [
+            UrlRewrite::REQUEST_PATH => 'generate-for-custom-by-user.html',
+            UrlRewrite::TARGET_PATH => 'custom-target-path.html',
+            UrlRewrite::REDIRECT_TYPE => 'some-type',
+            UrlRewrite::IS_AUTOGENERATED => 0,
+            UrlRewrite::METADATA => ['is_user_generated' => 1],
+        ],
+        [
+            UrlRewrite::REQUEST_PATH => 'generate-for-custom-without-redirect-type.html',
+            UrlRewrite::TARGET_PATH => 'custom-target-path2.html',
+            UrlRewrite::REDIRECT_TYPE => 0,
+            UrlRewrite::IS_AUTOGENERATED => 0,
+            UrlRewrite::METADATA => ['is_user_generated' => false],
+        ],
+        [
+            UrlRewrite::REQUEST_PATH => 'skip-equals-paths.html',
+            UrlRewrite::TARGET_PATH => 'skip-equals-paths.html',
+            UrlRewrite::REDIRECT_TYPE => 0,
+            UrlRewrite::IS_AUTOGENERATED => 0,
+        ],
+    ], [
+        [
+            'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            'entity_id' => 1,
+            'store_id' => 1,
+            'request_path' => 'test-category.html',
+            'target_path' => 'catalog/category/view/id/1',
+            'redirect_type' => 0,
+            'is_autogenerated' => true,
+            'metadata' => null
+        ],
+        [
+            'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            'entity_id' => 1,
+            'store_id' => 2,
+            'request_path' => 'generate-for-autogenerated.html',
+            'target_path' => 'test-category.html',
+            'redirect_type' => OptionProvider::PERMANENT,
+            'is_autogenerated' => false,
+            'metadata' => null
+        ],
+        [
+            'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            'entity_id' => 1,
+            'store_id' => 1,
+            'request_path' => 'generate-for-custom-by-user.html',
+            'target_path' => 'custom-target-path.html',
+            'redirect_type' => 'some-type',
+            'is_autogenerated' => false,
+            'metadata' => serialize(['is_user_generated' => 1]),
+        ],
+        [
+            'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE,
+            'entity_id' => 1,
+            'store_id' => 1,
+            'request_path' => 'generate-for-custom-without-redirect-type.html',
+            'target_path' => 'custom-target-path2.html',
+            'redirect_type' => 0,
+            'is_autogenerated' => false,
+            'metadata' => serialize(['is_user_generated' => false]),
+        ],
+    ]],
+];
diff --git a/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Service/V1/StoreViewServiceTest.php b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Service/V1/StoreViewServiceTest.php
new file mode 100644
index 00000000000..db2969459d1
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogUrlRewrite/Service/V1/StoreViewServiceTest.php
@@ -0,0 +1,129 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogUrlRewrite\Service\V1;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use \Magento\Catalog\Model\Category;
+use \Magento\Catalog\Model\Product;
+
+class StoreViewServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService */
+    protected $storeViewService;
+
+    /** @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $config;
+
+    /** @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resource;
+
+    /** @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $connection;
+
+    /** @var  \Magento\Framework\Db\Select|\PHPUnit_Framework_MockObject_MockObject */
+    protected $select;
+
+    protected function setUp()
+    {
+        $this->config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
+        $this->select = $this->getMock('Magento\Framework\Db\Select', [], [], '', false);
+        $this->connection = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface', [], [], '', false);
+        $this->resource = $this->getMock('Magento\Framework\App\Resource', [], [], '', false);
+        $this->resource->expects($this->any())->method('getConnection')->will($this->returnValue($this->connection));
+
+        $this->storeViewService = (new ObjectManager($this))->getObject(
+            'Magento\CatalogUrlRewrite\Service\V1\StoreViewService',
+            [
+                'eavConfig' => $this->config,
+                'resource' => $this->resource,
+            ]
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function isRootCategoryForStoreDataProvider()
+    {
+        return [
+            [1, 1, 1, true],
+            [1, 2, 1, false],
+            [2, 0, 1, false],
+        ];
+    }
+
+    /**
+     * @return array
+     */
+    public function overriddenUrlKeyForStoreDataProvider()
+    {
+        return [
+            [1, [1, 2], true],
+            [1, [2, 3], false],
+            [1, [], false],
+        ];
+    }
+
+    /**
+     * @dataProvider overriddenUrlKeyForStoreDataProvider
+     * @param int $storeId
+     * @param array $fetchedStoreIds
+     * @param bool $result
+     */
+    public function testDoesEntityHaveOverriddenUrlKeyForStore($storeId, $fetchedStoreIds, $result)
+    {
+        $entityType = 'entity_type';
+        $productId = 'product_id';
+        $attribute = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\AbstractAttribute')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup', 'getBackendTable', 'getId'])
+            ->getMockForAbstractClass();
+        $this->config->expects($this->once())->method('getAttribute')->with($entityType, 'url_key')
+            ->will($this->returnValue($attribute));
+        $attribute->expects($this->once())->method('getBackendTable')->will($this->returnValue('backend_table'));
+        $attribute->expects($this->once())->method('getId')->will($this->returnValue('attribute-id'));
+        $this->select->expects($this->once())->method('from')->with('backend_table', 'store_id')
+            ->will($this->returnSelf());
+        $this->select->expects($this->any())->method('where')->will($this->returnSelf());
+        $this->connection->expects($this->once())->method('select')->will($this->returnValue($this->select));
+        $this->connection->expects($this->once())->method('fetchCol')->will($this->returnValue($fetchedStoreIds));
+
+        $this->assertEquals(
+            $result,
+            $this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore($storeId, $productId, $entityType)
+        );
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Cannot retrieve attribute for entity type "invalid_type"
+     */
+    public function testInvalidAttributeRetrieve()
+    {
+        $invalidEntityType = 'invalid_type';
+        $this->config->expects($this->once())->method('getAttribute')->will($this->returnValue(false));
+
+        $this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore(1, 1, $invalidEntityType);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
index c1bcb590b01..556312aebae 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
@@ -95,6 +95,16 @@ class IndexTest extends \PHPUnit_Framework_TestCase
      */
     private $model;
 
+    /**
+     * @var \Magento\Framework\View\Result\Page
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfigMock;
+
     public function setUp()
     {
         // mock objects
@@ -110,12 +120,16 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         $this->requestMock = $this->basicMock('\Magento\Framework\App\RequestInterface');
         $this->responseMock = $this->basicMock('\Magento\Framework\App\ResponseInterface');
         $this->redirectMock = $this->basicMock('\Magento\Framework\App\Response\RedirectInterface');
+        $this->resultPageMock = $this->basicMock('\Magento\Framework\View\Result\Page');
+        $this->pageConfigMock = $this->basicMock('\Magento\Framework\View\Page\Config');
 
         // stubs
         $this->basicStub($this->onepageMock, 'getQuote')->willReturn($this->quoteMock);
         $this->basicStub($this->viewMock, 'getLayout')->willReturn($this->layoutMock);
+        $this->basicStub($this->viewMock, 'getPage')->willReturn($this->resultPageMock);
         $this->basicStub($this->layoutMock, 'getBlock')
             ->willReturn($this->basicMock('Magento\Theme\Block\Html\Head'));
+        $this->basicStub($this->resultPageMock, 'getConfig')->willReturn($this->pageConfigMock);
 
         // objectManagerMock
         $objectManagerReturns = [
@@ -141,7 +155,8 @@ class IndexTest extends \PHPUnit_Framework_TestCase
 
 
         // SUT
-        $this->model = $this->objectManager->getObject('\Magento\Checkout\Controller\Onepage\Index',
+        $this->model = $this->objectManager->getObject(
+            '\Magento\Checkout\Controller\Onepage\Index',
             [
                 'context' => $this->contextMock,
                 'customerSession' => $this->sessionMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
index 54ee89203cb..ee6ac8d6e75 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
@@ -53,6 +53,16 @@ class CartTest extends \PHPUnit_Framework_TestCase
      */
     protected $scopeConfigMock;
 
+    /**
+     * @var \Magento\Sales\Model\Quote|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
     protected function setUp()
     {
         $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false);
@@ -65,6 +75,8 @@ class CartTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->quoteMock = $this->getMock('Magento\Sales\Model\Quote', [], [], '', false);
+        $this->eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
 
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->cart = $this->objectManagerHelper->getObject(
@@ -74,6 +86,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
                 'checkoutSession' => $this->checkoutSessionMock,
                 'stockItemService' => $this->stockItemMock,
                 'customerSession' => $this->customerSessionMock,
+                'eventManager' => $this->eventManagerMock
             ]
         );
     }
@@ -81,9 +94,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
     public function testSuggestItemsQty()
     {
         $data = [[], ['qty' => -2], ['qty' => 3], ['qty' => 3.5], ['qty' => 5], ['qty' => 4]];
-
-        $quote = $this->getMock('Magento\Sales\Model\Quote', [], [], '', false);
-        $quote->expects($this->any())
+        $this->quoteMock->expects($this->any())
             ->method('getItemById')
             ->will($this->returnValueMap([
                 [2, $this->prepareQuoteItemMock(2)],
@@ -98,7 +109,7 @@ class CartTest extends \PHPUnit_Framework_TestCase
 
         $this->checkoutSessionMock->expects($this->once())
             ->method('getQuote')
-            ->will($this->returnValue($quote));
+            ->will($this->returnValue($this->quoteMock));
 
         $this->assertSame(
             [
@@ -113,6 +124,27 @@ class CartTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    public function testUpdateItems()
+    {
+        $data = [['qty' => 5.5, 'before_suggest_qty' => 5.5]];
+        $infoDataObject = $this->objectManagerHelper->getObject('Magento\Framework\Object', ['data' => $data]);
+
+        $this->checkoutSessionMock->expects($this->once())
+            ->method('getQuote')
+            ->will($this->returnValue($this->quoteMock));
+        $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with(
+            'checkout_cart_update_items_before',
+            ['cart' => $this->cart, 'info' => $infoDataObject]
+        );
+        $this->eventManagerMock->expects($this->at(1))->method('dispatch')->with(
+            'checkout_cart_update_items_after',
+            ['cart' => $this->cart, 'info' => $infoDataObject]
+        );
+
+        $result = $this->cart->updateItems($data);
+        $this->assertSame($this->cart, $result);
+    }
+
     /**
      * @param int|bool $itemId
      * @return \PHPUnit_Framework_MockObject_MockObject
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
index 67ffa0e07f7..a38b796cd38 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
@@ -1,6 +1,5 @@
 <?php
-/** 
- * 
+/**
  * Magento
  *
  * NOTICE OF LICENSE
@@ -135,13 +134,6 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
             ->expects($this->any())
             ->method('getFilterGroups')
             ->will($this->returnValue([$filterGroupMock]));
-        $sortOrderMock = $this->getMock('\Magento\Framework\Service\V1\Data\SortOrder', [], [], '', false);
-        $searchCriteriaMock
-            ->expects($this->any())
-            ->method('getSortOrders')
-            ->will($this->returnValue([$sortOrderMock]));
-        $sortOrderMock->expects($this->once())->method('getField')->will($this->returnValue('id'));
-        $sortOrderMock->expects($this->once())->method('getDirection')->will($this->returnValue($direction));
 
         $filterMock = $this->getMock('\Magento\Framework\Service\V1\Data\Filter', [], [], '', false);
         $filterGroupMock->expects($this->any())->method('getFilters')->will($this->returnValue([$filterMock]));
@@ -155,7 +147,16 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
 
         $this->quoteCollectionMock->expects($this->once())->method('getSize')->will($this->returnValue(10));
         $this->searchResultsBuilderMock->expects($this->once())->method('setTotalCount')->with(10);
-
+        $sortOrderMock = $this->getMockBuilder('Magento\Framework\Service\V1\Data\SortOrder')
+            ->setMethods(['getField', 'getDirection'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $sortOrderMock->expects($this->once())->method('getField')->will($this->returnValue('id'));
+        $sortOrderMock->expects($this->once())->method('getDirection')->will($this->returnValue($direction));
+        $searchCriteriaMock
+            ->expects($this->once())
+            ->method('getSortOrders')
+            ->will($this->returnValue([$sortOrderMock]));
         $this->quoteCollectionMock->expects($this->once())->method('addOrder')->with('entity_id', $expected);
         $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->will($this->returnValue(1));
         $searchCriteriaMock->expects($this->once())->method('getPageSize')->will($this->returnValue(10));
diff --git a/dev/tests/unit/testsuite/Magento/Cms/Model/Page/UrlrewriteTest.php b/dev/tests/unit/testsuite/Magento/Cms/Model/Page/UrlrewriteTest.php
deleted file mode 100644
index 5e47a105253..00000000000
--- a/dev/tests/unit/testsuite/Magento/Cms/Model/Page/UrlrewriteTest.php
+++ /dev/null
@@ -1,87 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Test for \Magento\Cms\Model\Page\UrlrewriteTest
- */
-namespace Magento\Cms\Model\Page;
-
-class UrlrewriteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Cms\Model\Page\Urlrewrite
-     */
-    protected $_model = null;
-
-    /**
-     * @var \Magento\Framework\Object
-     */
-    protected $_cmsPage = null;
-
-    /**
-     * Prepare test classes
-     */
-    protected function setUp()
-    {
-        $this->_model = $this->getMockBuilder(
-            'Magento\Cms\Model\Page\Urlrewrite'
-        )->setMethods(
-            array('getResourceModelInstance', '__wakeup')
-        )->disableOriginalConstructor()->getMock();
-        $this->_cmsPage = new \Magento\Framework\Object(array('id' => 3, 'identifier' => 'cms-page'));
-    }
-
-    /**
-     * Clear created objects
-     */
-    protected function tearDown()
-    {
-        unset($this->_model);
-        unset($this->_cmsPage);
-    }
-
-    /**
-     * Test generateIdPath
-     */
-    public function testGenerateIdPath()
-    {
-        $this->assertEquals('cms_page/3', $this->_model->generateIdPath($this->_cmsPage));
-    }
-
-    /**
-     * Test generateTargetPath
-     */
-    public function testGenerateTargetPath()
-    {
-        $this->assertEquals('cms/page/view/page_id/3', $this->_model->generateTargetPath($this->_cmsPage));
-    }
-
-    /**
-     * Test generateRequestPath
-     */
-    public function testGenerateRequestPath()
-    {
-        $this->assertEquals('cms-page', $this->_model->generateRequestPath($this->_cmsPage));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/DataTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/DataTest.php
new file mode 100644
index 00000000000..ac0a0a468b8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Price/DataTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price;
+
+/**
+ * Class DataTest
+ */
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /*
+     * Test for setProductPrice and getProductPrice data
+     */
+    public function testGetProductPrice()
+    {
+        $productId = 1;
+        $productPrice = ['pricing' => 'test'];
+        $priceData = new Data();
+        $priceData->setProductPrice($productId, $productPrice);
+        $this->assertEquals($productPrice, $priceData->getProductPrice($productId));
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Core/App/Router/BaseTest.php b/dev/tests/unit/testsuite/Magento/Core/App/Router/BaseTest.php
new file mode 100644
index 00000000000..85ef5764eb8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/App/Router/BaseTest.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Tests Magento\Core\App\Router\Base
+ *
+ * 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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\App\Router;
+
+class BaseTest extends \Magento\Test\BaseTestCase
+{
+    /**
+     * @var \Magento\Core\App\Router\Base
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\RequestInterface
+     */
+    private $requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Route\ConfigInterface
+     */
+    private $routeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\State
+     */
+    private $appStateMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Router\ActionList
+     */
+    private $actionListMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\ActionFactory
+     */
+    private $actionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Code\NameBuilder
+     */
+    private $nameBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\DefaultPathInterface
+     */
+    private $defaultPathMock;
+
+    public function setUp()
+    {
+        parent::setUp();
+        // Create mocks
+        $requestMethods = [
+            'getActionName',
+            'getModuleName',
+            'getParam',
+            'setActionName',
+            'setModuleName',
+            'setRouteName',
+            'getPathInfo',
+            'getControllerName',
+            'setControllerName',
+            'setControllerModule',
+            'setAlias',
+            'getCookie',
+            'getOriginalPathInfo',
+            'getPost',
+            'isSecure',
+            'setParams',
+        ];
+
+        $this->requestMock = $this->getMock('Magento\Framework\App\RequestInterface', $requestMethods);
+        $this->routeConfigMock = $this->basicMock('Magento\Framework\App\Route\ConfigInterface');
+        $this->appStateMock = $this->basicMock('Magento\Framework\App\State');
+        $this->actionListMock = $this->basicMock('Magento\Framework\App\Router\ActionList');
+        $this->actionFactoryMock = $this->basicMock('Magento\Framework\App\ActionFactory');
+        $this->nameBuilderMock = $this->basicMock('Magento\Framework\Code\NameBuilder');
+        $this->defaultPathMock = $this->basicMock('Magento\Framework\App\DefaultPathInterface');
+
+        // Prepare SUT
+        $mocks = [
+            'actionList' => $this->actionListMock,
+            'actionFactory' => $this->actionFactoryMock,
+            'routeConfig' => $this->routeConfigMock,
+            'appState' => $this->appStateMock,
+            'nameBuilder' => $this->nameBuilderMock,
+            'defaultPath' => $this->defaultPathMock,
+        ];
+        $this->model = $this->objectManager->getObject('Magento\Core\App\Router\Base', $mocks);
+    }
+
+    public function testMatch()
+    {
+        // Test Data
+        $actionInstance = 'action instance';
+        $moduleFrontName = 'module front name';
+        $actionPath = 'action path';
+        $actionName = 'action name';
+        $actionClassName = 'Magento\Cms\Controller\Index\Index';
+        $moduleName = 'module name';
+        $moduleList = [$moduleName];
+
+        // Stubs
+        $this->requestMock->expects($this->any())->method('getModuleName')->willReturn($moduleFrontName);
+        $this->requestMock->expects($this->any())->method('getControllerName')->willReturn($actionPath);
+        $this->requestMock->expects($this->any())->method('getActionName')->willReturn($actionName);
+        $this->routeConfigMock->expects($this->any())->method('getModulesByFrontName')->willReturn($moduleList);
+        $this->appStateMock->expects($this->any())->method('isInstalled')->willReturn(true);
+        $this->actionListMock->expects($this->any())->method('get')->willReturn($actionClassName);
+        $this->actionFactoryMock->expects($this->any())->method('create')->willReturn($actionInstance);
+
+        // Expectations and Test
+        $this->requestExpects('setModuleName', $moduleFrontName)
+            ->requestExpects('setControllerName', $actionPath)
+            ->requestExpects('setActionName', $actionName)
+            ->requestExpects('setControllerModule', $moduleName);
+
+        $this->assertSame($actionInstance, $this->model->match($this->requestMock));
+    }
+
+    public function testMatchUseParams()
+    {
+        // Test Data
+        $actionInstance = 'action instance';
+        $moduleFrontName = 'module front name';
+        $actionPath = 'action path';
+        $actionName = 'action name';
+        $actionClassName = 'Magento\Cms\Controller\Index\Index';
+        $moduleName = 'module name';
+        $moduleList = [$moduleName];
+        $paramList = $moduleFrontName . '/' . $actionPath . '/' . $actionName . '/key/val/key2/val2/';
+
+        // Stubs
+        $this->requestMock->expects($this->any())->method('getPathInfo')->willReturn($paramList);
+        $this->routeConfigMock->expects($this->any())->method('getModulesByFrontName')->willReturn($moduleList);
+        $this->appStateMock->expects($this->any())->method('isInstalled')->willReturn(false);
+        $this->actionListMock->expects($this->any())->method('get')->willReturn($actionClassName);
+        $this->actionFactoryMock->expects($this->any())->method('create')->willReturn($actionInstance);
+
+        // Expectations and Test
+        $this->requestExpects('setModuleName', $moduleFrontName)
+            ->requestExpects('setControllerName', $actionPath)
+            ->requestExpects('setActionName', $actionName)
+            ->requestExpects('setControllerModule', $moduleName);
+
+        $this->assertSame($actionInstance, $this->model->match($this->requestMock));
+    }
+
+    public function testMatchUseDefaultPath()
+    {
+        // Test Data
+        $actionInstance = 'action instance';
+        $moduleFrontName = 'module front name';
+        $actionPath = 'action path';
+        $actionName = 'action name';
+        $actionClassName = 'Magento\Cms\Controller\Index\Index';
+        $moduleName = 'module name';
+        $moduleList = [$moduleName];
+
+        // Stubs
+        $defaultReturnMap = [
+            ['module', $moduleFrontName],
+            ['controller', $actionPath],
+            ['action', $actionName]
+        ];
+        $this->defaultPathMock->expects($this->any())->method('getPart')->willReturnMap($defaultReturnMap);
+        $this->routeConfigMock->expects($this->any())->method('getModulesByFrontName')->willReturn($moduleList);
+        $this->appStateMock->expects($this->any())->method('isInstalled')->willReturn(false);
+        $this->actionListMock->expects($this->any())->method('get')->willReturn($actionClassName);
+        $this->actionFactoryMock->expects($this->any())->method('create')->willReturn($actionInstance);
+
+        // Expectations and Test
+        $this->requestExpects('setModuleName', $moduleFrontName)
+            ->requestExpects('setControllerName', $actionPath)
+            ->requestExpects('setActionName', $actionName)
+            ->requestExpects('setControllerModule', $moduleName);
+
+        $this->assertSame($actionInstance, $this->model->match($this->requestMock));
+    }
+
+    public function testMatchEmptyModuleList()
+    {
+        // Test Data
+        $actionInstance = 'action instance';
+        $moduleFrontName = 'module front name';
+        $actionPath = 'action path';
+        $actionName = 'action name';
+        $actionClassName = 'Magento\Cms\Controller\Index\Index';
+        $emptyModuleList = [];
+
+        // Stubs
+        $this->requestMock->expects($this->any())->method('getModuleName')->willReturn($moduleFrontName);
+        $this->routeConfigMock->expects($this->any())->method('getModulesByFrontName')->willReturn($emptyModuleList);
+        $this->requestMock->expects($this->any())->method('getControllerName')->willReturn($actionPath);
+        $this->requestMock->expects($this->any())->method('getActionName')->willReturn($actionName);
+        $this->appStateMock->expects($this->any())->method('isInstalled')->willReturn(false);
+        $this->actionListMock->expects($this->any())->method('get')->willReturn($actionClassName);
+        $this->actionFactoryMock->expects($this->any())->method('create')->willReturn($actionInstance);
+
+        // Test
+        $this->assertNull($this->model->match($this->requestMock));
+    }
+
+    public function testMatchEmptyActionInstance()
+    {
+        // Test Data
+        $nullActionInstance = null;
+        $moduleFrontName = 'module front name';
+        $actionPath = 'action path';
+        $actionName = 'action name';
+        $actionClassName = 'Magento\Cms\Controller\Index\Index';
+        $moduleName = 'module name';
+        $moduleList = [$moduleName];
+
+        // Stubs
+        $this->requestMock->expects($this->any())->method('getModuleName')->willReturn($moduleFrontName);
+        $this->routeConfigMock->expects($this->any())->method('getModulesByFrontName')->willReturn($moduleList);
+        $this->requestMock->expects($this->any())->method('getControllerName')->willReturn($actionPath);
+        $this->requestMock->expects($this->any())->method('getActionName')->willReturn($actionName);
+        $this->appStateMock->expects($this->any())->method('isInstalled')->willReturn(false);
+        $this->actionListMock->expects($this->any())->method('get')->willReturn($actionClassName);
+        $this->actionFactoryMock->expects($this->any())->method('create')->willReturn($nullActionInstance);
+
+        // Expectations and Test
+        $this->assertNull($this->model->match($this->requestMock));
+    }
+
+    public function testGetActionClassName()
+    {
+        $className = 'name of class';
+        $module = 'module';
+        $prefix = 'Controller';
+        $actionPath = 'action path';
+        $this->nameBuilderMock->expects($this->once())
+            ->method('buildClassName')
+            ->with([$module, $prefix, $actionPath])
+            ->willReturn($className);
+        $this->assertEquals($className, $this->model->getActionClassName($module, $actionPath));
+
+    }
+
+    /**
+     * Generate a stub with an expected usage for the request mock object
+     *
+     * @param string $method
+     * @param string $with
+     * @return $this
+     */
+    private function requestExpects($method, $with)
+    {
+        $this->requestMock->expects($this->once())
+            ->method($method)
+            ->with($with);
+        return $this;
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Core/App/Router/NoRouteHandlerTest.php b/dev/tests/unit/testsuite/Magento/Core/App/Router/NoRouteHandlerTest.php
new file mode 100644
index 00000000000..7468fbbfd79
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/App/Router/NoRouteHandlerTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Tests Magento\Core\App\Router\NoRouteHandler
+ *
+ * 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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\App\Router;
+
+class NoRouteHandlerTest extends \Magento\Test\BaseTestCase
+{
+    /**
+     * @var \Magento\Core\App\Router\NoRouteHandler
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    private $configMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\RequestInterface
+     */
+    private $requestMock;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->configMock = $this->basicMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $requestMethods = [
+            'getActionName',
+            'getModuleName',
+            'getParam',
+            'setActionName',
+            'setModuleName',
+            'setControllerName',
+            'getCookie',
+        ];
+        $this->requestMock = $this->getMock(
+            'Magento\Framework\App\RequestInterface',
+            $requestMethods
+        );
+        $this->model = $this->objectManager->getObject('Magento\Core\App\Router\NoRouteHandler',
+            [
+                'config' => $this->configMock,
+            ]
+        );
+    }
+
+    public function testProcessDefault()
+    {
+        // Default path from config
+        $default = 'moduleName/actionPath/actionName';
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with('web/default/no_route', 'default')
+            ->willReturn($default);
+
+        // Set expectations
+        $this->requestMock->expects($this->once())
+            ->method('setModuleName')
+            ->with('moduleName')
+            ->willReturnSelf();
+        $this->requestMock->expects($this->once())
+            ->method('setControllerName')
+            ->with('actionPath')
+            ->willReturnSelf();
+        $this->requestMock->expects($this->once())
+            ->method('setActionName')
+            ->with('actionName')
+            ->willReturnSelf();
+
+        // Test
+        $this->assertTrue($this->model->process($this->requestMock));
+    }
+
+    public function testProcessNoDefault()
+    {
+        // Default path from config
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with('web/default/no_route', 'default')
+            ->willReturn(null);
+
+        // Set expectations
+        $this->requestMock->expects($this->once())
+            ->method('setModuleName')
+            ->with('core')
+            ->willReturnSelf();
+        $this->requestMock->expects($this->once())
+            ->method('setControllerName')
+            ->with('index')
+            ->willReturnSelf();
+        $this->requestMock->expects($this->once())
+            ->method('setActionName')
+            ->with('index')
+            ->willReturnSelf();
+
+        // Test
+        $this->assertTrue($this->model->process($this->requestMock));
+    }
+} 
\ No newline at end of file
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Link.php b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/IndexTest.php
similarity index 62%
rename from app/code/Magento/Backend/Block/Urlrewrite/Link.php
rename to dev/tests/unit/testsuite/Magento/Core/Controller/Index/IndexTest.php
index df79d224878..1f721c3101b 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite/Link.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/IndexTest.php
@@ -21,29 +21,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Core\Controller\Index;
 
-/**
- * Label & link block
- *
- * @method string getLabel()
- * @method string getItemUrl()
- * @method string getItemName()
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Backend\Block\Urlrewrite;
+use Magento\TestFramework\Helper\ObjectManager;
 
-class Link extends \Magento\Framework\View\Element\AbstractBlock
+class IndexTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * Render output
-     *
-     * @return string
-     */
-    protected function _toHtml()
+    public function testExecute()
     {
-        return '<p>' . $this->getLabel() . ' <a href="' . $this->getItemUrl() . '">' . $this->escapeHtml(
-            $this->getItemName()
-        ) . '</a></p>';
+        $objectManager = new ObjectManager($this);
+        /**
+         * @var \Magento\Core\Controller\Index
+         */
+        $controller = $objectManager->getObject('Magento\Core\Controller\Index\Index');
+
+        // The execute method is empty and returns void, just calling to verify
+        // the method exists and does not throw an exception
+        $controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NoCookiesTest.php b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NoCookiesTest.php
new file mode 100644
index 00000000000..23fd6a2dcec
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NoCookiesTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Controller\Index;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class NoCookiesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Core\Controller\Index\NoCookies
+     */
+    private $controller;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Event\ManagerInterface
+     */
+    private $eventManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Request\Http
+     */
+    private $requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Response\Http
+     */
+    private $responseMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Response\RedirectInterface
+     */
+    private $redirectResponseMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\ViewInterface
+     */
+    protected $viewMock;
+
+    const REDIRECT_URL = 'http://www.example.com/redirect';
+    const REDIRECT_PATH = '\a\path';
+    const REDIRECT_ARGUMENTS = '&arg1key=arg1value';
+
+    public function setup()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->responseMock = $this->getMockBuilder('Magento\Framework\App\Response\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->redirectResponseMock = $this->getMockBuilder('Magento\Framework\App\Response\RedirectInterface')
+            ->getMock();
+        $this->viewMock = $this->getMock('Magento\Framework\App\ViewInterface');
+
+        $this->controller = $objectManager->getObject(
+            'Magento\Core\Controller\Index\NoCookies',
+            [
+                'eventManager' => $this->eventManagerMock,
+                'request' => $this->requestMock,
+                'response' => $this->responseMock,
+                'redirect' => $this->redirectResponseMock,
+                'view' => $this->viewMock,
+            ]
+        );
+    }
+
+    public function testExecuteRedirectUrl()
+    {
+        // redirect is new'ed in the execute function, so need to set the redirect URL in dispatch call
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with(
+                $this->equalTo('controller_action_nocookies'),
+                $this->callback(
+                    function ($dataArray) {
+                        $redirect = $dataArray['redirect'];
+                        $this->assertInstanceOf('Magento\Framework\Object', $redirect);
+                        $redirect->setRedirectUrl(self::REDIRECT_URL);
+                        return true;
+                    }
+                )
+            );
+
+        // Verify response is set with redirect url
+        $this->responseMock->expects($this->once())
+            ->method('setRedirect')
+            ->with(self::REDIRECT_URL);
+
+        // Verify request is set to dispatched
+        $this->requestMock->expects($this->once())->method('setDispatched')->with($this->isTrue());
+
+        // Make the call to test
+        $this->controller->execute();
+    }
+
+    public function testExecuteRedirectPath()
+    {
+        // redirect is new'ed in the execute function, so need to set the redirect in dispatch call
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with(
+                $this->equalTo('controller_action_nocookies'),
+                $this->callback(
+                    function ($dataArray) {
+                        $redirect = $dataArray['redirect'];
+                        $this->assertInstanceOf('Magento\Framework\Object', $redirect);
+                        $redirect->setArguments(self::REDIRECT_ARGUMENTS);
+                        $redirect->setPath(self::REDIRECT_PATH);
+                        $redirect->setRedirect(self::REDIRECT_URL);
+                        return true;
+                    }
+                )
+            );
+
+        // Verify response is set with redirect, which
+        $this->redirectResponseMock->expects($this->once())
+            ->method('redirect')
+            ->with($this->responseMock, $this->equalTo('\a\path'), $this->equalTo('&arg1key=arg1value'));
+
+        // Verify request is set to dispatched
+        $this->requestMock->expects($this->once())->method('setDispatched')->with($this->isTrue());
+
+        // Make the call to test
+        $this->controller->execute();
+    }
+
+    public function testExecuteDefault()
+    {
+        // Verify view is called to load and render
+        $this->viewMock->expects($this->once())->method('loadLayout')->with(['default', 'noCookie']);
+        $this->viewMock->expects($this->once())->method('renderLayout');
+
+        // Verify request is set to dispatched
+        $this->requestMock->expects($this->once())->method('setDispatched')->with($this->isTrue());
+
+        // Make the call to test
+        $this->controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NotFoundTest.php b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NotFoundTest.php
new file mode 100644
index 00000000000..9616ffee576
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Controller/Index/NotFoundTest.php
@@ -0,0 +1,56 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Controller\Index;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class NotFoundTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        /**
+         * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Response\Http
+         */
+        $responseMock = $this->getMockBuilder('Magento\Framework\App\Response\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $responseMock->expects($this->once())->method('setHeader')->with('HTTP/1.1', '404 Not Found');
+        $responseMock->expects($this->once())->method('setHttpResponseCode')->with(404);
+        $responseMock->expects($this->once())->method('setBody')->with('Requested resource not found');
+
+        $objectManager = new ObjectManager($this);
+
+        /**
+         * @var \Magento\Core\Controller\Index
+         */
+        $controller = $objectManager->getObject(
+            'Magento\Core\Controller\Index\NotFound',
+            ['response' => $responseMock]
+        );
+
+        // Make the call to test
+        $controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Core/Helper/DataTest.php
index b226ddce11c..dfe1c50d487 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Helper/DataTest.php
@@ -28,23 +28,19 @@ use Magento\Framework\Pricing\PriceCurrencyInterface;
 class DataTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var Data
+     * @var \Magento\TestFramework\Helper\ObjectManager
      */
-    protected $model;
+    protected $objectManager;
 
     /**
      * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $priceCurrency;
+    protected $priceCurrencyMock;
 
     public function setUp()
     {
-        $this->priceCurrency = $this->getMock('Magento\Framework\Pricing\PriceCurrencyInterface');
-
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $objectManager->getObject('Magento\Core\Helper\Data', array(
-            'priceCurrency' => $this->priceCurrency
-        ));
+        $this->priceCurrencyMock = $this->getMock('Magento\Framework\Pricing\PriceCurrencyInterface');
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
     }
 
     /**
@@ -57,26 +53,27 @@ class DataTest extends \PHPUnit_Framework_TestCase
     public function testCurrency($amount, $format, $includeContainer, $result)
     {
         if ($format) {
-            $this->priceCurrency->expects($this->once())
+            $this->priceCurrencyMock->expects($this->once())
                 ->method('convertAndFormat')
                 ->with($amount, $includeContainer)
                 ->will($this->returnValue($result));
         } else {
-            $this->priceCurrency->expects($this->once())
+            $this->priceCurrencyMock->expects($this->once())
                 ->method('convert')
                 ->with($amount)
                 ->will($this->returnValue($result));
         }
-        $this->assertEquals($result, $this->model->currency($amount, $format, $includeContainer));
+        $helper = $this->getHelper(['priceCurrency' => $this->priceCurrencyMock]);
+        $this->assertEquals($result, $helper->currency($amount, $format, $includeContainer));
     }
 
     public function currencyDataProvider()
     {
-        return array(
-            array('amount' => '100', 'format' => true, 'includeContainer' => true, 'result' => '100grn.'),
-            array('amount' => '115', 'format' => true, 'includeContainer' => false, 'result' => '1150'),
-            array('amount' => '120', 'format' => false, 'includeContainer' => null, 'result' => '1200'),
-        );
+        return [
+            ['amount' => '100', 'format' => true, 'includeContainer' => true, 'result' => '100grn.'],
+            ['amount' => '115', 'format' => true, 'includeContainer' => false, 'result' => '1150'],
+            ['amount' => '120', 'format' => false, 'includeContainer' => null, 'result' => '1200'],
+        ];
     }
 
     /**
@@ -90,26 +87,27 @@ class DataTest extends \PHPUnit_Framework_TestCase
     public function testCurrencyByStore($amount, $store, $format, $includeContainer, $result)
     {
         if ($format) {
-            $this->priceCurrency->expects($this->once())
+            $this->priceCurrencyMock->expects($this->once())
                 ->method('convertAndFormat')
                 ->with($amount, $includeContainer, PriceCurrencyInterface::DEFAULT_PRECISION, $store)
                 ->will($this->returnValue($result));
         } else {
-            $this->priceCurrency->expects($this->once())
+            $this->priceCurrencyMock->expects($this->once())
                 ->method('convert')
                 ->with($amount, $store)
                 ->will($this->returnValue($result));
         }
-        $this->assertEquals($result, $this->model->currencyByStore($amount, $store, $format, $includeContainer));
+        $helper = $this->getHelper(['priceCurrency' => $this->priceCurrencyMock]);
+        $this->assertEquals($result, $helper->currencyByStore($amount, $store, $format, $includeContainer));
     }
 
     public function currencyByStoreDataProvider()
     {
-        return array(
-            array('amount' => '10', 'store' => 1, 'format' => true, 'includeContainer' => true, 'result' => '10grn.'),
-            array('amount' => '115', 'store' => 4,  'format' => true, 'includeContainer' => false, 'result' => '1150'),
-            array('amount' => '120', 'store' => 5,  'format' => false, 'includeContainer' => null, 'result' => '1200'),
-        );
+        return [
+            ['amount' => '10', 'store' => 1, 'format' => true, 'includeContainer' => true, 'result' => '10grn.'],
+            ['amount' => '115', 'store' => 4,  'format' => true, 'includeContainer' => false, 'result' => '1150'],
+            ['amount' => '120', 'store' => 5,  'format' => false, 'includeContainer' => null, 'result' => '1200'],
+        ];
     }
 
     public function testFormatCurrency()
@@ -118,12 +116,13 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $includeContainer = false;
         $result = '10grn.';
 
-        $this->priceCurrency->expects($this->once())
+        $this->priceCurrencyMock->expects($this->once())
             ->method('convertAndFormat')
             ->with($amount, $includeContainer)
             ->will($this->returnValue($result));
 
-        $this->assertEquals($result, $this->model->formatCurrency($amount, $includeContainer));
+        $helper = $this->getHelper(['priceCurrency' => $this->priceCurrencyMock]);
+        $this->assertEquals($result, $helper->formatCurrency($amount, $includeContainer));
     }
 
     public function testFormatPrice()
@@ -132,11 +131,207 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $includeContainer = false;
         $result = '10grn.';
 
-        $this->priceCurrency->expects($this->once())
+        $this->priceCurrencyMock->expects($this->once())
             ->method('format')
             ->with($amount, $includeContainer)
             ->will($this->returnValue($result));
 
-        $this->assertEquals($result, $this->model->formatPrice($amount, $includeContainer));
+        $helper = $this->getHelper(['priceCurrency' => $this->priceCurrencyMock]);
+        $this->assertEquals($result, $helper->formatPrice($amount, $includeContainer));
+    }
+
+    /**
+     * @param array $allowedIps
+     * @param bool $expected
+     * @dataProvider isDevAllowedDataProvider
+     */
+    public function testIsDevAllowed($allowedIps, $expected, $callNum = 1)
+    {
+        $storeId = 'storeId';
+
+        $scopeConfigMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(
+                Data::XML_PATH_DEV_ALLOW_IPS,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $storeId
+            )->will($this->returnValue($allowedIps));
+
+        $remoteAddressMock = $this->getMockBuilder('Magento\Framework\HTTP\PhpEnvironment\RemoteAddress')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $remoteAddressMock->expects($this->once())
+            ->method('getRemoteAddress')
+            ->will($this->returnValue('remoteAddress'));
+
+        $httpHeaderMock = $this->getMockBuilder('Magento\Framework\HTTP\Header')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $httpHeaderMock->expects($this->exactly($callNum))
+            ->method('getHttpHost')
+            ->will($this->returnValue('httpHost'));
+
+        $context = $this->objectManager->getObject(
+            'Magento\Framework\App\Helper\Context',
+            [
+                'remoteAddress' => $remoteAddressMock,
+                'httpHeader' => $httpHeaderMock,
+            ]
+        );
+        $helper = $this->getHelper(
+            [
+                'scopeConfig' => $scopeConfigMock,
+                'context' => $context,
+            ]
+        );
+        $this->assertEquals($expected, $helper->isDevAllowed($storeId));
+
+    }
+
+    public function isDevAllowedDataProvider()
+    {
+        return [
+            'allow_nothing' => [
+                '',
+                true,
+                0,
+            ],
+            'allow_remote_address' => [
+                'ip1, ip2, remoteAddress',
+                true,
+                0,
+            ],
+            'allow_http_host' => [
+                'ip1, ip2, httpHost',
+                true,
+            ],
+            'allow_neither' => [
+                'ip1, ip2, ip3',
+                false,
+            ],
+        ];
+    }
+
+    public function testGetCacheTypes()
+    {
+        $cachedTypes = [
+            'type1' => ['label' => 'node1', 'other' => 'other1'],
+            'type2' => ['label' => 'node2', 'other' => 'other2'],
+            'type3' => ['other' => 'other3'],
+        ];
+        $types = [
+            'type1' => 'node1',
+            'type2' => 'node2',
+        ];
+        $cacheConfigMock = $this->getMockBuilder('Magento\Framework\Cache\ConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $cacheConfigMock->expects($this->once())
+            ->method('getTypes')
+            ->will($this->returnValue($cachedTypes));
+        $context = $this->objectManager->getObject(
+            'Magento\Framework\App\Helper\Context',
+            [
+                'cacheConfig' => $cacheConfigMock,
+            ]
+        );
+        $helper = $this->getHelper(
+            [
+                'context' => $context,
+            ]
+        );
+
+        $this->assertEquals($types, $helper->getCacheTypes());
+    }
+
+    public function testJsonEncode()
+    {
+        $valueToEncode = 'valueToEncode';
+        $translateInlineMock = $this->getMockBuilder('Magento\Framework\Translate\InlineInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $translateInlineMock->expects($this->once())
+            ->method('processResponseBody');
+        $context = $this->objectManager->getObject(
+            'Magento\Framework\App\Helper\Context',
+            [
+                'translateInline' => $translateInlineMock,
+            ]
+        );
+        $helper = $this->getHelper(
+            [
+                'context' => $context,
+            ]
+        );
+
+        $this->assertEquals('"valueToEncode"', $helper->jsonEncode($valueToEncode));
+    }
+
+    public function testJsonDecode()
+    {
+        $helper = $this->getHelper([]);
+        $this->assertEquals('"valueToDecode"', $helper->jsonEncode('valueToDecode'));
+    }
+
+    public function testGetDefaultCountry()
+    {
+        $storeId = 'storeId';
+        $country = 'country';
+
+        $scopeConfigMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(
+                Data::XML_PATH_DEFAULT_COUNTRY,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $storeId
+            )->will($this->returnValue($country));
+
+        $helper = $this->getHelper(
+            [
+                'scopeConfig' => $scopeConfigMock,
+            ]
+        );
+        $this->assertEquals($country, $helper->getDefaultCountry($storeId));
+    }
+
+    /**
+     * @param bool $expected
+     * @param bool $dbCompatibleMode
+     * @dataProvider useDbCompatibleModelDataProvider
+     */
+    public function testUseDbCompatibleModel($expected, $dbCompatibleMode = null)
+    {
+        $arguments = [];
+        if (null !== $dbCompatibleMode) {
+            $arguments['dbCompatibleMode'] = $dbCompatibleMode;
+        }
+        $helper = $this->getHelper($arguments);
+        $this->assertEquals($expected, $helper->useDbCompatibleMode());
+    }
+
+    public function useDbCompatibleModelDataProvider()
+    {
+        return [
+            'default' => [true],
+            'false' => [false, false],
+            'true' => [true, true],
+        ];
+    }
+
+    /**
+     * Get helper instance
+     *
+     * @param array $arguments
+     * @return Data
+     */
+    private function getHelper($arguments)
+    {
+        return $this->objectManager->getObject('Magento\Core\Helper\Data', $arguments);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Core/Helper/File/MediaTest.php b/dev/tests/unit/testsuite/Magento/Core/Helper/File/MediaTest.php
new file mode 100644
index 00000000000..b974bc56950
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Helper/File/MediaTest.php
@@ -0,0 +1,172 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Helper\File;
+
+class MediaTest extends \PHPUnit_Framework_TestCase
+{
+    const UPDATE_TIME = 'update_time';
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /** @var \Magento\Framework\Filesystem\Directory\ReadInterface | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $dirMock;
+
+    /** @var  Media */
+    protected $helper;
+
+    public function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->dirMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\ReadInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filesystemMock = $this->getMockBuilder('Magento\Framework\App\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filesystemMock->expects($this->any())
+            ->method('getDirectoryRead')
+            ->with(\Magento\Framework\App\Filesystem::MEDIA_DIR)
+            ->will($this->returnValue($this->dirMock));
+        $dateMock = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\DateTime')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $dateMock->expects($this->any())
+            ->method('date')
+            ->will($this->returnValue(self::UPDATE_TIME));
+        $this->helper = $this->objectManager->getObject(
+            'Magento\Core\Helper\File\Media',
+            ['filesystem' => $filesystemMock, 'date' => $dateMock]
+        );
+    }
+
+    /**
+     * @param string $path
+     * @param string $expectedDir
+     * @param string $expectedFile
+     * @dataProvider pathDataProvider
+     */
+    public function testCollectFileInfo($path, $expectedDir, $expectedFile)
+    {
+        $content = 'content';
+        $mediaDirectory = 'mediaDir';
+        $relativePath = 'relativePath';
+
+        $this->dirMock->expects($this->once())
+            ->method('getRelativePath')
+            ->with($mediaDirectory . '/' . $path)
+            ->will($this->returnValue($relativePath));
+        $this->dirMock->expects($this->once())
+            ->method('isFile')
+            ->with($relativePath)
+            ->will($this->returnValue(true));
+        $this->dirMock->expects($this->once())
+            ->method('isReadable')
+            ->with($relativePath)
+            ->will($this->returnValue(true));
+        $this->dirMock->expects($this->once())
+            ->method('readFile')
+            ->with($relativePath)
+            ->will($this->returnValue($content));
+
+        $expected = [
+            'filename' => $expectedFile,
+            'content' => $content,
+            'update_time' => self::UPDATE_TIME,
+            'directory' => $expectedDir,
+        ];
+
+        $this->assertEquals($expected, $this->helper->collectFileInfo($mediaDirectory, $path));
+    }
+
+    public function pathDataProvider()
+    {
+        return [
+            'file only' => ['filename', null, 'filename'],
+            'with dir' => ['dir/filename', 'dir', 'filename'],
+        ];
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage File mediaDir/path does not exist
+     */
+    public function testCollectFileInfoNotFile()
+    {
+        $content = 'content';
+        $mediaDirectory = 'mediaDir';
+        $relativePath = 'relativePath';
+        $path = 'path';
+        $this->dirMock->expects($this->once())
+            ->method('getRelativePath')
+            ->with($mediaDirectory . '/' . $path)
+            ->will($this->returnValue($relativePath));
+        $this->dirMock->expects($this->once())
+            ->method('isFile')
+            ->with($relativePath)
+            ->will($this->returnValue(false));
+        $this->dirMock->expects($this->never())
+            ->method('isReadable')
+            ->with($relativePath)
+            ->will($this->returnValue(true));
+        $this->dirMock->expects($this->never())
+            ->method('readFile')
+            ->with($relativePath)
+            ->will($this->returnValue($content));
+
+        $this->helper->collectFileInfo($mediaDirectory, $path);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage File mediaDir/path is not readable
+     */
+    public function testCollectFileInfoNotReadable()
+    {
+        $content = 'content';
+        $mediaDirectory = 'mediaDir';
+        $relativePath = 'relativePath';
+        $path = 'path';
+        $this->dirMock->expects($this->once())
+            ->method('getRelativePath')
+            ->with($mediaDirectory . '/' . $path)
+            ->will($this->returnValue($relativePath));
+        $this->dirMock->expects($this->once())
+            ->method('isFile')
+            ->with($relativePath)
+            ->will($this->returnValue(true));
+        $this->dirMock->expects($this->once())
+            ->method('isReadable')
+            ->with($relativePath)
+            ->will($this->returnValue(false));
+        $this->dirMock->expects($this->never())
+            ->method('readFile')
+            ->with($relativePath)
+            ->will($this->returnValue($content));
+
+        $this->helper->collectFileInfo($mediaDirectory, $path);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Helper/File/Storage/DatabaseTest.php b/dev/tests/unit/testsuite/Magento/Core/Helper/File/Storage/DatabaseTest.php
new file mode 100644
index 00000000000..89daad349df
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Helper/File/Storage/DatabaseTest.php
@@ -0,0 +1,503 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Helper\File\Storage;
+
+class DatabaseTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /** @var \Magento\Core\Model\File\Storage\DatabaseFactory | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $dbStorageFactoryMock;
+
+    /** @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $filesystemMock;
+
+    /** @var \Magento\Core\Model\File\Storage\File | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $fileStorageMock;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $configMock;
+
+    /** @var Database */
+    protected $helper;
+
+    public function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->dbStorageFactoryMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\DatabaseFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->filesystemMock = $this->getMockBuilder('Magento\Framework\App\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fileStorageMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->helper = $this->objectManager->getObject(
+            'Magento\Core\Helper\File\Storage\Database',
+            [
+                'filesystem' => $this->filesystemMock,
+                'fileStorage' => $this->fileStorageMock,
+                'dbStorageFactory' => $this->dbStorageFactoryMock,
+                'config' => $this->configMock,
+            ]
+        );
+    }
+
+    /**
+     * @param int $storage
+     * @param bool $expected
+     * @dataProvider checkDbUsageDataProvider
+     */
+    public function testCheckDbUsage($storage, $expected)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+
+        $this->assertEquals($expected, $this->helper->checkDbUsage());
+        $this->assertEquals($expected, $this->helper->checkDbUsage());
+    }
+
+    public function checkDbUsageDataProvider()
+    {
+        return [
+            'media database' => [\Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE, true],
+            'non-media database' => [10, false],
+        ];
+    }
+
+    public function testGetStorageDatabaseModel()
+    {
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->assertSame($dbModelMock, $this->helper->getStorageDatabaseModel());
+        $this->assertSame($dbModelMock, $this->helper->getStorageDatabaseModel());
+    }
+
+    public function testGetStorageFileModel()
+    {
+        $this->assertSame($this->fileStorageMock, $this->helper->getStorageFileModel());
+    }
+
+    public function testGetResourceStorageModel()
+    {
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $resourceModelMock = $this->getMockBuilder('Magento\Framework\Model\Resource\Db\AbstractDb')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup'])
+            ->getMockForAbstractClass();
+        $dbModelMock->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($resourceModelMock));
+
+        $this->assertSame($resourceModelMock, $this->helper->getResourceStorageModel());
+        $this->assertSame($resourceModelMock, $this->helper->getResourceStorageModel());
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider updateFileDataProvider
+     */
+    public function testSaveFile($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('saveFile');
+
+        $this->helper->saveFile('filename');
+    }
+
+    public function updateFileDataProvider()
+    {
+        return [
+            'media database' => [\Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE, 1],
+            'non-media database' => [10, 0],
+        ];
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider updateFileDataProvider
+     */
+    public function testRenameFile($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('renameFile');
+
+        $this->helper->renameFile('oldName', 'newName');
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider updateFileDataProvider
+     */
+    public function testCopyFile($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('copyFile');
+
+        $this->helper->copyFile('oldName', 'newName');
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @param bool|null $expected
+     * @dataProvider fileExistsDataProvider
+     */
+    public function testFileExists($storage, $callNum, $expected)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('fileExists')
+            ->will($this->returnValue(true));
+
+        $this->assertEquals($expected, $this->helper->fileExists('file'));
+    }
+
+    public function fileExistsDataProvider()
+    {
+        return [
+            'media database' => [\Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE, 1, true],
+            'non-media database' => [10, 0, null],
+        ];
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider getUniqueFilenameDataProvider
+     */
+    public function testGetUniqueFilename($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $map = [
+            ['directory/filename.ext', true],
+            ['directory/filename_1.ext', true],
+            ['directory/filename_2.ext', false],
+        ];
+        $dbModelMock->expects($this->any())
+            ->method('fileExists')
+            ->will($this->returnValueMap($map));
+
+        $this->helper->getUniqueFilename('directory/', 'filename.ext');
+    }
+
+    public function getUniqueFilenameDataProvider()
+    {
+        return [
+            'media database' => [\Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE, 1, 'filename_2.ext'],
+            'non-media database' => [10, 0, 'filename.ext'],
+        ];
+    }
+
+    /**
+     * @param bool $expected
+     * @param int $storage
+     * @param int $callNum
+     * @param int $id
+     * @param int $callSaveFile
+     * @dataProvider saveFileToFileSystemDataProvider
+     */
+    public function testSaveFileToFileSystem($expected, $storage, $callNum, $id = 0, $callSaveFile = 0)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('loadByFilename')
+            ->will($this->returnSelf());
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('getId')
+            ->will($this->returnValue($id));
+        $dbModelMock->expects($this->exactly($callSaveFile))
+            ->method('getData')
+            ->will($this->returnValue(['data']));
+        $this->fileStorageMock->expects($this->exactly($callSaveFile))
+            ->method('saveFile')
+            ->will($this->returnValue(true));
+        $this->assertEquals($expected, $this->helper->saveFileToFilesystem('filename'));
+    }
+
+    public function saveFileToFileSystemDataProvider()
+    {
+        return [
+            'media database, no id' => [
+                false,
+                \Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE,
+                1,
+            ],
+            'media database, with id' => [
+                true,
+                \Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE,
+                1,
+                1,
+                1,
+            ],
+            'non-media database' => [false, 10, 0,],
+        ];
+    }
+
+    public function testGetMediaRelativePath()
+    {
+        $this->filesystemMock->expects($this->once())
+            ->method('getPath')
+            ->with(\Magento\Framework\App\Filesystem::MEDIA_DIR)
+            ->will($this->returnValue('/media/dir/'));
+        $this->assertEquals('fullPath', $this->helper->getMediaRelativePath('/media/dir/fullPath'));
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider updateFileDataProvider
+     */
+    public function testDeleteFolder($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $resourceModelMock = $this->getMockBuilder('Magento\Framework\Model\Resource\Db\AbstractDb')
+            ->disableOriginalConstructor()
+            ->setMethods(['deleteFolder', '__wakeup'])
+            ->getMockForAbstractClass();
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('getResource')
+            ->will($this->returnValue($resourceModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $resourceModelMock->expects($this->exactly($callNum))
+            ->method('deleteFolder');
+
+        $this->helper->deleteFolder('folder');
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @dataProvider updateFileDataProvider
+     */
+    public function testDeleteFile($storage, $callNum)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('deleteFile');
+
+        $this->helper->deleteFile('file');
+    }
+
+    /**
+     * @param array $result
+     * @param string $expected
+     * @param int $storage
+     * @param int $callNum
+     * @param int $callDirWrite
+     * @dataProvider saveUploadedFileDataProvider
+     */
+    public function testSaveUploadedFile($result, $expected, $storage, $callNum, $callDirWrite = 0)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+        $dbModelMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dbStorageFactoryMock->expects($this->exactly($callNum))
+            ->method('create')
+            ->will($this->returnValue($dbModelMock));
+        $this->filesystemMock->expects($this->exactly($callNum))
+            ->method('getPath')
+            ->will($this->returnValue('media-dir'));
+        $dirWriteMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\WriteInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->filesystemMock->expects($this->exactly($callDirWrite))
+            ->method('getDirectoryWrite')
+            ->with(\Magento\Framework\App\Filesystem::ROOT_DIR)
+            ->will($this->returnValue($dirWriteMock));
+        $dirWriteMock->expects($this->exactly($callDirWrite))
+            ->method('renameFile');
+        $map = [
+            ['directory/filename.ext', true],
+            ['directory/filename_1.ext', true],
+            ['directory/filename_2.ext', false],
+        ];
+        $dbModelMock->expects($this->any())
+            ->method('fileExists')
+            ->will($this->returnValueMap($map));
+        $dbModelMock->expects($this->exactly($callNum))
+            ->method('saveFile');
+        $this->assertEquals($expected, $this->helper->saveUploadedFile($result));
+    }
+
+    public function saveUploadedFileDataProvider()
+    {
+        return [
+            'media database, file not unique' => [
+                ['file' => 'filename.ext', 'path' => 'directory/'],
+                '/filename_2.ext',
+                \Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE,
+                1,
+                1,
+            ],
+            'media database, file unique' => [
+                ['file' => 'file.ext', 'path' => 'directory/'],
+                '/file.ext',
+                \Magento\Core\Model\File\Storage::STORAGE_MEDIA_DATABASE,
+                1,
+            ],
+            'non-media database' => [
+                ['file' => 'filename.ext', 'path' => 'directory/'],
+                'filename.ext',
+                10,
+                0,
+            ],
+        ];
+    }
+
+    public function testGetMediaBaseDir()
+    {
+        $this->filesystemMock->expects($this->once())
+            ->method('getPath')
+            ->with(\Magento\Framework\App\Filesystem::MEDIA_DIR)
+            ->will($this->returnValue('/media/dir/'));
+
+        $this->assertEquals('/media/dir', $this->helper->getMediaBaseDir());
+        $this->assertEquals('/media/dir', $this->helper->getMediaBaseDir());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Helper/File/StorageTest.php b/dev/tests/unit/testsuite/Magento/Core/Helper/File/StorageTest.php
new file mode 100644
index 00000000000..1f15e9eb2f7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Helper/File/StorageTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Helper\File;
+
+class StorageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /** @var \Magento\Core\Model\File\Storage\File | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $filesystemStorageMock;
+
+    /** @var \Magento\Core\Helper\File\Storage\Database | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $coreFileStorageDbMock;
+
+    /** @var \Magento\Core\Model\File\Storage | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $storageMock;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface | \PHPUnit_Framework_MockObject_MockObject  */
+    protected $configMock;
+
+    /** @var  Storage */
+    protected $helper;
+
+    public function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->filesystemStorageMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->coreFileStorageDbMock = $this->getMockBuilder('Magento\Core\Helper\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storageMock = $this->getMockBuilder('Magento\Core\Model\File\Storage')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->helper = $this->objectManager->getObject(
+            'Magento\Core\Helper\File\Storage',
+            [
+                'coreFileStorageDb' => $this->coreFileStorageDbMock,
+                'storage' => $this->storageMock,
+                'filesystemStorage' => $this->filesystemStorageMock,
+                'config' => $this->configMock,
+            ]
+        );
+    }
+
+    public function testGetCurrentStorageCode()
+    {
+        $currentStorage = '10';
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($currentStorage));
+
+        $this->assertEquals($currentStorage, $this->helper->getCurrentStorageCode());
+        $this->assertEquals($currentStorage, $this->helper->getCurrentStorageCode());
+    }
+
+    public function testGetStorageFileModel()
+    {
+        $this->assertSame($this->filesystemStorageMock, $this->helper->getStorageFileModel());
+    }
+
+    /**
+     * @param int $storage
+     * @param int $callNum
+     * @param bool $expected
+     * @dataProvider isInternalStorageDataProvider
+     */
+    public function testIsInternalStorage($storage, $callNum, $expected)
+    {
+        $currentStorage = '10';
+        $this->configMock->expects($this->exactly($callNum))
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($currentStorage));
+
+        $this->assertEquals($expected, $this->helper->isInternalStorage($storage));
+    }
+
+    public function isInternalStorageDataProvider()
+    {
+        return [
+            'given external storage' => [5, 0, false],
+            'given internal storage' => [0, 0, true],
+            'not given storage' => [null, 1, false],
+        ];
+    }
+
+    public function testGetStorageModel()
+    {
+        $storageModelMock = $this->getMockBuilder('Magento\Framework\Model\AbstractModel')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storageMock->expects($this->once())
+            ->method('getStorageModel')
+            ->will($this->returnValue($storageModelMock));
+        $this->assertSame($storageModelMock, $this->helper->getStorageModel());
+    }
+
+    /**
+     * @param bool|int $expected
+     * @param int $storage
+     * @param int $callNum
+     * @param int $callSaveFileNum
+     * @param int $fileId
+     * @dataProvider processStorageFileDataProvider
+     */
+    public function testProcessStorageFile($expected, $storage, $callNum, $callSaveFileNum, $fileId = null)
+    {
+        $this->configMock->expects($this->once())
+            ->method('getValue')
+            ->with(\Magento\Core\Model\File\Storage::XML_PATH_STORAGE_MEDIA, 'default')
+            ->will($this->returnValue($storage));
+
+        $filename = 'filename';
+        $relativePath = 'relativePath';
+        $this->coreFileStorageDbMock->expects($this->exactly($callNum))
+            ->method('getMediaRelativePath')
+            ->with($filename)
+            ->will($this->returnValue($relativePath));
+
+        $storageModelMock = $this->getMockBuilder('Magento\Framework\Model\AbstractModel')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadByFileName', '__wakeup'])
+            ->getMock();
+        $this->storageMock->expects($this->exactly($callNum))
+            ->method('getStorageModel')
+            ->will($this->returnValue($storageModelMock));
+        $fileMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', '__wakeup'])
+            ->getMock();
+        $storageModelMock->expects($this->exactly($callNum))
+            ->method('loadByFilename')
+            ->with($relativePath)
+            ->will($this->returnValue($fileMock));
+        $fileMock->expects($this->exactly($callNum))
+            ->method('getId')
+            ->will($this->returnValue($fileId));
+
+        $this->filesystemStorageMock->expects($this->exactly($callSaveFileNum))
+            ->method('saveFile')
+            ->with($fileMock, true)
+            ->will($this->returnValue(1));
+
+        $this->assertEquals($expected, $this->helper->processStorageFile($filename));
+    }
+
+    public function processStorageFileDataProvider()
+    {
+        return [
+            'internal storage' => [false, 0, 0, 0],
+            'external storage, no file' => [false, 5, 1, 0],
+            'external storage, with file' => [1, 5, 1, 1, 1],
+        ];
+    }
+
+    public function testSaveFileToFileSystem()
+    {
+        $file = 'file';
+        $this->filesystemStorageMock->expects($this->once())
+            ->method('saveFile')
+            ->with($file, true)
+            ->will($this->returnValue(1));
+        $this->assertEquals(1, $this->helper->saveFileToFileSystem($file));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Helper/UrlTest.php b/dev/tests/unit/testsuite/Magento/Core/Helper/UrlTest.php
new file mode 100644
index 00000000000..44b125aefc0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Helper/UrlTest.php
@@ -0,0 +1,218 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Helper;
+
+class UrlTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    public function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+    }
+
+    public function testGetCurrentBase64Url()
+    {
+        $storeManagerMock = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+        ->disableOriginalConstructor()
+        ->getMock();
+        $urlBuilderMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $url = 'http://example.com';
+        $urlBuilderMock->expects($this->once())
+            ->method('getCurrentUrl')
+            ->will($this->returnValue($url));
+        $context = $this->objectManager->getObject(
+            'Magento\Framework\App\Helper\Context',
+            [
+                'urlBuilder' => $urlBuilderMock,
+            ]
+        );
+        /** @var \Magento\Core\Helper\Url | \PHPUnit_Framework_MockObject_MockObject $helper */
+        $helper = $this->getMockBuilder('Magento\Core\Helper\Url')
+            ->setConstructorArgs([$context, $storeManagerMock])
+            ->setMethods(['urlEncode'])
+            ->getMock();
+        $encodedUrl = 'encodedUrl';
+        $helper->expects($this->once())
+            ->method('urlEncode')
+            ->with($url)
+            ->will($this->returnValue($encodedUrl));
+        $this->assertEquals($encodedUrl, $helper->getCurrentBase64Url());
+    }
+
+    /**
+     * @param string $url
+     * @param int $callNum
+     * @dataProvider getEncodedUrlDataProvider
+     */
+    public function testGetEncodedUrl($url, $callNum)
+    {
+        $storeManagerMock = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $urlBuilderMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $encodingUrl = $url ? $url : 'http://example.com';
+        $urlBuilderMock->expects($this->exactly($callNum))
+            ->method('getCurrentUrl')
+            ->will($this->returnValue($encodingUrl));
+        $context = $this->objectManager->getObject(
+            'Magento\Framework\App\Helper\Context',
+            [
+                'urlBuilder' => $urlBuilderMock,
+            ]
+        );
+        /** @var \Magento\Core\Helper\Url | \PHPUnit_Framework_MockObject_MockObject $helper */
+        $helper = $this->getMockBuilder('Magento\Core\Helper\Url')
+            ->setConstructorArgs([$context, $storeManagerMock])
+            ->setMethods(['urlEncode'])
+            ->getMock();
+        $encodedUrl = 'encodedUrl';
+        $helper->expects($this->once())
+            ->method('urlEncode')
+            ->with($encodingUrl)
+            ->will($this->returnValue($encodedUrl));
+        $this->assertEquals($encodedUrl, $helper->getEncodedUrl($url));
+    }
+
+    public function getEncodedUrlDataProvider()
+    {
+        return [
+            'no url' => [null, 1],
+            'with url' => ['http://test.com', 0],
+        ];
+    }
+
+    public function testGetHomeUrl()
+    {
+        $storeManagerMock = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeMock));
+        $baseUrl = 'baseUrl';
+        $storeMock->expects($this->once())
+            ->method('getBaseUrl')
+            ->will($this->returnValue($baseUrl));
+        $helper = $this->getHelper(['storeManager' => $storeManagerMock]);
+        $this->assertEquals($baseUrl, $helper->getHomeUrl());
+    }
+
+    /**
+     * @param array $param
+     * @param string $expected
+     * @dataProvider addRequestParamDataProvider
+     */
+    public function testAddRequestParam($param, $expected)
+    {
+        $helper = $this->getHelper([]);
+        $this->assertEquals($expected, $helper->addRequestParam('http://example.com', $param));
+    }
+
+    public function addRequestParamDataProvider()
+    {
+        return [
+            'string' => [
+                ['key1' => 'value1', 'key2' => 'value2'],
+                'http://example.com?key1=value1&key2=value2',
+            ],
+            'numeric key' => [
+                ['1' => 'value1', '2' => 'value2'],
+                'http://example.com',
+            ],
+            'single param' => [
+                ['key1' => 'value1'],
+                'http://example.com?key1=value1',
+            ],
+            'valid/invalid param' => [
+                ['1' => 'value1', 'key2' => 'value2'],
+                'http://example.com?key2=value2',
+            ],
+            'mixed' => [
+                [
+                    'null' => null,
+                    'string' => 'value',
+                    'array' => ['arrayVal1', 'arrayVal2', 'arrayVal3']
+                ],
+                'http://example.com?null&string=value&array[]=arrayVal1&array[]=arrayVal2&array[]=arrayVal3',
+            ],
+            'object' => [
+                ['object' => new \Magento\Framework\Object()],
+                'http://example.com',
+            ]
+        ];
+    }
+
+    /**
+     * @param string $paramKey
+     * @param string $expected
+     * @dataProvider removeRequestParamDataProvider
+     */
+    public function testRemoveRequestParam($paramKey, $expected)
+    {
+        $url = 'http://example.com?null&string=value&array[]=arrayVal1&array[]=arrayVal2&array[]=arrayVal3';
+
+        $helper = $this->getHelper([]);
+        $this->assertEquals($expected, $helper->removeRequestParam($url, $paramKey));
+    }
+
+    public function removeRequestParamDataProvider()
+    {
+        return [
+            'no match' => [
+                'other',
+                'http://example.com?null&string=value&array[]=arrayVal1&array[]=arrayVal2&array[]=arrayVal3'
+            ],
+            'one match' => [
+                'string',
+                'http://example.com?null&array[]=arrayVal1&array[]=arrayVal2&array[]=arrayVal3'
+            ],
+            'array match' => [
+                'array[]',
+                'http://example.com?null&string=value'
+            ],
+        ];
+    }
+
+    /**
+     * Get helper instance
+     *
+     * @param array $arguments
+     * @return Url
+     */
+    private function getHelper($arguments)
+    {
+        return $this->objectManager->getObject('Magento\Core\Helper\Url', $arguments);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/App/EmulationTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/App/EmulationTest.php
new file mode 100644
index 00000000000..3511ddf0ad5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/App/EmulationTest.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Tests Magento\Core\Model\App\Emulation
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Model\App;
+
+class EmulationTest extends \Magento\Test\BaseTestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\StoreManagerInterface
+     */
+    private $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\TranslateInterface
+     */
+    private $translateMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    private $scopeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Locale\ResolverInterface
+     */
+    private $localeResolverMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Core\Model\Design
+     */
+    private $designMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Translate\Inline\ConfigInterface
+     */
+    private $inlineConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Translate\Inline\StateInterface
+     */
+    private $inlineTranslationMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\View\DesignInterface
+     */
+    private $viewDesignMock;
+
+    /**
+     * @var \Magento\Core\Model\App\Emulation
+     */
+    private $model;
+
+    public function setUp()
+    {
+        parent::setUp();
+        // Mocks
+        $this->designMock = $this->basicMock('Magento\Core\Model\Design');
+        $this->storeManagerMock = $this->basicMock('Magento\Framework\StoreManagerInterface');
+        $this->translateMock = $this->basicMock('Magento\Framework\TranslateInterface');
+        $this->scopeConfigMock = $this->basicMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->localeResolverMock = $this->basicMock('Magento\Framework\Locale\ResolverInterface');
+        $this->inlineConfigMock = $this->basicMock('Magento\Framework\Translate\Inline\ConfigInterface');
+        $this->inlineTranslationMock = $this->basicMock('Magento\Framework\Translate\Inline\StateInterface');
+        $this->viewDesignMock = $this->getMockForAbstractClass('Magento\Framework\View\DesignInterface');
+
+        // Stubs
+        $this->designMock->expects($this->any())->method('loadChange')->willReturnSelf();
+        $this->designMock->expects($this->any())->method('getData')->willReturn(false);
+        $this->translateMock->expects($this->any())->method('setLocale')->willReturnSelf();
+
+        // Prepare SUT
+        $this->model = $this->objectManager->getObject('Magento\Core\Model\App\Emulation',
+            [
+                'storeManager' => $this->storeManagerMock,
+                'viewDesign' => $this->viewDesignMock,
+                'design' => $this->designMock,
+                'translate' => $this->translateMock,
+                'scopeConfig' => $this->scopeConfigMock,
+                'inlineConfig' => $this->inlineConfigMock,
+                'inlineTranslation' => $this->inlineTranslationMock,
+                'localeResolver' => $this->localeResolverMock,
+            ]
+        );
+    }
+
+    public function testStartDefaults()
+    {
+        // Test data
+        $newDesignData = ['array', 'with', 'data'];
+        $inlineTranslate = false;
+        $initArea = 'initial area';
+        $initTheme = 'initial design theme';
+        $initStore = 1;
+        $initLocale = 'initial locale code';
+        $newInlineTranslate = false;
+        $newLocale = 'new locale code';
+        $newStoreId = 9;
+        $initDesignData = ['area' => $initArea, 'theme' => $initTheme, 'store' => $initStore];
+
+        // Stubs
+
+        $this->inlineTranslationMock->expects($this->any())->method('isEnabled')->willReturn($inlineTranslate);
+        $this->viewDesignMock->expects($this->any())->method('getArea')->willReturn($initArea);
+        $this->viewDesignMock->expects($this->any())->method('getDesignTheme')->willReturn($initTheme);
+        $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($initStore);
+        $this->localeResolverMock->expects($this->any())->method('getLocaleCode')->willReturn($initLocale);
+        $this->inlineConfigMock->expects($this->any())->method('isActive')->willReturn($newInlineTranslate);
+        $this->viewDesignMock->expects($this->any())->method('getConfigurationDesignTheme')->willReturn($newDesignData);
+        $this->scopeConfigMock->expects($this->any())->method('getValue')->willReturn($newLocale);
+
+        // Expectations
+        $this->inlineTranslationMock->expects($this->once())->method('suspend')->with($newInlineTranslate);
+        $this->viewDesignMock->expects($this->once())->method('setDesignTheme')->with($newDesignData);
+        $this->localeResolverMock->expects($this->once())->method('setLocaleCode')->with($newLocale);
+        $this->translateMock->expects($this->once())->method('setLocale')->with($newLocale);
+        $this->storeManagerMock->expects($this->once())->method('setCurrentStore')->with($newStoreId);
+
+        // Test
+        $initialEnvironment = $this->model->startEnvironmentEmulation($newStoreId);
+        $this->assertSame($inlineTranslate, $initialEnvironment->getInitialTranslateInline());
+        $this->assertSame($initDesignData, $initialEnvironment->getInitialDesign());
+        $this->assertSame($initLocale, $initialEnvironment->getInitialLocaleCode());
+    }
+
+    public function testStartWithInlineTranslation()
+    {
+        $inlineTranslation = true;
+
+        $this->inlineConfigMock->expects($this->any())->method('isActive')->willReturn($inlineTranslation);
+
+        $this->inlineTranslationMock->expects($this->once())
+            ->method('suspend')
+            ->with($inlineTranslation);
+
+        $this->model->startEnvironmentEmulation(1, null, true);
+
+    }
+
+    public function testStartAreaNotDefault()
+    {
+        $area = 'backend';
+        $newDesignData = ['array', 'with', 'data'];
+
+        $this->viewDesignMock->expects($this->any())->method('getConfiguratioNDesignTheme')->willReturn($newDesignData);
+
+        $this->viewDesignMock->expects($this->once())
+            ->method('setDesignTheme')
+            ->with($newDesignData, $area);
+
+        $this->model->startEnvironmentEmulation(1, $area);
+    }
+
+    public function testStop()
+    {
+        // Test data
+        $initialEnvInfo = $this->objectManager->getObject('\Magento\Framework\Object');
+        $initArea = 'initial area';
+        $initTheme = 'initial design theme';
+        $initStore = 1;
+        $initLocale = 'initial locale code';
+        $initTranslateInline = false;
+        $initDesignData = ['area' => $initArea, 'theme' => $initTheme, 'store' => $initStore];
+        $initialEnvInfo->setInitialTranslateInline($initTranslateInline)
+            ->setInitialDesign($initDesignData)
+            ->setInitialLocaleCode($initLocale);
+
+        // Expectations
+        $this->inlineTranslationMock->expects($this->once())
+            ->method('resume')
+            ->with($initTranslateInline);
+        $this->viewDesignMock->expects($this->once())
+            ->method('setDesignTheme')
+            ->with($initTheme, $initArea);
+        $this->storeManagerMock->expects($this->once())
+            ->method('setCurrentStore')
+            ->with($initStore);
+        $this->localeResolverMock->expects($this->once())
+            ->method('setLocaleCode')
+            ->with($initLocale);
+        $this->translateMock->expects($this->once())
+            ->method('setLocale')
+            ->with($initLocale);
+
+        // Test
+        $this->assertSame($this->model, $this->model->stopEnvironmentEmulation($initialEnvInfo));
+    }
+} 
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Asset/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Asset/ConfigTest.php
new file mode 100644
index 00000000000..c6baae82c17
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Asset/ConfigTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Tests Magento\Core\Model\Asset\Config
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Model\Asset;
+
+class ConfigTest extends \Magento\Test\BaseTestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    private $scopeConfigMock;
+
+    /**
+     * @var \Magento\Core\Model\Asset\Config
+     */
+    private $model;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->scopeConfigMock = $this->basicMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->model = $this->objectManager->getObject('Magento\Core\Model\Asset\Config',
+            ['scopeConfig' => $this->scopeConfigMock]
+        );
+
+    }
+
+    /**
+     * @dataProvider booleanDataProvider
+     */
+    public function testIsMergeCssFiles($booleanData)
+    {
+        $this->scopeConfigMock->expects($this->once())
+            ->method('isSetFlag')
+            ->with(Config::XML_PATH_MERGE_CSS_FILES, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->willReturn($booleanData);
+        $this->assertSame($booleanData, $this->model->isMergeCssFiles());
+    }
+
+    /**
+     * @dataProvider booleanDataProvider
+     */
+    public function testIsMergeJsFiles($booleanData)
+    {
+        $this->scopeConfigMock->expects($this->once())
+            ->method('isSetFlag')
+            ->with(Config::XML_PATH_MERGE_JS_FILES, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->willReturn($booleanData);
+        $this->assertSame($booleanData, $this->model->isMergeJsFiles());
+
+    }
+
+    public function testIsAssetMinification()
+    {
+        $contentType = 'content type';
+        $this->scopeConfigMock->expects($this->once())
+            ->method('isSetFlag')
+            ->with(
+                sprintf(Config::XML_PATH_MINIFICATION_ENABLED, $contentType),
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )->willReturn(true);
+        $this->assertTrue($this->model->isAssetMinification($contentType));
+    }
+
+    public function testGetAssetMinificationAdapter()
+    {
+        $contentType = 'content type';
+        $adapter = 'adapter';
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(
+                sprintf(Config::XML_PATH_MINIFICATION_ADAPTER, $contentType),
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )->willReturn($adapter);
+        $this->assertSame($adapter, $this->model->getAssetMinificationAdapter($contentType));
+    }
+}
+
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Asset/Plugin/CleanMergedJsCssTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Asset/Plugin/CleanMergedJsCssTest.php
new file mode 100644
index 00000000000..e06b5b5adac
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Asset/Plugin/CleanMergedJsCssTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Tests Magento\Core\Model\Asset\Plugin\CleanMergedJsCss
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Model\Asset\Plugin;
+
+class CleanMergedJsCssTest extends \Magento\Test\BaseTestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Core\Helper\File\Storage\Database
+     */
+    private $databaseMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Filesystem
+     */
+    private $filesystemMock;
+
+    /**
+     * @var bool
+     */
+    private $hasBeenCalled = false;
+
+    /**
+     * @var \Magento\Core\Model\Asset\Plugin\CleanMergedJsCss
+     */
+    private $model;
+
+    public function setUp()
+    {
+        parent::setUp();
+        $this->filesystemMock = $this->basicMock('\Magento\Framework\App\Filesystem');
+        $this->databaseMock = $this->basicMock('\Magento\Core\Helper\File\Storage\Database');
+        $this->model = $this->objectManager->getObject('Magento\Core\Model\Asset\Plugin\CleanMergedJsCss',
+            [
+                'database' => $this->databaseMock,
+                'filesystem' => $this->filesystemMock,
+            ]
+        );
+    }
+
+    public function testAroundCleanMergedJsCss()
+    {
+        $callable = function () {
+            $this->hasBeenCalled = true;
+        };
+        $readDir = 'read directory';
+        $mergedDir = $readDir .  '/' . \Magento\Framework\View\Asset\Merged::getRelativeDir();
+
+        $readDirectoryMock = $this->basicMock('\Magento\Framework\Filesystem\Directory\ReadInterface');
+        $readDirectoryMock->expects($this->any())->method('getAbsolutePath')->willReturn($readDir);
+
+        $this->databaseMock->expects($this->once())
+            ->method('deleteFolder')
+            ->with($mergedDir);
+        $this->filesystemMock->expects($this->once())
+            ->method('getDirectoryRead')
+            ->with(\Magento\Framework\App\Filesystem::STATIC_VIEW_DIR)
+            ->willReturn($readDirectoryMock);
+
+        $this->model->aroundCleanMergedJsCss(
+            $this->basicMock('\Magento\Framework\View\Asset\MergeService'),
+            $callable
+        );
+
+        $this->assertTrue($this->hasBeenCalled);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Address/AbstractAddressTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Address/AbstractAddressTest.php
index 499362a7e7e..46f4a837228 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Address/AbstractAddressTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Address/AbstractAddressTest.php
@@ -312,7 +312,7 @@ class AbstractAddressTest extends \PHPUnit_Framework_TestCase
             ),
             'telephone' => array(
                 array_merge(array_diff_key($data, array('telephone' => '')), array('country_id' => $countryId++)),
-                array('Please enter the telephone number.')
+                array('Please enter the phone number.')
             ),
             'postcode' => array(
                 array_merge(array_diff_key($data, array('postcode' => '')), array('country_id' => $countryId++)),
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/GroupRegistryTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/GroupRegistryTest.php
index 77c25de53e6..36aedf3d94a 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/GroupRegistryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/GroupRegistryTest.php
@@ -63,7 +63,7 @@ class GroupRegistryTest extends \PHPUnit_Framework_TestCase
             ->method('load')
             ->with($groupId)
             ->will($this->returnValue($group));
-        $group->expects($this->once())
+        $group->expects($this->exactly(2))
             ->method('getId')
             ->will($this->returnValue($groupId));
         $this->groupFactory->expects($this->once())
@@ -117,7 +117,7 @@ class GroupRegistryTest extends \PHPUnit_Framework_TestCase
             ->method('load')
             ->with($groupId)
             ->will($this->returnValue($group));
-        $group->expects($this->exactly(2))
+        $group->expects($this->exactly(4))
             ->method('getId')
             ->will($this->returnValue($groupId));
         $this->groupFactory->expects($this->exactly(2))
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
index 3455908ed9d..3064eb42201 100755
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
@@ -47,7 +47,7 @@ use Magento\Framework\Service\ExtensibleDataObjectConverter;
 class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
 {
     /** Sample values for testing */
-    const ID = 1;
+    const ID = '1';
     const FIRSTNAME = 'Jane';
     const LASTNAME = 'Doe';
     const NAME = 'J';
@@ -232,10 +232,6 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
 
         $this->_setupStoreMock();
 
-        $this->_mathRandomMock = $this->getMockBuilder(
-            '\Magento\Framework\Math\Random'
-        )->disableOriginalConstructor()->getMock();
-
         $this->_validator = $this->getMockBuilder(
             '\Magento\Customer\Model\Metadata\Validator'
         )->disableOriginalConstructor()->getMock();
@@ -667,7 +663,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $customerService = $this->_createService();
 
         try {
-            $customerService->validateResetPasswordLinkToken(1, $resetToken);
+            $customerService->validateResetPasswordLinkToken('1', $resetToken);
             $this->fail("Expected NoSuchEntityException not caught");
         } catch (NoSuchEntityException $nsee) {
             $this->assertSame('No such entity with customerId = 1', $nsee->getMessage());
@@ -681,7 +677,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_mockReturnValue(
             $this->_customerModelMock,
             array(
-                'getId' => 0,
+                'getId' => '0',
                 'load' => $this->_customerModelMock,
                 'getRpToken' => $resetToken,
                 'isResetPasswordLinkTokenExpired' => false
@@ -698,7 +694,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $customerService = $this->_createService();
 
         try {
-            $customerService->validateResetPasswordLinkToken(14, null);
+            $customerService->validateResetPasswordLinkToken('14', null);
             $this->fail('Expected exception not thrown.');
         } catch (InputException $e) {
             $this->assertEquals(InputException::REQUIRED_FIELD, $e->getRawMessage());
@@ -917,8 +913,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
     public function testResetPasswordShortPassword()
     {
         $resetToken = 'lsdj579slkj5987slkj595lkj';
-        $password = '';
-        $encryptedHash = 'password_encrypted_hash';
+        $password = '12345';
 
         $this->_mockReturnValue(
             $this->_customerModelMock,
@@ -945,17 +940,13 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ->method('setRpTokenCreatedAt')
             ->with(null)
             ->will($this->returnSelf());
-        $this->_encryptorMock->expects($this->once())
-            ->method('getHash')
-            ->with($password, true)
-            ->will($this->returnValue($encryptedHash));
-        $this->_customerModelMock->expects($this->once())
-            ->method('setPasswordHash')
-            ->with($encryptedHash)
-            ->will($this->returnSelf());
 
         $customerService = $this->_createService();
 
+        $this->setExpectedException(
+            'Magento\Framework\Exception\InputException',
+            'The password must have at least 6 characters.'
+        );
         $customerService->resetPassword(self::ID, $resetToken, $password);
     }
 
@@ -1032,7 +1023,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
     {
         $resetToken = 'lsdj579slkj5987slkj595lkj';
         $password = 'password_secret';
-        $invalidCustomerId = 4200;
+        $invalidCustomerId = '4200';
 
         $this->_customerRegistry
             ->expects($this->any())
@@ -1524,7 +1515,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             $this->assertEquals(InputException::DEFAULT_MESSAGE, $inputException->getRawMessage());
             $this->assertEquals(InputException::DEFAULT_MESSAGE, $inputException->getMessage());
             $this->assertEquals(InputException::DEFAULT_MESSAGE, $inputException->getLogMessage());
-            
+
             $errors = $inputException->getErrors();
             $this->assertCount(6, $errors);
 
@@ -1880,7 +1871,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ->method('getEmail')
             ->will($this->returnValue('somebody@example.com'));
 
-        
+
 
         $this->_customerModelMock->expects($this->any())
             ->method('getId')
@@ -2184,6 +2175,8 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
                 'encryptor' => $this->_encryptorMock,
                 'logger' => $this->_loggerMock,
                 'url' => $this->_urlMock,
+                'stringHelper' => new \Magento\Framework\Stdlib\String(),
+                'mathRandom' => new \Magento\Framework\Math\Random()
             ]
         );
         return $customerService;
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
index 85ccfa59eeb..938710bc58e 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
@@ -104,6 +104,7 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute'
         )->setMethods(
             array(
+                'getId',
                 'getAttributeCode',
                 'getFrontendInput',
                 'getInputFilter',
@@ -145,6 +146,11 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             ->method('getAttribute')
             ->will($this->returnValue($this->attributeEntityMock));
 
+        $this->attributeEntityMock
+            ->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+
         $this->attributeMetadataConverter
             ->expects($this->any())
             ->method('createMetadataAttribute')
diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Varien/Router/StandardTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Varien/Router/StandardTest.php
index 15e977101d8..21ab170383f 100644
--- a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Varien/Router/StandardTest.php
+++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Varien/Router/StandardTest.php
@@ -80,7 +80,6 @@ class StandardTest extends \PHPUnit_Framework_TestCase
         $matchedValue = null
     ) {
         $this->_model = $this->_prepareMocksForTestMatch($request, $isVde, $isLoggedIn, $routers);
-
         $this->assertEquals($matchedValue, $this->_model->match($request));
         if ($isVde && $isLoggedIn) {
             $this->assertEquals(self::TEST_PATH, $request->getPathInfo());
@@ -190,6 +189,7 @@ class StandardTest extends \PHPUnit_Framework_TestCase
      * @param bool $isLoggedIn
      * @param array $routers
      * @return \Magento\DesignEditor\Controller\Varien\Router\Standard
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     protected function _prepareMocksForTestMatch(
         \Magento\Framework\App\RequestInterface $request,
@@ -201,39 +201,34 @@ class StandardTest extends \PHPUnit_Framework_TestCase
         $helperMock = $this->_getHelperMock($isVde);
         $backendSessionMock = $this->_getBackendSessionMock($isVde, $isLoggedIn);
         $stateMock = $this->_getStateModelMock($routers);
-        $rewriteServiceMock = $this->getMock(
-            'Magento\UrlRewrite\App\Request\RewriteService', array(), array(), '', false
-        );
-        $routerListMock = $this->getMock('Magento\Framework\App\RouterList',
+        $routerListMock = $this->getMock(
+            'Magento\Framework\App\RouterList',
             array(
                 'current',
                 'next',
                 'key',
                 'valid',
                 'rewind'
-            ), array(
+            ),
+            array(
                 'routerList' => $routers
-            ), '', false
+            ),
+            '',
+            false
         );
         if (array_key_exists('matched', $routers)) {
             $routerListMock = $this->mockIterator($routerListMock, $routers, true);
         }
-
-        if ($isVde && $isLoggedIn) {
-            $rewriteServiceMock->expects($this->once())
-                ->method('applyRewrites')
-                ->with($request);
-        }
-        $arguments = array(
-            'routerId' => 'frontend',
-            'routerList' => $routerListMock,
-            'urlRewriteService' => $rewriteServiceMock,
-            'designEditorHelper' => $helperMock,
-            'designEditorState' => $stateMock,
-            'session' => $backendSessionMock
+        $router = (new \Magento\TestFramework\Helper\ObjectManager($this))->getObject(
+            'Magento\DesignEditor\Controller\Varien\Router\Standard',
+            array(
+                'routerId' => 'frontend',
+                'routerList' => $routerListMock,
+                'designEditorHelper' => $helperMock,
+                'designEditorState' => $stateMock,
+                'session' => $backendSessionMock
+            )
         );
-        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $router = $helper->getObject('\Magento\DesignEditor\Controller\Varien\Router\Standard', $arguments);
         return $router;
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Directory/Model/Config/Source/AllRegionTest.php b/dev/tests/unit/testsuite/Magento/Directory/Model/Config/Source/AllRegionTest.php
new file mode 100644
index 00000000000..4470da0be6d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Directory/Model/Config/Source/AllRegionTest.php
@@ -0,0 +1,238 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Directory\Model\Config\Source;
+
+class AllRegionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Directory\Model\Config\Source\AllRegion
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Directory\Model\Resource\Country\Collection
+     */
+    protected $countryCollection;
+
+    /**
+     * @var \Magento\Directory\Model\Resource\Region\Collection
+     */
+    protected $regionCollection;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $countryCollectionFactory = $this->getMockBuilder(
+            'Magento\Directory\Model\Resource\Country\CollectionFactory'
+        )->setMethods(['create', '__wakeup', '__sleep'])->disableOriginalConstructor()->getMock();
+
+        $this->countryCollection = $this->getMockBuilder('Magento\Directory\Model\Resource\Country\Collection')
+            ->setMethods(['load', 'toOptionArray', '__wakeup', '__sleep'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $countryCollectionFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->countryCollection));
+        $this->countryCollection->expects($this->once())
+            ->method('load')
+            ->will($this->returnSelf());
+
+        $regionCollectionFactory = $this->getMockBuilder(
+            'Magento\Directory\Model\Resource\Region\CollectionFactory'
+        )->disableOriginalConstructor()->setMethods(['create', '__wakeup', '__sleep'])->getMock();
+        $this->regionCollection = $this->getMockBuilder('Magento\Directory\Model\Resource\Region\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'getIterator', '__wakeup', '__sleep'])
+            ->getMock();
+        $regionCollectionFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->regionCollection));
+        $this->regionCollection->expects($this->once())
+            ->method('load')
+            ->will($this->returnValue($this->regionCollection));
+
+
+        $this->model = $objectManagerHelper->getObject(
+            'Magento\Directory\Model\Config\Source\Allregion',
+            [
+                'countryCollectionFactory' => $countryCollectionFactory,
+                'regionCollectionFactory' => $regionCollectionFactory
+            ]
+        );
+    }
+
+    /**
+     * @dataProvider toOptionArrayDataProvider
+     * @param bool $isMultiselect
+     * @param array $countries
+     * @param array $regions
+     * @param array $expectedResult
+     */
+    public function testToOptionArray($isMultiselect, $countries, $regions, $expectedResult)
+    {
+        $this->countryCollection->expects($this->once())
+            ->method('toOptionArray')
+            ->with(false)
+            ->will($this->returnValue(new \ArrayIterator($countries)));
+        $this->regionCollection->expects($this->once())
+            ->method('getIterator')
+            ->will($this->returnValue(new \ArrayIterator($regions)));
+
+        $this->assertEquals($expectedResult, $this->model->toOptionArray($isMultiselect));
+    }
+
+    /**
+     * Return data sets for testToOptionArray()
+     *
+     * @return array
+     */
+    public function toOptionArrayDataProvider()
+    {
+        return [
+            [
+                false,
+                [
+                    $this->generateCountry('France', 'fr'),
+                ],
+                [
+                    $this->generateRegion('fr', 1, 'Paris')
+                ],
+                [
+                    [
+                        'label' => '',
+                        'value' => ''
+                    ],
+                    [
+                        'label' => 'France',
+                        'value' => [
+                            [
+                                'label' => 'Paris',
+                                'value' => 1
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            [
+                true,
+                [
+                    $this->generateCountry('France', 'fr'),
+                ],
+                [
+                    $this->generateRegion('fr', 1, 'Paris'),
+                    $this->generateRegion('fr', 2, 'Marseille')
+                ],
+                [
+                    [
+                        'label' => 'France',
+                        'value' => [
+                            [
+                                'label' => 'Paris',
+                                'value' => 1
+                            ],
+                            [
+                                'label' => 'Marseille',
+                                'value' => 2
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            [
+                true,
+                [
+                    $this->generateCountry('France', 'fr'),
+                    $this->generateCountry('Germany', 'de'),
+                ],
+                [
+                    $this->generateRegion('fr', 1, 'Paris'),
+                    $this->generateRegion('de', 2, 'Berlin')
+                ],
+                [
+                    [
+                        'label' => 'France',
+                        'value' => [
+                            [
+                                'label' => 'Paris',
+                                'value' => 1
+                            ]
+                        ]
+                    ],
+                    [
+                        'label' => 'Germany',
+                        'value' => [
+                            [
+                                'label' => 'Berlin',
+                                'value' => 2
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+        ];
+    }
+
+    /**
+     * Generate a country array.
+     *
+     * @param string $countryLabel
+     * @param string $countryValue
+     * @return array
+     */
+    private function generateCountry($countryLabel, $countryValue)
+    {
+        return [
+            'label' => $countryLabel,
+            'value' => $countryValue
+        ];
+    }
+
+    /**
+     * Generate a mocked region.
+     *
+     * @param string $countryId
+     * @param string $id
+     * @param string $defaultName
+     * @return \Magento\Directory\Model\Region
+     */
+    private function generateRegion($countryId, $id, $defaultName)
+    {
+        $region = $this->getMockBuilder('Magento\Directory\Model\Region')
+            ->disableOriginalConstructor()
+            ->setMethods(['getCountryId', 'getId', 'getDefaultName', '__wakeup', '__sleep'])
+            ->getMock();
+        $region->expects($this->once())
+            ->method('getCountryId')
+            ->will($this->returnValue($countryId));
+        $region->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($id));
+        $region->expects($this->once())
+            ->method('getDefaultName')
+            ->will($this->returnValue($defaultName));
+
+        return $region;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Directory/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Directory/Model/ObserverTest.php
new file mode 100644
index 00000000000..c7d0bc37a9c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Directory/Model/ObserverTest.php
@@ -0,0 +1,143 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Directory\Model;
+
+use Magento\Store\Model\ScopeInterface;
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManager;
+
+    /** @var Observer */
+    protected $observer;
+
+    /** @var  \Magento\Directory\Model\Currency\Import\Factory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $importFactory;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    /** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $transportBuilder;
+
+    /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Directory\Model\CurrencyFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $currencyFactory;
+
+    /** @var \Magento\Framework\Translate\Inline\StateInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $inlineTranslation;
+
+    public function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->importFactory = $this->getMockBuilder('Magento\Directory\Model\Currency\Import\Factory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->scopeConfig = $this->getMockBuilder('Magento\Framework\App\MutableScopeConfig')
+            ->disableOriginalConstructor()
+            ->setMethods(['getValue'])
+            ->getMock();
+        $this->transportBuilder = $this->getMockBuilder('Magento\Framework\Mail\Template\TransportBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->currencyFactory = $this->getMockBuilder('Magento\Directory\Model\CurrencyFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->inlineTranslation = $this->getMockBuilder('Magento\Framework\Translate\Inline\StateInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->observer = $this->objectManager->getObject(
+            'Magento\Directory\Model\Observer',
+            array(
+                'importFactory' => $this->importFactory,
+                'scopeConfig' => $this->scopeConfig,
+                'transportBuilder' => $this->transportBuilder,
+                'storeManager' => $this->storeManager,
+                'currencyFactory' => $this->currencyFactory,
+                'inlineTranslation' => $this->inlineTranslation
+            )
+        );
+    }
+
+    public function testScheduledUpdateCurrencyRates()
+    {
+        $this->scopeConfig
+            ->expects($this->at(0))
+            ->method('getValue')
+            ->with(Observer::IMPORT_ENABLE, ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(1));
+        $this->scopeConfig
+            ->expects($this->at(1))
+            ->method('getValue')
+            ->with(Observer::CRON_STRING_PATH, ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue('cron-path'));
+        $this->scopeConfig
+            ->expects($this->at(2))
+            ->method('getValue')
+            ->with(Observer::IMPORT_SERVICE, ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue('import-service'));
+        $importInterfaceMock = $this->getMockBuilder('Magento\Directory\Model\Currency\Import\Webservicex')
+            ->disableOriginalConstructor()
+            ->setMethods(['fetchRates', 'getMessages'])
+            ->getMock();
+        $importInterfaceMock->expects($this->once())
+            ->method('fetchRates')
+            ->will($this->returnValue(array()));
+        $importInterfaceMock->expects($this->once())
+            ->method('getMessages')
+            ->will($this->returnValue(array()));
+
+        $this->importFactory
+            ->expects($this->once())
+            ->method('create')
+            ->with('import-service')
+            ->will($this->returnValue($importInterfaceMock));
+
+        $currencyMock = $this->getMockBuilder('Magento\Directory\Model\Currency')
+            ->disableOriginalConstructor()
+            ->setMethods(['saveRates', '__wakeup', '__sleep'])
+            ->getMock();
+        $currencyMock->expects($this->once())
+            ->method('saveRates')
+            ->will($this->returnValue(null));
+        $this->currencyFactory
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($currencyMock));
+
+        $this->observer->scheduledUpdateCurrencyRates(null);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php
index 2e26b78c295..a7272fa9afd 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Source/TableTest.php
@@ -24,6 +24,7 @@
 namespace Magento\Eav\Model\Entity\Attribute\Source;
 
 use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Eav\Model\Resource\Entity\Attribute\Option\CollectionFactory;
 
 class TableTest extends \PHPUnit_Framework_TestCase
 {
@@ -32,10 +33,35 @@ class TableTest extends \PHPUnit_Framework_TestCase
      */
     protected $_model;
 
+    /**
+     * @var CollectionFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactory;
+
     public function setUp()
     {
         $objectManager = new ObjectManager($this);
-        $this->_model = $objectManager->getObject('Magento\Eav\Model\Entity\Attribute\Source\Table');
+
+        $this->collectionFactory = $this->getMock(
+            'Magento\Eav\Model\Resource\Entity\Attribute\Option\CollectionFactory',
+            [
+                'create',
+                'setPositionOrder',
+                'setAttributeFilter',
+                'addFieldToFilter',
+                'setStoreFilter',
+                'load',
+                'toOptionArray'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->_model = $objectManager->getObject(
+            'Magento\Eav\Model\Entity\Attribute\Source\Table',
+            ['attrOptionCollectionFactory' => $this->collectionFactory]
+        );
     }
 
     public function testGetFlatColumns()
@@ -83,4 +109,141 @@ class TableTest extends \PHPUnit_Framework_TestCase
             $this->assertArrayHasKey('length', $result, 'FlatColumns must have "length" column');
         }
     }
+
+    /**
+     * @dataProvider specificOptionsProvider
+     * @param array $optionIds
+     * @param bool $withEmpty
+     */
+    public function testGetSpecificOptions($optionIds, $withEmpty)
+    {
+        $attributeId = 1;
+        $storeId = 5;
+        $options = [['label' => 'The label', 'value' => 'A value']];
+
+        $attribute = $this->getMock(
+            'Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
+            ['getId', 'getStoreId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $attribute->expects($this->once())
+            ->method('getId')
+            ->willReturn($attributeId);
+        $attribute->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+
+        $this->_model->setAttribute($attribute);
+
+        $this->collectionFactory->expects($this->once())
+            ->method('create')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setPositionOrder')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setAttributeFilter')
+            ->with($attributeId)
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('addFieldToFilter')
+            ->with('main_table.option_id', ['in' => $optionIds])
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setStoreFilter')
+            ->with($storeId)
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('load')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('toOptionArray')
+            ->willReturn($options);
+
+        if ($withEmpty) {
+            array_unshift($options, ['label' => '', 'value' => '']);
+        }
+
+        $this->assertEquals($options, $this->_model->getSpecificOptions($optionIds, $withEmpty));
+
+    }
+
+    public function specificOptionsProvider()
+    {
+        return [
+            [['1', '2'], true],
+            [[1, 2], false]
+        ];
+    }
+
+    /**
+     * @dataProvider getOptionTextProvider
+     * @param array $optionsIds
+     * @param array|string $value
+     * @param array $options
+     * @param array|string $expectedResult
+     */
+    public function testGetOptionText($optionsIds, $value, $options, $expectedResult)
+    {
+        $attributeId = 1;
+        $storeId = 5;
+        $attribute = $this->getMock(
+            'Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
+            ['getId', 'getStoreId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $attribute->expects($this->once())
+            ->method('getId')
+            ->willReturn($attributeId);
+        $attribute->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+
+        $this->_model->setAttribute($attribute);
+
+        $this->collectionFactory->expects($this->once())
+            ->method('create')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setPositionOrder')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setAttributeFilter')
+            ->with($attributeId)
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('addFieldToFilter')
+            ->with('main_table.option_id', ['in' => $optionsIds])
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('setStoreFilter')
+            ->with($storeId)
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('load')
+            ->willReturnSelf();
+        $this->collectionFactory->expects($this->once())
+            ->method('toOptionArray')
+            ->willReturn($options);
+
+        $this->assertEquals($expectedResult, $this->_model->getOptionText($value));
+    }
+
+    public function getOptionTextProvider()
+    {
+        return [
+            [
+                ['1', '2'],
+                '1,2',
+                [['label' => 'test label 1', 'value' => '1'], ['label' => 'test label 2', 'value' => '1']],
+                ['test label 1', 'test label 2']
+            ],
+            ['1', '1', [['label' => 'test label', 'value' => '1']], 'test label'],
+            ['5', '5', [['label' => 'test label', 'value' => '5']], 'test label']
+        ];
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
index 6e174fdf614..44290f3dff6 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
@@ -59,7 +59,17 @@ class ActionTest extends \PHPUnit_Framework_TestCase
      */
     protected $_redirectMock;
 
-    /*
+    /**
+     * @var \Magento\Framework\App\ViewInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
      * Full action name
      */
     const FULL_ACTION_NAME = 'module/controller/someaction';
@@ -114,6 +124,11 @@ class ActionTest extends \PHPUnit_Framework_TestCase
         );
         $this->_responseMock = $this->getMock('Magento\Framework\App\ResponseInterface', [], [], '', false);
 
+        $this->pageConfigMock = $this->getMock('Magento\Framework\View\Page\Config', ['getConfig'], [], '', false);
+        $this->viewMock = $this->getMock('Magento\Framework\App\ViewInterface');
+        $this->viewMock->expects($this->any())->method('getPage')->will($this->returnValue($this->pageConfigMock));
+        $this->pageConfigMock->expects($this->any())->method('getConfig')->will($this->returnValue(1));
+
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->action = $this->objectManagerHelper->getObject(
             'Magento\Framework\App\Action\ActionFake',
@@ -123,6 +138,7 @@ class ActionTest extends \PHPUnit_Framework_TestCase
                 'eventManager' => $this->_eventManagerMock,
                 'redirect' => $this->_redirectMock,
                 'actionFlag' => $this->_actionFlagMock,
+                'view' => $this->viewMock,
             ]
         );
         \Magento\Framework\Profiler::disable();
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
index 2fd488c5459..2b3c4397377 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
@@ -245,4 +245,4 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
             [true, false],
         ];
     }
-}
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/FactoryStub.php b/dev/tests/unit/testsuite/Magento/Framework/App/FactoryStub.php
new file mode 100644
index 00000000000..12c0120a65a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/FactoryStub.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App;
+
+/**
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+class FactoryStub implements \Magento\Framework\ObjectManager\Factory
+{
+    /**
+     * @param \Magento\Framework\ObjectManager\Config $config
+     * @param \Magento\Framework\ObjectManager $objectManager
+     * @param \Magento\Framework\ObjectManager\Definition $definitions
+     * @param array $globalArguments
+     * @throws \BadMethodCallException
+     */
+    public function __construct($config, $objectManager = null, $definitions = null, $globalArguments = array())
+    {
+        throw new \BadMethodCallException(__METHOD__);
+    }
+
+    /**
+     * Create instance with call time arguments
+     *
+     * @param string $requestedType
+     * @param array $arguments
+     * @return object
+     * @throws \BadMethodCallException
+     */
+    public function create($requestedType, array $arguments = array())
+    {
+        throw new \BadMethodCallException(__METHOD__);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/MaintenanceModeTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/MaintenanceModeTest.php
index c7b0e0ffa90..31f77f1d04a 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/MaintenanceModeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/MaintenanceModeTest.php
@@ -36,7 +36,7 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
      */
     protected $flagDir ;
 
-    protected function setUp()
+    protected function setup()
     {
         $this->flagDir = $this->getMockForAbstractClass('\Magento\Framework\Filesystem\Directory\WriteInterface');
         $filesystem = $this->getMock('Magento\Framework\App\Filesystem', [], [], '', false);
@@ -55,7 +55,37 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
         $this->assertFalse($this->model->isOn());
     }
 
-    public function testSetMaintenanceModeOn()
+    public function testisOnWithoutIP()
+    {
+        $mapisExist = [
+            [MaintenanceMode::FLAG_FILENAME, true],
+            [MaintenanceMode::IP_FILENAME, false]
+        ];
+        $this->flagDir->expects($this->exactly(2))->method('isExist')
+            ->will(($this->returnValueMap($mapisExist)));
+        $this->assertTrue($this->model->isOn());
+    }
+
+    public function testisOnWithIP()
+    {
+        $mapisExist = [
+            [MaintenanceMode::FLAG_FILENAME, true],
+            [MaintenanceMode::IP_FILENAME, true]
+        ];
+        $this->flagDir->expects($this->exactly(2))->method('isExist')
+            ->will(($this->returnValueMap($mapisExist)));
+        $this->assertFalse($this->model->isOn());
+    }
+
+    public function testisOnWithIPNoMaintenance()
+    {
+        $this->flagDir->expects($this->once())->method('isExist')
+            ->with(MaintenanceMode::FLAG_FILENAME)
+            ->willReturn(false);
+        $this->assertFalse($this->model->isOn());
+    }
+
+    public function testMaintenanceModeOn()
     {
         $this->flagDir->expects($this->at(0))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME)
             ->will($this->returnValue(false));
@@ -71,7 +101,7 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->model->isOn());
     }
 
-    public function testSetMaintenanceModeOff()
+    public function testMaintenanceModeOff()
     {
         $this->flagDir->expects($this->at(0))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME)
             ->will($this->returnValue(true));
@@ -86,11 +116,11 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
 
     public function testSetAddresses()
     {
-        $mapIsExist = [
+        $mapisExist = [
             [MaintenanceMode::FLAG_FILENAME, true],
             [MaintenanceMode::IP_FILENAME, true]
         ];
-        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapIsExist));
+        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist));
         $this->flagDir->expects($this->any())->method('writeFile')
             ->with(MaintenanceMode::IP_FILENAME)
             ->will($this->returnValue(true));
@@ -105,12 +135,12 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
 
     public function testSetSingleAddresses()
     {
-        $mapIsExist = [
+        $mapisExist = [
             [MaintenanceMode::FLAG_FILENAME, true],
             [MaintenanceMode::IP_FILENAME, true]
         ];
-        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapIsExist));
-        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapIsExist));
+        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist));
+        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist));
 
         $this->flagDir->expects($this->any())->method('writeFile')
             ->will($this->returnValue(10));
@@ -125,12 +155,12 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
 
     public function testOnSetMultipleAddresses()
     {
-        $mapIsExist = [
+        $mapisExist = [
             [MaintenanceMode::FLAG_FILENAME, true],
             [MaintenanceMode::IP_FILENAME, true]
         ];
-        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapIsExist));
-        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapIsExist));
+        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist));
+        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist));
 
         $this->flagDir->expects($this->any())->method('writeFile')
             ->will($this->returnValue(10));
@@ -148,12 +178,12 @@ class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
 
     public function testOffSetMultipleAddresses()
     {
-        $mapIsExist = [
+        $mapisExist = [
             [MaintenanceMode::FLAG_FILENAME, false],
             [MaintenanceMode::IP_FILENAME, true]
         ];
-        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapIsExist));
-        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapIsExist));
+        $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist));
+        $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist));
 
         $this->flagDir->expects($this->any())->method('readFile')
             ->with(MaintenanceMode::IP_FILENAME)
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/ObjectManagerFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/ObjectManagerFactoryTest.php
new file mode 100644
index 00000000000..561461936f6
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/ObjectManagerFactoryTest.php
@@ -0,0 +1,68 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App;
+
+/**
+ * @covers \Magento\Framework\App\ObjectManagerFactory
+ */
+class ObjectManagerFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var callable[] */
+    protected static $originalAutoloadFunctions;
+
+    /** @var string */
+    protected static $originalIncludePath;
+
+    public static function setUpBeforeClass()
+    {
+        self::$originalAutoloadFunctions = spl_autoload_functions();
+        self::$originalIncludePath = get_include_path();
+    }
+
+    /**
+     * Avoid impact of initialized \Magento\Framework\Code\Generator\Autoloader on other tests
+     */
+    public static function tearDownAfterClass()
+    {
+        foreach (spl_autoload_functions() as $autoloadFunction) {
+            spl_autoload_unregister($autoloadFunction);
+        }
+        foreach (self::$originalAutoloadFunctions as $autoloadFunction) {
+            spl_autoload_register($autoloadFunction);
+        }
+        set_include_path(self::$originalIncludePath);
+        \Magento\Framework\Io\File::rmdirRecursive(__DIR__ . '/_files/var/');
+    }
+
+    /**
+     * @expectedException \BadMethodCallException
+     * @expectedExceptionMessage Magento\Framework\App\FactoryStub::__construct
+     */
+    public function testCreateObjectManagerFactoryCouldBeOverridden()
+    {
+        $rootPath = __DIR__ . '/_files/';
+        $factory = new ObjectManagerFactory();
+        $factory->create($rootPath, array(), false);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/ViewTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/ViewTest.php
index bd77b734bf6..c1f888bd325 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/ViewTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/ViewTest.php
@@ -60,6 +60,16 @@ class ViewTest extends \PHPUnit_Framework_TestCase
      */
     protected $_eventManagerMock;
 
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPage;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
     protected function setUp()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
@@ -71,13 +81,13 @@ class ViewTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->_layoutProcessor));
         $this->_actionFlagMock = $this->getMock('Magento\Framework\App\ActionFlag', array(), array(), '', false);
         $this->_eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
-        $resultPage = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+        $this->resultPage = $this->getMockBuilder('Magento\Framework\View\Result\Page')
             ->setConstructorArgs(
                 $helper->getConstructArguments('Magento\Framework\View\Result\Page', ['request' => $this->_requestMock])
             )
-            ->setMethods(['getLayout'])
+            ->setMethods(['getLayout', 'renderResult'])
             ->getMock();
-        $resultPage->expects($this->any())
+        $this->resultPage->expects($this->any())
             ->method('getLayout')
             ->will($this->returnValue($this->_layoutMock));
         $pageFactory = $this->getMockBuilder('Magento\Framework\View\Result\PageFactory')
@@ -86,14 +96,16 @@ class ViewTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $pageFactory->expects($this->once())
             ->method('create')
-            ->will($this->returnValue($resultPage));
+            ->will($this->returnValue($this->resultPage));
+
+        $this->response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
 
         $this->_view = $helper->getObject(
             'Magento\Framework\App\View',
             array(
                 'layout' => $this->_layoutMock,
                 'request' => $this->_requestMock,
-                'response' => $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false),
+                'response' => $this->response,
                 'configScope' => $this->_configScopeMock,
                 'eventManager' => $this->_eventManagerMock,
                 'actionFlag' => $this->_actionFlagMock,
@@ -168,62 +180,29 @@ class ViewTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('expectedvalue', $this->_view->getDefaultLayoutHandle());
     }
 
-    public function testAddActionLayoutHandlesWhenPageLayoutHandlesNotExist()
-    {
-        $defaultHandles = 'full_action_name';
-        $this->_requestMock->expects(
-            $this->exactly(2)
-        )->method(
-            'getFullActionName'
-        )->will(
-            $this->returnValue('Full_Action_Name')
-        );
-        $this->_layoutProcessor->expects(
-            $this->once()
-        )->method(
-            'addPageHandles'
-        )->with(
-            array($defaultHandles)
-        )->will(
-            $this->returnValue(false)
-        );
-        $this->_layoutProcessor->expects($this->once())->method('addHandle')->with($defaultHandles);
-        $this->_view->addActionLayoutHandles();
-    }
-
     public function testAddActionLayoutHandlesWhenPageLayoutHandlesExist()
     {
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getFullActionName'
-        )->will(
-            $this->returnValue('Full_Action_Name')
-        );
-        $this->_layoutProcessor->expects(
-            $this->once()
-        )->method(
-            'addPageHandles'
-        )->with(
-            array('full_action_name')
-        )->will(
-            $this->returnValue(true)
-        );
-        $this->_layoutProcessor->expects($this->never())->method('addHandle');
+        $this->_requestMock->expects($this->once())
+            ->method('getFullActionName')
+            ->will($this->returnValue('Full_Action_Name'));
+
+        $this->_layoutProcessor->expects($this->once())
+            ->method('addHandle')
+            ->with('full_action_name');
+
         $this->_view->addActionLayoutHandles();
     }
 
     public function testAddPageLayoutHandles()
     {
         $pageHandles = array('full_action_name', 'full_action_name_key_value');
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getFullActionName'
-        )->will(
-            $this->returnValue('Full_Action_Name')
-        );
-        $this->_layoutProcessor->expects($this->once())->method('addPageHandles')->with($pageHandles);
+        $this->_requestMock->expects($this->once())
+            ->method('getFullActionName')
+            ->will($this->returnValue('Full_Action_Name'));
+
+        $this->_layoutProcessor->expects($this->once())
+            ->method('addHandle')
+            ->with($pageHandles);
         $this->_view->addPageLayoutHandles(array('key' => 'value'));
     }
 
@@ -294,35 +273,24 @@ class ViewTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderLayoutWhenOutputNotEmpty()
     {
-        $this->_actionFlagMock->expects(
-            $this->once()
-        )->method(
-            'get'
-        )->with(
-            '',
-            'no-renderLayout'
-        )->will(
-            $this->returnValue(false)
-        );
+        $this->_actionFlagMock->expects($this->once())
+            ->method('get')
+            ->with('', 'no-renderLayout')
+            ->will($this->returnValue(false));
         $this->_layoutMock->expects($this->once())->method('addOutputElement')->with('output');
-        $this->_layoutMock->expects($this->once())->method('getOutput');
+        $this->resultPage->expects($this->once())->method('renderResult')->with($this->response);
         $this->_view->renderLayout('output');
     }
 
     public function testRenderLayoutWhenOutputEmpty()
     {
-        $this->_actionFlagMock->expects(
-            $this->once()
-        )->method(
-            'get'
-        )->with(
-            '',
-            'no-renderLayout'
-        )->will(
-            $this->returnValue(false)
-        );
+        $this->_actionFlagMock->expects($this->once())
+            ->method('get')
+            ->with('', 'no-renderLayout')
+            ->will($this->returnValue(false));
+
         $this->_layoutMock->expects($this->never())->method('addOutputElement');
-        $this->_layoutMock->expects($this->once())->method('getOutput');
+        $this->resultPage->expects($this->once())->method('renderResult')->with($this->response);
         $this->_view->renderLayout();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers.xml b/dev/tests/unit/testsuite/Magento/Framework/App/_files/app/etc/di.xml
similarity index 81%
rename from dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers.xml
rename to dev/tests/unit/testsuite/Magento/Framework/App/_files/app/etc/di.xml
index ced9ee67f87..7af0f7f8529 100644
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers.xml
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/_files/app/etc/di.xml
@@ -23,9 +23,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../app/code/Magento/Index/etc/indexers.xsd">
-    <indexer name="name_one" instance="Node_One_Two" />
-    <indexer name="name_two">
-        <depends name="name_three" />
-    </indexer>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Framework\ObjectManager\Factory\Factory" type="Magento\Framework\App\FactoryStub" />
 </config>
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php b/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
index 5c4197d6d2b..dae7338b528 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
@@ -53,8 +53,8 @@ class NameBuilderTest extends \PHPUnit_Framework_TestCase
             [['Checkout', 'Controller', 'Index'], 'Checkout\Controller\Index'],
             [['checkout', 'controller', 'index'], 'Checkout\Controller\Index'],
             [
-                ['Magento_Backend', 'Block', 'urlrewrite', 'edit', 'form'],
-                'Magento\Backend\Block\Urlrewrite\Edit\Form'
+                ['magento_backend', 'block', 'system', 'store', 'edit'],
+                'Magento\Backend\Block\System\Store\Edit'
             ],
             [['MyNamespace', 'MyModule'], 'MyNamespace\MyModule'],
             [['uc', 'words', 'test'], 'Uc\Words\Test'],
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Config/DataTest.php b/dev/tests/unit/testsuite/Magento/Framework/Config/DataTest.php
new file mode 100644
index 00000000000..0d7216828b2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Config/DataTest.php
@@ -0,0 +1,76 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Config;
+
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\Config\ReaderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $reader;
+    /** @var \Magento\Framework\Config\CacheInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $cache;
+    /** @var \Magento\TestFramework\Helper\ObjectManager */
+    protected $objectManagerHelper;
+
+    public function setUp()
+    {
+        $this->reader = $this->getMockBuilder('Magento\\Framework\\Config\\ReaderInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->cache = $this->getMockBuilder('Magento\\Framework\\Config\\CacheInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+    }
+
+    public function testGet()
+    {
+        $data = ['a' => 'b'];
+        $cacheid = 'test';
+        $this->cache->expects($this->once())->method('load')->will($this->returnValue(false));
+        $this->reader->expects($this->once())->method('read')->will($this->returnValue($data));
+
+        $config = new \Magento\Framework\Config\Data(
+            $this->reader, $this->cache, $cacheid
+        );
+        $this->assertEquals($data, $config->get());
+        $this->assertEquals('b', $config->get('a'));
+        $this->assertEquals(null, $config->get('a/b'));
+        $this->assertEquals(33, $config->get('a/b', 33));
+    }
+
+    public function testReset()
+    {
+        $cacheid = 'test';
+        $this->cache->expects($this->once())->method('load')->will($this->returnValue(serialize([])));
+        $this->cache->expects($this->once())->method('remove')->with($cacheid);
+
+        $config = new \Magento\Framework\Config\Data(
+            $this->reader,
+            $this->cache,
+            $cacheid
+        );
+
+        $config->reset();
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
index 0ade1982c2e..11d63cf5875 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
@@ -24,41 +24,48 @@
 
 namespace Magento\Framework\Search\Adapter\Mysql;
 
-
 use Magento\Framework\App\Resource\Config;
 use Magento\Framework\App\Resource;
 use Magento\TestFramework\Helper\ObjectManager;
 
 class AdapterTest extends \PHPUnit_Framework_TestCase
 {
+
     /**
      * @var ResponseFactory|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $responseFactory;
+
     /**
      * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $connectionAdapter;
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Mapper|\PHPUnit_Framework_MockObject_MockObject
      */
     private $mapper;
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Adapter
      */
     private $adapter;
+
     /**
      * @var ObjectManager
      */
     private $objectManager;
+
     /**
      * @var \Magento\Framework\Search\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $request;
+
     /**
      * @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject
      */
     private $select;
+
     /**
      * @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject
      */
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
index c8e7a7c2b4b..66c7601bb16 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php
@@ -61,11 +61,11 @@ class MatchTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $select->expects($this->once())->method('getMatchQuery')
-            ->with($this->equalTo('some_field'), $this->equalTo('-some_value'))
+            ->with($this->equalTo(['some_field']), $this->equalTo('-some_value'))
             ->will($this->returnValue('matchedQuery'));
         $select->expects($this->once())->method('match')
             ->with(
-                $this->equalTo('some_field'),
+                $this->equalTo(['some_field']),
                 $this->equalTo('-some_value'),
                 $this->equalTo(true),
                 $this->equalTo(Select::FULLTEXT_MODE_BOOLEAN)
@@ -73,12 +73,12 @@ class MatchTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Framework\Search\Request\Query\Match|\PHPUnit_Framework_MockObject_MockObject $query */
         $query = $this->getMockBuilder('Magento\Framework\Search\Request\Query\Match')
-            ->setMethods(['getMatches'])
+            ->setMethods(['getMatches', 'getValue', 'getBoost'])
             ->disableOriginalConstructor()
             ->getMock();
-        $query->expects($this->once())->method('getMatches')->will(
-            $this->returnValue([['field' => 'some_field', 'value' => 'some_value', 'boost' => $boost]])
-        );
+        $query->expects($this->once())->method('getValue')->willReturn('some_value');
+        $query->expects($this->once())->method('getBoost')->willReturn($boost);
+        $query->expects($this->once())->method('getMatches')->willReturn([['field' => 'some_field']]);
 
         $this->scoreBuilder->expects($this->once())->method('addCondition')
             ->with(
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
new file mode 100644
index 00000000000..e1240645cfb
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
@@ -0,0 +1,173 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Search\Adapter\Mysql;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ConditionManagerTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resource;
+
+    /** @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager */
+    private $conditionManager;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $adapter;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['quote', 'quoteIdentifier'])
+            ->getMockForAbstractClass();
+        $this->adapter->expects($this->any())
+            ->method('quote')
+            ->will(
+                $this->returnCallback(
+                    function ($value) {
+                        return sprintf('\'%s\'', $value);
+                    }
+                )
+            );
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will(
+                $this->returnCallback(
+                    function ($value) {
+                        return sprintf('`%s`', $value);
+                    }
+                )
+            );
+
+        $this->resource = $this->getMockBuilder('Magento\Framework\App\Resource')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                ['getConnection']
+            )
+            ->getMock();
+        $this->resource->expects($this->once())
+            ->method('getConnection')
+            ->will($this->returnValue($this->adapter));
+
+        $this->conditionManager = $objectManager->getObject(
+            '\Magento\Framework\Search\Adapter\Mysql\ConditionManager',
+            [
+                'resource' => $this->resource
+            ]
+        );
+    }
+
+    /**
+     * @dataProvider wrapBracketsDataProvider
+     * @param $query
+     * @param $expectedResult
+     */
+    public function testWrapBrackets($query, $expectedResult)
+    {
+        $actualResult = $this->conditionManager->wrapBrackets($query);
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+
+    /**
+     * Data provider for wrapBrackets test
+     *
+     * @return array
+     */
+    public function wrapBracketsDataProvider()
+    {
+        return [
+            'validQuery' => [
+                'query' => 'a = b',
+                'expectedResult' => '(a = b)',
+            ],
+            'emptyQuery' => [
+                'query' => '',
+                'expectedResult' => '',
+            ],
+            'invalidQuery' => [
+                'query' => '1',
+                'expectedResult' => '(1)',
+            ]
+        ];
+    }
+
+    public function testCombineQueries()
+    {
+        $queries = [
+            'a = b',
+            false,
+            true,
+            '',
+            0,
+            'test'
+        ];
+        $unionOperator = 'AND';
+        $expectedResult = 'a = b AND 1 AND 0 AND test';
+        $actualResult = $this->conditionManager->combineQueries($queries, $unionOperator);
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+
+    /**
+     * @dataProvider generateConditionDataProvider
+     * @param $field
+     * @param $operator
+     * @param $value
+     * @param $expectedResult
+     */
+    public function testGenerateCondition($field, $operator, $value, $expectedResult)
+    {
+        $actualResult = $this->conditionManager->generateCondition($field, $operator, $value);
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+
+    /**
+     * @return array
+     */
+    public function generateConditionDataProvider()
+    {
+        return [
+            [
+                'field' => 'a',
+                'operator' => '=',
+                'value' => 1,
+                'expectedResult' => '`a` = \'1\''
+            ],
+            [
+                'field' => 'a',
+                'operator' => '=',
+                'value' => '123',
+                'expectedResult' => '`a` = \'123\''
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
index 797a53395a3..448baeca0d5 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
@@ -32,48 +32,26 @@ class DimensionsTest extends \PHPUnit_Framework_TestCase
 
     /** @var \Magento\TestFramework\Helper\ObjectManager */
     private $objectManager;
-    /** @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject */
-    private $adapter;
-    /** @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject */
-    private $resource;
+
     /** @var \Magento\Framework\App\ScopeInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $scope;
+
     /** @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
     private $scopeResolver;
+
     /** @var \Magento\Framework\Search\Request\Dimension|\PHPUnit_Framework_MockObject_MockObject */
     private $dimension;
+
     /** @var DimensionsBuilder */
     private $builder;
 
+    /** @var  \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject */
+    private $conditionManager;
+
     protected function setUp()
     {
         $this->objectManager = new ObjectManager($this);
 
-        $this->adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
-            ->disableOriginalConstructor()
-            ->setMethods(['quote', 'quoteIdentifier'])
-            ->getMockForAbstractClass();
-
-        $escapeValueCallback = function ($value) {
-            return '`' . $value . '`';
-        };
-
-        $this->adapter->expects($this->once())
-            ->method('quote')
-            ->will($this->returnCallback($escapeValueCallback));
-        $this->adapter->expects($this->once())
-            ->method('quoteIdentifier')
-            ->will($this->returnCallback($escapeValueCallback));
-
-        $this->resource = $this->getMockBuilder('\Magento\Framework\App\Resource')
-            ->disableOriginalConstructor()
-            ->setMethods(['getConnection'])
-            ->getMock();
-        $this->resource->expects($this->once())
-            ->method('getConnection')
-            ->with(\Magento\Framework\App\Resource::DEFAULT_READ_RESOURCE)
-            ->will($this->returnValue($this->adapter));
-
         $this->scope = $this->getMockBuilder('\Magento\Framework\App\ScopeInterface')
             ->disableOriginalConstructor()
             ->setMethods(['getId'])
@@ -89,10 +67,24 @@ class DimensionsTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['getName', 'getValue'])
             ->getMock();
 
+        $this->conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
+            ->disableOriginalConstructor()
+            ->setMethods(['generateCondition'])
+            ->getMock();
+        $this->conditionManager->expects($this->any())
+            ->method('generateCondition')
+            ->will(
+                $this->returnCallback(
+                    function ($field, $operator, $value) {
+                        return sprintf('`%s` %s `%s`', $field, $operator, $value);
+                    }
+                )
+            );
+
         $this->builder = $this->objectManager->getObject(
             '\Magento\Framework\Search\Adapter\Mysql\Dimensions',
             [
-                'resource' => $this->resource,
+                'conditionManager' => $this->conditionManager,
                 'scopeResolver' => $this->scopeResolver
             ]
         );
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/RangeTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/RangeTest.php
index 644ed1ee919..c13b5e5f740 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/RangeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/RangeTest.php
@@ -28,23 +28,22 @@ use Magento\TestFramework\Helper\ObjectManager;
 
 class RangeTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $adapter;
-    /**
-     * @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $resource;
+
     /**
      * @var \Magento\Framework\Search\Request\Filter\Term|\PHPUnit_Framework_MockObject_MockObject
      */
     private $requestFilter;
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Range
      */
     private $filter;
 
+    /**
+     * @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $conditionManager;
+
     /**
      * Set Up
      */
@@ -56,23 +55,24 @@ class RangeTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
-            ->setMethods(['quote'])
-            ->getMockForAbstractClass();
-
-        $this->resource = $this->getMockBuilder('Magento\Framework\App\Resource')
-            ->setMethods(['getConnection'])
+        $this->conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
             ->disableOriginalConstructor()
+            ->setMethods(['generateCondition'])
             ->getMock();
-        $this->resource->expects($this->once())
-            ->method('getConnection')
-            ->with(\Magento\Framework\App\Resource::DEFAULT_READ_RESOURCE)
-            ->will($this->returnValue($this->adapter));
+        $this->conditionManager->expects($this->any())
+            ->method('generateCondition')
+            ->will(
+                $this->returnCallback(
+                    function ($field, $operator, $value) {
+                        return sprintf('%s %s \'%s\'', $field, $operator, $value);
+                    }
+                )
+            );
 
         $this->filter = $objectManager->getObject(
             'Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Range',
             [
-                'resource' => $this->resource,
+                'conditionManager' => $this->conditionManager,
             ]
         );
     }
@@ -81,36 +81,29 @@ class RangeTest extends \PHPUnit_Framework_TestCase
      * @param string $field
      * @param string $from
      * @param string $to
+     * @param bool $isNegation
      * @param string $expectedResult
      * @dataProvider buildQueryDataProvider
      */
-    public function testBuildQuery($field, $from, $to, $expectedResult)
+    public function testBuildQuery($field, $from, $to, $isNegation, $expectedResult)
     {
-        $this->requestFilter->expects($this->once())
+        $this->requestFilter->expects($this->any())
             ->method('getField')
             ->will($this->returnValue($field));
-        $this->requestFilter->expects($this->once())
+        $this->requestFilter->expects($this->atLeastOnce())
             ->method('getFrom')
             ->will($this->returnValue($from));
-        $this->requestFilter->expects($this->once())
+        $this->requestFilter->expects($this->atLeastOnce())
             ->method('getTo')
             ->will($this->returnValue($to));
-        $this->adapter->expects($this->any())
-            ->method('quote')
-            ->will(
-                $this->returnCallback(
-                    function ($value) {
-                        return '\'' . $value . '\'';
-                    }
-                )
-            );
 
-        $actualResult = $this->filter->buildFilter($this->requestFilter);
+        $actualResult = $this->filter->buildFilter($this->requestFilter, $isNegation);
         $this->assertEquals($expectedResult, $actualResult);
     }
 
     /**
      * Data provider for BuildQuery
+     *
      * @return array
      */
     public function buildQueryDataProvider()
@@ -120,36 +113,70 @@ class RangeTest extends \PHPUnit_Framework_TestCase
                 'field' => 'testField',
                 'from' => '0',
                 'to' => '10',
+                'isNegation' => false,
                 'expectedResult' => 'testField >= \'0\' AND testField < \'10\'',
             ],
             'rangeWithIntegers' => [
                 'field' => 'testField',
                 'from' => 50,
                 'to' => 50,
+                'isNegation' => false,
                 'expectedResult' => 'testField >= \'50\' AND testField < \'50\'',
             ],
             'rangeWithFloats' => [
                 'field' => 'testField',
                 'from' => 50.5,
                 'to' => 55.5,
+                'isNegation' => false,
                 'expectedResult' => 'testField >= \'50.5\' AND testField < \'55.5\'',
             ],
+            'rangeWithStringsNegative' => [
+                'field' => 'testField',
+                'from' => '0',
+                'to' => '10',
+                'isNegation' => true,
+                'expectedResult' => 'testField < \'0\' OR testField >= \'10\'',
+            ],
             'rangeWithoutFromValue' => [
                 'field' => 'testField',
                 'from' => null,
                 'to' => 50,
+                'isNegation' => false,
                 'expectedResult' => 'testField < \'50\'',
             ],
+            'rangeWithoutFromValueNegative' => [
+                'field' => 'testField',
+                'from' => null,
+                'to' => 50,
+                'isNegation' => true,
+                'expectedResult' => 'testField >= \'50\'',
+            ],
             'rangeWithoutToValue' => [
                 'field' => 'testField',
                 'from' => 50,
                 'to' => null,
+                'isNegation' => false,
                 'expectedResult' => 'testField >= \'50\'',
             ],
+            'rangeWithoutToValueNegative' => [
+                'field' => 'testField',
+                'from' => 50,
+                'to' => null,
+                'isNegation' => true,
+                'expectedResult' => 'testField < \'50\'',
+            ],
             'rangeWithEmptyValues' => [
                 'field' => 'testField',
                 'from' => null,
                 'to' => null,
+                'isNegation' => false,
+                'expectedResult' => '',
+            ],
+            'rangeWithEmptyValuesNegative' => [
+                'field' => 'testField',
+                'from' => null,
+                'to' => null,
+                'isNegation' => true,
                 'expectedResult' => '',
             ],
         ];
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/TermTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/TermTest.php
index b51d66be798..47d6342a5bd 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/TermTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/TermTest.php
@@ -28,23 +28,22 @@ use Magento\TestFramework\Helper\ObjectManager;
 
 class TermTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $adapter;
-    /**
-     * @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $resource;
+
     /**
      * @var \Magento\Framework\Search\Request\Filter\Term|\PHPUnit_Framework_MockObject_MockObject
      */
     private $requestFilter;
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Term
      */
     private $filter;
 
+    /**
+     * @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $conditionManager;
+
     /**
      * Set up
      */
@@ -56,23 +55,29 @@ class TermTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
-            ->setMethods(['quote'])
-            ->getMockForAbstractClass();
-
-        $this->resource = $this->getMockBuilder('Magento\Framework\App\Resource')
-            ->setMethods(['getConnection'])
+        $this->conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
             ->disableOriginalConstructor()
+            ->setMethods(['generateCondition'])
             ->getMock();
-        $this->resource->expects($this->once())
-            ->method('getConnection')
-            ->with(\Magento\Framework\App\Resource::DEFAULT_READ_RESOURCE)
-            ->will($this->returnValue($this->adapter));
+        $this->conditionManager->expects($this->any())
+            ->method('generateCondition')
+            ->will(
+                $this->returnCallback(
+                    function ($field, $operator, $value) {
+                        return sprintf(
+                            is_array($value) ? '%s %s (%s)' : '%s %s %s',
+                            $field,
+                            $operator,
+                            is_array($value) ? implode(', ', $value) : $value
+                        );
+                    }
+                )
+            );
 
         $this->filter = $objectManager->getObject(
             'Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Term',
             [
-                'resource' => $this->resource,
+                'conditionManager' => $this->conditionManager,
             ]
         );
     }
@@ -80,42 +85,55 @@ class TermTest extends \PHPUnit_Framework_TestCase
     /**
      * @param string $field
      * @param string $value
+     * @param bool $isNegation
      * @param string $expectedResult
      * @dataProvider buildQueryDataProvider
      */
-    public function testBuildQuery($field, $value, $expectedResult)
+    public function testBuildQuery($field, $value, $isNegation, $expectedResult)
     {
         $this->requestFilter->expects($this->once())
             ->method('getField')
             ->will($this->returnValue($field));
-        $this->requestFilter->expects($this->once())
+        $this->requestFilter->expects($this->atLeastOnce())
             ->method('getValue')
             ->will($this->returnValue($value));
-        $this->adapter->expects($this->once())
-            ->method('quote')
-            ->will($this->returnArgument(0));
 
-        $actualResult = $this->filter->buildFilter($this->requestFilter);
+        $actualResult = $this->filter->buildFilter($this->requestFilter, $isNegation);
         $this->assertEquals($expectedResult, $actualResult);
     }
 
     /**
      * Data provider for BuildQuery
+     *
      * @return array
      */
     public function buildQueryDataProvider()
     {
         return [
-            [
+            'positive' => [
                 'field' => 'testField',
                 'value' => 'testValue',
+                'isNegation' => false,
                 'expectedResult' => 'testField = testValue',
             ],
-            [
+            'negative' => [
                 'field' => 'testField2',
                 'value' => 'testValue2',
-                'expectedResult' => 'testField2 = testValue2',
+                'isNegation' => true,
+                'expectedResult' => 'testField2 != testValue2',
             ],
+            'positiveIn' => [
+                'field' => 'testField2',
+                'value' => ['testValue2'],
+                'isNegation' => false,
+                'expectedResult' => 'testField2 IN (testValue2)',
+            ],
+            'negativeIn' => [
+                'field' => 'testField2',
+                'value' => ['testValue2'],
+                'isNegation' => true,
+                'expectedResult' => 'testField2 NOT IN (testValue2)',
+            ]
         ];
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/WildcardTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/WildcardTest.php
new file mode 100644
index 00000000000..5e4ba895fa0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/WildcardTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Search\Adapter\Mysql\Filter\Builder;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class WildcardTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \Magento\Framework\Search\Request\Filter\Wildcard|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $requestFilter;
+
+    /**
+     * @var \Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Wildcard
+     */
+    private $filter;
+
+    /**
+     * @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $conditionManager;
+
+    /**
+     * Set up
+     */
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->requestFilter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Term')
+            ->setMethods(['getField', 'getValue'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
+            ->disableOriginalConstructor()
+            ->setMethods(['generateCondition'])
+            ->getMock();
+        $this->conditionManager->expects($this->any())
+            ->method('generateCondition')
+            ->will(
+                $this->returnCallback(
+                    function ($field, $operator, $value) {
+                        return sprintf('%s %s %s', $field, $operator, $value);
+                    }
+                )
+            );
+
+        $this->filter = $objectManager->getObject(
+            'Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Wildcard',
+            [
+                'conditionManager' => $this->conditionManager,
+            ]
+        );
+    }
+
+    /**
+     * @param string $field
+     * @param string $value
+     * @param $isNegation
+     * @param string $expectedResult
+     * @dataProvider buildQueryDataProvider
+     */
+    public function testBuildQuery($field, $value, $isNegation, $expectedResult)
+    {
+        $this->requestFilter->expects($this->once())
+            ->method('getField')
+            ->will($this->returnValue($field));
+        $this->requestFilter->expects($this->once())->method('getValue')->willReturn($value);
+
+        $actualResult = $this->filter->buildFilter($this->requestFilter, $isNegation);
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+
+    /**
+     * Data provider for BuildQuery
+     *
+     * @return array
+     */
+    public function buildQueryDataProvider()
+    {
+        return [
+            'positive' => [
+                'field' => 'testField',
+                'value' => 'testValue',
+                'isNegation' => false,
+                'expectedResult' => "testField LIKE %testValue%",
+            ],
+            'negative' => [
+                'field' => 'testField2',
+                'value' => 'testValue2',
+                'isNegation' => true,
+                'expectedResult' => "testField2 NOT LIKE %testValue2%",
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderTest.php
index 8c1713f8d4a..adbd5ce90be 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderTest.php
@@ -24,15 +24,13 @@
 
 namespace Magento\Framework\Search\Adapter\Mysql\Filter;
 
+use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
 use Magento\TestFramework\Helper\ObjectManager;
+use \Magento\Framework\Search\Request\Query\Bool as RequestBoolQuery;
 
 class BuilderTest extends \PHPUnit_Framework_TestCase
 {
 
-    /**
-     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $adapter;
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Filter\Builder
      */
@@ -45,12 +43,41 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
     {
         $objectManager = new ObjectManager($this);
 
-        $this->adapter = $adapter = $this->getMockBuilder('\Magento\Framework\DB\Adapter\AdapterInterface')
-            ->setMethods(['quote'])
-            ->getMockForAbstractClass();
-        $this->adapter->expects($this->any())
-            ->method('quote')
-            ->will($this->returnArgument(0));
+        /** @var ConditionManager|\PHPUnit_Framework_MockObject_MockObject $conditionManager */
+        $conditionManager = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\ConditionManager')
+            ->disableOriginalConstructor()
+            ->setMethods(['generateCondition', 'combineQueries', 'wrapBrackets'])
+            ->getMock();
+        $conditionManager->expects($this->any())
+            ->method('generateCondition')
+            ->will(
+                $this->returnCallback(
+                    function ($field, $operator, $value) {
+                        return sprintf('%s %s %s', $field, $operator, $value);
+                    }
+                )
+            );
+        $conditionManager->expects($this->any())
+            ->method('combineQueries')
+            ->will(
+                $this->returnCallback(
+                    function ($queries, $operator) {
+                        return implode(
+                            ' ' . $operator . ' ',
+                            array_filter($queries, 'strlen')
+                        );
+                    }
+                )
+            );
+        $conditionManager->expects($this->any())
+            ->method('wrapBrackets')
+            ->will(
+                $this->returnCallback(
+                    function ($query) {
+                        return !empty($query) ? sprintf('(%s)', $query) : '';
+                    }
+                )
+            );
 
         $rangeBuilder = $this->getMockBuilder('\Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Range')
             ->setMethods(['buildFilter'])
@@ -60,18 +87,32 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
             ->method('buildFilter')
             ->will(
                 $this->returnCallback(
-                    function (\Magento\Framework\Search\Request\FilterInterface $filter) use ($adapter) {
+                    function (\Magento\Framework\Search\Request\FilterInterface $filter, $isNegation) use (
+                        $conditionManager
+                    ) {
                         /**
                          * @var \Magento\Framework\Search\Request\Filter\Range $filter
                          * @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter
                          */
-                        return sprintf(
-                            '%s >= %s AND %s < %s',
-                            $filter->getField(),
-                            $adapter->quote($filter->getFrom()),
-                            $filter->getField(),
-                            $adapter->quote($filter->getTo())
-                        );
+                        $fromCondition = '';
+                        if (!is_null($filter->getFrom())) {
+                            $fromCondition = $conditionManager->generateCondition(
+                                $filter->getField(),
+                                ($isNegation ? '<' : '>='),
+                                $filter->getFrom()
+                            );
+                        }
+                        $toCondition = '';
+                        if (!is_null($filter->getTo())) {
+                            $toCondition = $conditionManager->generateCondition(
+                                $filter->getField(),
+                                ($isNegation ? '>=' : '<'),
+                                $filter->getTo()
+                            );
+                        }
+                        $unionOperator = $isNegation ? \Zend_Db_Select::SQL_OR : \Zend_Db_Select::SQL_AND;
+
+                        return $conditionManager->combineQueries([$fromCondition, $toCondition], $unionOperator);
                     }
                 )
             );
@@ -84,15 +125,17 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
             ->method('buildFilter')
             ->will(
                 $this->returnCallback(
-                    function (\Magento\Framework\Search\Request\FilterInterface $filter) use ($adapter) {
+                    function (\Magento\Framework\Search\Request\FilterInterface $filter, $isNegation) use (
+                        $conditionManager
+                    ) {
                         /**
                          * @var \Magento\Framework\Search\Request\Filter\Term $filter
                          * @var \Magento\Framework\DB\Adapter\AdapterInterface $adapter
                          */
-                        return sprintf(
-                            '%s = %s',
+                        return $conditionManager->generateCondition(
                             $filter->getField(),
-                            $adapter->quote($filter->getValue())
+                            ($isNegation ? '!=' : '='),
+                            $filter->getValue()
                         );
                     }
                 )
@@ -103,21 +146,26 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
             [
                 'range' => $rangeBuilder,
                 'term' => $termBuilder,
+                'conditionManager' => $conditionManager,
             ]
         );
     }
 
     /**
      * @param \Magento\Framework\Search\Request\FilterInterface|\PHPUnit_Framework_MockObject_MockObject $filter
+     * @param string $conditionType
      * @param string $expectedResult
      * @dataProvider buildFilterDataProvider
      */
-    public function testBuildFilter($filter, $expectedResult)
+    public function testBuildFilter($filter, $conditionType, $expectedResult)
     {
-        $actualResult = $this->builder->build($filter);
+        $actualResult = $this->builder->build($filter, $conditionType);
         $this->assertEquals($expectedResult, $actualResult);
     }
 
+    /**
+     * @return array
+     */
     public function buildFilterDataProvider()
     {
         return array_merge(
@@ -127,8 +175,28 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * @return array
+     */
+    public function buildTermFilterDataProvider()
+    {
+        return [
+            'termFilter' => [
+                'filter' => $this->createTermFilter('term1', 123),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
+                'expectedResult' => '(term1 = 123)',
+            ],
+            'termFilterNegative' => [
+                'filter' => $this->createTermFilter('term1', 123),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_NOT,
+                'expectedResult' => '(term1 != 123)',
+            ],
+        ];
+    }
+
     /**
      * Data provider for BuildFilter
+     *
      * @return array
      */
     public function buildRangeFilterDataProvider()
@@ -136,21 +204,21 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
         return [
             'rangeFilter' => [
                 'filter' => $this->createRangeFilter('range1', 0, 10),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '(range1 >= 0 AND range1 < 10)',
+            ],
+            'rangeFilterNegative' => [
+                'filter' => $this->createRangeFilter('range1', 0, 10),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_NOT,
+                'expectedResult' => '(range1 < 0 OR range1 >= 10)',
             ]
-        ];
-    }
 
-    public function buildTermFilterDataProvider()
-    {
-        return [
-            'termFilter' => [
-                'filter' => $this->createTermFilter('term1', 123),
-                'expectedResult' => '(term1 = 123)',
-            ],
         ];
     }
 
+    /**
+     * @return array
+     */
     public function buildBoolFilterDataProvider()
     {
         return [
@@ -163,6 +231,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                     [], //should
                     [] // mustNot
                 ),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10))',
             ],
             'boolFilterWithShould' => [
@@ -174,6 +243,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                     ],
                     [] // mustNot
                 ),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '(((term1 = 1) OR (range1 >= 0 AND range1 < 10)))',
             ],
             'boolFilterWithMustNot' => [
@@ -185,7 +255,8 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                         $this->createRangeFilter('range1', 0, 10),
                     ]
                 ),
-                'expectedResult' => '(!((term1 = 1) AND (range1 >= 0 AND range1 < 10)))',
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
+                'expectedResult' => '(((term1 != 1) AND (range1 < 0 OR range1 >= 10)))',
             ],
             'boolFilterWithAllFields' => [
                 'filter' => $this->createBoolFilter(
@@ -202,9 +273,10 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                         $this->createRangeFilter('range3', 0, 10),
                     ]
                 ),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10)'
                     . ' AND ((term2 = 1) OR (range2 >= 0 AND range2 < 10))'
-                    . ' AND !((term3 = 1) AND (range3 >= 0 AND range3 < 10)))',
+                    . ' AND ((term3 != 1) AND (range3 < 0 OR range3 >= 10)))',
             ],
             'boolFilterInBoolFilter' => [
                 'filter' => $this->createBoolFilter(
@@ -235,17 +307,19 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                         ),
                     ]
                 ),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '((term1 = 1) AND (range1 >= 0 AND range1 < 10)'
                     . ' AND ((term2 = 1) OR (range2 >= 0 AND range2 < 10))'
-                    . ' AND !((term3 = 1) AND (range3 >= 0 AND range3 < 10)'
-                    . ' AND ((term4 = 1) AND (range4 >= 0 AND range4 < 10)'
-                    . ' AND ((term5 = 1) OR (range5 >= 0 AND range5 < 10))'
-                    . ' AND !((term6 = 1) AND (range6 >= 0 AND range6 < 10)))'
+                    . ' AND ((term3 != 1) AND (range3 < 0 OR range3 >= 10)'
+                    . ' AND ((term4 != 1) AND (range4 < 0 OR range4 >= 10)'
+                    . ' AND ((term5 != 1) OR (range5 < 0 OR range5 >= 10))'
+                    . ' AND ((term6 = 1) AND (range6 >= 0 AND range6 < 10)))'
                     . '))',
 
             ],
             'boolEmpty' => [
                 'filter' => $this->createBoolFilter([], [], []),
+                'conditionType' => RequestBoolQuery::QUERY_CONDITION_MUST,
                 'expectedResult' => '',
             ]
         ];
@@ -264,52 +338,52 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
         $filter->expects($this->exactly(2))
             ->method('getType')
             ->will($this->returnValue('unknownType'));
-        $this->builder->build($filter);
+        $this->builder->build($filter, RequestBoolQuery::QUERY_CONDITION_MUST);
     }
 
     /**
      * @param $field
-     * @param $from
-     * @param $to
+     * @param $value
      * @return \Magento\Framework\Search\Request\Filter\Bool|\PHPUnit_Framework_MockObject_MockObject
      */
-    private function createRangeFilter($field, $from, $to)
+    private function createTermFilter($field, $value)
     {
-        $filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Range')
-            ->setMethods(['getField', 'getFrom', 'getTo'])
+        $filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Term')
+            ->setMethods(['getField', 'getValue'])
             ->disableOriginalConstructor()
             ->getMock();
 
-        $filter->expects($this->exactly(2))
+        $filter->expects($this->exactly(1))
             ->method('getField')
             ->will($this->returnValue($field));
         $filter->expects($this->once())
-            ->method('getFrom')
-            ->will($this->returnValue($from));
-        $filter->expects($this->once())
-            ->method('getTo')
-            ->will($this->returnValue($to));
+            ->method('getValue')
+            ->will($this->returnValue($value));
         return $filter;
     }
 
     /**
      * @param $field
-     * @param $value
+     * @param $from
+     * @param $to
      * @return \Magento\Framework\Search\Request\Filter\Bool|\PHPUnit_Framework_MockObject_MockObject
      */
-    private function createTermFilter($field, $value)
+    private function createRangeFilter($field, $from, $to)
     {
-        $filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Term')
-            ->setMethods(['getField', 'getValue'])
+        $filter = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Range')
+            ->setMethods(['getField', 'getFrom', 'getTo'])
             ->disableOriginalConstructor()
             ->getMock();
 
-        $filter->expects($this->exactly(1))
+        $filter->expects($this->exactly(2))
             ->method('getField')
             ->will($this->returnValue($field));
-        $filter->expects($this->once())
-            ->method('getValue')
-            ->will($this->returnValue($value));
+        $filter->expects($this->atLeastOnce())
+            ->method('getFrom')
+            ->will($this->returnValue($from));
+        $filter->expects($this->atLeastOnce())
+            ->method('getTo')
+            ->will($this->returnValue($to));
         return $filter;
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/MapperTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/MapperTest.php
index fad795c9f70..ff26baf6216 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/MapperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/MapperTest.php
@@ -25,6 +25,7 @@ namespace Magento\Framework\Search\Adapter\Mysql;
 
 use Magento\Framework\App\Resource;
 use Magento\Framework\App\Resource\Config;
+use Magento\Framework\Search\Request\Query\Bool;
 use Magento\Framework\Search\Request\Query\Filter;
 use Magento\Framework\Search\Request\QueryInterface;
 use Magento\TestFramework\Helper\ObjectManager;
@@ -34,10 +35,12 @@ use Magento\TestFramework\Helper\ObjectManager;
  */
 class MapperTest extends \PHPUnit_Framework_TestCase
 {
+
     /**
      * @var \Magento\Framework\Search\Adapter\Mysql\Dimensions|\PHPUnit_Framework_MockObject_MockObject
      */
     private $dimensionsBuilder;
+
     /**
      * @var \Magento\Framework\Search\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -171,7 +174,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                 $this->equalTo($this->scoreBuilder),
                 $this->equalTo($this->select),
                 $this->equalTo($query),
-                $this->equalTo(Mapper::BOOL_MUST)
+                $this->equalTo(Bool::QUERY_CONDITION_MUST)
             )
             ->will($this->returnValue($this->select));
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BinderTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BinderTest.php
new file mode 100644
index 00000000000..edb1bc89055
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BinderTest.php
@@ -0,0 +1,74 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Request;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class BinderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Search\Request\Binder
+     */
+    private $binder;
+
+    protected function setUp()
+    {
+        $helper = new ObjectManager($this);
+
+        $this->binder = $helper->getObject('Magento\Framework\Search\Request\Binder');
+    }
+
+    public function testBind()
+    {
+        $requestData = [
+            'dimensions' => ['scope' => ['value' => '$sss$']],
+            'queries' => ['query' => ['value' => '$query$']],
+            'filters' => ['filter' => ['from' => '$from$', 'to' => '$to$', 'value' => '$filter$']],
+            'from' => 0,
+            'size' => 15
+        ];
+        $bindData = [
+            'dimensions' => ['scope' => 'default'],
+            'placeholder' => [
+                '$query$' => 'match_query',
+                '$from$' => 'filter_from',
+                '$to$' => 'filter_to',
+                '$filter$' => 'filter_value'
+            ],
+            'from' => 1,
+            'size' => 10
+        ];
+        $expectedResult = [
+            'dimensions' => ['scope' => ['value' => 'default']],
+            'queries' => ['query' => ['value' => 'match_query']],
+            'filters' => ['filter' => ['from' => 'filter_from', 'to' => 'filter_to', 'value' => 'filter_value']],
+            'from' => 1,
+            'size' => 10
+        ];
+
+        $result = $this->binder->bind($requestData, $bindData);
+
+        $this->assertEquals($result, $expectedResult);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BuilderTest.php
new file mode 100644
index 00000000000..cd13b6cff5a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/BuilderTest.php
@@ -0,0 +1,231 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Request;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class BuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Search\Request\Builder
+     */
+    private $requestBuilder;
+
+    /**
+     * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $objectManager;
+
+    /**
+     * @var \Magento\Framework\Search\Request\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $config;
+
+    /**
+     * @var \Magento\Framework\Search\Request\Mapper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $requestMapper;
+
+    /**
+     * @var \Magento\Framework\Search\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $request;
+
+    /**
+     * @var \Magento\Framework\Search\Request\Binder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $binder;
+
+    /**
+     * @var \Magento\Framework\Search\Request\Cleaner|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cleaner;
+
+    protected function setUp()
+    {
+        $helper = new ObjectManager($this);
+
+        $this->config = $this->getMockBuilder('Magento\Framework\Search\Request\Config')
+            ->setMethods(['get'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->objectManager = $this->getMockBuilder('Magento\Framework\ObjectManager')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $this->requestMapper = $this->getMockBuilder('Magento\Framework\Search\Request\Mapper')
+            ->setMethods(['getRootQuery', 'getBuckets'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->request = $this->getMockBuilder('Magento\Framework\Search\Request')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->binder = $this->getMockBuilder('Magento\Framework\Search\Request\Binder')
+            ->setMethods(['bind'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->cleaner = $this->getMockBuilder('Magento\Framework\Search\Request\Cleaner')
+            ->setMethods(['clean'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->requestBuilder = $helper->getObject(
+            'Magento\Framework\Search\Request\Builder',
+            [
+                'config' => $this->config,
+                'objectManager' => $this->objectManager,
+                'binder' => $this->binder,
+                'cleaner' => $this->cleaner
+            ]
+        );
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Request name 'rn' doesn't exist.
+     */
+    public function testCreateInvalidArgumentException()
+    {
+        $requestName = 'rn';
+
+        $this->requestBuilder->setRequestName($requestName);
+        $this->config->expects($this->once())->method('get')->with($this->equalTo($requestName))->willReturn(null);
+
+        $this->requestBuilder->create();
+    }
+
+    public function testCreate()
+    {
+        $data = [
+            'dimensions' => [
+                'scope' => [
+                    'name' => 'scope',
+                    'value' => 'default',
+                ],
+            ],
+            'queries' => [
+                'one_match_filters' => [
+                    'name' => 'one_match_filters',
+                    'boost' => '2',
+                    'queryReference' => [
+                        [
+                            'clause' => 'must',
+                            'ref' => 'fulltext_search_query',
+                        ],
+                        [
+                            'clause' => 'must',
+                            'ref' => 'fulltext_search_query2',
+                        ],
+                    ],
+                    'type' => 'boolQuery',
+                ],
+                'fulltext_search_query' => [
+                    'name' => 'fulltext_search_query',
+                    'boost' => '5',
+                    'value' => '$fulltext_search_query$',
+                    'match' => [
+                        [
+                            'field' => 'data_index',
+                            'boost' => '2',
+                        ],
+                    ],
+                    'type' => 'matchQuery',
+                ],
+                'fulltext_search_query2' => [
+                    'name' => 'fulltext_search_query2',
+                    'filterReference' => [
+                        [
+                            'ref' => 'pid',
+                        ],
+                    ],
+                    'type' => 'filteredQuery',
+                ],
+            ],
+            'filters' => [
+                'pid' => [
+                    'name' => 'pid',
+                    'filterReference' => [
+                        [
+                            'clause' => 'should',
+                            'ref' => 'pidm',
+                        ],
+                        [
+                            'clause' => 'should',
+                            'ref' => 'pidsh',
+                        ],
+                    ],
+                    'type' => 'boolFilter',
+                ],
+                'pidm' => [
+                    'name' => 'pidm',
+                    'field' => 'product_id',
+                    'type' => 'rangeFilter',
+                    'from' => '$pidm_from$',
+                    'to' => '$pidm_to$'
+                ],
+                'pidsh' => [
+                    'name' => 'pidsh',
+                    'field' => 'product_id',
+                    'type' => 'termFilter',
+                    'value' => '$pidsh$'
+                ],
+            ],
+            'from' => '10',
+            'size' => '10',
+            'query' => 'one_match_filters',
+            'index' => 'catalogsearch_fulltext',
+            'aggregations' => [],
+        ];
+
+        $requestName = 'rn';
+
+        $this->requestBuilder->bind('fulltext_search_query', 'socks');
+        $this->requestBuilder->bind('pidsh', 4);
+        $this->requestBuilder->bind('pidm_from', 1);
+        $this->requestBuilder->bind('pidm_to', 3);
+        $this->requestBuilder->setRequestName($requestName);
+        $this->requestBuilder->setSize(10);
+        $this->requestBuilder->setFrom(10);
+        $this->requestBuilder->bindDimension('scope', 'default');
+
+        $this->binder->expects($this->once())->method('bind')->willReturn($data);
+
+        $this->cleaner->expects($this->once())->method('clean')->willReturn($data);
+
+        $this->requestMapper->expects($this->once())->method('getRootQuery')->willReturn([]);
+
+        $this->objectManager->expects($this->at(0))->method('create')->willReturn($this->requestMapper);
+        $this->objectManager->expects($this->at(2))->method('create')->willReturn($this->request);
+        $this->config->expects($this->once())->method('get')->with($this->equalTo($requestName))->willReturn($data);
+
+        $result = $this->requestBuilder->create();
+
+        $this->assertInstanceOf('\Magento\Framework\Search\Request', $result);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Request/CleanerTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/CleanerTest.php
new file mode 100644
index 00000000000..400af47ee18
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/CleanerTest.php
@@ -0,0 +1,260 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Request;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class CleanerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Search\Request\Cleaner
+     */
+    private $cleaner;
+
+    protected function setUp()
+    {
+        $helper = new ObjectManager($this);
+
+        $this->cleaner = $helper->getObject('Magento\Framework\Search\Request\Cleaner');
+    }
+
+    public function testClean()
+    {
+        $requestData = [
+            'query' => 'bool_query',
+            'queries' => [
+                'bool_query' => [
+                    'queryReference' => [
+                        ['ref' => 'bool_query_rm'],
+                        ['ref' => 'match_query'],
+                        ['ref' => 'filtered_query_to_filter2']
+                    ],
+                    'type' => 'boolQuery'
+                ],
+                'match_query' => ['value' => 'ok', 'type' => 'matchQuery'],
+                'bool_query_rm' => [
+                    'queryReference' => [
+                        ['ref' => 'match_query_rm'],
+                        ['ref' => 'filtered_query_to_query'],
+                        ['ref' => 'filtered_query_to_filter']
+                    ],
+                    'type' => 'boolQuery'
+                ],
+                'match_query_rm' => ['value' => '$some$', 'type' => 'matchQuery'],
+                'match_query_rm2' => ['value' => '$some2$', 'type' => 'matchQuery'],
+                'filtered_query_to_query' => [
+                    'queryReference' => [['ref' => 'match_query_rm2']],
+                    'type' => 'filteredQuery'
+                ],
+                'filtered_query_to_filter' => [
+                    'filterReference' => [['ref' => 'bool_filter']],
+                    'type' => 'filteredQuery'
+                ],
+                'filtered_query_to_filter2' => [
+                    'filterReference' => [['ref' => 'bool_filter2']],
+                    'type' => 'filteredQuery'
+                ]
+            ],
+            'filters' => [
+                'bool_filter' => [
+                    'filterReference' => [['ref' => 'term_filter'], ['ref' => 'range_filter']],
+                    'type' => 'boolFilter'
+                ],
+                'term_filter' => ['value' => '$val$', 'type' => 'termFilter'],
+                'range_filter' => ['from' => '$from$', 'to' => '$to$', 'type' => 'rangeFilter'],
+                'bool_filter2' => [
+                    'filterReference' => [['ref' => 'term_filter2']],
+                    'type' => 'boolFilter'
+                ],
+                'term_filter2' => ['value' => 'value_good', 'type' => 'termFilter']
+            ]
+        ];
+        $exceptedRequestData = [
+            'query' => 'bool_query',
+            'queries' => [
+                'bool_query' => [
+                    'queryReference' => [['ref' => 'match_query'], ['ref' => 'filtered_query_to_filter2']],
+                    'type' => 'boolQuery'
+                ],
+                'match_query' => ['value' => 'ok', 'type' => 'matchQuery'],
+                'filtered_query_to_filter2' => [
+                    'filterReference' => [['ref' => 'bool_filter2']],
+                    'type' => 'filteredQuery'
+                ]
+            ],
+            'filters' => [
+                'bool_filter2' => [
+                    'filterReference' => [['ref' => 'term_filter2']],
+                    'type' => 'boolFilter'
+                ],
+                'term_filter2' => ['value' => 'value_good', 'type' => 'termFilter']
+            ]
+        ];
+
+        $result = $this->cleaner->clean($requestData);
+
+        $this->assertEquals($exceptedRequestData, $result);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Reference is not provided
+     */
+    public function testCleanFilteredQueryType()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'type' => 'filteredQuery'
+                ],
+            ],
+            'filters' => []
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Invalid query type
+     */
+    public function testCleanQueryType()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'type' => 'fQuery'
+                ],
+            ],
+            'filters' => []
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Invalid filter type
+     */
+    public function testCleanFilterType()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'filterReference' => [['ref' => 'filter']],
+                    'type' => 'filteredQuery'
+                ],
+            ],
+            'filters' => [
+                'filter' => [
+                    'type' => 'fType'
+                ]
+            ]
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\StateException
+     * @expectedExceptionMessage Cycle found. Query filtered_query already used in request hierarchy
+     */
+    public function testCleanQueryCycle()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'queryReference' => [['ref' => 'filtered_query']],
+                    'type' => 'boolQuery'
+                ],
+            ],
+            'filters' => []
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\StateException
+     */
+    public function testCleanFilterCycle()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'filterReference' => [['ref' => 'bool_filter']],
+                    'type' => 'filteredQuery'
+                ],
+            ],
+            'filters' => [
+                'bool_filter' => [
+                    'filterReference' => [['ref' => 'bool_filter']],
+                    'type' => 'boolFilter'
+                ]
+            ]
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Filter bool_filter does not exist
+     */
+    public function testCleanFilterNotFound()
+    {
+        $requestData = [
+            'query' => 'filtered_query',
+            'queries' => [
+                'filtered_query' => [
+                    'filterReference' => [['ref' => 'bool_filter']],
+                    'type' => 'filteredQuery'
+                ],
+            ],
+            'filters' => []
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Query test does not exist
+     */
+    public function testCleanQueryNotExists()
+    {
+        $requestData = [
+            'query' => 'test',
+            'queries' => [],
+            'filters' => []
+        ];
+
+        $this->cleaner->clean($requestData);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Request/MapperTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/MapperTest.php
index b0e7b9baa97..be02eb065ea 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Request/MapperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Request/MapperTest.php
@@ -60,6 +60,11 @@ class MapperTest extends \PHPUnit_Framework_TestCase
      */
     private $filterTerm;
 
+    /**
+     * @var \Magento\Framework\Search\Request\Filter\Wildcard|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filterWildcard;
+
     /**
      * @var \Magento\Framework\Search\Request\Filter\Range|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -102,6 +107,10 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $this->filterBool = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Bool')
             ->disableOriginalConstructor()
             ->getMock();
+
+        $this->filterWildcard = $this->getMockBuilder('Magento\Framework\Search\Request\Filter\Wildcard')
+            ->disableOriginalConstructor()
+            ->getMock();
     }
 
     /**
@@ -117,6 +126,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                 $this->equalTo(
                     [
                         'name' => $query['name'],
+                        'value' => $query['value'],
                         'boost' => isset($query['boost']) ? $query['boost'] : 1,
                         'matches' => $query['match']
                     ]
@@ -149,12 +159,14 @@ class MapperTest extends \PHPUnit_Framework_TestCase
             self::ROOT_QUERY => [
                 'type' => QueryInterface::TYPE_MATCH,
                 'name' => 'someName',
+                'value' => 'someValue',
                 'boost' => 3,
                 'match' => 'someMatches'
             ],
             'notUsedQuery' => [
                 'type' => QueryInterface::TYPE_MATCH,
                 'name' => 'someName',
+                'value' => 'someValue',
                 'boost' => 3,
                 'match' => 'someMatches'
             ]
@@ -166,6 +178,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                 $this->equalTo(
                     [
                         'name' => $query['name'],
+                        'value' => $query['value'],
                         'boost' => isset($query['boost']) ? $query['boost'] : 1,
                         'matches' => $query['match']
                     ]
@@ -233,6 +246,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                 $this->equalTo(
                     [
                         'name' => $query['name'],
+                        'value' => $query['value'],
                         'boost' => 1,
                         'matches' => 'someMatches'
                     ]
@@ -307,6 +321,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                 $this->equalTo(
                     [
                         'name' => $query['name'],
+                        'value' => $query['value'],
                         'boost' => 1,
                         'matches' => 'someMatches'
                     ]
@@ -450,6 +465,71 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->queryFilter, $mapper->getRootQuery());
     }
 
+    public function testGetFilterWildcard()
+    {
+        $queries = [
+            self::ROOT_QUERY => [
+                'type' => QueryInterface::TYPE_FILTER,
+                'name' => 'someName',
+                'filterReference' => [
+                    [
+                        'ref' => 'someFilter'
+                    ]
+                ]
+            ]
+        ];
+        $filters = [
+            'someFilter' => [
+                'type' => FilterInterface::TYPE_WILDCARD,
+                'name' => 'someName',
+                'field' => 'someField',
+                'value' => 'someValue'
+            ]
+        ];
+
+        $filter = $filters['someFilter'];
+        $this->objectManager->expects($this->at(0))->method('create')
+            ->with(
+                $this->equalTo('Magento\Framework\Search\Request\Filter\Wildcard'),
+                $this->equalTo(
+                    [
+                        'name' => $filter['name'],
+                        'field' => $filter['field'],
+                        'value' => $filter['value']
+                    ]
+                )
+            )
+            ->will($this->returnValue($this->filterTerm));
+        $query = $queries[self::ROOT_QUERY];
+        $this->objectManager->expects($this->at(1))->method('create')
+            ->with(
+                $this->equalTo('Magento\Framework\Search\Request\Query\Filter'),
+                $this->equalTo(
+                    [
+                        'name' => $query['name'],
+                        'boost' => 1,
+                        'reference' => $this->filterTerm,
+                        'referenceType' => Filter::REFERENCE_FILTER
+                    ]
+                )
+            )
+            ->will($this->returnValue($this->queryFilter));
+
+        /** @var \Magento\Framework\Search\Request\Mapper $mapper */
+        $mapper = $this->helper->getObject(
+            'Magento\Framework\Search\Request\Mapper',
+            [
+                'objectManager' => $this->objectManager,
+                'queries' => $queries,
+                'rootQueryName' => self::ROOT_QUERY,
+                'aggregation' => [],
+                'filters' => $filters
+            ]
+        );
+
+        $this->assertEquals($this->queryFilter, $mapper->getRootQuery());
+    }
+
     public function testGetFilterRange()
     {
         $queries = [
@@ -798,6 +878,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     self::ROOT_QUERY => [
                         'type' => QueryInterface::TYPE_MATCH,
                         'name' => 'someName',
+                        'value' => 'someValue',
                         'boost' => 3,
                         'match' => 'someMatches'
                     ]
@@ -808,6 +889,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     self::ROOT_QUERY => [
                         'type' => QueryInterface::TYPE_MATCH,
                         'name' => 'someName',
+                        'value' => 'someValue',
                         'match' => 'someMatches'
                     ]
                 ]
@@ -833,6 +915,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     ],
                     'someQueryMatch' => [
                         'type' => QueryInterface::TYPE_MATCH,
+                        'value' => 'someValue',
                         'name' => 'someName',
                         'match' => 'someMatches'
                     ]
@@ -852,6 +935,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     ],
                     'someQueryMatch' => [
                         'type' => QueryInterface::TYPE_MATCH,
+                        'value' => 'someValue',
                         'name' => 'someName',
                         'match' => 'someMatches'
                     ]
@@ -878,6 +962,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     ],
                     'someQueryMatch' => [
                         'type' => QueryInterface::TYPE_MATCH,
+                        'value' => 'someValue',
                         'name' => 'someName',
                         'match' => 'someMatches'
                     ]
@@ -897,6 +982,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
                     ],
                     'someQueryMatch' => [
                         'type' => QueryInterface::TYPE_MATCH,
+                        'value' => 'someValue',
                         'name' => 'someName',
                         'match' => 'someMatches'
                     ]
@@ -910,6 +996,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $queries = [
             self::ROOT_QUERY => [
                 'type' => QueryInterface::TYPE_MATCH,
+                'value' => 'someValue',
                 'name' => 'someName',
                 'match' => 'someMatches'
             ]
@@ -931,6 +1018,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $queryClass = 'Magento\Framework\Search\Request\Query\Match';
         $queryArguments = [
             'name' => $queries[self::ROOT_QUERY]['name'],
+            'value' => $queries[self::ROOT_QUERY]['value'],
             'boost' => 1,
             'matches' => $queries[self::ROOT_QUERY]['match']
         ];
@@ -968,6 +1056,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $queries = [
             self::ROOT_QUERY => [
                 'type' => QueryInterface::TYPE_MATCH,
+                'value' => 'someValue',
                 'name' => 'someName',
                 'match' => 'someMatches'
             ]
@@ -995,6 +1084,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase
         $queryClass = 'Magento\Framework\Search\Request\Query\Match';
         $queryArguments = [
             'name' => $queries[self::ROOT_QUERY]['name'],
+            'value' => $queries[self::ROOT_QUERY]['value'],
             'boost' => 1,
             'matches' => $queries[self::ROOT_QUERY]['match']
         ];
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/RequestFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/RequestFactoryTest.php
deleted file mode 100644
index 3b5b018bbb4..00000000000
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/RequestFactoryTest.php
+++ /dev/null
@@ -1,167 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Framework\Search;
-
-use Magento\TestFramework\Helper\ObjectManager;
-
-class RequestFactoryTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\Search\RequestFactory
-     */
-    private $factory;
-
-    /**
-     * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $objectManager;
-
-    /**
-     * @var \Magento\Framework\Search\Request\Config|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $config;
-
-    protected function setUp()
-    {
-        $helper = new ObjectManager($this);
-
-        $this->objectManager = $this->getMockBuilder('Magento\Framework\ObjectManager')
-            ->setMethods(['create', 'get', 'configure'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->config = $this->getMockBuilder('Magento\Framework\Search\Request\Config')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->factory = $helper->getObject(
-            'Magento\Framework\Search\RequestFactory',
-            [
-                'objectManager' => $this->objectManager,
-                'config' => $this->config
-            ]
-        );
-    }
-
-    public function testCreate()
-    {
-        $requestName = 'request';
-        $bindValues = [':str' => 'rpl'];
-        $configData = [
-            'queries' => ':str',
-            'filters' => 'f',
-            'query' => 'q',
-            'aggregations' => 'a',
-            'index' => 'i',
-            'from' => '1',
-            'size' => '15',
-            'dimensions' => [
-                'name' => ['name' => '', 'value' => '']
-            ]
-        ];
-        $mappedQuery = $configData['query'] . 'Mapped';
-        $this->config->expects($this->once())->method('get')->with($this->equalTo($requestName))
-            ->will($this->returnValue($configData));
-
-        /** @var \Magento\Framework\Search\Request\Mapper|\PHPUnit_Framework_MockObject_MockObject $mapper */
-        $mapper = $this->getMockBuilder('Magento\Framework\Search\Request\Mapper')
-            ->setMethods(['getRootQuery', 'getBuckets'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var \Magento\Framework\Search\Request|\PHPUnit_Framework_MockObject_MockObject $request */
-        $request = $this->getMockBuilder('Magento\Framework\Search\Request')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->objectManager->expects($this->at(0))->method('create')
-            ->with(
-                $this->equalTo('Magento\Framework\Search\Request\Mapper'),
-                $this->equalTo(
-                    [
-                        'objectManager' => $this->objectManager,
-                        'queries' => $bindValues[':str'],
-                        'rootQueryName' => $configData['query'],
-                        'aggregations' => $configData['aggregations'],
-                        'filters' => $configData['filters']
-                    ]
-                )
-            )
-            ->will($this->returnValue($mapper));
-
-        /** @var \Magento\Framework\Search\Request\Dimension|\PHPUnit_Framework_MockObject_MockObject $dimension */
-        $dimension = $this->getMockBuilder('Magento\Framework\Search\Request\Dimension')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->objectManager->expects($this->at(1))->method('create')
-            ->with(
-                $this->equalTo('Magento\Framework\Search\Request\Dimension'),
-                $this->equalTo(
-                    [
-                        'name' => '',
-                        'value' => '',
-                    ]
-                )
-            )
-            ->will($this->returnValue($dimension));
-
-        $this->objectManager->expects($this->at(2))->method('create')
-            ->with(
-                $this->equalTo('Magento\Framework\Search\Request'),
-                $this->equalTo(
-                    [
-                        'name' => $configData['query'],
-                        'indexName' => $configData['index'],
-                        'from' => $configData['from'],
-                        'size' => $configData['size'],
-                        'query' => $mappedQuery,
-                        'dimensions' => [
-                            'name' => $dimension
-                        ],
-                        'buckets' => [],
-                    ]
-                )
-            )
-            ->will($this->returnValue($request));
-
-        $mapper->expects($this->once())->method('getRootQuery')
-            ->will($this->returnValue($mappedQuery));
-        $mapper->expects($this->once())->method('getBuckets')->will($this->returnValue([]));
-
-        $this->assertEquals($request, $this->factory->create($requestName, $bindValues));
-    }
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    public function testCreateInvalidArgumentException()
-    {
-        $requestName = 'rn';
-        $this->config->expects($this->once())->method('get')->with($this->equalTo($requestName))
-            ->will($this->returnValue(null));
-
-        $this->factory->create($requestName);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Session/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/Session/ConfigTest.php
index ac9bdfcdd78..bb1e9132c80 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Session/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Session/ConfigTest.php
@@ -29,119 +29,108 @@ namespace Magento\Framework\Session;
 
 class ConfigTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $helper;
+
     /**
      * @var \Magento\Framework\Session\Config
      */
     protected $config;
 
     /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configMock;
+
+    /**
+     * @var \Magento\Framework\ValidatorFactory | \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_configMock;
+    protected $validatorFactoryMock;
 
     /**
-     * @var \Magento\Framework\Stdlib\String
+     * @var \Magento\Framework\Validator\ValidatorInterface | \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_stringHelperMock;
+    protected $validatorMock;
 
     /**
-     * @var \Magento\Framework\App\RequestInterface
+     * @var \Magento\Framework\App\Request\Http | \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_requestMock;
+    protected $requestMock;
 
     /**
-     * @var \Magento\Framework\App\Filesystem
+     * @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_filesystem;
+    protected $filesystem;
 
     protected function setUp()
     {
-        $this->_configMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-
-        $this->_stringHelperMock = $this->getMock('\Magento\Framework\Stdlib\String', array(), array(), '', false, false);
-        $this->_requestMock = $this->getMock(
-            '\Magento\Framework\App\Request\Http',
-            array('getBasePath', 'isSecure', 'getHttpHost'),
-            array(),
-            '',
-            false,
-            false
-        );
-        $this->_requestMock->expects($this->atLeastOnce())->method('getBasePath')->will($this->returnValue('/'));
-        $this->_requestMock->expects(
-            $this->atLeastOnce()
-        )->method(
-            'getHttpHost'
-        )->will(
-            $this->returnValue('init.host')
-        );
-        $this->_filesystem = $this->getMock('\Magento\Framework\App\Filesystem', array(), array(), '', false, false);
-
-        $this->config = new \Magento\Framework\Session\Config(
-            $this->_configMock,
-            $this->_stringHelperMock,
-            $this->_requestMock,
-            $this->_filesystem,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            \Magento\Framework\Session\SaveHandlerInterface::DEFAULT_HANDLER,
-            __DIR__
-        );
+        $this->helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(true);
     }
 
-    public function testSetOptionsWrongType()
+    public function testSetOptionsInvalidValue()
     {
-        $this->setExpectedException(
-            '\InvalidArgumentException',
-            'Parameter provided to Magento\Framework\Session\Config::setOptions must be an array or Traversable'
-        );
+        $this->getModel($this->validatorMock);
+        $preVal = $this->config->getOptions();
         $this->config->setOptions('');
+        $this->assertEquals($preVal, $this->config->getOptions());
     }
 
     /**
      * @dataProvider optionsProvider
      */
-    public function testSetOptionsTranslatesUnderscoreSeparatedKeys($option, $getter, $value)
+    public function testSetOptions($option, $getter, $value)
     {
-        $options = array($option => $value);
+        $this->getModel($this->validatorMock);
+        $options = [$option => $value];
         $this->config->setOptions($options);
         $this->assertSame($value, $this->config->{$getter}());
     }
 
     public function optionsProvider()
     {
-        return array(
-            array('save_path', 'getSavePath', __DIR__),
-            array('name', 'getName', 'FOOBAR'),
-            array('save_handler', 'getSaveHandler', 'user'),
-            array('gc_probability', 'getGcProbability', 42),
-            array('gc_divisor', 'getGcDivisor', 3),
-            array('gc_maxlifetime', 'getGcMaxlifetime', 180),
-            array('serialize_handler', 'getSerializeHandler', 'php_binary'),
-            array('cookie_lifetime', 'getCookieLifetime', 180),
-            array('cookie_path', 'getCookiePath', '/foo/bar'),
-            array('cookie_domain', 'getCookieDomain', 'framework.zend.com'),
-            array('cookie_secure', 'getCookieSecure', true),
-            array('cookie_httponly', 'getCookieHttpOnly', true),
-            array('use_cookies', 'getUseCookies', false),
-            array('use_only_cookies', 'getUseOnlyCookies', true),
-            array('referer_check', 'getRefererCheck', 'foobar'),
-            array('entropy_file', 'getEntropyFile', __FILE__),
-            array('entropy_length', 'getEntropyLength', 42),
-            array('cache_limiter', 'getCacheLimiter', 'private'),
-            array('cache_expire', 'getCacheExpire', 42),
-            array('use_trans_sid', 'getUseTransSid', true),
-            array('hash_function', 'getHashFunction', 'md5'),
-            array('hash_bits_per_character', 'getHashBitsPerCharacter', 5),
-            array('url_rewriter_tags', 'getUrlRewriterTags', 'a=href')
-        );
+        return [
+            ['save_path', 'getSavePath', __DIR__],
+            ['name', 'getName', 'FOOBAR'],
+            ['save_handler', 'getSaveHandler', 'user'],
+            ['gc_probability', 'getGcProbability', 42],
+            ['gc_divisor', 'getGcDivisor', 3],
+            ['gc_maxlifetime', 'getGcMaxlifetime', 180],
+            ['serialize_handler', 'getSerializeHandler', 'php_binary'],
+            ['cookie_lifetime', 'getCookieLifetime', 180],
+            ['cookie_path', 'getCookiePath', '/foo/bar'],
+            ['cookie_domain', 'getCookieDomain', 'framework.zend.com'],
+            ['cookie_secure', 'getCookieSecure', true],
+            ['cookie_httponly', 'getCookieHttpOnly', true],
+            ['use_cookies', 'getUseCookies', false],
+            ['use_only_cookies', 'getUseOnlyCookies', true],
+            ['referer_check', 'getRefererCheck', 'foobar'],
+            ['entropy_file', 'getEntropyFile', __FILE__],
+            ['entropy_length', 'getEntropyLength', 42],
+            ['cache_limiter', 'getCacheLimiter', 'private'],
+            ['cache_expire', 'getCacheExpire', 42],
+            ['use_trans_sid', 'getUseTransSid', true],
+            ['hash_function', 'getHashFunction', 'md5'],
+            ['hash_bits_per_character', 'getHashBitsPerCharacter', 5],
+            ['url_rewriter_tags', 'getUrlRewriterTags', 'a=href']
+        ];
     }
 
     public function testGetOptions()
     {
+        $this->getModel($this->validatorMock);
         $appStateProperty = new \ReflectionProperty('Magento\Framework\Session\Config', 'options');
         $appStateProperty->setAccessible(true);
         $original = $appStateProperty->getValue($this->config);
-        $valueForTest = array('test' => 'test2');
+        $valueForTest = ['test' => 'test2'];
         $appStateProperty->setValue($this->config, $valueForTest);
         $this->assertEquals($valueForTest, $this->config->getOptions());
         $this->assertEquals($valueForTest, $this->config->toArray());
@@ -152,12 +141,14 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testNameIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setName('FOOBAR');
         $this->assertEquals('FOOBAR', $this->config->getName());
     }
 
     public function testSaveHandlerDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame(
             ini_get('session.save_handler'),
             $this->config->getSaveHandler(),
@@ -167,39 +158,56 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testSaveHandlerIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setSaveHandler('user');
         $this->assertEquals('user', $this->config->getSaveHandler());
     }
 
     public function testCookieLifetimeIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setCookieLifetime(20);
         $this->assertEquals(20, $this->config->getCookieLifetime());
     }
 
     public function testCookieLifetimeCanBeZero()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setCookieLifetime(0);
         $this->assertEquals(0, ini_get('session.cookie_lifetime'));
     }
 
-    public function testSettingInvalidCookieLifetimeRaisesException()
+    public function testSettingInvalidCookieLifetime()
     {
-        $this->setExpectedException('\InvalidArgumentException', 'Invalid cookie_lifetime; must be numeric');
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(false);
+        $this->getModel($validatorMock);
+        $preVal = $this->config->getCookieLifetime();
         $this->config->setCookieLifetime('foobar_bogus');
+        $this->assertEquals($preVal, $this->config->getCookieLifetime());
     }
 
-    public function testSettingInvalidCookieLifetimeRaisesException2()
+    public function testSettingInvalidCookieLifetime2()
     {
-        $this->setExpectedException(
-            '\InvalidArgumentException',
-            'Invalid cookie_lifetime; must be a positive integer or zero'
-        );
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(false);
+        $this->getModel($validatorMock);
+        $preVal = $this->config->getCookieLifetime();
         $this->config->setCookieLifetime(-1);
+        $this->assertEquals($preVal, $this->config->getCookieLifetime());
     }
 
     public function testWrongMethodCall()
     {
+        $this->getModel($this->validatorMock);
         $this->setExpectedException(
             '\BadMethodCallException',
             'Method "methodThatNotExist" does not exist in Magento\Framework\Session\Config'
@@ -209,11 +217,13 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testCookieSecureDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame((bool)ini_get('session.cookie_secure'), $this->config->getCookieSecure());
     }
 
     public function testCookieSecureIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $value = ini_get('session.cookie_secure') ? false : true;
         $this->config->setCookieSecure($value);
         $this->assertEquals($value, $this->config->getCookieSecure());
@@ -221,38 +231,55 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testCookieDomainIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setCookieDomain('example.com');
         $this->assertEquals('example.com', $this->config->getCookieDomain());
     }
 
     public function testCookieDomainCanBeEmpty()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setCookieDomain('');
         $this->assertEquals('', $this->config->getCookieDomain());
     }
 
-    public function testSettingInvalidCookieDomainRaisesException()
+    public function testSettingInvalidCookieDomain()
     {
-        $this->setExpectedException('\InvalidArgumentException', 'Invalid cookie domain: must be a string');
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(false);
+        $this->getModel($validatorMock);
+        $preVal = $this->config->getCookieDomain();
         $this->config->setCookieDomain(24);
+        $this->assertEquals($preVal, $this->config->getCookieDomain());
     }
 
-    public function testSettingInvalidCookieDomainRaisesException2()
+    public function testSettingInvalidCookieDomain2()
     {
-        $this->setExpectedException(
-            '\InvalidArgumentException',
-            'does not match the expected structure for a DNS hostname'
-        );
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $validatorMock->expects($this->any())
+            ->method('isValid')
+            ->willReturn(false);
+        $this->getModel($validatorMock);
+        $preVal = $this->config->getCookieDomain();
         $this->config->setCookieDomain('D:\\WINDOWS\\System32\\drivers\\etc\\hosts');
+        $this->assertEquals($preVal, $this->config->getCookieDomain());
     }
 
     public function testCookieHttpOnlyDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame((bool)ini_get('session.cookie_httponly'), $this->config->getCookieHttpOnly());
     }
 
     public function testCookieHttpOnlyIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $value = ini_get('session.cookie_httponly') ? false : true;
         $this->config->setCookieHttpOnly($value);
         $this->assertEquals($value, $this->config->getCookieHttpOnly());
@@ -260,11 +287,13 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testUseCookiesDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame((bool)ini_get('session.use_cookies'), $this->config->getUseCookies());
     }
 
     public function testUseCookiesIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $value = ini_get('session.use_cookies') ? false : true;
         $this->config->setUseCookies($value);
         $this->assertEquals($value, (bool)$this->config->getUseCookies());
@@ -272,11 +301,13 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testUseOnlyCookiesDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame((bool)ini_get('session.use_only_cookies'), $this->config->getUseOnlyCookies());
     }
 
     public function testUseOnlyCookiesIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $value = ini_get('session.use_only_cookies') ? false : true;
         $this->config->setOption('use_only_cookies', $value);
         $this->assertEquals($value, (bool)$this->config->getOption('use_only_cookies'));
@@ -284,54 +315,162 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testRefererCheckDefaultsToIniSettings()
     {
+        $this->getModel($this->validatorMock);
         $this->assertSame(ini_get('session.referer_check'), $this->config->getRefererCheck());
     }
 
     public function testRefererCheckIsMutable()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setOption('referer_check', 'FOOBAR');
         $this->assertEquals('FOOBAR', $this->config->getOption('referer_check'));
     }
 
     public function testRefererCheckMayBeEmpty()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setOption('referer_check', '');
         $this->assertEquals('', $this->config->getOption('referer_check'));
     }
 
     public function testSetSavePath()
     {
+        $this->getModel($this->validatorMock);
         $this->config->setSavePath('some_save_path');
         $this->assertEquals($this->config->getOption('save_path'), 'some_save_path');
     }
 
-    public function testSetLifetimePath()
+    /**
+     * @param bool $isValidSame
+     * @param bool $isValid
+     * @param array $expected
+     * @dataProvider constructorDataProvider
+     */
+    public function testConstructor($isValidSame, $isValid, $expected)
     {
-        $getValueReturnMap = [
-            [
-                'test_web/test_cookie/test_cookie_lifetime', 'store', null, 7200
+        $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\ValidatorInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        if ($isValidSame) {
+            $validatorMock->expects($this->any())
+                ->method('isValid')
+                ->willReturn($isValid);
+        } else {
+            for ($x=0; $x<6; $x++) {
+                if ($x % 2 == 0 ) {
+                    $validatorMock->expects($this->at($x))
+                        ->method('isValid')
+                        ->willReturn(false);
+                } else {
+                    $validatorMock->expects($this->at($x))
+                        ->method('isValid')
+                        ->willReturn(true);
+                }
+            }
+        }
+
+        $this->getModel($validatorMock);
+
+        $this->assertEquals($expected, $this->config->getOptions());
+    }
+
+    public function constructorDataProvider()
+    {
+        return [
+            'all valid' => [
+                true,
+                true,
+                [
+                    'session.save_handler' => 'files',
+                    'session.save_path' => null,
+                    'session.cache_limiter' => 'files',
+                    'session.cookie_lifetime' => 7200,
+                    'session.cookie_path' => '/',
+                    'session.cookie_domain' => 'init.host',
+                    'session.cookie_httponly'=> false,
+                ]
             ],
-            [
-                'web/cookie/cookie_path', 'store', null, ''
+            'all invalid' => [
+                true,
+                false,
+                [
+                    'session.save_handler' => 'files',
+                    'session.save_path' => null,
+                    'session.cache_limiter' => 'files',
+                    'session.cookie_httponly'=> false,
+                ]
+            ],
+            'invalid_valid' => [
+                false,
+                true,
+                [
+                    'session.save_handler' => 'files',
+                    'session.save_path' => null,
+                    'session.cache_limiter' => 'files',
+                    'session.cookie_lifetime' => 3600,
+                    'session.cookie_path' => '/',
+                    'session.cookie_domain' => 'init.host',
+                    'session.cookie_httponly'=> false,
+                ]
             ],
         ];
+    }
+
+    /**
+     * Get test model
+     *
+     * @param $validator
+     * @return Config
+     */
+    protected function getModel($validator)
+    {
+        $this->requestMock = $this->getMock(
+            '\Magento\Framework\App\Request\Http',
+            ['getBasePath', 'isSecure', 'getHttpHost'],
+            [],
+            '',
+            false,
+            false
+        );
+        $this->requestMock->expects($this->atLeastOnce())->method('getBasePath')->will($this->returnValue('/'));
+        $this->requestMock->expects(
+            $this->atLeastOnce()
+        )->method(
+            'getHttpHost'
+        )->will(
+            $this->returnValue('init.host')
+        );
 
-        $this->_configMock
-            ->method('getValue')
+        $this->validatorFactoryMock = $this->getMockBuilder('Magento\Framework\ValidatorFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->validatorFactoryMock->expects($this->any())
+            ->method('setInstanceName')
+            ->willReturnSelf();
+        $this->validatorFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($validator);
+
+        $this->configMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $getValueReturnMap = [
+            ['test_web/test_cookie/test_cookie_lifetime', 'store', null, 7200],
+            ['web/cookie/cookie_path', 'store', null, ''],
+        ];
+        $this->configMock->method('getValue')
             ->will($this->returnValueMap($getValueReturnMap));
 
-        $config = new \Magento\Framework\Session\Config(
-            $this->_configMock,
-            $this->_stringHelperMock,
-            $this->_requestMock,
-            $this->_filesystem,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            \Magento\Framework\Session\SaveHandlerInterface::DEFAULT_HANDLER,
-            __DIR__,
-            null,
-            'test_web/test_cookie/test_cookie_lifetime'
-        );
+        $this->config = $this->helper->getObject(
+            'Magento\Framework\Session\Config',
+            [
+                'scopeConfig' => $this->configMock,
+                'validatorFactory' => $this->validatorFactoryMock,
+                'scopeType' => \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                'cacheLimiter' => \Magento\Framework\Session\SaveHandlerInterface::DEFAULT_HANDLER,
+                'lifetimePath' => 'test_web/test_cookie/test_cookie_lifetime',
+                'request' => $this->requestMock,
+            ]
 
-        $this->assertEquals(7200, $config->getCookieLifetime());
+        );
+        return $this->config;
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php
index fe7d96dcdf2..f086b5a9725 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/DateTimeTest.php
@@ -57,8 +57,19 @@ class DateTimeTest extends \PHPUnit_Framework_TestCase
 
     public function testCalculateOffset()
     {
-        $this->assertSame(-28800, $this->dateTime->calculateOffset());
-        $this->assertSame(10800, $this->dateTime->calculateOffset('Europe/Kiev'));
+        if (date('I')) {
+            $this->assertSame(-25200, $this->dateTime->calculateOffset());
+        } else {
+            $this->assertSame(-28800, $this->dateTime->calculateOffset());
+        }
+        $curZone = @date_default_timezone_get();
+        date_default_timezone_set('Europe/Kiev');
+        if (date('I')) {
+            $this->assertSame(10800, $this->dateTime->calculateOffset('Europe/Kiev'));
+        } else {
+            $this->assertSame(7200, $this->dateTime->calculateOffset('Europe/Kiev'));
+        }
+        date_default_timezone_set($curZone);
     }
 
     public function testGmtDate()
@@ -110,9 +121,16 @@ class DateTimeTest extends \PHPUnit_Framework_TestCase
 
     public function testGetGmtOffset()
     {
-        $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds'));
-        $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds11'));
-        $this->assertSame(-480, $this->dateTime->getGmtOffset('minutes'));
-        $this->assertSame(-8, $this->dateTime->getGmtOffset('hours'));
+        if (date('I')) {
+            $this->assertSame(-25200, $this->dateTime->getGmtOffset('seconds'));
+            $this->assertSame(-25200, $this->dateTime->getGmtOffset('seconds11'));
+            $this->assertSame(-420, $this->dateTime->getGmtOffset('minutes'));
+            $this->assertSame(-7, $this->dateTime->getGmtOffset('hours'));
+        } else {
+            $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds'));
+            $this->assertSame(-28800, $this->dateTime->getGmtOffset('seconds11'));
+            $this->assertSame(-480, $this->dateTime->getGmtOffset('minutes'));
+            $this->assertSame(-8, $this->dateTime->getGmtOffset('hours'));
+        }
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php
index 3b9e726bb7b..3e6a839e15a 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Stdlib/DateTime/TimezoneTest.php
@@ -56,7 +56,9 @@ class TimezoneTest extends \PHPUnit_Framework_TestCase
         $this->scopeResolver = $this->getMock('Magento\Store\Model\Resolver\Store', ['getScope'], [], '', false);
 
         $this->localeResolver->expects($this->any())->method('getLocale')->will($this->returnValue($this->locale));
-        $this->scopeConfig->expects($this->any())->method('getValue')->with('general/locale/timezone', 'store')
+        $this->scopeConfig->expects($this->any())
+            ->method('getValue')
+            ->with(\Magento\Core\Helper\Data::XML_PATH_DEFAULT_TIMEZONE, 'store')
             ->will($this->returnValue('America/Los_Angeles'));
         $this->locale->expects($this->any())->method('toString')->will($this->returnValue('en_US'));
 
@@ -70,7 +72,7 @@ class TimezoneTest extends \PHPUnit_Framework_TestCase
                 'dateFactory' => $this->dateFactory,
                 'scopeConfig' => $this->scopeConfig,
                 'scopeType' => 'store',
-                'defaultTimezonePath' => 'general/locale/timezone'
+                'defaultTimezonePath' => \Magento\Core\Helper\Data::XML_PATH_DEFAULT_TIMEZONE
             ]
         );
     }
@@ -176,7 +178,7 @@ class TimezoneTest extends \PHPUnit_Framework_TestCase
             ->with(['date' => 1347260470, 'part' => null, 'locale' => $this->locale])
             ->will($this->returnValue(new \Magento\Framework\Stdlib\DateTime\Date(1347260470, null, $this->locale)));
 
-        $date = $this->timezone->utcDate('general/locale/timezone', 1347260470);
+        $date = $this->timezone->utcDate(\Magento\Core\Helper\Data::XML_PATH_DEFAULT_TIMEZONE, 1347260470);
         $this->assertSame('UTC', $date->getTimezone());
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/ValidatorFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/ValidatorFactoryTest.php
new file mode 100644
index 00000000000..5030c007046
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/ValidatorFactoryTest.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Unit test for Magento\Framework\ValidatorFactory
+ *
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class ValidatorFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\Framework\ValidatorFactory */
+    private $model;
+
+    /** @var \Magento\Framework\ObjectManager | \PHPUnit_Framework_MockObject_MockObject */
+    private $objectManagerMock;
+
+    public function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = $objectManager->getObject('Magento\Framework\ValidatorFactory',
+            ['objectManager' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreateWithInstanceName()
+    {
+        $setName = 'Magento\Framework\Object';
+        $returnMock = $this->getMock($setName);
+        $this->objectManagerMock->expects($this->once())->method('create')
+            ->willReturn($returnMock);
+
+        $this->assertSame($returnMock, $this->model->create());
+    }
+
+    public function testCreateDefault()
+    {
+        $default = 'Magento\Framework\Validator';
+        $returnMock = $this->getMock($default);
+        $this->objectManagerMock->expects($this->once())->method('create')
+            ->willReturn($returnMock);
+        $this->assertSame($returnMock, $this->model->create());
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/GeneratorTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/GeneratorTest.php
new file mode 100644
index 00000000000..6a25bef81a5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/GeneratorTest.php
@@ -0,0 +1,134 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\View\Page\Config as PageConfig;
+
+/**
+ * Test for page config generator model
+ */
+class GeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Generator
+     */
+    protected $generator;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config\Structure|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $structureMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    protected function setUp()
+    {
+        $this->structureMock = $this->getMockBuilder('Magento\Framework\View\Page\Config\Structure')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->generator = $objectManagerHelper->getObject(
+            'Magento\Framework\View\Page\Config\Generator',
+            [
+                'structure' => $this->structureMock,
+                'pageConfig' => $this->pageConfigMock,
+            ]
+        );
+    }
+
+    public function testProcess()
+    {
+        $this->structureMock->expects($this->once())->method('processRemoveAssets');
+        $this->structureMock->expects($this->once())->method('processRemoveElementAttributes');
+
+        $assets = [
+            'remoteName' => ['src' => 'file-url', 'src_type' => 'url', 'media'=> "all"],
+            'name' => ['src' => 'file-path', 'ie_condition' => 'lt IE 7', 'media'=> "print"]
+        ];
+        $this->pageConfigMock->expects($this->once())
+            ->method('addRemotePageAsset')
+            ->with('remoteName', Generator::VIRTUAL_CONTENT_TYPE_LINK, ['attributes' => ['media'=> 'all']]);
+        $this->pageConfigMock->expects($this->once())
+            ->method('addPageAsset')
+            ->with('name', ['attributes' => ['media'=> 'print'], 'ie_condition' => 'lt IE 7']);
+        $this->structureMock->expects($this->once())
+            ->method('getAssets')
+            ->will($this->returnValue($assets));
+
+        $title = 'Page title';
+        $this->structureMock->expects($this->once())
+            ->method('getTitle')
+            ->will($this->returnValue($title));
+        $this->pageConfigMock->expects($this->once())
+            ->method('setTitle')
+            ->with($title);
+
+        $metadata = ['name1' => 'content1', 'name2' => 'content2'];
+        $this->structureMock->expects($this->once())
+            ->method('getMetadata')
+            ->will($this->returnValue($metadata));
+        $this->pageConfigMock->expects($this->exactly(2))
+            ->method('setMetadata')
+            ->withConsecutive(['name1', 'content1'], ['name2', 'content2']);
+
+        $elementAttributes = [
+            PageConfig::ELEMENT_TYPE_BODY => [
+                'body_attr_1' => 'body_value_1',
+                'body_attr_2' => 'body_value_2',
+            ],
+            PageConfig::ELEMENT_TYPE_HTML => [
+                'html_attr_1' => 'html_attr_1',
+            ]
+        ];
+        $this->structureMock->expects($this->once())
+            ->method('getElementAttributes')
+            ->will($this->returnValue($elementAttributes));
+        $this->pageConfigMock->expects($this->exactly(3))
+            ->method('setElementAttribute')
+            ->withConsecutive(
+                [PageConfig::ELEMENT_TYPE_BODY, 'body_attr_1', 'body_value_1'],
+                [PageConfig::ELEMENT_TYPE_BODY, 'body_attr_2', 'body_value_2'],
+                [PageConfig::ELEMENT_TYPE_HTML, 'html_attr_1', 'html_attr_1']
+            );
+
+        $bodyClasses = ['class_1', 'class_2'];
+        $this->structureMock->expects($this->once())
+            ->method('getBodyClasses')
+            ->will($this->returnValue($bodyClasses));
+        $this->pageConfigMock->expects($this->exactly(2))
+            ->method('addBodyClass')
+            ->withConsecutive(['class_1'], ['class_2']);
+
+        $this->assertEquals($this->generator, $this->generator->process());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/ReaderTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/ReaderTest.php
new file mode 100644
index 00000000000..a68bf44fdaf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/ReaderTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\View\Layout\Element as LayoutElement;
+use Magento\Framework\View\Page\Config as PageConfig;
+
+/**
+ * Test for page config reader model
+ */
+class ReaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Reader
+     */
+    protected $reader;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config\Structure|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $structureMock;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    protected function setUp()
+    {
+        $this->structureMock = $this->getMockBuilder('Magento\Framework\View\Page\Config\Structure')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->reader = $this->objectManagerHelper->getObject(
+            'Magento\Framework\View\Page\Config\Reader',
+            [
+                'structure' => $this->structureMock
+            ]
+        );
+    }
+
+    public function testReadHead()
+    {
+        $this->structureMock->expects($this->once())
+            ->method('setTitle')
+            ->with('Test title');
+
+        $this->structureMock->expects($this->once())
+            ->method('setMetaData')
+            ->with('meta_name', 'meta_content');
+
+        $this->structureMock->expects($this->exactly(3))
+            ->method('addAssets')
+            ->withConsecutive(
+                array('path/file.css', ['src' => 'path/file.css', "media" => "all"]),
+                array(
+                    'mage/jquery-no-conflict.js',
+                    ['src' => 'mage/jquery-no-conflict.js', "ie_condition" => "lt IE 7"]
+                ),
+                array('path/file.js', ['src' => 'path/file.js', "defer" => "defer"])
+            );
+
+        $this->structureMock->expects($this->once())
+            ->method('removeAssets')
+            ->with('path/remove/file.css');
+
+        $this->structureMock->expects($this->once())
+            ->method('setElementAttribute')
+            ->with(PageConfig::ELEMENT_TYPE_HEAD, 'head_attribute_name', 'head_attribute_value');
+
+        $xmlElement = new LayoutElement(file_get_contents(__DIR__ . '/_files/template_head.xml'));
+        $this->assertEquals($this->reader, $this->reader->readHead(current($xmlElement->children())));
+    }
+
+    public function testReadHtml()
+    {
+        $this->structureMock->expects($this->once())
+            ->method('setElementAttribute')
+            ->with(PageConfig::ELEMENT_TYPE_HTML, 'html_attribute_name', 'html_attribute_value');
+
+        $xmlElement = new LayoutElement(file_get_contents(__DIR__ . '/_files/template_html.xml'));
+        $this->assertEquals($this->reader, $this->reader->readHtml(current($xmlElement->children())));
+    }
+
+    public function testReadBody()
+    {
+        $this->structureMock->expects($this->once())
+            ->method('setElementAttribute')
+            ->with(PageConfig::ELEMENT_TYPE_BODY, 'body_attribute_name', 'body_attribute_value');
+
+        $xmlElement = new LayoutElement(file_get_contents(__DIR__ . '/_files/template_body.xml'));
+        $this->assertEquals($this->reader, $this->reader->readBody(current($xmlElement->children())));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
new file mode 100644
index 00000000000..8f2938da13b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
@@ -0,0 +1,386 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\View\Asset\GroupedCollection;
+
+/**
+ * Test for page config renderer model
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class RendererTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Renderer
+     */
+    protected $renderer;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\MinifyService|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetMinifyServiceMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\AssetInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetInterfaceMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\MergeService|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetMergeServiceMock;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaperMock;
+
+    /**
+     * @var \Magento\Framework\Stdlib\String|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stringMock;
+
+    /**
+     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loggerMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\GroupedCollection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetsCollection;
+
+    /**
+     * @var \Magento\Framework\View\Asset\PropertyGroup|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $propertyGroupMock;
+
+    /**
+     * @var \Magento\Framework\App\Action\Title|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $titlesMock;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    protected function setUp()
+    {
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->assetMinifyServiceMock = $this->getMockBuilder('Magento\Framework\View\Asset\MinifyService')
+            ->setMethods(['getAssets'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->assetMergeServiceMock = $this->getMockBuilder('Magento\Framework\View\Asset\MergeService')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->urlBuilderMock = $this->getMockForAbstractClass('Magento\Framework\UrlInterface');
+
+        $this->escaperMock = $this->getMockBuilder('Magento\Framework\Escaper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->escaperMock->expects($this->any())
+            ->method('escapeHtml')
+            ->willReturnArgument(0);
+
+        $this->stringMock = $this->getMockBuilder('Magento\Framework\Stdlib\String')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->loggerMock = $this->getMockBuilder('Magento\Framework\Logger')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->assetsCollection = $this->getMockBuilder('Magento\Framework\View\Asset\GroupedCollection')
+            ->setMethods(['getGroups'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->propertyGroupMock = $this->getMockBuilder('Magento\Framework\View\Asset\PropertyGroup')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->assetInterfaceMock = $this->getMockForAbstractClass('Magento\Framework\View\Asset\AssetInterface');
+
+        $this->titlesMock = $this->getMockBuilder('Magento\Framework\App\Action\Title')
+            ->setMethods(['add', 'get'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->renderer = $this->objectManagerHelper->getObject(
+            'Magento\Framework\View\Page\Config\Renderer',
+            [
+                'pageConfig' => $this->pageConfigMock,
+                'assetMinifyService' => $this->assetMinifyServiceMock,
+                'assetMergeService' => $this->assetMergeServiceMock,
+                'urlBuilder' => $this->urlBuilderMock,
+                'escaper' => $this->escaperMock,
+                'string' => $this->stringMock,
+                'logger' => $this->loggerMock,
+                'titles' => $this->titlesMock
+            ]
+        );
+    }
+
+    public function testRenderElementAttributes()
+    {
+        $elementType = 'elementType';
+        $attributes = ['attr1' => 'value1', 'attr2' => 'value2'];
+        $expected = 'attr1="value1" attr2="value2"';
+
+        $this->pageConfigMock->expects($this->once())
+            ->method('getElementAttributes')
+            ->with($elementType)
+            ->willReturn($attributes);
+
+        $this->assertEquals($expected, $this->renderer->renderElementAttributes($elementType));
+    }
+
+    public function testRenderMetadata()
+    {
+        $metadata = [
+            'charset' => 'charsetValue',
+            'metadataName' => 'metadataValue',
+            'content_type' => 'content_type_value',
+            'x_ua_compatible' => 'x_ua_compatible_value',
+            'media_type' => 'media_type_value'
+        ];
+        $metadataValueCharset = 'newCharsetValue';
+
+        $expected = '<meta charset="newCharsetValue"/>' . "\n"
+            . '<meta name="metadataName" content="metadataValue"/>' . "\n"
+            . '<meta http-equiv="Content-Type" content="content_type_value"/>' . "\n"
+            . '<meta http-equiv="X-UA-Compatible" content="x_ua_compatible_value"/>' . "\n";
+
+        $this->stringMock->expects($this->at(0))
+            ->method('upperCaseWords')
+            ->with('charset', '_', '')
+            ->willReturn('Charset');
+
+        $this->pageConfigMock->expects($this->once())
+            ->method('getCharset')
+            ->willReturn($metadataValueCharset);
+
+        $this->pageConfigMock
+            ->expects($this->once())
+            ->method('getMetadata')
+            ->will($this->returnValue($metadata));
+
+        $this->assertEquals($expected, $this->renderer->renderMetadata());
+    }
+
+    public function testRenderTitle()
+    {
+        $title = 'some_title';
+        $expected = "<title>some_title</title>" . "\n";
+
+        $this->pageConfigMock->expects($this->any())
+            ->method('getTitle')
+            ->will($this->returnValue($title));
+
+        $this->titlesMock->expects($this->once())
+            ->method('add')
+            ->with($title, true)
+            ->will($this->returnSelf());
+
+        $this->titlesMock->expects($this->once())
+            ->method('get')
+            ->will($this->returnValue([$title]));
+
+        $this->pageConfigMock->expects($this->once())
+            ->method('setTitle')
+            ->with([$title])
+            ->will($this->returnSelf());
+
+        $this->assertEquals($expected, $this->renderer->renderTitle());
+    }
+
+    public function testPrepareFavicon()
+    {
+        $filePath = 'file';
+        $this->pageConfigMock->expects($this->exactly(3))
+            ->method('getFaviconFile')
+            ->willReturn($filePath);
+
+        $this->pageConfigMock->expects($this->exactly(2))
+            ->method('addRemotePageAsset')
+            ->withConsecutive(
+                [
+                    $filePath,
+                    Generator::VIRTUAL_CONTENT_TYPE_LINK,
+                    ['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
+                    'icon'
+                ],
+                [
+                    $filePath,
+                    Generator::VIRTUAL_CONTENT_TYPE_LINK,
+                    ['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
+                    'shortcut-icon'
+                ]
+            );
+
+        $this->renderer->prepareFavicon();
+    }
+
+    public function testPrepareFaviconDefault()
+    {
+        $defaultFilePath = 'default_file';
+        $this->pageConfigMock->expects($this->once())
+            ->method('getFaviconFile')
+            ->willReturn(false);
+        $this->pageConfigMock->expects($this->exactly(2))
+            ->method('getDefaultFavicon')
+            ->willReturn($defaultFilePath);
+
+        $this->pageConfigMock->expects($this->exactly(2))
+            ->method('addPageAsset')
+            ->withConsecutive(
+                [
+                    $defaultFilePath,
+                    ['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
+                    'icon'
+                ],
+                [
+                    $defaultFilePath,
+                    ['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
+                    'shortcut-icon'
+                ]
+            );
+        $this->renderer->prepareFavicon();
+    }
+
+    /**
+     * @param $contentType
+     * @param $attributes
+     * @param $ieCondition
+     * @param $expectedResult
+     * @dataProvider dataProviderRenderAsset
+     */
+    public function testRenderAsset($contentType, $attributes, $ieCondition, $expectedResult)
+    {
+        $assetUrl = 'url';
+        $assetNoRoutUrl = 'no_route_url';
+
+        $exception = new \Magento\Framework\Exception('my message');
+
+        $assetMock1 = $this->getMock('Magento\Framework\View\Asset\AssetInterface');
+        $assetMock1->expects($this->once())
+            ->method('getUrl')
+            ->willReturn($assetUrl);
+
+        $assetMock2 = $this->getMock('Magento\Framework\View\Asset\AssetInterface');
+        $assetMock2->expects($this->once())
+            ->method('getUrl')
+            ->willThrowException($exception);
+
+        $groupAssets = [$assetMock1, $assetMock2];
+
+        $this->pageConfigMock->expects($this->once())
+            ->method('getAssetCollection')
+            ->willReturn($this->assetsCollection);
+
+        $this->assetsCollection->expects($this->once())
+            ->method('getGroups')
+            ->willReturn([$this->propertyGroupMock]);
+
+        $this->propertyGroupMock->expects($this->once())
+            ->method('getAll')
+            ->willReturn($groupAssets);
+        $this->propertyGroupMock->expects($this->any())
+            ->method('getProperty')
+            ->willReturnMap([
+                [GroupedCollection::PROPERTY_CAN_MERGE, true],
+                [GroupedCollection::PROPERTY_CONTENT_TYPE, $contentType],
+                ['attributes', $attributes],
+                ['ie_condition', $ieCondition]
+            ]);
+
+        $this->assetMinifyServiceMock
+            ->expects($this->once())
+            ->method('getAssets')
+            ->with($groupAssets)
+            ->willReturn($groupAssets);
+
+        $this->assetMergeServiceMock->expects($this->once())
+            ->method('getMergedAssets')
+            ->with($groupAssets, $contentType)
+            ->willReturnArgument(0);
+
+        $this->loggerMock->expects($this->once())
+            ->method('logException')
+            ->with($exception);
+
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('', ['_direct' => 'core/index/notFound'])
+            ->willReturn($assetNoRoutUrl);
+
+        $this->assertEquals($expectedResult, $this->renderer->renderAssets());
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderRenderAsset()
+    {
+        $css = '<link  rel="stylesheet" type="text/css"  media="all" href="url" />' . "\n"
+            . '<link  rel="stylesheet" type="text/css"  media="all" href="no_route_url" />' . "\n";
+
+        $cssWithAttr = '<link  rel="stylesheet" type="text/css"  attr="value" href="url" />' . "\n"
+            . '<link  rel="stylesheet" type="text/css"  attr="value" href="no_route_url" />' . "\n";
+
+        $js = '<script  type="text/javascript"  attr="value" src="url"></script>' . "\n"
+            . '<script  type="text/javascript"  attr="value" src="no_route_url"></script>' . "\n";
+
+        $jsWithIfIe = '<!--[if lt IE 7]>' . "\n"
+            . '<script  type="text/javascript"  attr="value" src="url"></script>' . "\n"
+            . '<script  type="text/javascript"  attr="value" src="no_route_url"></script>' . "\n"
+            . '<![endif]-->' . "\n";
+
+        return [
+            ['css', '', null, $css],
+            ['css', 'attr="value"', null, $cssWithAttr],
+            ['js', ['attr' => 'value'], null, $js],
+            ['js', ['attr' => 'value'], 'lt IE 7', $jsWithIfIe]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/StructureTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/StructureTest.php
new file mode 100644
index 00000000000..dbc44af7220
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/StructureTest.php
@@ -0,0 +1,131 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Test for page config structure model
+ */
+class StructureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Structure
+     */
+    protected $structure;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->structure = $objectManagerHelper->getObject(
+            'Magento\Framework\View\Page\Config\Structure'
+        );
+    }
+
+    public function testSetElementAttribute()
+    {
+        $elementName1 = 'elementName1';
+        $attributeName1 = 'attributeName1';
+        $attributeValue1 = 'attributeValue1';
+
+        $elementName2 = 'elementName2';
+        $attributeName2 = 'attributeName2';
+        $attributeValue2 = 'attributeValue2';
+
+        $expected = [
+            'elementName1' => ['attributeName1' => 'attributeValue1'],
+            'elementName2' => ['attributeName2' => 'attributeValue2']
+        ];
+
+        $this->structure->setElementAttribute($elementName1, $attributeName1, $attributeValue1);
+        $this->structure->setElementAttribute($elementName2, $attributeName2, $attributeValue2);
+        $this->assertEquals($expected, $this->structure->getElementAttributes());
+
+        $expectedAfterRemove =[
+            'elementName2' => ['attributeName2' => 'attributeValue2']
+        ];
+        $this->structure->setElementAttribute($elementName1, $attributeName1, false);
+        $this->structure->processRemoveElementAttributes();
+        $this->assertEquals($expectedAfterRemove, $this->structure->getElementAttributes());
+    }
+
+    public function testSetBodyClass()
+    {
+        $class1 = 'class_1';
+        $class2 = 'class_2';
+        $expected = [$class1, $class2];
+        $this->structure->setBodyClass($class1);
+        $this->structure->setBodyClass($class2);
+        $this->assertEquals($expected, $this->structure->getBodyClasses());
+
+        $this->structure->setBodyClass('');
+        $this->assertEmpty($this->structure->getBodyClasses());
+    }
+
+    public function testTitle()
+    {
+        $data = 'test';
+        $this->structure->setTitle($data);
+        $this->assertEquals($data, $this->structure->getTitle());
+    }
+
+    public function testMetadata()
+    {
+        $metadataName = 'name';
+        $metadataContent = 'content';
+        $expected = [$metadataName => $metadataContent];
+
+        $this->structure->setMetadata($metadataName, $metadataContent);
+
+        $this->assertEquals($expected, $this->structure->getMetadata());
+    }
+
+    public function testAssets()
+    {
+        $assetName = 'test';
+        $assetAttributes = ['attr1', 'attr2'];
+        $expected = [$assetName => $assetAttributes];
+
+        $this->structure->addAssets($assetName, $assetAttributes);
+        $this->assertEquals($expected, $this->structure->getAssets());
+    }
+
+    public function testProcessRemoveAssets()
+    {
+        $assetName1 = 'test1';
+        $assetAttributes1 = ['attr1_1', 'attr1_2'];
+
+        $assetName2 = 'test2';
+        $assetAttributes2 = ['attr2_1', 'attr2_2'];
+
+        $expected = [$assetName1 => $assetAttributes1];
+
+        $this->structure->addAssets($assetName1, $assetAttributes1);
+        $this->structure->addAssets($assetName2, $assetAttributes2);
+        $this->structure->removeAssets($assetName2);
+        $this->structure->processRemoveAssets();
+        $this->assertEquals($expected, $this->structure->getAssets());
+    }
+}
diff --git a/app/code/Magento/Rss/view/adminhtml/layout/rss_order_new.xml b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_body.xml
similarity index 77%
rename from app/code/Magento/Rss/view/adminhtml/layout/rss_order_new.xml
rename to dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_body.xml
index 8fc8182b2be..a6eb7c93f8a 100644
--- a/app/code/Magento/Rss/view/adminhtml/layout/rss_order_new.xml
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_body.xml
@@ -23,8 +23,8 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Order\NewOrder" name="rss.order.new"/>
-    </container>
-</layout>
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <body>
+        <attribute name="body_attribute_name" value="body_attribute_value" />
+    </body>
+</page>
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_head.xml b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_head.xml
new file mode 100644
index 00000000000..d5aeeba16e4
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_head.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <head>
+        <title>Test title</title>
+        <meta name="meta_name" content="meta_content"/>
+        <css src="path/file.css" media="all" />
+        <link src="mage/jquery-no-conflict.js" ie_condition="lt IE 7" />
+        <script src="path/file.js" defer="defer"/>
+        <remove src="path/remove/file.css"/>
+        <attribute name="head_attribute_name" value="head_attribute_value"/>
+    </head>
+</page>
diff --git a/app/code/Magento/Rss/view/frontend/layout/rss_order_status.xml b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_html.xml
similarity index 77%
rename from app/code/Magento/Rss/view/frontend/layout/rss_order_status.xml
rename to dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_html.xml
index c9735da9caf..0561c11140b 100644
--- a/app/code/Magento/Rss/view/frontend/layout/rss_order_status.xml
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/_files/template_html.xml
@@ -23,8 +23,8 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Order\Status" name="rss.order.status"/>
-    </container>
-</layout>
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../app/code/Magento/Core/etc/page.xsd">
+    <html>
+        <attribute name="html_attribute_name" value="html_attribute_value" />
+    </html>
+</page>
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/ConfigTest.php
new file mode 100644
index 00000000000..dd9e3478fff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/ConfigTest.php
@@ -0,0 +1,84 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\PageLayout;
+
+/**
+ * Page layouts configuration
+ */
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\PageLayout\Config
+     */
+    protected $config;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->config = $objectManagerHelper->getObject(
+            'Magento\Framework\View\PageLayout\Config',
+            [
+                'configFiles' => [
+                    'layouts_one.xml' => file_get_contents(__DIR__ . '/_files/layouts_one.xml'),
+                    'layouts_two.xml' => file_get_contents(__DIR__ . '/_files/layouts_two.xml')
+                ]
+            ]
+        );
+    }
+
+    public function testGetPageLayouts()
+    {
+        $this->assertEquals(['one' => 'One', 'two' => 'Two'], $this->config->getPageLayouts());
+    }
+
+    public function testHasPageLayout()
+    {
+        $this->assertEquals(true, $this->config->hasPageLayout('one'));
+        $this->assertEquals(false, $this->config->hasPageLayout('three'));
+    }
+
+    public function testGetOptions()
+    {
+        $this->assertEquals(['one' => 'One', 'two' => 'Two'], $this->config->getPageLayouts());
+    }
+
+    public function testToOptionArray()
+    {
+        $this->assertEquals(
+            [
+                ['label' => 'One', 'value' => 'one'],
+                ['label' => 'Two', 'value' => 'two']
+            ],
+            $this->config->toOptionArray()
+        );
+        $this->assertEquals(
+            [
+                ['label' => '-- Please Select --', 'value' => ''],
+                ['label' => 'One', 'value' => 'one'],
+                ['label' => 'Two', 'value' => 'two']
+            ],
+            $this->config->toOptionArray(true)
+        );
+    }
+}
diff --git a/app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_notifystock.xml b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_one.xml
similarity index 73%
rename from app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_notifystock.xml
rename to dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_one.xml
index 34ac1a722cf..f96d89a491b 100644
--- a/app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_notifystock.xml
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_one.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
  * Magento
@@ -23,8 +23,8 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\NotifyStock" name="rss.catalog.notifystock"/>
-    </container>
-</layout>
+<page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/View/PageLayout/etc/layouts.xsd">
+    <layout id="one">
+        <label translate="true">One</label>
+    </layout>
+</page_layouts>
diff --git a/app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_review.xml b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_two.xml
similarity index 73%
rename from app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_review.xml
rename to dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_two.xml
index 47b956bf71a..9bedb2195c4 100644
--- a/app/code/Magento/Rss/view/adminhtml/layout/rss_catalog_review.xml
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/PageLayout/_files/layouts_two.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
  * Magento
@@ -23,8 +23,8 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_generic.xsd">
-    <container name="root">
-        <block class="Magento\Rss\Block\Catalog\Review" name="rss.catalog.review"/>
-    </container>
-</layout>
+<page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../lib/internal/Magento/Framework/View/PageLayout/etc/layouts.xsd">
+    <layout id="two">
+        <label translate="true">Two</label>
+    </layout>
+</page_layouts>
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Result/PageTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Result/PageTest.php
new file mode 100644
index 00000000000..aa61951f563
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Result/PageTest.php
@@ -0,0 +1,294 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Result;
+
+use Magento\Framework\View\Page\Config as PageConfig;
+
+/**
+ * Result Page Test
+ */
+class PageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\Result\Page
+     */
+    protected $page;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layout;
+
+    /**
+     * @var \Magento\Core\Model\Layout\Merge|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMerge;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfig;
+
+    /**
+     * @var \Magento\Framework\Translate\InlineInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $translateInline;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config\Renderer|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigRenderer;
+
+    protected function setUp()
+    {
+        $this->layout = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->layoutMerge = $this->getMockBuilder('Magento\Core\Model\Layout\Merge')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->layout->expects($this->any())
+            ->method('getUpdate')
+            ->will($this->returnValue($this->layoutMerge));
+
+        $this->request = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->pageConfig = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->context = $objectManagerHelper->getObject('Magento\Framework\View\Element\Template\Context', [
+            'layout' => $this->layout,
+            'request' => $this->request,
+            'pageConfig' => $this->pageConfig
+        ]);
+
+
+        $this->translateInline = $this->getMock('Magento\Framework\Translate\InlineInterface');
+
+        $this->pageConfigRenderer = $this->getMockBuilder('Magento\Framework\View\Page\Config\Renderer')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->page = $objectManagerHelper->getObject(
+            'Magento\Framework\View\Result\Page',
+            [
+                'context' => $this->context,
+                'translateInline' => $this->translateInline,
+                'pageConfigRenderer' => $this->pageConfigRenderer
+            ]
+        );
+    }
+
+    public function testInitLayout()
+    {
+        $handleDefault = 'default';
+        $fullActionName = 'full_action_name';
+        $this->request->expects($this->any())
+            ->method('getFullActionName')
+            ->will($this->returnValue($fullActionName));
+
+        $this->layoutMerge->expects($this->at(0))
+            ->method('addHandle')
+            ->with($handleDefault)
+            ->willReturnSelf();
+        $this->layoutMerge->expects($this->at(1))
+            ->method('addHandle')
+            ->with($fullActionName)
+            ->willReturnSelf();
+        $this->layoutMerge->expects($this->at(2))
+            ->method('isLayoutDefined')
+            ->willReturn(false);
+
+        $this->assertEquals($this->page, $this->page->initLayout());
+    }
+
+    public function testInitLayoutLayoutDefined()
+    {
+        $handleDefault = 'default';
+        $fullActionName = 'full_action_name';
+        $this->request->expects($this->any())
+            ->method('getFullActionName')
+            ->will($this->returnValue($fullActionName));
+
+        $this->layoutMerge->expects($this->at(0))
+            ->method('addHandle')
+            ->with($handleDefault)
+            ->willReturnSelf();
+        $this->layoutMerge->expects($this->at(1))
+            ->method('addHandle')
+            ->with($fullActionName)
+            ->willReturnSelf();
+        $this->layoutMerge->expects($this->at(2))
+            ->method('isLayoutDefined')
+            ->willReturn(true);
+        $this->layoutMerge->expects($this->at(3))
+            ->method('removeHandle')
+            ->with($handleDefault)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->page, $this->page->initLayout());
+    }
+
+    public function testGetConfig()
+    {
+        $this->assertEquals($this->pageConfig, $this->page->getConfig());
+    }
+
+    public function testGetDefaultLayoutHandle()
+    {
+        $fullActionName = 'Full_Action_Name';
+        $expectedFullActionName = 'full_action_name';
+
+        $this->request->expects($this->any())
+            ->method('getFullActionName')
+            ->will($this->returnValue($fullActionName));
+
+        $this->assertEquals($expectedFullActionName, $this->page->getDefaultLayoutHandle());
+    }
+
+    public function testAddPageLayoutHandles()
+    {
+        $fullActionName = 'Full_Action_Name';
+        $defaultHandle = null;
+        $parameters = [
+            'key_one' => 'val_one',
+            'key_two' => 'val_two'
+        ];
+        $expected = [
+            'full_action_name',
+            'full_action_name_key_one_val_one',
+            'full_action_name_key_two_val_two'
+        ];
+        $this->request->expects($this->any())
+            ->method('getFullActionName')
+            ->will($this->returnValue($fullActionName));
+
+        $this->layoutMerge->expects($this->any())
+            ->method('addHandle')
+            ->with($expected)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->layoutMerge, $this->page->addPageLayoutHandles($parameters, $defaultHandle));
+    }
+
+    public function testAddPageLayoutHandlesWithDefaultHandle()
+    {
+        $defaultHandle = 'default_handle';
+        $parameters = [
+            'key_one' => 'val_one',
+            'key_two' => 'val_two'
+        ];
+        $expected = [
+            'default_handle',
+            'default_handle_key_one_val_one',
+            'default_handle_key_two_val_two'
+        ];
+        $this->request->expects($this->never())
+            ->method('getFullActionName');
+
+        $this->layoutMerge->expects($this->any())
+            ->method('addHandle')
+            ->with($expected)
+            ->willReturnSelf();
+
+        $this->assertEquals($this->layoutMerge, $this->page->addPageLayoutHandles($parameters, $defaultHandle));
+    }
+
+    public function testRenderResult()
+    {
+        $pageLayout  = 'page_layout';
+        $fullActionName = 'full_action_aame';
+        $requireJs = 'require_js';
+        $layoutOutput = 'layout_output';
+        $headContent =  'head_content';
+        $attributesHtml =  'attributes_html';
+        $attributesHead =  'attributes_head';
+        $attributesBody =  'attributes_body';
+
+        $response = $this->getMock('Magento\Framework\App\ResponseInterface', ['sendResponse', 'appendBody']);
+        $response->expects($this->once())
+            ->method('appendBody');
+
+        $this->request->expects($this->atLeastOnce())
+            ->method('getFullActionName')
+            ->with('-')
+            ->willReturn($fullActionName);
+
+        $this->pageConfig->expects($this->any())
+            ->method('getPageLayout')
+            ->willReturn($pageLayout);
+        $this->pageConfig->expects($this->any())
+            ->method('addBodyClass')
+            ->withConsecutive([$fullActionName], ['page-layout-' . $pageLayout]);
+
+        $requireJsBlock = $this->getMock('Magento\Framework\View\Element\BlockInterface');
+        $requireJsBlock->expects($this->once())
+            ->method('toHtml')
+            ->willReturn($requireJs);
+
+        $this->layout->expects($this->any())
+            ->method('getBlock')
+            ->with('require.js')
+            ->willReturn($requireJsBlock);
+
+        $this->layout->expects($this->once())
+            ->method('getOutput')
+            ->willReturn($layoutOutput);
+
+        $this->translateInline->expects($this->once())
+            ->method('processResponseBody')
+            ->with($layoutOutput);
+
+        $this->pageConfigRenderer->expects($this->any())
+            ->method('renderElementAttributes')
+            ->willReturnMap([
+                [PageConfig::ELEMENT_TYPE_HTML, $attributesHtml],
+                [PageConfig::ELEMENT_TYPE_HEAD, $attributesHead],
+                [PageConfig::ELEMENT_TYPE_BODY, $attributesBody]
+            ]);
+
+        $this->pageConfigRenderer->expects($this->any())
+            ->method('renderHeadContent')
+            ->willReturn($headContent);
+
+        $this->page->renderResult($response);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ConditionTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ConditionTest.php
new file mode 100644
index 00000000000..c9b343cb578
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ConditionTest.php
@@ -0,0 +1,131 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Model\Attribute;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class ConditionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider convertAttributeDataProvider
+     *
+     * @param $productAttributeValue
+     * @param $attributeFrontendType
+     * @param $conditionValue
+     */
+    public function testConvertAttribute($productAttributeValue, $attributeFrontendType, $conditionValue)
+    {
+        $googleAttributeId = 1;
+        $conditionType = \Magento\GoogleShopping\Model\Attribute\Condition::ATTRIBUTE_TYPE_TEXT;
+        $conditionName = 'condition';
+        $googleShoppingAttribute = $this->getMock(
+            'Magento\Framework\Gdata\Gshopping\Extension\Attribute',
+            null,
+            [$conditionName]
+        );
+        $googleShoppingEntry = $this->getMock(
+            'Magento\Framework\Gdata\Gshopping\Entry',
+            ['getContentAttributeByName'],
+            [],
+            '',
+            false
+        );
+        $googleShoppingEntry->expects($this->any())
+            ->method('getContentAttributeByName')
+            ->with($conditionName)
+            ->will($this->returnValue($googleShoppingAttribute));
+        $product = $this->getMock('Magento\Catalog\Model\Product', ['__wakeup', 'getData'], [], '', false);
+        $product->expects($this->any())
+            ->method('getData')
+            ->with($conditionName)
+            ->will($this->returnValue($productAttributeValue));
+        $attributeFrontend = $this->getMock(
+            'Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend',
+            ['getValue'],
+            [],
+            '',
+            false
+        );
+        $attributeFrontend->expects($this->any())
+            ->method('getValue')
+            ->with($product)
+            ->will($this->returnValue($productAttributeValue));
+        $catalogEntityAttribute = $this->getMock(
+            'Magento\Catalog\Model\Entity\Attribute',
+            ['__wakeup', 'getFrontend', 'getFrontendInput', 'getAttributeCode'],
+            [],
+            '',
+            false
+        );
+        $catalogEntityAttribute->expects($this->any())
+            ->method('getFrontend')
+            ->will($this->returnValue($attributeFrontend));
+        $catalogEntityAttribute->expects($this->any())
+            ->method('getFrontendInput')
+            ->will($this->returnValue($attributeFrontendType));
+        $catalogEntityAttribute->expects($this->any())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($conditionName));
+        $googleShoppingProduct = $this->getMock(
+            'Magento\GoogleShopping\Helper\Product',
+            ['getProductAttribute'],
+            [],
+            '',
+            false
+        );
+        $googleShoppingProduct->expects($this->any())
+            ->method('getProductAttribute')
+            ->with($product, $googleAttributeId)
+            ->will($this->returnValue($catalogEntityAttribute));
+
+        $model = (new ObjectManagerHelper($this))->getObject(
+            'Magento\GoogleShopping\Model\Attribute\Condition',
+            [
+                'gsProduct' => $googleShoppingProduct
+            ]
+        );
+        $model->setAttributeId($googleAttributeId);
+        $this->assertEquals($googleShoppingEntry, $model->convertAttribute($product, $googleShoppingEntry));
+        $this->assertEquals(
+            [
+                $conditionValue,
+                $conditionType,
+                $conditionName
+            ],
+            [
+                $googleShoppingAttribute->getText(),
+                $googleShoppingAttribute->getType(),
+                $googleShoppingAttribute->getName()
+            ]
+        );
+    }
+
+    public function convertAttributeDataProvider()
+    {
+        return [
+            ['Used', 'text', \Magento\GoogleShopping\Model\Attribute\Condition::CONDITION_USED],
+            ['2014-10-25T15:14:13', 'date', \Magento\GoogleShopping\Model\Attribute\Condition::CONDITION_NEW],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Index/App/IndexerTest.php b/dev/tests/unit/testsuite/Magento/Index/App/IndexerTest.php
deleted file mode 100644
index a799d189971..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/App/IndexerTest.php
+++ /dev/null
@@ -1,101 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\App;
-
-class IndexerTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\App\Indexer
-     */
-    protected $_entryPoint;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Index\Model\IndexerFactory
-     */
-    protected $_indexFactory;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_filesystem;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_response;
-
-    protected function setUp()
-    {
-        $this->_filesystem = $this->getMock('Magento\Framework\App\Filesystem', ['getDirectoryWrite'], [], '', false);
-        $this->_indexFactory = $this->getMock('Magento\Index\Model\IndexerFactory', ['create'], [], '', false);
-        $this->_response = $this->getMock('Magento\Framework\App\Console\Response', [], [], '', false);
-        $this->_entryPoint = new Indexer('reportDir', $this->_filesystem, $this->_indexFactory, $this->_response);
-    }
-
-    /**
-     * @param bool $value
-     * @dataProvider executeDataProvider
-     */
-    public function testLaunch($value)
-    {
-        $dir = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
-        $dir->expects($this->any())->method('getRelativePath')->will($this->returnArgument(0));
-        $this->_filesystem->expects($this->once())->method('getDirectoryWrite')->will($this->returnValue($dir));
-        $process = $this->getMock(
-            'Magento\Index\Model\Process',
-            ['getIndexer', 'reindexEverything', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $indexer = $this->getMock('Magento\Index\Model\Indexer', array('getProcessesCollection'), [], '', false);
-        $indexerInterface = $this->getMock('Magento\Index\Model\IndexerInterface');
-        $this->_indexFactory->expects($this->once())->method('create')->will($this->returnValue($indexer));
-        $indexer->expects($this->once())->method('getProcessesCollection')->will($this->returnValue(array($process)));
-        $process->expects($this->any())->method('getIndexer')->will($this->returnValue($indexerInterface));
-
-        if ($value) {
-            $indexerInterface->expects($this->once())->method('isVisible')->will($this->returnValue(true));
-            $process->expects($this->once())->method('reindexEverything');
-        } else {
-            $indexerInterface->expects($this->once())->method('isVisible')->will($this->returnValue(false));
-            $process->expects($this->never())->method('reindexEverything');
-        }
-        $this->assertEquals($this->_response, $this->_entryPoint->launch());
-    }
-
-    /**
-     * @return array
-     */
-    public function executeDataProvider()
-    {
-        return [[true], [false]];
-    }
-
-    public function testCatchException()
-    {
-        $bootstrap = $this->getMock('Magento\Framework\App\Bootstrap', [], [], '', false);
-        $this->assertFalse($this->_entryPoint->catchException($bootstrap, new \Exception));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/App/ShellTest.php b/dev/tests/unit/testsuite/Magento/Index/App/ShellTest.php
deleted file mode 100644
index 033629a976a..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/App/ShellTest.php
+++ /dev/null
@@ -1,82 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\App;
-
-class ShellTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\App\Shell
-     */
-    protected $_entryPoint;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_shellFactory;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_responseMock;
-
-    protected function setUp()
-    {
-        $this->_shellFactory = $this->getMock('Magento\Index\Model\ShellFactory', array('create'), array(), '', false);
-        $this->_responseMock = $this->getMock('Magento\Framework\App\Console\Response', array(), array(), '', false);
-        $this->_entryPoint = new \Magento\Index\App\Shell('indexer.php', $this->_shellFactory, $this->_responseMock);
-    }
-
-    /**
-     * @param boolean $shellHasErrors
-     * @dataProvider processRequestDataProvider
-     */
-    public function testProcessRequest($shellHasErrors)
-    {
-        $shell = $this->getMock('Magento\Index\Model\Shell', array(), array(), '', false);
-        $shell->expects($this->once())->method('hasErrors')->will($this->returnValue($shellHasErrors));
-        $shell->expects($this->once())->method('run');
-        if ($shellHasErrors) {
-            $this->_responseMock->expects($this->once())->method('setCode')->with(-1);
-        } else {
-            $this->_responseMock->expects($this->once())->method('setCode')->with(0);
-        }
-        $this->_shellFactory->expects($this->any())->method('create')->will($this->returnValue($shell));
-
-        $this->_entryPoint->launch();
-    }
-
-    /**
-     * @return array
-     */
-    public function processRequestDataProvider()
-    {
-        return array(array(true), array(false));
-    }
-
-    public function testCatchException()
-    {
-        $bootstrap = $this->getMock('Magento\Framework\App\Bootstrap', array(), array(), '', false);
-        $this->assertFalse($this->_entryPoint->catchException($bootstrap, new \Exception));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Config/XsdTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Config/XsdTest.php
deleted file mode 100644
index 6520bee5dac..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Config/XsdTest.php
+++ /dev/null
@@ -1,115 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Config;
-
-class XsdTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Path to xsd file
-     * @var string
-     */
-    protected $_xsdSchemaPath;
-
-    /**
-     * @var \Magento\TestFramework\Utility\XsdValidator
-     */
-    protected $_xsdValidator;
-
-    protected function setUp()
-    {
-        $this->_xsdSchemaPath = BP . '/app/code/Magento/Index/etc/';
-        $this->_xsdValidator = new \Magento\TestFramework\Utility\XsdValidator();
-    }
-
-    /**
-     * @param string $schemaName
-     * @param string $xmlString
-     * @param array $expectedError
-     */
-    protected function _loadDataForTest($schemaName, $xmlString, $expectedError)
-    {
-        $actualError = $this->_xsdValidator->validate($this->_xsdSchemaPath . $schemaName, $xmlString);
-        $this->assertEquals($expectedError, $actualError);
-    }
-
-    /**
-     * @param string $xmlString
-     * @param array $expectedError
-     * @dataProvider schemaCorrectlyIdentifiesInvalidIndexersXmlDataProvider
-     */
-    public function testSchemaCorrectlyIdentifiesInvalidIndexersXml($xmlString, $expectedError)
-    {
-        $this->_loadDataForTest('indexers.xsd', $xmlString, $expectedError);
-    }
-
-    /**
-     * @param string $xmlString
-     * @param array $expectedError
-     * @dataProvider schemaCorrectlyIdentifiesInvalidIndexersMergedXmlDataProvider
-     */
-    public function testSchemaCorrectlyIdentifiesInvalidIndexersMergedXml($xmlString, $expectedError)
-    {
-        $this->_loadDataForTest('indexers_merged.xsd', $xmlString, $expectedError);
-    }
-
-    /**
-     * @param string $schemaName
-     * @param string $validFileName
-     * @dataProvider schemaCorrectlyIdentifiesValidXmlDataProvider
-     */
-    public function testSchemaCorrectlyIdentifiesValidXml($schemaName, $validFileName)
-    {
-        $xmlString = file_get_contents(__DIR__ . '/_files/' . $validFileName);
-        $schemaPath = $this->_xsdSchemaPath . $schemaName;
-        $actualResult = $this->_xsdValidator->validate($schemaPath, $xmlString);
-        $this->assertEquals(array(), $actualResult);
-    }
-
-    /**
-     * Data provider with valid xml files according to schemas
-     */
-    public function schemaCorrectlyIdentifiesValidXmlDataProvider()
-    {
-        return array(
-            'indexers' => array('indexers.xsd', 'valid_indexers.xml'),
-            'indexers_merged' => array('indexers_merged.xsd', 'valid_indexers_merged.xml')
-        );
-    }
-
-    /**
-     * Data provider with invalid xml array according to schema
-     */
-    public function schemaCorrectlyIdentifiesInvalidIndexersXmlDataProvider()
-    {
-        return include __DIR__ . '/_files/invalidIndexersXmlArray.php';
-    }
-
-    /**
-     * Data provider with invalid xml array according to schema
-     */
-    public function schemaCorrectlyIdentifiesInvalidIndexersMergedXmlDataProvider()
-    {
-        return include __DIR__ . '/_files/invalidIndexersXmlMergedArray.php';
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlArray.php b/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlArray.php
deleted file mode 100644
index 7b6d0d8253c..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlArray.php
+++ /dev/null
@@ -1,79 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-return array(
-    'indexer_node_is_required' => array(
-        '<?xml version="1.0"?><config><depends name="name one"/></config>',
-        array("Element 'depends': This element is not expected. Expected is ( indexer ).")
-    ),
-    'indexer_name_must_be_unique' => array(
-        '<?xml version="1.0"?><config><indexer name="name" instance="instance" />' .
-        '<indexer name="name" instance="instance" /></config>',
-        array("Element 'indexer': Duplicate key-sequence ['name'] in unique identity-constraint 'uniqueIndexerName'.")
-    ),
-    'depends_name_must_be_unique' => array(
-        '<?xml version="1.0"?><config><indexer name="name" instance="instance"><depends name="name" />' .
-        '<depends name="name" /></indexer></config>',
-        array("Element 'depends': Duplicate key-sequence ['name'] in unique identity-constraint 'uniqueDependsName'.")
-    ),
-    'indexer_node_without_required_attribute' => array(
-        '<?xml version="1.0"?><config><indexer name="name"/><indexer instance="instance" /></config>',
-        array("Element 'indexer': The attribute 'name' is required but missing.")
-    ),
-    'depends_without_required_attribute' => array(
-        '<?xml version="1.0"?><config><indexer name="name" instance="instance"><depends/></indexer></config>',
-        array("Element 'depends': The attribute 'name' is required but missing.")
-    ),
-    'name_attribute_with_invalid_value' => array(
-        '<?xml version="1.0"?><config><indexer name="name" instance="instance"><depends name="Name" />' .
-        '<depends name="name12" /></indexer></config>',
-        array(
-            "Element 'depends', attribute 'name': [facet 'pattern'] The value 'Name' is not accepted by the pattern " .
-            "'[a-z_]+'.",
-            "Element 'depends', attribute 'name': 'Name' is not a valid value of the atomic type " .
-            "'identifierType'.",
-            "Element 'depends', attribute 'name': Warning: No precomputed value available, the value" .
-            " was either invalid or something strange happend.",
-            "Element 'depends', attribute 'name': [facet 'pattern'] " .
-            "The value 'name12' is not accepted by the pattern '[a-z_]+'.",
-            "Element 'depends', attribute 'name': " .
-            "'name12' is not a valid value of the atomic type 'identifierType'.",
-            "Element 'depends', attribute 'name': " .
-            "Warning: No precomputed value available, the value was either invalid or something strange happend."
-        )
-    ),
-    'instance_attribute_with_invalid_value' => array(
-        '<?xml version="1.0"?><config><indexer name="name" instance="10"/><indexer name="name_one" ' .
-        'instance="One_Two1" /></config>',
-        array(
-            "Element 'indexer', attribute 'instance': [facet 'pattern'] The value '10' is not accepted by the pattern" .
-            " '[a-zA-Z_\\\\\\\\]+'.",
-            "Element 'indexer', attribute 'instance': '10' is not a valid value of the atomic type " .
-            "'instanceType'.",
-            "Element 'indexer', attribute 'instance': [facet 'pattern'] The value 'One_Two1' is not " .
-            "accepted by the pattern '[a-zA-Z_\\\\\\\\]+'.",
-            "Element 'indexer', attribute 'instance': 'One_Two1' is not a valid " .
-            "value of the atomic type 'instanceType'."
-        )
-    )
-);
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlMergedArray.php b/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlMergedArray.php
deleted file mode 100644
index 06a1b794d29..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/invalidIndexersXmlMergedArray.php
+++ /dev/null
@@ -1,32 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-return array(
-    'indexer_node_without_required_attributes' => array(
-        '<?xml version="1.0"?><config><indexer name="name"/><indexer instance="instance" /></config>',
-        array(
-            "Element 'indexer': The attribute 'instance' is required but missing.",
-            "Element 'indexer': The attribute" . " 'name' is required but missing."
-        )
-    )
-);
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers_merged.xml b/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers_merged.xml
deleted file mode 100644
index 270f4010015..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Config/_files/valid_indexers_merged.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../app/code/Magento/Index/etc/indexers.xsd">
-    <indexer name="name" instance="One_Two_Three" />
-    <indexer name="name_node" instance="Some_Name">
-        <depends name="name_three" />
-    </indexer>
-</config>
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/EventRepositoryTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/EventRepositoryTest.php
deleted file mode 100644
index 29c7a148c0a..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/EventRepositoryTest.php
+++ /dev/null
@@ -1,92 +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.
- * 
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model;
-
-class EventRepositoryTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\Model\EventRepository
-     */
-    protected $_model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_eventCollection;
-
-    protected function setUp()
-    {
-        $this->_eventCollection = $this->getMock(
-            'Magento\Index\Model\Resource\Event\Collection',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $collectionFactory = $this->getMock(
-            'Magento\Index\Model\Resource\Event\CollectionFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-        $collectionFactory->expects($this->any())->method('create')->will($this->returnValue($this->_eventCollection));
-        $this->_model = new \Magento\Index\Model\EventRepository($collectionFactory);
-    }
-
-    protected function tearDown()
-    {
-        unset($this->_model);
-    }
-
-    public function testHasUnprocessedReturnsTrueIfUnprocessedEventsExist()
-    {
-        $process = 'proc1';
-        $this->_eventCollection->expects($this->once())->method('getSize')->will($this->returnValue(1));
-        $this->_eventCollection->expects($this->once())->method('addProcessFilter')->with($process);
-        $this->assertTrue($this->_model->hasUnprocessed($process));
-    }
-
-    public function testHasUnprocessedReturnsFalseIfUnprocessedEventsExist()
-    {
-        $process = 'proc2';
-        $this->_eventCollection->expects($this->once())->method('getSize')->will($this->returnValue(0));
-        $this->_eventCollection->expects($this->once())->method('addProcessFilter')->with($process);
-        $this->assertFalse($this->_model->hasUnprocessed($process));
-    }
-
-    public function testGetUnprocessedReturnsConfiguredCollectionOfEvents()
-    {
-        $process = $this->getMock('Magento\Index\Model\Process', array(), array(), '', false);
-        $this->_eventCollection->expects(
-            $this->once()
-        )->method(
-            'addProcessFilter'
-        )->with(
-            $process,
-            \Magento\Index\Model\Process::EVENT_STATUS_NEW
-        );
-        $this->assertEquals($this->_eventCollection, $this->_model->getUnprocessed($process));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/ConverterTest.php
deleted file mode 100644
index 805187dac0e..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/ConverterTest.php
+++ /dev/null
@@ -1,50 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer\Config;
-
-class ConverterTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\Model\Indexer\Config\Converter
-     */
-    protected $_model;
-
-    protected function setUp()
-    {
-        $this->_model = new \Magento\Index\Model\Indexer\Config\Converter();
-    }
-
-    /**
-     * @covers \Magento\Index\Model\Indexer\Config\Converter::convert
-     */
-    public function testConvert()
-    {
-        $basePath = realpath(__DIR__) . '/_files/';
-        $path = $basePath . 'indexers.xml';
-        $domDocument = new \DOMDocument();
-        $domDocument->load($path);
-        $expectedData = include $basePath . 'indexers.php';
-        $this->assertEquals($expectedData, $this->_model->convert($domDocument));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/SchemaLocatorTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/SchemaLocatorTest.php
deleted file mode 100644
index c05bb84b712..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/SchemaLocatorTest.php
+++ /dev/null
@@ -1,73 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer\Config;
-
-class SchemaLocatorTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\Model\Indexer\Config\SchemaLocator
-     */
-    protected $_model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_modulesReaderMock;
-
-    protected function setUp()
-    {
-        $this->_modulesReaderMock = $this->getMock('Magento\Framework\Module\Dir\Reader', array(), array(), '', false);
-
-        $this->_modulesReaderMock->expects(
-            $this->any()
-        )->method(
-            'getModuleDir'
-        )->with(
-            'etc',
-            'Magento_Index'
-        )->will(
-            $this->returnValue('some_path')
-        );
-
-        $this->_model = new \Magento\Index\Model\Indexer\Config\SchemaLocator($this->_modulesReaderMock);
-    }
-
-    /**
-     * @covers \Magento\Index\Model\Indexer\Config\SchemaLocator::getSchema
-     */
-    public function testGetSchema()
-    {
-        $expectedSchema = 'some_path/indexers_merged.xsd';
-        $this->assertEquals($expectedSchema, $this->_model->getSchema());
-    }
-
-    /**
-     * @covers \Magento\Index\Model\Indexer\Config\SchemaLocator::getPerFileSchema
-     */
-    public function testGetPerFileSchema()
-    {
-        $expectedSchema = 'some_path/indexers.xsd';
-        $this->assertEquals($expectedSchema, $this->_model->getPerFileSchema());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/ConfigTest.php
deleted file mode 100644
index b6d82e1075c..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/ConfigTest.php
+++ /dev/null
@@ -1,97 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Indexer;
-
-class ConfigTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Index\Model\Indexer\Config
-     */
-    protected $_model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_readerMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_configScopeMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_cacheMock;
-
-    protected function setUp()
-    {
-        $this->_readerMock = $this->getMock('Magento\Index\Model\Indexer\Config\Reader', array(), array(), '', false);
-        $this->_configScopeMock = $this->getMock('Magento\Framework\Config\ScopeInterface');
-        $this->_cacheMock = $this->getMock('Magento\Framework\Config\CacheInterface');
-        $this->_model = new \Magento\Index\Model\Indexer\Config(
-            $this->_readerMock,
-            $this->_configScopeMock,
-            $this->_cacheMock
-        );
-    }
-
-    /**
-     * @covers \Magento\Index\Model\Indexer\Config::getIndexer
-     */
-    public function testGetIndexer()
-    {
-        $indexerConfig = array('indexerName' => 'indexerConfig');
-        $this->_configScopeMock->expects($this->once())->method('getCurrentScope')->will($this->returnValue('global'));
-        $this->_cacheMock->expects(
-            $this->once()
-        )->method(
-            'load'
-        )->with(
-            'global::indexerConfigCache'
-        )->will(
-            $this->returnValue(serialize($indexerConfig))
-        );
-        $this->assertEquals('indexerConfig', $this->_model->getIndexer('indexerName'));
-    }
-
-    /**
-     * @covers \Magento\Index\Model\Indexer\Config::getAll
-     */
-    public function testGetAll()
-    {
-        $indexerConfig = array('indexerName' => 'indexerConfig');
-        $this->_configScopeMock->expects($this->once())->method('getCurrentScope')->will($this->returnValue('global'));
-        $this->_cacheMock->expects(
-            $this->once()
-        )->method(
-            'load'
-        )->with(
-            'global::indexerConfigCache'
-        )->will(
-            $this->returnValue(serialize($indexerConfig))
-        );
-        $this->assertEquals($indexerConfig, $this->_model->getAll());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Lock/StorageTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Lock/StorageTest.php
deleted file mode 100644
index c4769726616..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Lock/StorageTest.php
+++ /dev/null
@@ -1,100 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Index\Model\Lock;
-
-class StorageTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Keep current process id for tests
-     *
-     * @var integer
-     */
-    protected $_callbackProcessId;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_dirsMock;
-
-    public function testGetFile()
-    {
-        $streamMock = $this->getMockBuilder('Magento\Framework\Filesystem\File\Write')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $directoryMock = $this->getMockBuilder(
-            'Magento\Framework\Filesystem\Directory\Write'
-        )->disableOriginalConstructor()->getMock();
-        $directoryMock->expects($this->exactly(2))->method('create');
-
-        $directoryMock->expects($this->any())->method('openFile')->will($this->returnValue($streamMock));
-
-        $filesystemMock =
-            $this->getMockBuilder('Magento\Framework\App\Filesystem')->disableOriginalConstructor()->getMock();
-        $filesystemMock->expects(
-            $this->once()
-        )->method(
-            'getDirectoryWrite'
-        )->with(
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        )->will(
-            $this->returnValue($directoryMock)
-        );
-
-        $fileModel = $this->getMock('Magento\Index\Model\Process\File', array(), array($streamMock), '');
-
-        $fileFactory = $this->getMock(
-            'Magento\Index\Model\Process\FileFactory',
-            array('create'),
-            array($streamMock),
-            '',
-            false
-        );
-        $fileFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($fileModel));
-
-        $storage = new \Magento\Index\Model\Lock\Storage($fileFactory, $filesystemMock);
-
-        /**
-         * List if test process IDs.
-         * We need to test cases when new ID and existed ID passed into tested method.
-         */
-        $processIdList = array(1, 2, 2);
-        foreach ($processIdList as $processId) {
-            $this->_callbackProcessId = $processId;
-            $this->assertInstanceOf('Magento\Index\Model\Process\File', $storage->getFile($processId));
-        }
-        $this->assertAttributeCount(2, '_fileHandlers', $storage);
-    }
-
-    /**
-     * Check file name (callback subroutine for testGetFile())
-     *
-     * @param string $filename
-     */
-    public function checkFilenameCallback($filename)
-    {
-        $expected = 'index_process_' . $this->_callbackProcessId . '.lock';
-        $this->assertEquals($expected, $filename);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Process/FileFactoryTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/Process/FileFactoryTest.php
deleted file mode 100644
index f4c6edbf844..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Process/FileFactoryTest.php
+++ /dev/null
@@ -1,64 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Unit test for \Magento\Index\Model\Process\FileFactory
- */
-namespace Magento\Index\Model\Process;
-
-class FileFactoryTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Bogus string to return from object manager's create() method
-     */
-    const CREATE_RESULT = 'create_result';
-
-    /**
-     * Expected class name
-     */
-    const EXPECTED_CLASS_NAME = 'Magento\Index\Model\Process\File';
-
-    /**
-     * @var array
-     */
-    protected $_arguments = array('key' => 'value');
-
-    public function testCreate()
-    {
-        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager', array(), array(), '', false);
-        $objectManagerMock->expects(
-            $this->once()
-        )->method(
-            'create'
-        )->with(
-            self::EXPECTED_CLASS_NAME,
-            $this->_arguments
-        )->will(
-            $this->returnValue(self::CREATE_RESULT)
-        );
-
-        $factory = new \Magento\Index\Model\Process\FileFactory($objectManagerMock);
-        $this->assertEquals(self::CREATE_RESULT, $factory->create($this->_arguments));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/ProcessTest.php b/dev/tests/unit/testsuite/Magento/Index/Model/ProcessTest.php
deleted file mode 100644
index 31f89eb3569..00000000000
--- a/dev/tests/unit/testsuite/Magento/Index/Model/ProcessTest.php
+++ /dev/null
@@ -1,200 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Test class for \Magento\Index\Model\Process
- */
-namespace Magento\Index\Model;
-
-class ProcessTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Process ID for tests
-     */
-    const PROCESS_ID = 'testProcessId';
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Index\Model\Process\File
-     */
-    protected $_processFile;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Index\Model\Process
-     */
-    protected $_indexProcess;
-
-    protected function tearDown()
-    {
-        unset($this->_processFile);
-        unset($this->_indexProcess);
-    }
-
-    public function testLock()
-    {
-        $this->_prepareMocksForTestLock(true);
-
-        $result = $this->_indexProcess->lock();
-        $this->assertEquals($this->_indexProcess, $result);
-    }
-
-    public function testLockAndBlock()
-    {
-        $this->_prepareMocksForTestLock(false);
-
-        $result = $this->_indexProcess->lockAndBlock();
-        $this->assertEquals($this->_indexProcess, $result);
-    }
-
-    public function testGetProcessFile()
-    {
-        $this->_processFile = $this->getMock('Magento\Index\Model\Process\File', array(), array(), '', false, false);
-        $this->_prepareIndexProcess();
-
-        // assert that process file is stored in process entity instance and isn't changed after several invocations
-        // lock method is used as invocation of _getProcessFile
-        for ($i = 1; $i <= 2; $i++) {
-            $this->_indexProcess->lock();
-            $this->assertAttributeEquals($this->_processFile, '_processFile', $this->_indexProcess);
-        }
-    }
-
-    /**
-     * Create \Magento\Index\Model\Process instance for lock tests
-     *
-     * @param bool $nonBlocking
-     */
-    protected function _prepareMocksForTestLock($nonBlocking)
-    {
-        $this->_processFile = $this->getMock(
-            'Magento\Index\Model\Process\File',
-            array('processLock'),
-            array(),
-            '',
-            false,
-            false
-        );
-        $this->_processFile->expects($this->once())->method('processLock')->with($nonBlocking);
-
-        $this->_prepareIndexProcess();
-    }
-
-    /**
-     * Create index process instance
-     */
-    protected function _prepareIndexProcess()
-    {
-        $lockStorage = $this->getMock('Magento\Index\Model\Lock\Storage', array('getFile'), array(), '', false);
-        $lockStorage->expects(
-            $this->once()
-        )->method(
-            'getFile'
-        )->with(
-            self::PROCESS_ID
-        )->will(
-            $this->returnValue($this->_processFile)
-        );
-
-        $resource = $this->getMockForAbstractClass(
-            'Magento\Framework\Model\Resource\Db\AbstractDb',
-            array(),
-            '',
-            false,
-            false,
-            true,
-            array('getIdFieldName', '__wakeup')
-        );
-        $resource->expects($this->any())->method('getIdFieldName')->will($this->returnValue('process_id'));
-        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_indexProcess = $helper->getObject(
-            'Magento\Index\Model\Process',
-            array(
-                'lockStorage' => $lockStorage,
-                'resource' => $resource,
-                'data' => array('process_id' => self::PROCESS_ID)
-            )
-        );
-    }
-
-    public function testUnlock()
-    {
-        $streamLock = $this->getMockBuilder(
-            'Magento\Framework\Filesystem\File\Write'
-        )->setMethods(
-            array('unlock')
-        )->disableOriginalConstructor()->getMock();
-        $this->_processFile = $this->getMock(
-            'Magento\Index\Model\Process\File',
-            array('processUnlock', '__wakeup'),
-            array($streamLock)
-        );
-        $this->_processFile->expects($this->once())->method('processUnlock');
-        $this->_prepareIndexProcess();
-
-        $result = $this->_indexProcess->unlock();
-        $this->assertEquals($this->_indexProcess, $result);
-    }
-
-    /**
-     * Data Provider for testIsLocked
-     *
-     * @return array
-     */
-    public function isLockedDataProvider()
-    {
-        return array(
-            'need to unlock process' => array('$needUnlock' => true),
-            'no need to unlock process' => array('$needUnlock' => false)
-        );
-    }
-
-    /**
-     * @dataProvider isLockedDataProvider
-     * @param bool $needUnlock
-     */
-    public function testIsLocked($needUnlock)
-    {
-        $streamLock = $this->getMockBuilder(
-            'Magento\Framework\Filesystem\File\Write'
-        )->setMethods(
-            array('unlock')
-        )->disableOriginalConstructor()->getMock();
-        $this->_processFile = $this->getMock(
-            'Magento\Index\Model\Process\File',
-            array('isProcessLocked', '__wakeup'),
-            array($streamLock)
-        );
-        $this->_processFile->expects(
-            $this->once()
-        )->method(
-            'isProcessLocked'
-        )->with(
-            $needUnlock
-        )->will(
-            $this->returnArgument(0)
-        );
-        $this->_prepareIndexProcess();
-
-        $this->assertEquals($needUnlock, $this->_indexProcess->isLocked($needUnlock));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Indexer/App/ShellTest.php b/dev/tests/unit/testsuite/Magento/Indexer/App/ShellTest.php
index 655bf3a6d9f..1e0a0eb3096 100644
--- a/dev/tests/unit/testsuite/Magento/Indexer/App/ShellTest.php
+++ b/dev/tests/unit/testsuite/Magento/Indexer/App/ShellTest.php
@@ -26,7 +26,7 @@ namespace Magento\Indexer\App;
 class ShellTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Index\App\Shell
+     * @var \Magento\Indexer\App\Shell
      */
     protected $entryPoint;
 
diff --git a/dev/tests/unit/testsuite/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrpTest.php b/dev/tests/unit/testsuite/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrpTest.php
new file mode 100644
index 00000000000..81665418a7f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Msrp/Model/Observer/Frontend/Quote/SetCanApplyMsrpTest.php
@@ -0,0 +1,112 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Msrp\Model\Observer\Frontend\Quote;
+
+use Magento\Framework\Object;
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Sales\Model\Quote\Address;
+
+/**
+ * Tests Magento\Msrp\Model\Observer\Frontend\Quote\SetCanApplyMsrp
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class SetCanApplyMsrpTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Msrp\Model\Observer\Frontend\Quote\SetCanApplyMsrp
+     */
+    protected $observer;
+
+    /**
+     * @var \Magento\Msrp\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configMock;
+
+    protected function setUp()
+    {
+        $this->configMock = $this->getMockBuilder('Magento\Msrp\Model\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->observer = (new ObjectManager($this))->getObject(
+            'Magento\Msrp\Model\Observer\Frontend\Quote\SetCanApplyMsrp',
+            ['config' => $this->configMock]
+        );
+    }
+
+    /**
+     * @param bool $isMsrpEnabled
+     * @param bool $canApplyMsrp
+     * @dataProvider setQuoteCanApplyMsrpDataProvider
+     */
+    public function testSetQuoteCanApplyMsrp($isMsrpEnabled, $canApplyMsrp)
+    {
+        $eventMock = $this->getMockBuilder('Magento\Framework\Event')
+            ->disableOriginalConstructor()
+            ->setMethods(['getQuote'])
+            ->getMock();
+        $quoteMock = $this->getMockBuilder('Magento\Sales\Model\Quote')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup', 'setCanApplyMsrp', 'getAllAddresses'])
+            ->getMock();
+        $observerMock = $this->getMockBuilder('Magento\Framework\Event\Observer')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $observerMock->expects($this->once())
+            ->method('getEvent')
+            ->will($this->returnValue($eventMock));
+        $eventMock->expects($this->once())
+            ->method('getQuote')
+            ->will($this->returnValue($quoteMock));
+        $this->configMock->expects($this->once())
+            ->method('isEnabled')
+            ->will($this->returnValue($isMsrpEnabled));
+        $quoteMock->expects($this->once())
+            ->method('setCanApplyMsrp')
+            ->with($canApplyMsrp);
+        $addressMock1 = $this->getMockBuilder('Magento\Customer\Model\Address\AbstractAddress')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup'])
+            ->getMockForAbstractClass();
+        $addressMock1->setCanApplyMsrp($canApplyMsrp);
+        $addressMock2 = $this->getMockBuilder('Magento\Customer\Model\Address\AbstractAddress')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup'])
+            ->getMockForAbstractClass();
+        $addressMock2->setCanApplyMsrp(false);
+        $quoteMock->expects($this->any())
+            ->method('getAllAddresses')
+            ->will($this->returnValue([$addressMock1, $addressMock2]));
+        $this->observer->execute($observerMock);
+    }
+
+    public function setQuoteCanApplyMsrpDataProvider()
+    {
+        return [
+            [false, false],
+            [true, true],
+            [true, false]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php b/dev/tests/unit/testsuite/Magento/Msrp/Model/Product/Attribute/Source/Type/PriceTest.php
similarity index 90%
rename from dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php
rename to dev/tests/unit/testsuite/Magento/Msrp/Model/Product/Attribute/Source/Type/PriceTest.php
index cbef25f0bc8..4396fe87511 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/PriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Msrp/Model/Product/Attribute/Source/Type/PriceTest.php
@@ -21,21 +21,21 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type;
+namespace Magento\Msrp\Model\Product\Attribute\Source\Type;
 
 use Magento\TestFramework\Helper\ObjectManager;
 
 class PriceTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price
+     * @var \Magento\Msrp\Model\Product\Attribute\Source\Type\Price
      */
     protected $_model;
 
     public function setUp()
     {
         $objectManager = new ObjectManager($this);
-        $this->_model = $objectManager->getObject('Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Price');
+        $this->_model = $objectManager->getObject('Magento\Msrp\Model\Product\Attribute\Source\Type\Price');
     }
 
     public function testGetFlatColumns()
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/MsrpPriceTest.php b/dev/tests/unit/testsuite/Magento/Msrp/Pricing/Price/MsrpPriceTest.php
similarity index 89%
rename from dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/MsrpPriceTest.php
rename to dev/tests/unit/testsuite/Magento/Msrp/Pricing/Price/MsrpPriceTest.php
index a434ebb9221..703ed345b17 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/MsrpPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Msrp/Pricing/Price/MsrpPriceTest.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Pricing\Price;
+namespace Magento\Msrp\Pricing\Price;
 
 use \Magento\Framework\Pricing\PriceInfoInterface;
 
@@ -32,7 +32,7 @@ use \Magento\Framework\Pricing\PriceInfoInterface;
 class MsrpPriceTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Catalog\Pricing\Price\MsrpPrice
+     * @var \Magento\Msrp\Pricing\Price\MsrpPrice
      */
     protected $object;
 
@@ -60,6 +60,11 @@ class MsrpPriceTest extends \PHPUnit_Framework_TestCase
      */
     protected $calculator;
 
+    /**
+     * @var \Magento\Msrp\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $config;
+
     protected function setUp()
     {
         $this->saleableItem = $this->getMock(
@@ -91,18 +96,19 @@ class MsrpPriceTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->helper = $this->getMock(
-            'Magento\Catalog\Helper\Data',
-            ['isShowPriceOnGesture', 'getMsrpPriceMessage', 'isMsrpEnabled', 'canApplyMsrp'],
+            'Magento\Msrp\Helper\Data',
+            ['isShowPriceOnGesture', 'getMsrpPriceMessage', 'canApplyMsrp'],
             [],
             '',
             false
         );
-
+        $this->config = $this->getMock('Magento\Msrp\Model\Config', ['isEnabled'], [], '', false);
         $this->object = new MsrpPrice(
             $this->saleableItem,
             PriceInfoInterface::PRODUCT_QUANTITY_DEFAULT,
             $this->calculator,
-            $this->helper
+            $this->helper,
+            $this->config
         );
     }
 
@@ -139,8 +145,8 @@ class MsrpPriceTest extends \PHPUnit_Framework_TestCase
 
     public function testIsMsrpEnabled()
     {
-        $this->helper->expects($this->once())
-            ->method('isMsrpEnabled')
+        $this->config->expects($this->once())
+            ->method('isEnabled')
             ->will($this->returnValue(true));
 
         $this->assertTrue($this->object->isMsrpEnabled());
diff --git a/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php b/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
index 93c3c4a4d62..e78eaa61de3 100644
--- a/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
@@ -41,20 +41,47 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
      */
     private $fileManager;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfig;
+
+    /**
+     * @var Config
+     */
+    protected $blockConfig;
+
     protected function setUp()
     {
         $this->context = $this->getMock('\Magento\Framework\View\Element\Context', array(), array(), '', false);
         $this->config = $this->getMock('\Magento\Framework\RequireJs\Config', array(), array(), '', false);
         $this->fileManager = $this->getMock('\Magento\RequireJs\Model\FileManager', array(), array(), '', false);
+        $this->pageConfig = $this->getMock('\Magento\Framework\View\Page\Config', array(), array(), '', false);
     }
 
-    public function testGetAsset()
+    public function testSetLayout()
     {
+        $filePath = 'require_js_fie_path';
         $asset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
+        $asset->expects($this->atLeastOnce())
+            ->method('getFilePath')
+            ->willReturn($filePath);
         $this->fileManager->expects($this->once())->method('createRequireJsAsset')->will($this->returnValue($asset));
-        $object = new Config($this->context, $this->config, $this->fileManager);;
-        $this->assertSame($asset, $object->getAsset());
-        $this->assertSame($asset, $object->getAsset(), 'Asset is supposed to be cached in-memory');
+        $layout = $this->getMock('Magento\Framework\View\LayoutInterface');
+
+        $assetCollection = $this->getMockBuilder('Magento\Framework\View\Asset\GroupedCollection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $assetCollection->expects($this->once())
+            ->method('add')
+            ->with($filePath, $asset);
+        $this->pageConfig->expects($this->atLeastOnce())
+            ->method('getAssetCollection')
+            ->willReturn($assetCollection);
+
+        $object = new Config($this->context, $this->config, $this->fileManager, $this->pageConfig);
+        $object->setLayout($layout);
+
     }
 
     public function testToHtml()
@@ -70,7 +97,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             ))
         ;
         $this->config->expects($this->once())->method('getBaseConfig')->will($this->returnValue('the config data'));
-        $object = new Config($this->context, $this->config, $this->fileManager);;
+        $object = new Config($this->context, $this->config, $this->fileManager, $this->pageConfig);
         $html = $object->toHtml();
         $expectedFormat = <<<expected
 <script type="text/javascript">
diff --git a/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/Rss/Grid/LinkTest.php b/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/Rss/Grid/LinkTest.php
new file mode 100644
index 00000000000..41290e7dd5d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/Rss/Grid/LinkTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Block\Adminhtml\Rss\Grid;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class LinkTest
+ * @package Magento\Review\Block\Adminhtml\Rss\Grid
+ */
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Review\Block\Adminhtml\Rss\Grid\Link
+     */
+    protected $link;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    protected function setUp()
+    {
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->link = $this->objectManagerHelper->getObject(
+            'Magento\Review\Block\Adminhtml\Rss\Grid\Link',
+            [
+                'rssUrlBuilder' => $this->urlBuilderInterface
+            ]
+        );
+    }
+
+    public function testGetLink()
+    {
+        $rssUrl = 'http://rss.magento.com';
+        $this->urlBuilderInterface->expects($this->once())->method('getUrl')->will($this->returnValue($rssUrl));
+        $this->assertEquals($rssUrl, $this->link->getLink());
+    }
+
+    public function testGetLabel()
+    {
+        $this->assertEquals('Pending Reviews RSS', $this->link->getLabel());
+    }
+
+    public function testIsRssAllowed()
+    {
+        $this->assertEquals(true, $this->link->isRssAllowed());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/RssTest.php b/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/RssTest.php
new file mode 100644
index 00000000000..3de383fb02e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Review/Block/Adminhtml/RssTest.php
@@ -0,0 +1,161 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Block\Adminhtml;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class RssTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Review\Block\Adminhtml\Rss
+     */
+    protected $block;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerInterface;
+
+    /**
+     * @var \Magento\Review\Model\Rss|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rss;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilder;
+
+    protected function setUp()
+    {
+        $this->storeManagerInterface = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->rss = $this->getMock('Magento\Review\Model\Rss', ['__wakeUp', 'getProductCollection'], [], '', false);
+        $this->urlBuilder = $this->getMock('Magento\Framework\UrlInterface');
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Review\Block\Adminhtml\Rss',
+            [
+                'storeManager' => $this->storeManagerInterface,
+                'rssModel' => $this->rss,
+                'urlBuilder' => $this->urlBuilder,
+            ]
+        );
+    }
+
+    public function testGetRssData()
+    {
+        $rssData = array(
+            'title' => 'Pending product review(s)',
+            'description' => 'Pending product review(s)',
+            'link' => 'http://rss.magento.com',
+            'charset' => 'UTF-8',
+            'entries' =>
+                array(
+                    'title' => 'Product: "Product Name" reviewed by: Product Nick',
+                    'link' => 'http://product.magento.com',
+                    'description' =>
+                        array(
+                            'rss_url' => 'http://rss.magento.com',
+                            'name' => 'Product Name',
+                            'summary' => 'Product Title',
+                            'review' => 'Product Detail',
+                            'store' => 'Store Name',
+
+                        )
+                )
+        );
+        $rssUrl = 'http://rss.magento.com';
+        $productModel = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product',
+            [
+                'getStoreId',
+                'getId',
+                'getReviewId',
+                'getName',
+                'getDetail',
+                'getTitle',
+                'getNickname',
+                'getProductUrl'
+            ],
+            [],
+            '',
+            false
+        );
+        $storeModel = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $this->storeManagerInterface->expects($this->once())->method('getStore')->will($this->returnValue($storeModel));
+        $storeModel->expects($this->once())->method('getName')
+            ->will($this->returnValue($rssData['entries']['description']['store']));
+        $this->urlBuilder->expects($this->any())->method('getUrl')->will($this->returnValue($rssUrl));
+        $this->urlBuilder->expects($this->once())->method('setScope')->will($this->returnSelf());
+        $productModel->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $productModel->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $productModel->expects($this->once())->method('getReviewId')->will($this->returnValue(1));
+        $productModel->expects($this->any())->method('getNickName')->will($this->returnValue('Product Nick'));
+        $productModel->expects($this->any())->method('getName')
+            ->will($this->returnValue($rssData['entries']['description']['name']));
+        $productModel->expects($this->once())->method('getDetail')
+            ->will($this->returnValue($rssData['entries']['description']['review']));
+        $productModel->expects($this->once())->method('getTitle')
+            ->will($this->returnValue($rssData['entries']['description']['summary']));
+        $productModel->expects($this->any())->method('getProductUrl')
+            ->will($this->returnValue('http://product.magento.com'));
+        $this->rss->expects($this->once())->method('getProductCollection')
+            ->will($this->returnValue(array($productModel)));
+
+        $data = $this->block->getRssData();
+
+        $this->assertEquals($rssData['title'], $data['title']);
+        $this->assertEquals($rssData['description'], $data['description']);
+        $this->assertEquals($rssData['link'], $data['link']);
+        $this->assertEquals($rssData['charset'], $data['charset']);
+        $this->assertEquals($rssData['entries']['title'], $data['entries'][0]['title']);
+        $this->assertEquals($rssData['entries']['link'], $data['entries'][0]['link']);
+        $this->assertContains($rssData['entries']['description']['rss_url'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['name'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['summary'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['review'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['store'], $data['entries'][0]['description']);
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(0, $this->block->getCacheLifetime());
+    }
+
+    public function testIsAllowed()
+    {
+        $this->assertEquals(true, $this->block->isAllowed());
+    }
+
+    public function testGetFeeds()
+    {
+        $this->assertEquals(array(), $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Review/Model/RssTest.php b/dev/tests/unit/testsuite/Magento/Review/Model/RssTest.php
new file mode 100644
index 00000000000..a960f44bb34
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Review/Model/RssTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Model;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class RssTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Review\Model\Rss
+     */
+    protected $rss;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $managerInterface;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $reviewFactory;
+
+    protected function setUp()
+    {
+        $this->managerInterface = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $this->reviewFactory = $this->getMock('Magento\Review\Model\ReviewFactory', ['create']);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->rss = $this->objectManagerHelper->getObject(
+            'Magento\Review\Model\Rss',
+            [
+                'eventManager' => $this->managerInterface,
+                'reviewFactory' => $this->reviewFactory
+            ]
+        );
+    }
+
+    public function testGetProductCollection()
+    {
+        $reviewModel = $this->getMock(
+            'Magento\Review\Model\Review',
+            [
+                '__wakeUp',
+                'getProductCollection'
+            ],
+            [],
+            '',
+            false
+        );
+        $productCollection = $this->getMock(
+            'Magento\Review\Model\Resource\Review\Product\Collection',
+            [
+                'addStatusFilter',
+                'addAttributeToSelect',
+                'setDateOrder'
+            ],
+            [],
+            '',
+            false
+        );
+        $reviewModel->expects($this->once())->method('getProductCollection')
+            ->will($this->returnValue($productCollection));
+        $this->reviewFactory->expects($this->once())->method('create')->will($this->returnValue($reviewModel));
+        $productCollection->expects($this->once())->method('addStatusFilter')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('addAttributeToSelect')->will($this->returnSelf());
+        $productCollection->expects($this->once())->method('setDateOrder')->will($this->returnSelf());
+        $this->managerInterface->expects($this->once())->method('dispatch')->will($this->returnSelf());
+        $this->assertEquals($productCollection, $this->rss->getProductCollection());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/AbstractCatalogTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/AbstractCatalogTest.php
deleted file mode 100644
index f00503593c3..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/AbstractCatalogTest.php
+++ /dev/null
@@ -1,70 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Test for rendering price html in rss templates
- *
- */
-class AbstractCatalogTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * test renderPriceHtml function
-     */
-    public function testRenderPriceHtml()
-    {
-        $priceHtmlForTest = '<html>Price is 10 for example</html>';
-        $templateContextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
-        $httpContextMock = $this->getMock('Magento\Framework\App\Http\Context', [], [], '', false);
-        $helperMock = $this->getMock('Magento\Catalog\Helper\Data', [], [], '', false);
-        $productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
-        $layoutMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\LayoutInterface',
-            [],
-            '',
-            true,
-            true,
-            true,
-            ['getBlock']
-        );
-        $priceRendererMock = $this->getMock('Magento\Framework\Pricing\Render', ['render'], [], '', false);
-
-        $layoutMock->expects($this->once())
-            ->method('getBlock')
-            ->will($this->returnValue($priceRendererMock));
-        $priceRendererMock->expects($this->once())
-            ->method('render')
-            ->will($this->returnValue($priceHtmlForTest));
-
-        $block = new \Magento\Rss\Block\Catalog\AbstractCatalog(
-            $templateContextMock,
-            $httpContextMock,
-            $helperMock
-        );
-        $block->setLayout($layoutMock);
-
-        $this->assertEquals($priceHtmlForTest, $block->renderPriceHtml($productMock, true));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/CategoryTest.php
deleted file mode 100644
index 24abbace65b..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/CategoryTest.php
+++ /dev/null
@@ -1,146 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Test for rendering price html in rss templates
- *
- */
-class CategoryTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Rss\Block\Catalog\Category
-     */
-    protected $block;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $imageHelperMock;
-
-    /**
-     * Set up mock objects for tested class
-     */
-    public function setUp()
-    {
-        $templateContextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
-        $this->imageHelperMock = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
-        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
-        $requestMock = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
-
-        $templateContextMock->expects($this->once())
-            ->method('getEventManager')
-            ->will($this->returnValue($eventManagerMock));
-        $templateContextMock->expects($this->once())
-            ->method('getRequest')
-            ->will($this->returnValue($requestMock));
-
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $objectManager->getObject(
-            'Magento\Rss\Block\Catalog\Category',
-            [
-                'context' => $templateContextMock,
-                'imageHelper' => $this->imageHelperMock,
-            ]
-        );
-    }
-
-    /**
-     * Test for method addNewItemXmlCallback
-     */
-    public function testAddNewItemXmlCallback()
-    {
-        $priceHtmlForTest = '<div class="price">Price is 10 for example</div>';
-        $productMock = $this->getMock(
-            'Magento\Catalog\Model\Product',
-            ['getProductUrl', 'getDescription', 'getAllowedInRss', 'getName', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $rssObjMock = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
-        $layoutMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\LayoutInterface',
-            [],
-            '',
-            true,
-            true,
-            true,
-            ['getBlock']
-        );
-        $priceRendererMock = $this->getMock('Magento\Framework\Pricing\Render', ['render'], [], '', false);
-        $productTitle = 'Product title';
-        $productUrl = '<a href="http://product.url">Product Url</a>';
-        $imgThumbSrc = 'http://source-for-thumbnail';
-        $productDescription = 'Product description';
-        $description = '<table><tr><td><a href="' . $productUrl . '"><img src="' . $imgThumbSrc .
-            '" border="0" align="left" height="75" width="75"></a></td><td  style="text-decoration:none;">' .
-            $productDescription . $priceHtmlForTest . '</td></tr></table>';
-
-        $productMock->expects($this->exactly(2))
-            ->method('getProductUrl')
-            ->will($this->returnValue($productUrl));
-        $productMock->expects($this->once())
-            ->method('getDescription')
-            ->will($this->returnValue($productDescription));
-        $productMock->expects($this->any())
-            ->method('getAllowedInRss')
-            ->will($this->returnValue(true));
-        $productMock->expects($this->once())
-            ->method('getName')
-            ->will($this->returnValue($productTitle));
-        $this->imageHelperMock->expects($this->once())
-            ->method('init')
-            ->will($this->returnSelf());
-        $this->imageHelperMock->expects($this->once())
-            ->method('resize')
-            ->will($this->returnValue($imgThumbSrc));
-        $layoutMock->expects($this->once())
-            ->method('getBlock')
-            ->will($this->returnValue($priceRendererMock));
-        $priceRendererMock->expects($this->once())
-            ->method('render')
-            ->will($this->returnValue($priceHtmlForTest));
-
-        $expectedData = [
-            'title' => $productTitle,
-            'link' => $productUrl,
-            'description' => $description
-        ];
-        $rssObjMock->expects($this->once())
-            ->method('_addEntry')
-            ->with($expectedData)
-            ->will($this->returnSelf());
-
-
-        $args = [
-            'product' => $productMock,
-            'rssObj' => $rssObjMock
-        ];
-
-        $this->block->setLayout($layoutMock);
-        $this->assertNull($this->block->addNewItemXmlCallback($args));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/NewCatalogTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/NewCatalogTest.php
deleted file mode 100644
index f618db4b479..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/NewCatalogTest.php
+++ /dev/null
@@ -1,148 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Catalog;
-
-/**
- * Test for rendering price html in rss templates
- *
- */
-class NewCatalogTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Rss\Block\Catalog\NewCatalog
-     */
-    protected $block;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $imageHelperMock;
-
-    /**
-     * Set up mock objects for tested class
-     */
-    public function setUp()
-    {
-        $templateContextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
-        $this->imageHelperMock = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
-
-        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
-        $requestMock = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
-
-        $templateContextMock->expects($this->once())
-            ->method('getEventManager')
-            ->will($this->returnValue($eventManagerMock));
-        $templateContextMock->expects($this->once())
-            ->method('getRequest')
-            ->will($this->returnValue($requestMock));
-
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $objectManager->getObject(
-            'Magento\Rss\Block\Catalog\NewCatalog',
-            [
-                'context' => $templateContextMock,
-                'imageHelper' => $this->imageHelperMock,
-            ]
-        );
-    }
-
-    /**
-     * Test for method addNewItemXmlCallback
-     */
-    public function testAddNewItemXmlCallback()
-    {
-        $priceHtmlForTest = '<div class="price">Price is 10 for example</div>';
-        $productMock = $this->getMock(
-            'Magento\Catalog\Model\Product',
-            ['getProductUrl', 'getDescription', 'getAllowedInRss', 'getName', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $rssObjMock = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
-        $layoutMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\LayoutInterface',
-            [],
-            '',
-            true,
-            true,
-            true,
-            ['getBlock']
-        );
-        $priceRendererMock = $this->getMock('Magento\Framework\Pricing\Render', ['render'], [], '', false);
-        $productTitle = 'Product title';
-        $productUrl = '<a href="http://product.url">Product Url</a>';
-        $imgThumbSrc = 'http://source-for-thumbnail';
-        $productDescription = 'Product description';
-        $description = '<table><tr><td><a href="' . $productUrl . '"><img src="' . $imgThumbSrc .
-            '" border="0" align="left" height="75" width="75"></a></td><td  style="text-decoration:none;">' .
-            $productDescription . $priceHtmlForTest . '</td></tr></table>';
-
-        $productMock->expects($this->exactly(2))
-            ->method('getProductUrl')
-            ->will($this->returnValue($productUrl));
-        $productMock->expects($this->once())
-            ->method('getDescription')
-            ->will($this->returnValue($productDescription));
-        $productMock->expects($this->any())
-            ->method('getAllowedInRss')
-            ->will($this->returnValue(true));
-        $productMock->expects($this->once())
-            ->method('getName')
-            ->will($this->returnValue($productTitle));
-        $this->imageHelperMock->expects($this->once())
-            ->method('init')
-            ->will($this->returnSelf());
-        $this->imageHelperMock->expects($this->once())
-            ->method('resize')
-            ->will($this->returnValue($imgThumbSrc));
-        $layoutMock->expects($this->once())
-            ->method('getBlock')
-            ->will($this->returnValue($priceRendererMock));
-        $priceRendererMock->expects($this->once())
-            ->method('render')
-            ->will($this->returnValue($priceHtmlForTest));
-
-        $expectedData = [
-            'title' => $productTitle,
-            'link' => $productUrl,
-            'description' => $description
-        ];
-        $rssObjMock->expects($this->once())
-            ->method('_addEntry')
-            ->with($expectedData)
-            ->will($this->returnSelf());
-
-
-        $args = [
-            'product' => $productMock,
-            'rssObj' => $rssObjMock,
-            'row' => ''
-        ];
-
-        $this->block->setLayout($layoutMock);
-        $this->assertNull($this->block->addNewItemXmlCallback($args));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/ReviewTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/ReviewTest.php
deleted file mode 100644
index 7d92ee2e721..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/ReviewTest.php
+++ /dev/null
@@ -1,149 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Catalog;
-
-use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
-
-class ReviewTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var \Magento\Rss\Block\Catalog\Review */
-    protected $review;
-
-    /** @var ObjectManagerHelper */
-    protected $objectManagerHelper;
-
-    /** @var \Magento\Backend\Block\Context|\PHPUnit_Framework_MockObject_MockObject */
-    protected $contextMock;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject */
-    protected $rssFactoryMock;
-
-    /** @var \Magento\Framework\Model\Resource\Iterator|\PHPUnit_Framework_MockObject_MockObject */
-    protected $iteratorMock;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject */
-    protected $reviewFactoryMock;
-
-    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $storeManagerMock;
-
-    /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\UrlInterface */
-    protected $urlInterfaceMock;
-
-    protected function setUp()
-    {
-        $this->urlInterfaceMock = $this->getMock('Magento\Framework\UrlInterface', [], [], '', false);
-        $this->contextMock = $this->getMock('Magento\Backend\Block\Context', [], [], '', false);
-        $this->contextMock->expects($this->once())
-            ->method('getUrlBuilder')
-            ->will($this->returnValue($this->urlInterfaceMock));
-
-        $this->rssFactoryMock = $this->getMock('Magento\Rss\Model\RssFactory');
-        $this->iteratorMock = $this->getMock('Magento\Framework\Model\Resource\Iterator', [], [], '', false);
-        $this->reviewFactoryMock = $this->getMock('Magento\Review\Model\ReviewFactory');
-        $this->storeManagerMock = $this->getMock(
-            'Magento\Store\Model\StoreManager',
-            ['getStore', 'getName'],
-            [],
-            '',
-            false
-        );
-
-        $this->objectManagerHelper = new ObjectManagerHelper($this);
-        $this->review = $this->objectManagerHelper->getObject(
-            'Magento\Rss\Block\Catalog\Review',
-            [
-                'context' => $this->contextMock,
-                'rssFactory' => $this->rssFactoryMock,
-                'resourceIterator' => $this->iteratorMock,
-                'reviewFactory' => $this->reviewFactoryMock,
-                'storeManager' => $this->storeManagerMock
-            ]
-        );
-    }
-
-    public function testAddReviewItemXmlCallback()
-    {
-        $row = [
-            'entity_id' => 1,
-            'store_id' => 2,
-            'review_id' => 3,
-            'name' => 'Product Name',
-            'title' => 'Review Summary',
-            'detail' => 'Test of a review',
-            'nickname' => 'User Name',
-        ];
-        $productUrl = 'http://product.url';
-        $reviewUrl = 'http://review.url';
-
-
-        $reviewModel = $this->getMock('Magento\Review\Model\Review', [], [], '', false);
-        $reviewModel->expects($this->once())
-            ->method('getProductUrl')
-            ->with($this->equalTo($row['entity_id']), $this->equalTo($row['store_id']))
-            ->will($this->returnValue($productUrl));
-
-        $this->urlInterfaceMock->expects($this->once())
-            ->method('getUrl')
-            ->with(
-                $this->equalTo('review/product/edit/'),
-                $this->equalTo(array('id' => $row['review_id'], '_secure' => true, '_nosecret' => true))
-            )
-            ->will($this->returnValue($reviewUrl));
-
-        $storeName = 'Store Name';
-        $this->storeManagerMock->expects($this->once())->method('getStore')
-            ->with($this->equalTo($row['store_id']))->will($this->returnSelf());
-        $this->storeManagerMock->expects($this->once())
-            ->method('getName')
-            ->will($this->returnValue($storeName));
-        $rssObj = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
-        $description = '<p>' . __('Product: <a href="%1" target="_blank">%2</a> <br/>', $productUrl, $row['name'])
-            . __('Summary of review: %1 <br/>', $row['title']) . __('Review: %1 <br/>', $row['detail'])
-            . __('Store: %1 <br/>', $storeName)
-            . __('Click <a href="%1">here</a> to view the review.', $reviewUrl)
-            . '</p>';
-        $rssObj->expects($this->once())
-            ->method('_addEntry')
-            ->with(
-                $this->equalTo(
-                    [
-                        'title' => __('Product: "%1" reviewed by: %2', $row['name'], $row['nickname']),
-                        'link' => 'test',
-                        'description' => $description
-                    ]
-                )
-            )
-            ->will($this->returnSelf());
-
-        $args = [
-            'row' => $row,
-            'reviewModel' => $reviewModel,
-            'rssObj' => $rssObj
-        ];
-
-        $this->assertNull($this->review->addReviewItemXmlCallback($args));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/SpecialTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/SpecialTest.php
deleted file mode 100644
index ead8fc8130c..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Catalog/SpecialTest.php
+++ /dev/null
@@ -1,270 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Catalog;
-
-use \Magento\Framework\Pricing\PriceCurrencyInterface;
-
-/**
- * Test for rendering price html in rss templates
- *
- */
-class SpecialTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Rss\Block\Catalog\Special
-     */
-    protected $block;
-
-    /**
-     * @var \Magento\Catalog\Helper\Image
-     */
-    protected $imageHelperMock;
-
-    /**
-     * @var \Magento\Store\Model\Store
-     */
-    protected $storeMock;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $productFactoryMock;
-
-    /**
-     * @var \Magento\Rss\Model\RssFactory
-     */
-    protected $rssFactoryMock;
-
-    /**
-     * @var \Magento\Framework\Model\Resource\Iterator
-     */
-    protected $resourceIteratorMock;
-
-    /**
-     * @var \Magento\Catalog\Helper\Data
-     */
-    protected $catalogHelperMock;
-
-    /**
-     * @var \Magento\Framework\Pricing\PriceCurrencyInterface
-     */
-    protected $priceCurrencyMock;
-
-    /**
-     * Set up mock objects for tested class
-     *
-     * @return void
-     */
-    public function setUp()
-    {
-        $templateContextMock = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
-        $this->catalogHelperMock = $this->getMock('Magento\Catalog\Helper\Data', [], [], '', false);
-        $this->priceCurrencyMock = $this->getMockForAbstractClass(
-            'Magento\Framework\Pricing\PriceCurrencyInterface',
-            [],
-            '',
-            true,
-            true,
-            true,
-            ['convertAndFormat']
-        );
-        $this->rssFactoryMock = $this->getMock('Magento\Rss\Model\RssFactory', ['create'], [], '', false);
-        $this->productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create'], [], '', false);
-        $this->resourceIteratorMock = $this->getMock('Magento\Framework\Model\Resource\Iterator', [], [], '', false);
-        $this->imageHelperMock = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
-
-        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
-        $requestMock = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
-        $storeManagerMock = $this->getMock('Magento\Framework\StoreManagerInterface');
-        $urlBuilderMock = $this->getMock('Magento\Framework\UrlInterface', [], [], '', false);
-        $this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
-        $scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false);
-        $cacheStateMock = $this->getMock('Magento\Framework\App\Cache\StateInterface', [], [], '', false);
-
-        $templateContextMock->expects($this->any())
-            ->method('getRequest')
-            ->will($this->returnValue($requestMock));
-        $templateContextMock->expects($this->any())
-            ->method('getScopeConfig')
-            ->will($this->returnValue($scopeConfigMock));
-        $templateContextMock->expects($this->any())
-            ->method('getCacheState')
-            ->will($this->returnValue($cacheStateMock));
-        $templateContextMock->expects($this->any())
-            ->method('getEventManager')
-            ->will($this->returnValue($eventManagerMock));
-        $templateContextMock->expects($this->any())
-            ->method('getUrlBuilder')
-            ->will($this->returnValue($urlBuilderMock));
-        $templateContextMock->expects($this->any())
-            ->method('getStoreManager')
-            ->will($this->returnValue($storeManagerMock));
-        $storeManagerMock->expects($this->any())
-            ->method('getStore')
-            ->will($this->returnValue($this->storeMock));
-        $this->storeMock->expects($this->any())
-            ->method('getId')
-            ->will($this->returnValue(0));
-
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $objectManager->getObject(
-            'Magento\Rss\Block\Catalog\Special',
-            [
-                'context' => $templateContextMock,
-                'catalogData' => $this->catalogHelperMock,
-                'priceCurrency' => $this->priceCurrencyMock,
-                'productFactory' => $this->productFactoryMock,
-                'rssFactory' => $this->rssFactoryMock,
-                'resourceIterator' => $this->resourceIteratorMock,
-                'imageHelper' => $this->imageHelperMock,
-            ]
-        );
-    }
-
-    /**
-     * Test for method _toHtml
-     *
-     * @return void
-     */
-    public function testToHtml()
-    {
-        $productMock = $this->getMock(
-            'Magento\Catalog\Model\Product',
-            ['getProductUrl', 'getDescription', 'getAllowedPriceInRss', 'getName', '__wakeup', 'getResourceCollection'],
-            [],
-            '',
-            false
-        );
-        $productCollectionMock = $this->getMock(
-            'Magento\Catalog\Model\Resource\Product\CollectionFactory',
-            ['addPriceDataFieldFilter', 'addPriceData', 'addAttributeToSelect', 'addAttributeToSort', 'getSelect'],
-            [],
-            '',
-            false
-        );
-        $rssObjMock = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
-        $productUrl = '<a href="http://product.url">Product Url</a>';
-        $imgThumbSrc = 'http://source-for-thumbnail';
-        $productTitle = 'Product title';
-        $basePriceFormatted = '<span class="price">$10.00</span>';
-        $finalPriceFormatted = '<span class="price">$20.00</span>';
-        $productDescription = '<table><tr>' .
-            '<td><a href="' . $productUrl . '"><img src="' . $imgThumbSrc .
-            '" alt="" border="0" align="left" height="75" width="75" /></a></td>' .
-            '<td style="text-decoration:none;"><p>Price: ' . $basePriceFormatted . ' Special Price: ' .
-            $finalPriceFormatted . '</p></td></tr></table>';
-        $expectedData = [
-            'title' => $productTitle,
-            'link' => $productUrl,
-            'description' => $productDescription
-        ];
-        $expectedResult = new \Magento\Framework\Object(['rss_feed' => '<xml>Feed of the rss</xml>']);
-
-        $this->addMocks();
-        $this->productFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($productMock));
-        $productMock->expects($this->once())
-            ->method('getResourceCollection')
-            ->will($this->returnValue($productCollectionMock));
-        $productCollectionMock->expects($this->once())
-            ->method('addPriceDataFieldFilter')
-            ->will($this->returnSelf());
-        $productCollectionMock->expects($this->once())
-            ->method('addPriceData')
-            ->will($this->returnSelf());
-        $productCollectionMock->expects($this->once())
-            ->method('addAttributeToSelect')
-            ->will($this->returnSelf());
-        $productCollectionMock->expects($this->once())
-            ->method('addAttributeToSort')
-            ->will($this->returnSelf());
-        $this->rssFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($rssObjMock));
-        $productMock->expects($this->exactly(2))
-            ->method('getProductUrl')
-            ->will($this->returnValue($productUrl));
-        $this->imageHelperMock->expects($this->once())
-            ->method('resize')
-            ->will($this->returnValue($imgThumbSrc));
-        $productMock->expects($this->any())
-            ->method('getAllowedPriceInRss')
-            ->will($this->returnValue(true));
-        $productMock->expects($this->once())
-            ->method('getName')
-            ->will($this->returnValue($productTitle));
-        $this->priceCurrencyMock->expects($this->exactly(2))
-            ->method('convertAndFormat')
-            ->will($this->returnValueMap(
-                [
-                    [10, true, PriceCurrencyInterface::DEFAULT_PRECISION, null, null, $basePriceFormatted],
-                    [20, true, PriceCurrencyInterface::DEFAULT_PRECISION, null, null, $finalPriceFormatted],
-                ]
-            )
-        );
-        $rssObjMock->expects($this->once())
-            ->method('_addEntry')
-            ->with($expectedData)
-            ->will($this->returnSelf());
-        $rssObjMock->expects($this->once())
-            ->method('createRssXml')
-            ->will($this->returnValue($expectedResult));
-        $this->assertEquals($expectedResult, $this->block->toHtml());
-    }
-
-    /**
-     * Additional function to break up mocks initialization
-     *
-     * @return void
-     */
-    protected function addMocks()
-    {
-
-        $resIteratorcallback = function () {
-            $arguments = func_get_args();
-            $arguments[2]['results'] = [
-                ['use_special' => false, 'price' => 10, 'final_price' => 20]
-            ];
-        };
-
-        $this->storeMock->expects($this->once())
-            ->method('getWebsiteId')
-            ->will($this->returnValue(0));
-        $this->storeMock->expects($this->once())
-            ->method('getFrontendName')
-            ->will($this->returnValue('store name'));
-
-        $this->catalogHelperMock->expects($this->once())
-            ->method('canApplyMsrp')
-            ->will($this->returnValue(false));
-        $this->resourceIteratorMock->expects($this->once())
-            ->method('walk')
-            ->will($this->returnCallback($resIteratorcallback));
-        $this->imageHelperMock->expects($this->once())
-            ->method('init')
-            ->will($this->returnSelf());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/FeedsTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/FeedsTest.php
new file mode 100644
index 00000000000..edf5fd48639
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Rss/Block/FeedsTest.php
@@ -0,0 +1,87 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Block;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class FeedsTest
+ * @package Magento\Rss\Block
+ */
+class FeedsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Rss\Block\Feeds
+     */
+    protected $block;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Rss\RssManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssManagerInterface;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->rssManagerInterface = $this->getMock('Magento\Framework\App\Rss\RssManagerInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Rss\Block\Feeds',
+            [
+                'context' => $this->context,
+                'rssManager' => $this->rssManagerInterface
+            ]
+        );
+    }
+
+    public function testGetFeeds()
+    {
+        $provider1 = $this->getMock('\Magento\Framework\App\Rss\DataProviderInterface');
+        $provider2 = $this->getMock('\Magento\Framework\App\Rss\DataProviderInterface');
+        $feed1 = array(
+            'group' => 'Some Group',
+            'feeds' => array(
+                array('link' => 'feed 1 link', 'label' => 'Feed 1 Label')
+            )
+        );
+        $feed2 = array('link' => 'feed 2 link', 'label' => 'Feed 2 Label');
+        $provider1->expects($this->once())->method('getFeeds')->will($this->returnValue($feed1));
+        $provider2->expects($this->once())->method('getFeeds')->will($this->returnValue($feed2));
+        $this->rssManagerInterface->expects($this->once())->method('getProviders')
+            ->will($this->returnValue(array($provider1, $provider2)));
+
+        $this->assertEquals(array($feed2, $feed1), $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Block/Order/Info/Buttons/RssTest.php b/dev/tests/unit/testsuite/Magento/Rss/Block/Order/Info/Buttons/RssTest.php
deleted file mode 100644
index 30cb284ac86..00000000000
--- a/dev/tests/unit/testsuite/Magento/Rss/Block/Order/Info/Buttons/RssTest.php
+++ /dev/null
@@ -1,75 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Rss\Block\Order\Info\Buttons;
-
-use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
-
-class RssTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var \Magento\Rss\Block\Order\Info\Buttons\Rss */
-    protected $rss;
-
-    /** @var ObjectManagerHelper */
-    protected $objectManagerHelper;
-
-    /** @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
-    protected $context;
-
-    /** @var \Magento\Framework\Registry */
-    protected $registry;
-
-    /** @var \Magento\Rss\Helper\Order|\PHPUnit_Framework_MockObject_MockObject */
-    protected $rssOrderHelper;
-
-    protected function setUp()
-    {
-        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
-        $this->rssOrderHelper = $this->getMock('Magento\Rss\Helper\Order', [], [], '', false);
-        $this->objectManagerHelper = new ObjectManagerHelper($this);
-        $this->registry = $this->objectManagerHelper->getObject('Magento\Framework\Registry');
-
-        $this->rss = $this->objectManagerHelper->getObject(
-            'Magento\Rss\Block\Order\Info\Buttons\Rss',
-            [
-                'context' => $this->context,
-                'registry' => $this->registry,
-                'orderHelper' => $this->rssOrderHelper
-            ]
-        );
-    }
-
-    public function testGetOrder()
-    {
-        $currentOrder = $this->getMock('Magento\Sales\Model\Order', [], [], '', false);
-        $this->registry->register('current_order', $currentOrder);
-        $this->assertEquals($currentOrder, $this->rss->getOrder());
-    }
-
-    public function testGetOrderHelper()
-    {
-        $orderHelper = $this->rss->getOrderHelper();
-        $this->assertEquals($this->rssOrderHelper, $orderHelper);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Controller/Adminhtml/Feed/IndexTest.php b/dev/tests/unit/testsuite/Magento/Rss/Controller/Adminhtml/Feed/IndexTest.php
new file mode 100644
index 00000000000..6e94d8bcd69
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Rss/Controller/Adminhtml/Feed/IndexTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Adminhtml\Feed;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class IndexTest
+ * @package Magento\Rss\Controller\Feed
+ */
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Rss\Controller\Feed\Index
+     */
+    protected $controller;
+
+    /**
+     * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Rss\Model\RssManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
+    protected function setUp()
+    {
+        $this->rssManager = $this->getMock('Magento\Rss\Model\RssManager', ['getProvider'], [], '', false);
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->rssFactory = $this->getMock('Magento\Rss\Model\RssFactory', ['create'], [], '', false);
+
+        $request = $this->getMock('Magento\Framework\App\RequestInterface');
+        $request->expects($this->once())->method('getParam')->with('type')->will($this->returnValue('rss_feed'));
+
+        $this->response = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')
+            ->setMethods(['setHeader', 'setBody', 'sendResponse'])
+            ->disableOriginalConstructor()->getMock();
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->controller = $objectManagerHelper->getObject(
+            'Magento\Rss\Controller\Feed\Index',
+            [
+                'rssManager' => $this->rssManager,
+                'scopeConfig' => $this->scopeConfigInterface,
+                'rssFactory' => $this->rssFactory,
+                'request' => $request,
+                'response' => $this->response
+            ]
+        );
+    }
+
+    public function testExecute()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')->will($this->returnValue(true));
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
+
+        $rssModel = $this->getMock('Magento\Rss\Model\Rss', ['setDataProvider', 'createRssXml'], [], '', false);
+        $rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
+        $rssModel->expects($this->once())->method('createRssXml')->will($this->returnValue(''));
+
+        $this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
+        $this->response->expects($this->once())->method('setBody')->will($this->returnSelf());
+
+        $this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
+
+        $this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
+        $this->controller->execute();
+    }
+
+    public function testExecuteWithException()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')->will($this->returnValue(true));
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
+
+        $rssModel = $this->getMock('Magento\Rss\Model\Rss', ['setDataProvider'], [], '', false);
+        $rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
+
+        $this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
+        $this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
+        $this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
+
+        $this->setExpectedException('\Zend_Feed_Builder_Exception');
+        $this->controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Controller/Feed/IndexTest.php b/dev/tests/unit/testsuite/Magento/Rss/Controller/Feed/IndexTest.php
new file mode 100644
index 00000000000..ca27de6c0c3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Rss/Controller/Feed/IndexTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Feed;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class IndexTest
+ * @package Magento\Rss\Controller\Feed
+ */
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Rss\Controller\Feed\Index
+     */
+    protected $controller;
+
+    /**
+     * @var \Magento\Rss\Model\RssManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssManager;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
+    protected function setUp()
+    {
+        $this->rssManager = $this->getMock('Magento\Rss\Model\RssManager', ['getProvider'], [], '', false);
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->rssFactory = $this->getMock('Magento\Rss\Model\RssFactory', ['create'], [], '', false);
+
+        $request = $this->getMock('Magento\Framework\App\RequestInterface');
+        $request->expects($this->once())->method('getParam')->with('type')->will($this->returnValue('rss_feed'));
+
+        $this->response = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')
+            ->setMethods(['setHeader', 'setBody', 'sendResponse'])
+            ->disableOriginalConstructor()->getMock();
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->controller = $objectManagerHelper->getObject(
+            'Magento\Rss\Controller\Feed\Index',
+            [
+                'rssManager' => $this->rssManager,
+                'scopeConfig' => $this->scopeConfigInterface,
+                'rssFactory' => $this->rssFactory,
+                'request' => $request,
+                'response' => $this->response
+            ]
+        );
+    }
+
+    public function testExecute()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')->will($this->returnValue(true));
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
+
+        $rssModel = $this->getMock('Magento\Rss\Model\Rss', ['setDataProvider', 'createRssXml'], [], '', false);
+        $rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
+        $rssModel->expects($this->once())->method('createRssXml')->will($this->returnValue(''));
+
+        $this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
+        $this->response->expects($this->once())->method('setBody')->will($this->returnSelf());
+
+        $this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
+
+        $this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
+        $this->controller->execute();
+    }
+
+    public function testExecuteWithException()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')->will($this->returnValue(true));
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
+
+        $rssModel = $this->getMock('Magento\Rss\Model\Rss', ['setDataProvider'], [], '', false);
+        $rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
+
+        $this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
+        $this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
+        $this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
+
+        $this->setExpectedException('\Zend_Feed_Builder_Exception');
+        $this->controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Model/RssManagerTest.php b/dev/tests/unit/testsuite/Magento/Rss/Model/RssManagerTest.php
new file mode 100644
index 00000000000..635ae919217
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Rss/Model/RssManagerTest.php
@@ -0,0 +1,80 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Rss\Model;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class RssManagerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Rss\Model\RssManager
+     */
+    protected $rssManager;
+
+    /**
+     * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = $this->getMock('Magento\Framework\ObjectManager');
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->rssManager = $objectManagerHelper->getObject(
+            'Magento\Rss\Model\RssManager',
+            [
+                'objectManager' => $this->objectManager,
+                'dataProviders' => array(
+                    'rss_feed' => 'Magento\Framework\App\Rss\DataProviderInterface',
+                    'bad_rss_feed' => 'Some\Class\Not\Existent',
+                )
+            ]
+        );
+    }
+
+    public function testGetProvider()
+    {
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $this->objectManager->expects($this->once())->method('get')->will($this->returnValue($dataProvider));
+
+        $this->assertInstanceOf(
+             '\Magento\Framework\App\Rss\DataProviderInterface',
+             $this->rssManager->getProvider('rss_feed')
+        );
+    }
+
+    public function testGetProviderFirstException()
+    {
+        $this->setExpectedException('InvalidArgumentException');
+        $this->rssManager->getProvider('wrong_rss_feed');
+    }
+
+    public function testGetProviderSecondException()
+    {
+        $this->setExpectedException('InvalidArgumentException');
+        $this->rssManager->getProvider('bad_rss_feed');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Model/RssTest.php b/dev/tests/unit/testsuite/Magento/Rss/Model/RssTest.php
index a3c33b42eb1..1aff699ccaa 100644
--- a/dev/tests/unit/testsuite/Magento/Rss/Model/RssTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rss/Model/RssTest.php
@@ -21,35 +21,104 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Rss\Model;
 
-use Magento\TestFramework\Helper\ObjectManager;
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
 
 class RssTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Rss\Model\Rss
      */
-    private $model;
+    protected $rss;
+
+    /**
+     * @var array
+     */
+    protected $feedData = array(
+        'title' => 'Feed Title',
+        'link' => 'http://magento.com/rss/link',
+        'description' => 'Feed Description',
+        'charset' => 'UTF-8',
+        'entries' => array(
+            array(
+                'title' => 'Feed 1 Title',
+                'link' => 'http://magento.com/rss/link/id/1',
+                'description' => 'Feed 1 Description'
+            )
+        )
+    );
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheInterface;
 
     protected function setUp()
     {
-        $helper = new ObjectManager($this);
+        $this->cacheInterface = $this->getMock('Magento\Framework\App\CacheInterface');
 
-        $this->model = $helper->getObject('Magento\Rss\Model\Rss');
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->rss = $this->objectManagerHelper->getObject(
+            'Magento\Rss\Model\Rss',
+            [
+                'cache' => $this->cacheInterface
+            ]
+        );
     }
 
-    public function testCreateRssXml()
+    public function testGetFeeds()
     {
-        $this->model->_addHeader(['title' => 'someTitle', 'link' => 'someLink', 'charset' => 'utf8']);
-        $result = $this->model->createRssXml();
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->any())->method('getCacheKey')->will($this->returnValue('cache_key'));
+        $dataProvider->expects($this->any())->method('getCacheLifetime')->will($this->returnValue(100));
+        $dataProvider->expects($this->any())->method('getRssData')->will($this->returnValue($this->feedData));
 
-        $this->assertContains('<?xml version="1.0" encoding="utf8"?>', $result);
+        $this->rss->setDataProvider($dataProvider);
+
+        $this->cacheInterface->expects($this->once())->method('load')->will($this->returnValue(false));
+        $this->cacheInterface->expects($this->once())->method('save')->will($this->returnValue(true));
+
+        $this->assertEquals($this->feedData, $this->rss->getFeeds());
+    }
+
+    public function testGetFeedsWithCache()
+    {
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->any())->method('getCacheKey')->will($this->returnValue('cache_key'));
+        $dataProvider->expects($this->any())->method('getCacheLifetime')->will($this->returnValue(100));
+        $dataProvider->expects($this->never())->method('getRssData');
+
+        $this->rss->setDataProvider($dataProvider);
+
+        $this->cacheInterface->expects($this->once())->method('load')
+            ->will($this->returnValue(serialize($this->feedData)));
+        $this->cacheInterface->expects($this->never())->method('save');
+
+        $this->assertEquals($this->feedData, $this->rss->getFeeds());
     }
 
-    public function testCreateRssXmlError()
+    public function testCreateRssXml()
     {
-        $this->model->_addHeader(['test']);
-        $this->assertEquals('Error in processing xml. title key is missing', $this->model->createRssXml());
+        $dataProvider = $this->getMock('Magento\Framework\App\Rss\DataProviderInterface');
+        $dataProvider->expects($this->any())->method('getCacheKey')->will($this->returnValue('cache_key'));
+        $dataProvider->expects($this->any())->method('getCacheLifetime')->will($this->returnValue(100));
+        $dataProvider->expects($this->any())->method('getRssData')->will($this->returnValue($this->feedData));
+
+        $this->rss->setDataProvider($dataProvider);
+        $result = $this->rss->createRssXml();
+        $this->assertContains('<?xml version="1.0" encoding="UTF-8"?>', $result);
+        $this->assertContains('<title><![CDATA[Feed Title]]></title>', $result);
+        $this->assertContains('<title><![CDATA[Feed 1 Title]]></title>', $result);
+        $this->assertContains('<link>http://magento.com/rss/link</link>', $result);
+        $this->assertContains('<link>http://magento.com/rss/link/id/1</link>', $result);
+        $this->assertContains('<description><![CDATA[Feed Description]]></description>', $result);
+        $this->assertContains('<description><![CDATA[Feed 1 Description]]></description>', $result);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Rss/Model/UrlBuilderTest.php b/dev/tests/unit/testsuite/Magento/Rss/Model/UrlBuilderTest.php
new file mode 100644
index 00000000000..62c2d117f30
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Rss/Model/UrlBuilderTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Rss\Model;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class UrlBuilderTest
+ * @package Magento\Rss\Model
+ */
+class UrlBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Rss\Model\UrlBuilder
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlInterface;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    protected function setUp()
+    {
+        $this->urlInterface = $this->getMock('Magento\Framework\UrlInterface');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->urlBuilder = $objectManagerHelper->getObject(
+            'Magento\Rss\Model\UrlBuilder',
+            [
+                'urlBuilder' => $this->urlInterface,
+                'scopeConfig' => $this->scopeConfigInterface
+            ]
+        );
+    }
+
+    public function testGetUrlEmpty()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')
+            ->with('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(false));
+        $this->assertEquals('', $this->urlBuilder->getUrl());
+    }
+
+    public function testGetUrl()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')
+            ->with('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->urlInterface->expects($this->once())->method('getUrl')
+            ->with('rss/feed/index', array('type' => 'rss_feed'))
+            ->will($this->returnValue('http://magento.com/rss/feed/index/type/rss_feed'));
+        $this->assertEquals(
+            'http://magento.com/rss/feed/index/type/rss_feed',
+            $this->urlBuilder->getUrl(array('type' => 'rss_feed')));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
index 48e2691a5d5..117996721b1 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
@@ -29,35 +29,69 @@ namespace Magento\Sales\Block\Adminhtml\Order\Totals;
 
 class TaxTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * Test method for getFullTaxInfo
-     *
-     * @param \Magento\Sales\Model\Order $source
-     * @param array $getCalculatedTax
-     * @param array $expectedResult
-     *
-     * @dataProvider getFullTaxInfoDataProvider
-     */
-    public function testGetFullTaxInfo($source, $getCalculatedTax, $expectedResult)
+
+    /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Block\Adminhtml\Order\Totals\Tax */
+    private $taxMock;
+
+    public function setUp()
     {
+        $getCalculatedTax = [
+            'tax' => 'tax',
+            'shipping_tax' => 'shipping_tax'
+        ];
         $taxHelperMock = $this->getMockBuilder('Magento\Tax\Helper\Data')
-            ->setMethods(array('getCalculatedTaxes'))
+            ->setMethods(['getCalculatedTaxes'])
             ->disableOriginalConstructor()
             ->getMock();
         $taxHelperMock->expects($this->any())
             ->method('getCalculatedTaxes')
             ->will($this->returnValue($getCalculatedTax));
 
-        $mockObject = $this->getMockBuilder('Magento\Sales\Block\Adminhtml\Order\Totals\Tax')
+        $this->taxMock = $this->getMockBuilder('Magento\Sales\Block\Adminhtml\Order\Totals\Tax')
             ->setConstructorArgs($this->_getConstructArguments($taxHelperMock))
-            ->setMethods(array('getOrder'))
+            ->setMethods(['getOrder', 'getSource'])
             ->getMock();
-        $mockObject->expects($this->once())
+
+    }
+    
+    /**
+     * Test method for getFullTaxInfo
+     *
+     * @param \Magento\Sales\Model\Order $source
+     * @param array $getCalculatedTax
+     * @param array $getShippingTax
+     * @param array $expectedResult
+     *
+     * @dataProvider getFullTaxInfoDataProvider
+     */
+    public function testGetFullTaxInfo($source, $expectedResult)
+    {
+        $this->taxMock->expects($this->once())
             ->method('getOrder')
             ->will($this->returnValue($source));
 
-        $actualResult = $mockObject->getFullTaxInfo();
-        $this->assertEquals($expectedResult, $actualResult);
+        $actualResult = $this->taxMock->getFullTaxInfo();
+        $this->assertSame($expectedResult, $actualResult);
+    }
+
+    /**
+     * Test method for getFullTaxInfo with invoice or creditmemo
+     *
+     * @param \Magento\Sales\Model\Order\Invoice|\Magento\Sales\Model\Order\Creditmemo $source
+     * @param array $expectedResult
+     *
+     * @dataProvider getCreditAndInvoiceFullTaxInfoDataProvider
+     */
+    public function testGetFullTaxInfoWithCreditAndInvoice(
+        $source,
+        $expectedResult
+    ) {
+        $this->taxMock->expects($this->once())
+            ->method('getSource')
+            ->will($this->returnValue($source));
+
+        $actualResult = $this->taxMock->getFullTaxInfo();
+        $this->assertSame($expectedResult, $actualResult);
     }
 
     /**
@@ -71,7 +105,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
         return $objectManagerHelper->getConstructArguments(
             'Magento\Sales\Block\Adminhtml\Order\Totals\Tax',
-            array('taxHelper' => $taxHelperMock)
+            ['taxHelper' => $taxHelperMock]
         );
     }
 
@@ -84,23 +118,50 @@ class TaxTest extends \PHPUnit_Framework_TestCase
      */
     public function getFullTaxInfoDataProvider()
     {
-        $notAnInstanceOfASalesModelOrder = $this->getMock('stdClass');
-
         $salesModelOrderMock = $this->getMockBuilder('Magento\Sales\Model\Order')
             ->disableOriginalConstructor()
             ->getMock();
-
-        $getCalculatedTax = array(
-            'tax' => 'tax',
-            'shipping_tax' => 'shipping_tax'
-        );
-
-        return array(
+        return [
             'source is not an instance of \Magento\Sales\Model\Order' =>
-                array($notAnInstanceOfASalesModelOrder, $getCalculatedTax, array()),
+                [null, []],
             'source is an instance of \Magento\Sales\Model\Order and has reasonable data' =>
-                array($salesModelOrderMock, $getCalculatedTax, array('tax' => 'tax',
-                'shipping_tax' => 'shipping_tax'))
-        );
+                [
+                    $salesModelOrderMock,
+                    [
+                        'tax' => 'tax',
+                        'shipping_tax' => 'shipping_tax',
+                    ]
+                ]
+        ];
+    }
+
+    /**
+     * Data provider.
+     * 1st Case : $current an instance of \Magento\Sales\Model\Invoice
+     * 2nd Case : $current an instance of \Magento\Sales\Model\Creditmemo
+     *
+     * @return array
+     */
+    public function getCreditAndInvoiceFullTaxInfoDataProvider()
+    {
+        $invoiceMock = $this->getMockBuilder('Magento\Sales\Model\Order\Invoice')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup'])
+            ->getMock();
+        $creditMemoMock = $this->getMockBuilder('Magento\Sales\Model\Order\Creditmemo')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup'])
+            ->getMock();
+
+        $expected = [
+            'tax' => 'tax',
+            'shipping_tax' => 'shipping_tax',
+        ];
+        return [
+            'invoice' =>
+                [$invoiceMock, $expected],
+            'creditMemo' =>
+                [$creditMemoMock, $expected]
+        ];
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/LinkTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/LinkTest.php
new file mode 100644
index 00000000000..487d603115f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Rss/Order/Grid/LinkTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Block\Adminhtml\Rss\Order\Grid;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class LinkTest
+ * @package Magento\Sales\Block\Adminhtml\Rss\Order\Grid
+ */
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Block\Adminhtml\Rss\Order\Grid\Link
+     */
+    protected $link;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->link = $this->objectManagerHelper->getObject(
+            'Magento\Sales\Block\Adminhtml\Rss\Order\Grid\Link',
+            [
+                'context' => $this->context,
+                'rssUrlBuilder' => $this->urlBuilderInterface,
+                'scopeConfig' => $this->scopeConfigInterface
+            ]
+        );
+    }
+
+    public function testGetLink()
+    {
+        $link = 'http://magento.com/backend/rss/feed/index/type/new_order';
+        $this->urlBuilderInterface->expects($this->once())->method('getUrl')
+            ->with(array('type' => 'new_order'))
+            ->will($this->returnValue($link));
+        $this->assertEquals($link, $this->link->getLink());
+    }
+
+    public function testGetLabel()
+    {
+        $this->assertEquals('New Order RSS', $this->link->getLabel());
+    }
+
+    public function testIsRssAllowed()
+    {
+        $this->assertTrue($this->link->isRssAllowed());
+    }
+
+    public function getFeeds()
+    {
+        $this->assertEmpty($this->link->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Order/HistoryTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Order/HistoryTest.php
index 9c5fcf93f17..3f1e7bba0ae 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Block/Order/HistoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Order/HistoryTest.php
@@ -67,7 +67,7 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
         $this->orderConfig = $this->getMockBuilder('Magento\Sales\Model\Order\Config')
             ->setMethods(['getVisibleOnFrontStatuses'])->disableOriginalConstructor()->getMock();
 
-        $this->pageConfig = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+        $this->pageConfig = $this->getMockBuilder('Magento\Framework\View\Page\Config')->setMethods(['setTitle'])
             ->disableOriginalConstructor()->getMock();
     }
 
@@ -93,6 +93,14 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
             false,
             false
         );
+        $this->pageConfig->expects($this->any())
+            ->method('setTitle')
+            ->will($this->returnSelf());
+
+        $this->context->expects($this->any())
+            ->method('getPageConfig')
+            ->will($this->returnValue($this->pageConfig));
+
         $orderCollection->expects($this->at(0))
             ->method('addFieldToSelect')
             ->with($this->equalTo('*'))
@@ -118,7 +126,6 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
             $this->orderCollectionFactory,
             $this->customerSession,
             $this->orderConfig,
-            $this->pageConfig,
             $data
         );
         $this->assertEquals($orderCollection, $this->model->getOrders());
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Order/Info/Buttons/RssTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Order/Info/Buttons/RssTest.php
new file mode 100644
index 00000000000..76bc50778cf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Order/Info/Buttons/RssTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Block\Order\Info\Buttons;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class RssTest
+ * @package Magento\Sales\Block\Order\Info\Buttons
+ */
+class RssTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Block\Order\Info\Buttons\Rss
+     */
+    protected $rss;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->orderFactory = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $request = $this->getMock('Magento\Framework\App\RequestInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->rss = $this->objectManagerHelper->getObject(
+            'Magento\Sales\Block\Order\Info\Buttons\Rss',
+            [
+                'request' => $request,
+                'orderFactory' => $this->orderFactory,
+                'rssUrlBuilder' => $this->urlBuilderInterface,
+                'scopeConfig' => $this->scopeConfigInterface
+            ]
+        );
+    }
+
+    public function testGetLink()
+    {
+        $order = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->setMethods(array('getId', 'getCustomerId', 'getIncrementId', 'load', '__wakeup', '__sleep'))
+            ->disableOriginalConstructor()
+            ->getMock();
+        $order->expects($this->once())->method('load')->will($this->returnSelf());
+        $order->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $order->expects($this->once())->method('getCustomerId')->will($this->returnValue(1));
+        $order->expects($this->once())->method('getIncrementId')->will($this->returnValue('100000001'));
+
+        $this->orderFactory->expects($this->once())->method('create')->will($this->returnValue($order));
+
+        $data = base64_encode(json_encode(array('order_id' => 1, 'increment_id' => '100000001', 'customer_id' => 1, )));
+        $link = 'http://magento.com/rss/feed/index/type/order_status?data=' . $data;
+        $this->urlBuilderInterface->expects($this->once())->method('getUrl')
+            ->with(array(
+                'type' => 'order_status',
+                '_secure' => true,
+                '_query' => array('data' => $data)
+            ))->will($this->returnValue($link));
+        $this->assertEquals($link, $this->rss->getLink());
+    }
+
+    public function testGetLabel()
+    {
+        $this->assertEquals('Subscribe to Order Status', $this->rss->getLabel());
+    }
+
+    public function testIsRssAllowed()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('isSetFlag')
+            ->with('rss/order/status', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertTrue($this->rss->isRssAllowed());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/EmailTest.php b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/EmailTest.php
new file mode 100644
index 00000000000..615f58e1c67
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/EmailTest.php
@@ -0,0 +1,228 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\App\Action\Context;
+
+/**
+ * Class EmailTest
+ *
+ * @package Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice
+ */
+class EmailTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Email
+     */
+    protected $invoiceEmail;
+
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
+    /**
+     * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\ObjectManager\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $session;
+
+    /**
+     * @var \Magento\Framework\App\ActionFlag|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $actionFlag;
+
+    /**
+     * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $helper;
+
+    public function setUp()
+    {
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->context = $this->getMock('Magento\Backend\App\Action\Context', [], [], '', false);
+        $this->response = $this->getMock(
+            'Magento\Framework\App\ResponseInterface',
+            ['setRedirect', 'sendResponse'],
+            [],
+            '',
+            false
+        );
+        $this->request = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
+        $this->objectManager = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $this->messageManager = $this->getMock('Magento\Framework\Message\Manager', [], [], '', false);
+        $this->session = $this->getMock('Magento\Backend\Model\Session', ['setIsUrlNotice'], [], '', false);
+        $this->actionFlag = $this->getMock('Magento\Framework\App\ActionFlag', [], [], '', false);
+        $this->helper = $this->getMock('\Magento\Backend\Helper\Data', [], [], '', false);
+        $this->context->expects($this->once())
+            ->method('getMessageManager')
+            ->willReturn($this->messageManager);
+        $this->context->expects($this->once())
+            ->method('getRequest')
+            ->willReturn($this->request);
+        $this->context->expects($this->once())
+            ->method('getResponse')
+            ->willReturn($this->response);
+        $this->context->expects($this->once())
+            ->method('getObjectManager')
+            ->willReturn($this->objectManager);
+        $this->context->expects($this->once())
+            ->method('getSession')
+            ->willReturn($this->session);
+        $this->context->expects($this->once())
+            ->method('getActionFlag')
+            ->willReturn($this->actionFlag);
+        $this->context->expects($this->once())
+            ->method('getHelper')
+            ->willReturn($this->helper);
+        $this->invoiceEmail = $objectManagerHelper->getObject(
+            'Magento\Sales\Controller\Adminhtml\Order\Invoice\Email',
+            [
+                'context' => $this->context,
+                'request' => $this->request,
+                'response' => $this->response
+            ]
+        );
+    }
+
+    public function testEmail()
+    {
+        $invoiceId = 10000031;
+        $orderId = 100000030;
+        $invoiceClassName = 'Magento\Sales\Model\Order\Invoice';
+        $cmNotifierClassName = 'Magento\Sales\Model\Order\InvoiceNotifier';
+        $invoice = $this->getMock($invoiceClassName, [], [], '', false);
+        $notifier = $this->getMock($cmNotifierClassName, [], [], '', false);
+        $order = $this->getMock('Magento\Sales\Model\Order', [], [], '', false);
+        $order->expects($this->once())
+            ->method('getId')
+            ->willReturn($orderId);
+
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('invoice_id')
+            ->willReturn($invoiceId);
+        $this->objectManager->expects($this->at(0))
+            ->method('create')
+            ->with($invoiceClassName)
+            ->willReturn($invoice);
+        $invoice->expects($this->once())
+            ->method('load')
+            ->with($invoiceId)
+            ->willReturnSelf();
+        $invoice->expects($this->once())
+            ->method('getOrder')
+            ->willReturn($order);
+        $this->objectManager->expects($this->at(1))
+            ->method('create')
+            ->with($cmNotifierClassName)
+            ->willReturn($notifier);
+        $notifier->expects($this->once())
+            ->method('notify')
+            ->willReturn(true);
+        $this->messageManager->expects($this->once())
+            ->method('addSuccess')
+            ->with('We sent the message.');
+
+        $this->prepareRedirect($invoiceId, $orderId);
+
+        $this->invoiceEmail->execute();
+        $this->assertEquals($this->response, $this->invoiceEmail->getResponse());
+    }
+
+    public function testEmailNoInvoiceId()
+    {
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('invoice_id')
+            ->willReturn(null);
+        $this->assertNull($this->invoiceEmail->execute());
+    }
+
+    public function testEmailNoInvoice()
+    {
+        $invoiceId = 10000031;
+        $invoiceClassName = 'Magento\Sales\Model\Order\Invoice';
+        $invoice = $this->getMock($invoiceClassName, [], [], '', false);
+
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('invoice_id')
+            ->willReturn($invoiceId);
+        $this->objectManager->expects($this->at(0))
+            ->method('create')
+            ->with($invoiceClassName)
+            ->willReturn($invoice);
+        $invoice->expects($this->once())
+            ->method('load')
+            ->with($invoiceId)
+            ->willReturn(null);
+
+        $this->assertNull($this->invoiceEmail->execute());
+    }
+
+    /***
+     * @param $invoiceId
+     * @param $orderId
+     */
+    protected function prepareRedirect($invoiceId, $orderId)
+    {
+        $this->actionFlag->expects($this->once())
+            ->method('get')
+            ->with('', 'check_url_settings')
+            ->willReturn(true);
+        $this->session->expects($this->once())
+            ->method('setIsUrlNotice')
+            ->with(true);
+        $path = 'sales/invoice/view';
+        $this->response->expects($this->once())
+            ->method('setRedirect')
+            ->with($path . '/' . $invoiceId);
+        $this->helper->expects($this->atLeastOnce())
+            ->method('getUrl')
+            ->with($path, ['order_id' => $orderId, 'invoice_id' => $invoiceId])
+            ->willReturn($path . '/' . $invoiceId);
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/NewOrderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/NewOrderTest.php
new file mode 100644
index 00000000000..7c33cc11ac2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/NewOrderTest.php
@@ -0,0 +1,189 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class NewOrderTest
+ * @package Magento\Sales\Model\Rss
+ */
+class NewOrderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Rss\NewOrder
+     */
+    protected $model;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuiler;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneInterface;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dateTime;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManager;
+
+    /**
+     * @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layout;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssUrlBuilderInterface;
+
+    /**
+     * @var array
+     */
+    protected $feedData = array(
+        'title' => 'New Orders',
+        'link' => 'http://magento.com/backend/rss/feed/index/type/new_order',
+        'description' => 'New Orders',
+        'charset' => 'UTF-8',
+        'entries' => array(
+            array(
+                'title' => 'Order #100000001 created at 2014-09-10 17:39:50',
+                'link' => 'http://magento.com/sales/order/view/order_id/1',
+                'description' => 'Order Description'
+            )
+        )
+    );
+
+    protected function setUp()
+    {
+        $this->orderFactory = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
+        $this->urlBuiler = $this->getMock('Magento\Framework\UrlInterface');
+        $this->timezoneInterface = $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $this->dateTime = $this->getMock('Magento\Framework\Stdlib\DateTime');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $this->layout = $this->getMock('Magento\Framework\View\LayoutInterface');
+        $this->rssUrlBuilderInterface = $this->getMockBuilder('Magento\Framework\App\Rss\UrlBuilderInterface')
+            ->setMethods(array('getUrl'))
+            ->disableOriginalConstructor()->getMock();
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->model = $this->objectManagerHelper->getObject(
+            'Magento\Sales\Model\Rss\NewOrder',
+            [
+                'orderFactory' => $this->orderFactory,
+                'urlBuilder' => $this->urlBuiler,
+                'rssUrlBuilder' => $this->rssUrlBuilderInterface,
+                'localeDate' => $this->timezoneInterface,
+                'dateTime' => $this->dateTime,
+                'scopeConfig' => $this->scopeConfigInterface,
+                'eventManager' => $this->eventManager,
+                'layout' => $this->layout
+            ]
+        );
+    }
+
+    public function testIsAllowed()
+    {
+        $this->assertTrue($this->model->isAllowed());
+    }
+
+    public function testGetData()
+    {
+        $this->dateTime->expects($this->once())->method('formatDate')->will($this->returnValue(date('Y-m-d H:i:s')));
+
+        $this->rssUrlBuilderInterface->expects($this->once())->method('getUrl')
+            ->with(array('_secure' => true, '_nosecret' => true, 'type' => 'new_order'))
+            ->will($this->returnValue('http://magento.com/backend/rss/feed/index/type/new_order'));
+
+        $this->timezoneInterface->expects($this->once())->method('formatDate')
+            ->will($this->returnValue('2014-09-10 17:39:50'));
+
+        $order = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->setMethods(['__sleep', '__wakeup', 'getResourceCollection', 'getIncrementId', 'getId', 'getCreatedAt'])
+            ->disableOriginalConstructor()->getMock();
+        $order->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $order->expects($this->once())->method('getIncrementId')->will($this->returnValue('100000001'));
+        $order->expects($this->once())->method('getCreatedAt')->will($this->returnValue(time()));
+
+        $collection = $this->getMockBuilder('\Magento\Sales\Model\Resource\Order\Collection')
+            ->setMethods(['addAttributeToFilter', 'addAttributeToSort', 'getIterator'])
+            ->disableOriginalConstructor()->getMock();
+        $collection->expects($this->once())->method('addAttributeToFilter')->will($this->returnSelf());
+        $collection->expects($this->once())->method('addAttributeToSort')->will($this->returnSelf());
+        $collection->expects($this->once())->method('getIterator')
+            ->will($this->returnValue(new \ArrayIterator([$order])));
+
+        $order->expects($this->once())->method('getResourceCollection')->will($this->returnValue($collection));
+        $this->orderFactory->expects($this->once())->method('create')->will($this->returnValue($order));
+
+        $this->eventManager->expects($this->once())->method('dispatch')->will($this->returnSelf());
+
+        $block = $this->getMock('Magento\Sales\Block\Adminhtml\Order\Details', ['setOrder', 'toHtml'], [], '', false);
+        $block->expects($this->once())->method('setOrder')->with($order)->will($this->returnSelf());
+        $block->expects($this->once())->method('toHtml')->will($this->returnValue('Order Description'));
+
+        $this->layout->expects($this->once())->method('getBlockSingleton')->will($this->returnValue($block));
+        $this->urlBuiler->expects($this->once())->method('getUrl')
+            ->will($this->returnValue('http://magento.com/sales/order/view/order_id/1'));
+        $this->assertEquals($this->feedData, $this->model->getRssData());
+    }
+
+    public function testGetCacheKey()
+    {
+        $this->assertEquals('rss_new_orders_data', $this->model->getCacheKey());
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(60, $this->model->getCacheLifetime());
+    }
+
+    public function getFeeds()
+    {
+        $this->assertEmpty($this->model->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/OrderStatusTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/OrderStatusTest.php
new file mode 100644
index 00000000000..e2e8cabce74
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Rss/OrderStatusTest.php
@@ -0,0 +1,198 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class OrderStatusTest
+ * @package Magento\Sales\Model\Rss
+ */
+class OrderStatusTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Rss\OrderStatus
+     */
+    protected $model;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlInterface;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestInterface;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderStatusFactory;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneInterface;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    /**
+     * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $order;
+    /**
+     * @var array
+     */
+    protected $feedData = array(
+        'title' => 'Order # 100000001 Notification(s)',
+        'link' => 'http://magento.com/sales/order/view/order_id/1',
+        'description' => 'Order # 100000001 Notification(s)',
+        'charset' => 'UTF-8',
+        'entries' => array(
+            array(
+                'title' => 'Details for Order #100000001',
+                'link' => 'http://magento.com/sales/order/view/order_id/1',
+                'description' => '<p>Notified Date: <br/>Comment: Some comment<br/></p>'
+            ),
+            array(
+                'title' => 'Order #100000001 created at ',
+                'link' => 'http://magento.com/sales/order/view/order_id/1',
+                'description' => '<p>Current Status: Pending<br/>Total: 15.00<br/></p>'
+            ),
+        )
+    );
+
+    protected function setUp()
+    {
+        $this->objectManager = $this->getMock('Magento\Framework\ObjectManager');
+        $this->urlInterface = $this->getMock('Magento\Framework\UrlInterface');
+        $this->requestInterface = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->orderStatusFactory = $this->getMockBuilder('Magento\Sales\Model\Resource\Order\Rss\OrderStatusFactory')
+            ->setMethods(array('create'))
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->timezoneInterface = $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $this->orderFactory = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $this->order = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->setMethods([
+                '__sleep',
+                '__wakeup',
+                'getIncrementId',
+                'getId',
+                'getCustomerId',
+                'load',
+                'getStatusLabel',
+                'formatPrice',
+                'getGrandTotal'
+            ])->disableOriginalConstructor()->getMock();
+        $this->order->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->order->expects($this->any())->method('getIncrementId')->will($this->returnValue('100000001'));
+        $this->order->expects($this->any())->method('getCustomerId')->will($this->returnValue(1));
+        $this->order->expects($this->any())->method('getStatusLabel')->will($this->returnValue('Pending'));
+        $this->order->expects($this->any())->method('formatPrice')->will($this->returnValue('15.00'));
+        $this->order->expects($this->any())->method('getGrandTotal')->will($this->returnValue(15));
+        $this->order->expects($this->any())->method('load')->with(1)->will($this->returnSelf());
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->model = $this->objectManagerHelper->getObject(
+            'Magento\Sales\Model\Rss\OrderStatus',
+            [
+                'objectManager' => $this->objectManager,
+                'urlBuilder' => $this->urlInterface,
+                'request' => $this->requestInterface,
+                'orderResourceFactory' => $this->orderStatusFactory,
+                'localeDate' => $this->timezoneInterface,
+                'orderFactory' => $this->orderFactory,
+                'scopeConfig' => $this->scopeConfigInterface
+            ]
+        );
+    }
+    public function testGetData()
+    {
+        $this->orderFactory->expects($this->once())->method('create')->will($this->returnValue($this->order));
+        $this->requestInterface->expects($this->any())->method('getParam')
+            ->with('data')
+            ->will($this->returnValue('eyJvcmRlcl9pZCI6MSwiaW5jcmVtZW50X2lkIjoiMTAwMDAwMDAxIiwiY3VzdG9tZXJfaWQiOjF9'));
+        $resource = $this->getMockBuilder('\Magento\Sales\Model\Resource\Order\Rss\OrderStatus')
+            ->setMethods(['getAllCommentCollection'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $comment = array(
+            'entity_type_code' => 'order',
+            'increment_id' => '100000001',
+            'created_at' => '2014-10-09 18:25:50',
+            'comment' => 'Some comment'
+        );
+        $resource->expects($this->once())->method('getAllCommentCollection')->will($this->returnValue(array($comment)));
+        $this->orderStatusFactory->expects($this->once())->method('create')->will($this->returnValue($resource));
+        $this->urlInterface->expects($this->any())->method('getUrl')
+            ->with('sales/order/view', array('order_id' => 1))
+            ->will($this->returnValue('http://magento.com/sales/order/view/order_id/1'));
+
+        $this->assertEquals($this->feedData, $this->model->getRssData());
+    }
+
+    public function testIsAllowed()
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('getValue')
+            ->with('rss/order/status', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertTrue($this->model->isAllowed());
+    }
+
+    public function testGetCacheKey()
+    {
+        $this->requestInterface->expects($this->any())->method('getParam')
+            ->with('data')
+            ->will($this->returnValue('eyJvcmRlcl9pZCI6MSwiaW5jcmVtZW50X2lkIjoiMTAwMDAwMDAxIiwiY3VzdG9tZXJfaWQiOjF9'));
+        $this->orderFactory->expects($this->once())->method('create')->will($this->returnValue($this->order));
+        $this->assertEquals('rss_order_status_data_' . md5('11000000011'), $this->model->getCacheKey());
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(600, $this->model->getCacheLifetime());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Block/Rss/DiscountsTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Block/Rss/DiscountsTest.php
new file mode 100644
index 00000000000..cf14402d637
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Block/Rss/DiscountsTest.php
@@ -0,0 +1,254 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Block\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class DiscountsTest
+ * @package Magento\SalesRule\Block\Rss
+ */
+class DiscountsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SalesRule\Block\Rss\Discounts
+     */
+    protected $block;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerInterface;
+
+    /**
+     * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeModel;
+
+    /**
+     * @var \Magento\SalesRule\Model\Rss\Discounts|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $discounts;
+
+    /**
+     * @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssBuilderInterface;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderInterface;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestInterface;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigInterface;
+
+    /**
+     * @var \Magento\SalesRule\Model\Rss\Discounts|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $rssModel;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneInterface;
+
+    protected function setUp()
+    {
+        $this->storeManagerInterface = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->requestInterface = $this->getMock('Magento\Framework\App\RequestInterface');
+        $this->rssBuilderInterface = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->urlBuilderInterface = $this->getMock('Magento\Framework\UrlInterface');
+        $this->scopeConfigInterface = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->timezoneInterface = $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $this->discounts = $this->getMock('Magento\SalesRule\Model\Rss\Discounts', [], [], '', false);
+        $this->rssModel = $this->getMock(
+            'Magento\SalesRule\Model\Rss\Discounts',
+            [
+                '__wakeup',
+                'getDiscountCollection'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->storeModel = $this->getMock(
+            'Magento\Store\Model\Store',
+            [
+                '__wakeUp',
+                'getId',
+                'getWebsiteId',
+                'getName'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->storeManagerInterface->expects($this->any())->method('getStore')
+            ->will($this->returnValue($this->storeModel));
+        $this->storeModel->expects($this->any())->method('getId')->will($this->returnValue(1));
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\SalesRule\Block\Rss\Discounts',
+            [
+                'storeManager' => $this->storeManagerInterface,
+                'rssModel' => $this->discounts,
+                'rssUrlBuilder' => $this->rssBuilderInterface,
+                'urlBuilder' => $this->urlBuilderInterface,
+                'request' => $this->requestInterface,
+                'scopeConfig' => $this->scopeConfigInterface,
+                'rssModel' => $this->rssModel,
+                'localeDate' => $this->timezoneInterface
+            ]
+        );
+    }
+
+    public function testGetRssData()
+    {
+        $ruleData = array(
+            'to_date' => '12/12/14',
+            'from_date' => '12/12/14',
+            'coupon_code' => '1234567',
+            'description' => 'Rule Description',
+            'name' => 'Rule Name'
+        );
+        $rssData = array(
+            'title' => 'Store Name - Discounts and Coupons',
+            'description' => 'Store Name - Discounts and Coupons',
+            'link' => 'http://rss.magento.com/discount',
+            'charset' => 'UTF-8',
+            'language' => 'en_US',
+            'entries' =>
+            array(
+                'title' => 'Rule Name',
+                'link' => 'http://rss.magento.com',
+                'description' =>
+                    array(
+                        'description' => 'Rule Description',
+                        'start_date' => '12/12/14',
+                        'end_date' => '12/12/14',
+                        'coupon_code' => '1234567'
+                    )
+            )
+        );
+        $rssUrl = 'http://rss.magento.com/discount';
+        $url = 'http://rss.magento.com';
+
+        $ruleModel =  $this->getMock(
+            'Magento\SalesRule\Model\Rule',
+            [
+                '__wakeup',
+                'getCouponCode',
+                'getToDate',
+                'getFromDate',
+                'getDescription',
+                'getName'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->storeModel->expects($this->once())->method('getWebsiteId')->will($this->returnValue(1));
+        $this->storeModel->expects($this->once())->method('getName')->will($this->returnValue('Store Name'));
+        $this->requestInterface->expects($this->any())->method('getParam')->will($this->returnValue(1));
+        $this->urlBuilderInterface->expects($this->any())->method('getUrl')->will($this->returnValue($url));
+        $this->rssBuilderInterface->expects($this->any())->method('getUrl')->will($this->returnValue($rssUrl));
+        $this->scopeConfigInterface->expects($this->any())->method('getValue')->will($this->returnValue('en_US'));
+        $ruleModel->expects($this->any())->method('getCouponCode')->will($this->returnValue($ruleData['coupon_code']));
+        $ruleModel->expects($this->any())->method('getToDate')->will($this->returnValue($ruleData['to_date']));
+        $ruleModel->expects($this->once())->method('getFromDate')->will($this->returnValue($ruleData['from_date']));
+        $ruleModel->expects($this->once())->method('getDescription')
+            ->will($this->returnValue($ruleData['description']));
+        $ruleModel->expects($this->once())->method('getName')->will($this->returnValue($ruleData['name']));
+        $this->rssModel->expects($this->any())->method('getDiscountCollection')
+            ->will($this->returnValue(array($ruleModel)));
+        $this->timezoneInterface->expects($this->any())->method('formatDate')->will($this->returnValue('12/12/14'));
+
+        $data = $this->block->getRssData();
+
+        $this->assertEquals($rssData['title'], $data['title']);
+        $this->assertEquals($rssData['description'], $data['description']);
+        $this->assertEquals($rssData['link'], $data['link']);
+        $this->assertEquals($rssData['charset'], $data['charset']);
+        $this->assertEquals($rssData['language'], $data['language']);
+        $this->assertEquals($rssData['entries']['title'], $data['entries'][0]['title']);
+        $this->assertEquals($rssData['entries']['link'], $data['entries'][0]['link']);
+        $this->assertContains($rssData['entries']['description']['description'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['start_date'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['end_date'], $data['entries'][0]['description']);
+        $this->assertContains($rssData['entries']['description']['coupon_code'], $data['entries'][0]['description']);
+    }
+
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(0, $this->block->getCacheLifetime());
+    }
+
+    /**
+     * @dataProvider isAllowedDataProvider
+     * @param bool $isAllowed
+     */
+    public function testIsAllowed($isAllowed)
+    {
+        $this->scopeConfigInterface->expects($this->once())->method('isSetFlag')->will($this->returnValue($isAllowed));
+        $this->assertEquals($isAllowed, $this->block->isAllowed());
+    }
+
+    public function isAllowedDataProvider()
+    {
+        return array(
+            array(true),
+            array(false)
+        );
+    }
+
+    public function testGetFeeds()
+    {
+        $feedData = array(
+            'label' => 'Coupons/Discounts',
+            'link' => 'http://rss.magento.com/discount'
+        );
+        $this->rssBuilderInterface->expects($this->any())
+            ->method('getUrl')
+            ->will($this->returnValue($feedData['link']));
+
+        $this->scopeConfigInterface->expects($this->once())->method('isSetFlag')->will($this->returnValue(true));
+        $this->assertEquals($feedData, $this->block->getFeeds());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/Rss/DiscountsTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Rss/DiscountsTest.php
new file mode 100644
index 00000000000..76212ebbf85
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Rss/DiscountsTest.php
@@ -0,0 +1,96 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Model\Rss;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+/**
+ * Class DiscountsTest
+ * @package Magento\SalesRule\Model\Rss
+ */
+class DiscountsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SalesRule\Model\Rss\Discounts
+     */
+    protected $discounts;
+
+    /**
+     * @var ObjectManagerHelper
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dateTime;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactory;
+
+    protected function setUp()
+    {
+        $this->dateTime = $this->getMock('Magento\Framework\Stdlib\DateTime');
+        $this->collectionFactory = $this->getMock(
+            'Magento\SalesRule\Model\Resource\Rule\CollectionFactory',
+            [
+                'create'
+            ]
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->discounts = $this->objectManagerHelper->getObject(
+            'Magento\SalesRule\Model\Rss\Discounts',
+            [
+                'dateTime' => $this->dateTime,
+                'collectionFactory' => $this->collectionFactory
+            ]
+        );
+    }
+
+    public function testGetDiscountCollection()
+    {
+        $ruleCollection = $this->getMock(
+            'Magento\SalesRule\Model\Resource\Rule\Collection',
+            [
+                'addWebsiteGroupDateFilter',
+                'addFieldToFilter',
+                'setOrder',
+                'load'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->dateTime->expects($this->once())->method('now');
+        $this->collectionFactory->expects($this->once())->method('create')->will($this->returnValue($ruleCollection));
+        $ruleCollection->expects($this->once())->method('addWebsiteGroupDateFilter')->will($this->returnSelf());
+        $ruleCollection->expects($this->once())->method('addFieldToFilter')->will($this->returnSelf());
+        $ruleCollection->expects($this->once())->method('setOrder')->will($this->returnSelf());
+        $ruleCollection->expects($this->once())->method('load')->will($this->returnSelf());
+        $this->assertEquals($ruleCollection, $this->discounts->getDiscountCollection(1, 1));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sitemap/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Sitemap/Helper/DataTest.php
new file mode 100644
index 00000000000..1815d026fe0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sitemap/Helper/DataTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Sitemap\Helper;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Store\Model\ScopeInterface;
+
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Sitemap\Helper\Data */
+    protected $data;
+
+    /** @var \Magento\Framework\App\Helper\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $context;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Magento\Framework\App\Helper\Context', [], [], '', false);
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $this->data = (new ObjectManager($this))->getObject(
+            'Magento\Sitemap\Helper\Data',
+            [
+                'context' => $this->context,
+                'scopeConfig' => $this->scopeConfig
+            ]
+        );
+    }
+
+    public function testGetValidPaths()
+    {
+        $this->scopeConfig->expects($this->any())->method('getValue')->will($this->returnValueMap(
+            [
+                [Data::XML_PATH_SITEMAP_VALID_PATHS, ScopeInterface::SCOPE_STORE, null, ['path1']],
+                [Data::XML_PATH_PUBLIC_FILES_VALID_PATHS, ScopeInterface::SCOPE_STORE, null, ['path2']],
+            ]
+        ));
+
+        $this->assertEquals(['path1', 'path2'], $this->data->getValidPaths());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Store/Block/SwitchTest.php b/dev/tests/unit/testsuite/Magento/Store/Block/SwitchTest.php
deleted file mode 100644
index 8ecbdca177c..00000000000
--- a/dev/tests/unit/testsuite/Magento/Store/Block/SwitchTest.php
+++ /dev/null
@@ -1,77 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Store\Block;
-
-class SwitchTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Store\Block\Switcher
-     */
-    protected $_block;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_storeManagerMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_appMock;
-
-    protected function setUp()
-    {
-        $this->_storeManagerMock = $this->getMock('\Magento\Framework\StoreManagerInterface');
-
-        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_block = $helper->getObject(
-            'Magento\Store\Block\Switcher',
-            array('storeManager' => $this->_storeManagerMock)
-        );
-    }
-
-    /**
-     * @dataProvider testIsStoreInUrlDataProvider
-     */
-    public function testIsStoreInUrl($isUseStoreInUrl)
-    {
-        $storeMock = $this->getMock('Magento\Store\Model\Store', array(), array(), '', false);
-
-        $storeMock->expects($this->once())->method('isUseStoreInUrl')->will($this->returnValue($isUseStoreInUrl));
-
-        $this->_storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
-        $this->assertEquals($this->_block->isStoreInUrl(), $isUseStoreInUrl);
-        // check value is cached
-        $this->assertEquals($this->_block->isStoreInUrl(), $isUseStoreInUrl);
-    }
-
-    /**
-     * @see self::testIsStoreInUrlDataProvider()
-     * @return array
-     */
-    public function testIsStoreInUrlDataProvider()
-    {
-        return array(array(true), array(false));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Store/Block/SwitcherTest.php b/dev/tests/unit/testsuite/Magento/Store/Block/SwitcherTest.php
new file mode 100644
index 00000000000..f7d913d55a9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Store/Block/SwitcherTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Store\Block;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class SwitcherTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Store\Block\Switcher */
+    protected $switcher;
+
+    /** @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $context;
+
+    /** @var \Magento\Core\Helper\PostData|\PHPUnit_Framework_MockObject_MockObject */
+    protected $corePostDataHelper;
+
+    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    protected function setUp()
+    {
+        $this->storeManager = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')->getMock();
+        $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+        $this->context->expects($this->any())->method('getStoreManager')->will($this->returnValue($this->storeManager));
+        $this->corePostDataHelper = $this->getMock('Magento\Core\Helper\PostData', [], [], '', false);
+        $this->switcher = (new ObjectManager($this))->getObject(
+            'Magento\Store\Block\Switcher',
+            [
+                'context' => $this->context,
+                'postDataHelper' => $this->corePostDataHelper,
+            ]
+        );
+    }
+
+    public function testGetTargetStorePostData()
+    {
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getCode')->will($this->returnValue('new-store'));
+        $currentStore = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $currentStore->expects($this->any())->method('getCode')->will($this->returnValue('current-store'));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($currentStore));
+        $this->corePostDataHelper->expects($this->any())->method('getPostData')
+            ->with(null, ['___store' => 'new-store', '___from_store' => 'current-store']);
+
+        $this->switcher->getTargetStorePostData($store);
+    }
+
+
+    /**
+     * @dataProvider testIsStoreInUrlDataProvider
+     */
+    public function testIsStoreInUrl($isUseStoreInUrl)
+    {
+        $storeMock = $this->getMock('Magento\Store\Model\Store', array(), array(), '', false);
+
+        $storeMock->expects($this->once())->method('isUseStoreInUrl')->will($this->returnValue($isUseStoreInUrl));
+
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($storeMock));
+        $this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
+        // check value is cached
+        $this->assertEquals($this->switcher->isStoreInUrl(), $isUseStoreInUrl);
+    }
+
+    /**
+     * @see self::testIsStoreInUrlDataProvider()
+     * @return array
+     */
+    public function testIsStoreInUrlDataProvider()
+    {
+        return array(array(true), array(false));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Store/Model/StoreTest.php b/dev/tests/unit/testsuite/Magento/Store/Model/StoreTest.php
index 142a798e971..8406d16184c 100644
--- a/dev/tests/unit/testsuite/Magento/Store/Model/StoreTest.php
+++ b/dev/tests/unit/testsuite/Magento/Store/Model/StoreTest.php
@@ -389,8 +389,18 @@ class StoreTest extends \PHPUnit_Framework_TestCase
             ->method('getValue')
             ->will($this->returnValueMap([
                 ['catalog/price/scope', ScopeInterface::SCOPE_STORE, 'scope_code', $priceScope],
-                ['currency/options/base', \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, null, 'USD'],
-                ['currency/options/base', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, 'scope_code', 'UAH'],
+                [
+                    \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
+                    \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                    null,
+                    'USD'
+                ],
+                [
+                    \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                    'scope_code',
+                    'UAH'
+                ],
             ]));
 
         $currency = $this->getMock('\Magento\Directory\Model\Currency', [], [], '', false);
@@ -422,7 +432,7 @@ class StoreTest extends \PHPUnit_Framework_TestCase
             [1, 'UAH'],
         ];
     }
-    
+
     public function testGetAllowedCurrencies()
     {
         $currencyPath = 'cur/ren/cy/path';
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Tax/Helper/DataTest.php
index 22948240bfc..1fd93e81a1c 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Helper/DataTest.php
@@ -42,19 +42,12 @@ class DataTest extends \PHPUnit_Framework_TestCase
     /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Service\V1\OrderTaxService */
     private $orderTaxService;
 
-    /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Registry */
-    private $coreRegistry;
-
     /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Pricing\PriceCurrencyInterface */
     private $priceCurrency;
 
     public function setUp()
     {
         $objectManager = new ObjectManager($this);
-        $this->coreRegistry = $this->getMockBuilder('\Magento\Framework\Registry')
-            ->disableOriginalConstructor()
-            ->setMethods(['registry'])
-            ->getMock();
 
         $this->orderTaxService = $this->getMockBuilder('\Magento\Tax\Service\V1\OrderTaxService')
             ->disableOriginalConstructor()
@@ -73,7 +66,6 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $this->taxHelper = $objectManager->getObject(
             'Magento\Tax\Helper\Data',
             [
-                'coreRegistry' => $this->coreRegistry,
                 'orderTaxService' => $this->orderTaxService,
                 'priceCurrency' => $this->priceCurrency,
             ]
@@ -188,59 +180,85 @@ class DataTest extends \PHPUnit_Framework_TestCase
         return $data;
     }
 
-    protected function commonTestGetCalculatedTaxesInvoiceCreditmemo($source, $orderTaxDetails, $expectedResults)
-    {
+    /**
+     * @param \Magento\Framework\Object $source
+     * @param string $mockClassName
+     * @param \Magento\Framework\Object $invoiceOrCreditData
+     * @param OrderTaxDetails $orderTaxDetails
+     * @param array $expectedResults
+     */
+    protected function commonTestGetCalculatedTaxesInvoiceCreditmemo(
+        $source,
+        $mockClassName,
+        $invoiceOrCreditData,
+        $orderTaxDetails,
+        $expectedResults
+    ) {
         $this->orderTaxService->expects($this->once())
             ->method('getOrderTaxDetails')
             ->with($source->getId())
             ->will($this->returnValue($orderTaxDetails));
 
-        $orderTaxDetails = $this->taxHelper->getCalculatedTaxes($source);
-        $this->assertEquals($expectedResults, $orderTaxDetails);
+        $invoiceOrCreditMock = $this->getMockBuilder($mockClassName)
+            ->disableOriginalConstructor()
+            ->setMethods(
+                ['getOrder', 'getShippingTaxAmount', 'getBaseShippingTaxAmount', 'getItemsCollection', '__wakeup']
+            )
+            ->getMock();
+        $invoiceOrCreditMock->expects($this->once())
+            ->method('getOrder')
+            ->will($this->returnValue($source));
+        $invoiceOrCreditMock->expects($this->any())
+            ->method('getShippingTaxAmount')
+            ->will($this->returnValue($invoiceOrCreditData->getShippingTaxAmount()));
+        $invoiceOrCreditMock->expects($this->any())
+            ->method('getBaseShippingTaxAmount')
+            ->will($this->returnValue($invoiceOrCreditData->getBaseShippingTaxAmount()));
+
+        $invoiceOrCreditMock->expects($this->any())
+            ->method('getItemsCollection')
+            ->will($this->returnValue($invoiceOrCreditData->getItemsCollection()));
+
+        $result = $this->taxHelper->getCalculatedTaxes($invoiceOrCreditMock);
+        $this->assertEquals($expectedResults, $result);
     }
 
     /**
      * @param \Magento\Framework\Object $source
-     * @param \Magento\Framework\Object $invoice
+     * @param \Magento\Framework\Object $invoiceData
      * @param OrderTaxDetails $orderTaxDetails
      * @param array $expectedResults
-     * @dataProvider testGetCalculatedTaxesInvoiceCreditmemoDataProvider
+     * @dataProvider testGetCalculatedTaxesInvoiceCreditMemoDataProvider
      */
-    public function testGetCalculatedTaxesInvoice($source, $invoice, $orderTaxDetails, $expectedResults)
+    public function testGetCalculatedTaxesInvoice($source, $invoiceData, $orderTaxDetails, $expectedResults)
     {
-        $this->coreRegistry->expects($this->at(0))
-            ->method('registry')
-            ->with('current_invoice')
-            ->will($this->returnValue($invoice));
-        $this->coreRegistry->expects($this->at(1))
-            ->method('registry')
-            ->with('current_invoice')
-            ->will($this->returnValue($invoice));
-        $this->commonTestGetCalculatedTaxesInvoiceCreditmemo($source, $orderTaxDetails, $expectedResults);
+        $className = 'Magento\Sales\Model\Order\Invoice';
+        $this->commonTestGetCalculatedTaxesInvoiceCreditmemo(
+            $source,
+            $className,
+            $invoiceData,
+            $orderTaxDetails,
+            $expectedResults
+        );
     }
 
     /**
      * @param \Magento\Framework\Object $source
-     * @param \Magento\Framework\Object $creditmemo
+     * @param \Magento\Framework\Object $creditMemoData
      * @param OrderTaxDetails $orderTaxDetails
      * @param array $expectedResults
      * @dataProvider testGetCalculatedTaxesInvoiceCreditmemoDataProvider
      */
-    public function testGetCalculatedTaxesCreditmemo($source, $creditmemo, $orderTaxDetails, $expectedResults)
+    public function testGetCalculatedTaxesCreditmemo($source, $creditMemoData, $orderTaxDetails, $expectedResults)
     {
-        $this->coreRegistry->expects($this->at(0))
-            ->method('registry')
-            ->with('current_invoice')
-            ->will($this->returnValue(null));
-        $this->coreRegistry->expects($this->at(1))
-            ->method('registry')
-            ->with('current_creditmemo')
-            ->will($this->returnValue($creditmemo));
-        $this->coreRegistry->expects($this->at(2))
-            ->method('registry')
-            ->with('current_creditmemo')
-            ->will($this->returnValue($creditmemo));
-        $this->commonTestGetCalculatedTaxesInvoiceCreditmemo($source, $orderTaxDetails, $expectedResults);
+        $className = 'Magento\Sales\Model\Order\Creditmemo';
+        $this->commonTestGetCalculatedTaxesInvoiceCreditmemo(
+            $source,
+            $className,
+            $creditMemoData,
+            $orderTaxDetails,
+            $expectedResults
+        );
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Render/AdjustmentTest.php b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Render/AdjustmentTest.php
index 34febddc002..6561e6d9f38 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Render/AdjustmentTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Render/AdjustmentTest.php
@@ -296,16 +296,14 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
     public function testGetHtmlExcluding()
     {
         $arguments = [];
-        $totalDisplayValue = 10.0;
-        $taxAdjustment = 2.0;
         $displayValue = 8.0;
 
         $amountRender = $this->getMockForAbstractClass('Magento\Framework\Pricing\Render\AmountRenderInterface');
         $amountMock = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
         $amountMock->expects($this->once())
-            ->method('getAdjustmentAmount')
+            ->method('getValue')
             ->with(\Magento\Tax\Pricing\Adjustment::ADJUSTMENT_CODE)
-            ->will($this->returnValue($taxAdjustment));
+            ->willReturn($displayValue);
 
         $this->taxHelperMock->expects($this->once())
             ->method('displayBothPrices')
@@ -314,15 +312,12 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
             ->method('displayPriceExcludingTax')
             ->will($this->returnValue(true));
 
-        $amountRender->expects($this->at(0))
-            ->method('getDisplayValue')
-            ->will($this->returnValue($totalDisplayValue));
-        $amountRender->expects($this->at(1))
-            ->method('getAmount')
-            ->will($this->returnValue($amountMock));
-        $amountRender->expects($this->at(2))
+        $amountRender->expects($this->once())
             ->method('setDisplayValue')
             ->with($displayValue);
+        $amountRender->expects($this->once())
+            ->method('getAmount')
+            ->will($this->returnValue($amountMock));
 
         $this->model->render($amountRender, $arguments);
     }
@@ -330,30 +325,20 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
     public function testGetHtmlBoth()
     {
         $arguments = [];
-        $totalDisplayValue = 10.0;
-        $taxAdjustment = 2.0;
-        $displayValue = 8.0;
         $this->model->setZone(\Magento\Framework\Pricing\Render::ZONE_ITEM_VIEW);
 
         $amountRender = $this->getMock(
             'Magento\Framework\Pricing\Render\Amount',
             [
                 'setPriceDisplayLabel',
+                'setPriceWrapperCss',
                 'setPriceId',
-                'getSaleableItem',
-                'getDisplayValue',
-                'getAmount',
-                'setDisplayValue'
+                'getSaleableItem'
             ],
             [],
             '',
             false
         );
-        $amountMock = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
-        $amountMock->expects($this->once())
-            ->method('getAdjustmentAmount')
-            ->with(\Magento\Tax\Pricing\Adjustment::ADJUSTMENT_CODE)
-            ->will($this->returnValue($taxAdjustment));
         $product = $this->getMockForAbstractClass('Magento\Framework\Pricing\Object\SaleableInterface');
         $product->expects($this->once())
             ->method('getId');
@@ -362,22 +347,15 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
             ->method('displayBothPrices')
             ->will($this->returnValue(true));
 
-        $amountRender->expects($this->at(0))
+        $amountRender->expects($this->once())
             ->method('setPriceDisplayLabel');
-        $amountRender->expects($this->at(1))
+        $amountRender->expects($this->once())
             ->method('getSaleableItem')
             ->will($this->returnValue($product));
-        $amountRender->expects($this->at(2))
+        $amountRender->expects($this->once())
             ->method('setPriceId');
-        $amountRender->expects($this->at(3))
-            ->method('getDisplayValue')
-            ->will($this->returnValue($totalDisplayValue));
-        $amountRender->expects($this->at(4))
-            ->method('getAmount')
-            ->will($this->returnValue($amountMock));
-        $amountRender->expects($this->at(5))
-            ->method('setDisplayValue')
-            ->with($displayValue);
+        $amountRender->expects($this->once())
+            ->method('setPriceWrapperCss');
 
         $this->model->render($amountRender, $arguments);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/CssTest.php b/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/CssTest.php
deleted file mode 100644
index 90d8303182e..00000000000
--- a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/CssTest.php
+++ /dev/null
@@ -1,73 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Theme\Block\Html\Head;
-
-class CssTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Theme\Block\Html\Head\Css
-     */
-    protected $_block;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_assetRepo;
-
-    protected function setUp()
-    {
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $context = $this->getMock('\Magento\Framework\View\Element\Template\Context', array(), array(), '', false);
-        $this->_assetRepo = $this->getMock('\Magento\Framework\View\Asset\Repository', array(), array(), '', false);
-
-        $context->expects($this->once())
-            ->method('getAssetRepository')
-            ->will($this->returnValue($this->_assetRepo));
-
-        $this->_block = $objectManagerHelper->getObject(
-            '\Magento\Theme\Block\Html\Head\Css',
-            array('context' => $context)
-        );
-
-        $this->_block->setData('file', 'fileValue');
-    }
-
-    public function testConstructor()
-    {
-        $this->assertInstanceOf('Magento\Framework\View\Element\AbstractBlock', $this->_block);
-    }
-
-    public function testGetAsset()
-    {
-        $asset = $this->getMock('\Magento\Framework\View\Asset\File', array(), array(), '', false);
-
-        $this->_assetRepo->expects($this->once())
-            ->method('createAsset')
-            ->with('fileValue')
-            ->will($this->returnValue($asset));
-
-        $this->assertSame($this->_block->getAsset(), $asset);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/LinkTest.php b/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/LinkTest.php
deleted file mode 100644
index 5fc53db59a0..00000000000
--- a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/LinkTest.php
+++ /dev/null
@@ -1,73 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Theme\Block\Html\Head;
-
-class LinkTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Theme\Block\Html\Head\Link
-     */
-    protected $_block;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_assetRepo;
-
-    protected function setUp()
-    {
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $context = $this->getMock('\Magento\Framework\View\Element\Template\Context', array(), array(), '', false);
-        $this->_assetRepo = $this->getMock('\Magento\Framework\View\Asset\Repository', array(), array(), '', false);
-
-        $context->expects($this->once())
-            ->method('getAssetRepository')
-            ->will($this->returnValue($this->_assetRepo));
-
-        $this->_block = $objectManagerHelper->getObject(
-            '\Magento\Theme\Block\Html\Head\Link',
-            array('context' => $context)
-        );
-
-        $this->_block->setData('url', 'urlValue');
-    }
-
-    public function testConstructor()
-    {
-        $this->assertInstanceOf('Magento\Framework\View\Element\Template', $this->_block);
-    }
-
-    public function testGetAsset()
-    {
-        $asset = $this->getMock('\Magento\Framework\View\Asset\Remote', array(), array(), '', false);
-
-        $this->_assetRepo->expects($this->once())
-            ->method('createRemoteAsset')
-            ->with('urlValue', 'link')
-            ->will($this->returnValue($asset));
-
-        $this->assertSame($this->_block->getAsset(), $asset);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/ScriptTest.php b/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/ScriptTest.php
deleted file mode 100644
index bbfb0aefe20..00000000000
--- a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/Head/ScriptTest.php
+++ /dev/null
@@ -1,73 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Theme\Block\Html\Head;
-
-class ScriptTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Theme\Block\Html\Head\Script
-     */
-    protected $_block;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_assetRepo;
-
-    protected function setUp()
-    {
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $context = $this->getMock('\Magento\Framework\View\Element\Template\Context', array(), array(), '', false);
-        $this->_assetRepo = $this->getMock('\Magento\Framework\View\Asset\Repository', array(), array(), '', false);
-
-        $context->expects($this->once())
-            ->method('getAssetRepository')
-            ->will($this->returnValue($this->_assetRepo));
-
-        $this->_block = $objectManagerHelper->getObject(
-            '\Magento\Theme\Block\Html\Head\Script',
-            array('context' => $context)
-        );
-
-        $this->_block->setData('file', 'fileValue');
-    }
-
-    public function testConstructor()
-    {
-        $this->assertInstanceOf('Magento\Framework\View\Element\AbstractBlock', $this->_block);
-    }
-
-    public function testGetAsset()
-    {
-        $asset = $this->getMock('\Magento\Framework\View\Asset\File', array(), array(), '', false);
-
-        $this->_assetRepo->expects($this->once())
-            ->method('createAsset')
-            ->with('fileValue')
-            ->will($this->returnValue($asset));
-
-        $this->assertSame($this->_block->getAsset(), $asset);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/HeadTest.php b/dev/tests/unit/testsuite/Magento/Theme/Block/Html/HeadTest.php
deleted file mode 100644
index dd68390685f..00000000000
--- a/dev/tests/unit/testsuite/Magento/Theme/Block/Html/HeadTest.php
+++ /dev/null
@@ -1,137 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Theme\Block\Html;
-
-class HeadTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Theme\Block\Html\Head
-     */
-    protected $_block;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_pageAssets;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_objectManager;
-
-    /** @var  \Magento\Framework\View\Element\Template\Context */
-    protected $_context;
-
-    protected function setUp()
-    {
-        $this->_objectManager = $this->getMock('Magento\Framework\ObjectManager');
-        $this->_pageAssets = $this->getMock(
-            'Magento\Framework\View\Asset\GroupedCollection',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $arguments = $objectManagerHelper->getConstructArguments(
-            'Magento\Theme\Block\Html\Head',
-            array('assets' => $this->_pageAssets, 'objectManager' => $this->_objectManager)
-        );
-        $this->_context = $arguments['context'];
-        $this->_block = $objectManagerHelper->getObject('Magento\Theme\Block\Html\Head', $arguments);
-    }
-
-    protected function tearDown()
-    {
-        $this->_pageAssets = null;
-        $this->_objectManager = null;
-        $this->_block = null;
-    }
-
-    public function testAddRss()
-    {
-        $this->_pageAssets->expects(
-            $this->once()
-        )->method(
-            'add'
-        )->with(
-            'link/http://127.0.0.1/test.rss',
-            $this->isInstanceOf('Magento\Framework\View\Asset\Remote'),
-            array('attributes' => 'rel="alternate" type="application/rss+xml" title="RSS Feed"')
-        );
-        $assetRemoteFile = $this->getMock('Magento\Framework\View\Asset\Remote', array(), array(), '', false);
-        $this->_objectManager->expects(
-            $this->once('')
-        )->method(
-            'create'
-        )->with(
-            'Magento\Framework\View\Asset\Remote'
-        )->will(
-            $this->returnValue($assetRemoteFile)
-        );
-
-        $this->_block->addRss('RSS Feed', 'http://127.0.0.1/test.rss');
-    }
-
-    public function testGetFaviconFile()
-    {
-        $storeMock = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false);
-        $storeMock->expects($this->any())->method('getBaseUrl')->will($this->returnValue('baseUrl/'));
-        $this->_context->getStoreManager()->expects(
-            $this->any()
-        )->method(
-            'getStore'
-        )->will(
-            $this->returnValue($storeMock)
-        );
-
-        $this->_context->getScopeConfig()->expects(
-            $this->any()
-        )->method(
-            'getValue'
-        )->will(
-            $this->returnValue('scopeConfig')
-        );
-
-        $mediaDirMock = $this->getMock('\Magento\Framework\Filesystem\Directory\Read', array(), array(), '', false);
-        $mediaDirMock->expects(
-            $this->any()
-        )->method(
-            'isFile'
-        )->with(
-            'favicon/scopeConfig'
-        )->will(
-            $this->returnValue(true)
-        );
-        $this->_context->getFilesystem()->expects(
-            $this->once()
-        )->method(
-            'getDirectoryRead'
-        )->will(
-            $this->returnValue($mediaDirMock)
-        );
-
-        $this->assertEquals('baseUrl/favicon/scopeConfig', $this->_block->getFaviconFile());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigJsonTest.php b/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigJsonTest.php
new file mode 100644
index 00000000000..5506b18c090
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigJsonTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType\Builders;
+
+/**
+ * Class ConfigJsonTest
+ */
+class ConfigJsonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ConfigJson
+     */
+    protected $builder;
+
+    public function testToJson()
+    {
+        $this->builder = new ConfigJson();
+        $result = ['name' => 'resultName', 'parent_name' => 'resultParentName'];
+        $configurationMock = $this->getMock(
+            'Magento\Ui\Configuration',
+            ['getData', 'getName', 'getParentName'],
+            [],
+            '',
+            false
+        );
+        $configurationMock->expects($this->once())->method('getData')->willReturn($result);
+        $configurationMock->expects($this->once())->method('getName')->willReturn($result['name']);
+        $configurationMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']);
+        $this->assertEquals(json_encode($result), $this->builder->toJson($configurationMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigStorageJsonTest.php b/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigStorageJsonTest.php
new file mode 100644
index 00000000000..06b13f199ae
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/ContentType/Builders/ConfigStorageJsonTest.php
@@ -0,0 +1,108 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType\Builders;
+
+/**
+ * Class ConfigStorageJsonTest
+ */
+class ConfigStorageJsonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ConfigStorageJson
+     */
+    protected $builder;
+
+    public function testToJson()
+    {
+        $this->builder = new ConfigStorageJson();
+        $name = 'name';
+        $data = [];
+        $parentName = 'parentName';
+        $result = [
+            'config' => ['components' => [$name => $data], 'globalData' => ['globalData']],
+            'meta' => null,
+            'name' => $name,
+            'parent_name' => $parentName,
+            'data' => null,
+            'dump' => ['extenders' => []]
+        ];
+
+        $rootComponentMock = $this->getMock(
+            'Magento\Ui\Configuration',
+            ['getName', 'getParentName', 'getData'],
+            [],
+            '',
+            false
+        );
+        $storageMock = $this->getMock(
+            'Magento\Ui\ConfigurationStorage',
+            ['getComponentsData', 'getGlobalData', 'getMeta', 'getData'],
+            [],
+            '',
+            false
+        );
+
+        $storageMock->expects($this->once())
+            ->method('getComponentsData')
+            ->with($parentName)
+            ->will($this->returnValue($rootComponentMock));
+        $rootComponentMock->expects($this->any())->method('getName')->willReturn($result['name']);
+        $rootComponentMock->expects($this->once())->method('getParentName')->willReturn($result['parent_name']);
+        $rootComponentMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($data);
+        $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']);
+
+        $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock, $parentName));
+    }
+
+    public function testToJsonNoParentName()
+    {
+        $this->builder = new ConfigStorageJson();
+        $data = [];
+        $result = [
+            'config' => ['components' => ['name' => $data], 'globalData' => ['globalData']],
+            'meta' => null,
+            'data' => null,
+            'dump' => ['extenders' => []]
+        ];
+        $componentsMock = $this->getMock('Magento\Ui\Configuration', ['getData'], [], '', false);
+        $storageMock = $this->getMock(
+            'Magento\Ui\ConfigurationStorage',
+            ['getComponentsData', 'getGlobalData', 'getMeta', 'getData'],
+            [],
+            '',
+            false
+        );
+
+        $storageMock->expects($this->once())->method('getComponentsData')->will($this->returnValue($componentsMock));
+        $componentsMock->expects($this->any())->method('getData')->willReturn($data);
+
+        $storageMock->expects($this->once())->method('getMeta')->will($this->returnValue($result['meta']));
+        $storageMock->expects($this->once())->method('getData')->will($this->returnValue($result['data']));
+        $storageMock->expects($this->once())->method('getGlobalData')->willReturn($result['config']);
+
+        $this->assertEquals(json_encode($result), $this->builder->toJson($storageMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/ContentType/ContentTypeFactoryTest.php b/dev/tests/unit/testsuite/Magento/Ui/ContentType/ContentTypeFactoryTest.php
new file mode 100644
index 00000000000..e7f92a0a651
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/ContentType/ContentTypeFactoryTest.php
@@ -0,0 +1,102 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+/**
+ * Class ContentTypeFactoryTest
+ */
+class ContentTypeFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ContentTypeFactory
+     */
+    protected $contentTypeFactory;
+
+    /**
+     * @param $type
+     * @param @expected
+     * @dataProvider getDataProvider
+     */
+    public function testGet($type, $contentRender, $expected)
+    {
+        $objectManagerMock = $this->getMock(
+            'Magento\Framework\ObjectManager',
+            ['get', 'create', 'configure'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
+        $objectManagerMock->expects($this->once())->method('get')->with($expected)->willReturn($contentRender);
+        $this->assertInstanceOf($expected, $this->contentTypeFactory->get($type));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testGetTypeException()
+    {
+        $objectManagerMock = $this->getMock(
+            'Magento\Framework\ObjectManager',
+            ['get', 'create', 'configure'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
+        $this->contentTypeFactory->get('bad_type');
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testGetInstanceException()
+    {
+        $objectManagerMock = $this->getMock(
+            'Magento\Framework\ObjectManager',
+            ['get', 'create', 'configure'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactory = new ContentTypeFactory($objectManagerMock);
+        $objectManagerMock->expects($this->once())->method('get')->willReturnSelf();
+        $this->contentTypeFactory->get();
+    }
+
+    /**
+     * @return array
+     */
+    public function getDataProvider()
+    {
+        $htmlMock = $this->getMock('Magento\Ui\ContentType\Html', [], [], '', false);
+        $jsonMock = $this->getMock('Magento\Ui\ContentType\Json', [], [], '', false);
+        $xmlMock = $this->getMock('Magento\Ui\ContentType\Xml', [], [], '', false);
+        return [
+            ['html', $htmlMock, 'Magento\Ui\ContentType\Html'],
+            ['json', $jsonMock, 'Magento\Ui\ContentType\Json'],
+            ['xml', $xmlMock, 'Magento\Ui\ContentType\Xml']
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/ContentType/HtmlTest.php b/dev/tests/unit/testsuite/Magento/Ui/ContentType/HtmlTest.php
new file mode 100644
index 00000000000..257407833cb
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/ContentType/HtmlTest.php
@@ -0,0 +1,102 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ContentType;
+
+/**
+ * Class HtmlTest
+ */
+class HtmlTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Html
+     */
+    protected $html;
+
+    /**
+     * @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystemMock;
+
+    /**
+     * @var \Magento\Framework\View\TemplateEnginePool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $templateEnginePoolMock;
+
+    /**
+     * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewInterfaceMock;
+
+    public function setUp()
+    {
+        $this->filesystemMock = $this->getMock(
+            'Magento\Framework\View\FileSystem',
+            ['getTemplateFileName'],
+            [],
+            '',
+            false
+        );
+        $this->templateEnginePoolMock = $this->getMock(
+            'Magento\Framework\View\TemplateEnginePool',
+            ['get'],
+            [],
+            '',
+            false
+        );
+        $this->html = new Html($this->filesystemMock, $this->templateEnginePoolMock);
+        $this->viewInterfaceMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponentInterface'
+        );
+    }
+
+    public function testRender()
+    {
+        $template = 'test_template';
+        $result = 'result';
+        $path = 'path';
+        $this->viewInterfaceMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponentInterface'
+        );
+        $templateEngineMock = $this->getMockForAbstractClass('Magento\Framework\View\TemplateEngineInterface');
+
+        $this->templateEnginePoolMock->expects($this->once())
+            ->method('get')
+            ->willReturn($templateEngineMock);
+        $this->filesystemMock->expects($this->once())
+            ->method('getTemplateFileName')
+            ->with($template)
+            ->willReturn($path);
+        $templateEngineMock->expects($this->once())
+            ->method('render')
+            ->with($this->viewInterfaceMock, $path)
+            ->willReturn($result);
+
+        $this->assertEquals($result, $this->html->render($this->viewInterfaceMock, $template));
+    }
+
+    public function testRenderEmpty()
+    {
+        $this->assertEquals('', $this->html->render($this->viewInterfaceMock, ''));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/ListingContainer/Massaction/ViewTest.php b/dev/tests/unit/testsuite/Magento/Ui/ListingContainer/Massaction/ViewTest.php
new file mode 100644
index 00000000000..6036ade544c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/ListingContainer/Massaction/ViewTest.php
@@ -0,0 +1,167 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\ListingContainer\Massaction;
+
+use Magento\Framework\View\Element\Template;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class ViewTest
+ */
+class ViewTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $renderContextMock;
+
+    /**
+     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contentTypeFactoryMock;
+
+    /**
+     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configFactoryMock;
+
+    /**
+     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configBuilderMock;
+
+    /**
+     * @var View
+     */
+    protected $view;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMock(
+            'Magento\Framework\View\Element\Template\Context',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->renderContextMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\Context',
+            ['getNamespace', 'getStorage', 'getRequestParam'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactoryMock = $this->getMock(
+            'Magento\Ui\ContentType\ContentTypeFactory',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->configFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->configBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
+            [],
+            '',
+            false
+        );
+
+        $this->view = new View(
+            $this->contextMock,
+            $this->renderContextMock,
+            $this->contentTypeFactoryMock,
+            $this->configFactoryMock,
+            $this->configBuilderMock
+        );
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepare()
+    {
+        /**
+         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
+         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
+         */
+        $configurationMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
+            [],
+            '',
+            false
+        );
+        /**
+         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
+         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
+         */
+        $configStorageMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
+            ['addComponentsData', 'getDataCollection'],
+            '',
+            false
+        );
+
+        $this->renderContextMock->expects($this->at(0))
+            ->method('getNamespace')
+            ->will($this->returnValue('namespace'));
+        $this->renderContextMock->expects($this->at(1))
+            ->method('getNamespace')
+            ->will($this->returnValue('namespace'));
+        $this->configFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($configurationMock));
+
+        $this->renderContextMock->expects($this->any())
+            ->method('getStorage')
+            ->will($this->returnValue($configStorageMock));
+
+        $configStorageMock->expects($this->once())
+            ->method('addComponentsData')
+            ->with($configurationMock);
+
+        $this->assertNull($this->view->prepare());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/Paging/ViewTest.php b/dev/tests/unit/testsuite/Magento/Ui/Paging/ViewTest.php
new file mode 100644
index 00000000000..24214bb8eaf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/Paging/ViewTest.php
@@ -0,0 +1,145 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Paging;
+
+use Magento\Framework\View\Asset\Repository;
+use Magento\Framework\View\Element\Template;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class ViewTest
+ */
+class ViewTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var View
+     */
+    protected $view;
+
+    /**
+     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configurationBuilderMock;
+
+    /**
+     * @var TemplateContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $renderContextMock;
+
+    /**
+     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configurationFactoryMock;
+
+    /**
+     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contentTypeFactoryMock;
+
+    /**
+     * @var Repository|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetRepoMock;
+
+    public function setUp()
+    {
+        $this->configurationFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->renderContextMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\Context',
+            ['getNamespace', 'getStorage', 'getRequestParam'],
+            [],
+            '',
+            false
+        );
+        $this->contextMock = $this->getMock(
+            'Magento\Framework\View\Element\Template\Context',
+            ['getAssetRepository'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactoryMock = $this->getMock('Magento\Ui\ContentType\ContentTypeFactory', [], [], '', false);
+        $this->configurationBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface'
+        );
+        $this->assetRepoMock = $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false);
+        $this->contextMock->expects($this->any())->method('getAssetRepository')->willReturn($this->assetRepoMock);
+
+        $this->view = new \Magento\Ui\Paging\View(
+            $this->contextMock,
+            $this->renderContextMock,
+            $this->contentTypeFactoryMock,
+            $this->configurationFactoryMock,
+            $this->configurationBuilderMock
+        );
+    }
+
+    public function testPrepare()
+    {
+        $paramsSize = 20;
+        $paramsPage = 1;
+        $nameSpace = 'namespace';
+        $configurationMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigInterface'
+        );
+        $this->renderContextMock->expects($this->any())->method('getNamespace')->willReturn($nameSpace);
+        $this->configurationFactoryMock->expects($this->once())->method('create')->willReturn($configurationMock);
+
+        $storageMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface'
+        );
+        $dataCollectionMock = $this->getMock('Magento\Framework\Data\Collection', ['setCurPage'], [], '', false);
+
+        $this->renderContextMock->expects($this->any())->method('getStorage')->willReturn($storageMock);
+        $storageMock->expects($this->once())
+            ->method('addComponentsData')
+            ->with($configurationMock)
+            ->willReturnSelf();
+        $storageMock->expects($this->once())->method('getDataCollection')->willReturn($dataCollectionMock);
+
+        $configurationMock->expects($this->at(1))->method('getData')->with('current')->willReturn($paramsSize);
+        $this->renderContextMock->expects($this->any())->method('getRequestParam')->willReturn($paramsPage);
+        $configurationMock->expects($this->at(2))->method('getData')->with('pageSize')->willReturn($paramsPage);
+        $this->renderContextMock->expects($this->any())->method('getRequestParam')->willReturn($paramsSize);
+        $dataCollectionMock->expects($this->any())->method('setCurPage')->with($paramsPage)->willReturnSelf();
+        $dataCollectionMock->expects($this->any())->method('setPageSize')->with($paramsSize)->willReturnSelf();
+
+        $this->assertNull($this->view->prepare());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ui/Sorting/ViewTest.php b/dev/tests/unit/testsuite/Magento/Ui/Sorting/ViewTest.php
new file mode 100644
index 00000000000..65cd64c2b94
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ui/Sorting/ViewTest.php
@@ -0,0 +1,206 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ui\Sorting;
+
+use Magento\Ui\Sorting\View;
+use Magento\Framework\View\Element\Template;
+use Magento\Ui\ContentType\ContentTypeFactory;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\View\Element\UiComponent\ConfigFactory;
+use Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface;
+use Magento\Framework\View\Element\Template\Context as TemplateContext;
+
+/**
+ * Class ViewTest
+ */
+class ViewTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var TemplateContext||\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $renderContextMock;
+
+    /**
+     * @var ContentTypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contentTypeFactoryMock;
+
+    /**
+     * @var ConfigFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configFactoryMock;
+
+    /**
+     * @var ConfigBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configBuilderMock;
+
+    /**
+     * @var View
+     */
+    protected $view;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMock(
+            'Magento\Framework\View\Element\Template\Context',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->renderContextMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\Context',
+            ['getNamespace', 'getStorage', 'getRequestParam'],
+            [],
+            '',
+            false
+        );
+        $this->contentTypeFactoryMock = $this->getMock(
+            'Magento\Ui\ContentType\ContentTypeFactory',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->configFactoryMock = $this->getMock(
+            'Magento\Framework\View\Element\UiComponent\ConfigFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->configBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigBuilderInterface',
+            [],
+            '',
+            false
+        );
+
+        $this->view = new View(
+            $this->contextMock,
+            $this->renderContextMock,
+            $this->contentTypeFactoryMock,
+            $this->configFactoryMock,
+            $this->configBuilderMock
+        );
+    }
+
+    /**
+     * Run test prepare method
+     *
+     * @return void
+     */
+    public function testPrepare()
+    {
+        /**
+         * @var \Magento\Framework\View\Element\UiComponent\ConfigInterface
+         * |\PHPUnit_Framework_MockObject_MockObject $configurationMock
+         */
+        $configurationMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigInterface',
+            [],
+            '',
+            false
+        );
+        /**
+         * @var \Magento\Framework\View\Element\UiComponent\ConfigStorageInterface
+         * |\PHPUnit_Framework_MockObject_MockObject $configStorageMock
+         */
+        $configStorageMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\ConfigStorageInterface',
+            ['addComponentsData', 'getDataCollection'],
+            '',
+            false
+        );
+
+        $dataCollectionMock = $this->getMock(
+            'Magento\Framework\Data\Collection',
+            ['setOrder'],
+            [],
+            '',
+            false
+        );
+
+        $this->renderContextMock->expects($this->at(0))
+            ->method('getNamespace')
+            ->will($this->returnValue('namespace'));
+        $this->renderContextMock->expects($this->at(1))
+            ->method('getNamespace')
+            ->will($this->returnValue('namespace'));
+        $this->configFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($configurationMock));
+
+        $this->renderContextMock->expects($this->any())
+            ->method('getStorage')
+            ->will($this->returnValue($configStorageMock));
+
+        $configStorageMock->expects($this->once())
+            ->method('addComponentsData')
+            ->with($configurationMock);
+
+        $configurationMock->expects($this->at(0))
+            ->method('getData')
+            ->with('field')
+            ->will($this->returnValue('field'));
+
+        $configurationMock->expects($this->at(1))
+            ->method('getData')
+            ->with('direction')
+            ->will($this->returnValue('direction'));
+
+        $this->renderContextMock->expects($this->any())
+            ->method('getStorage')
+            ->will($this->returnValue($configStorageMock));
+
+        $configStorageMock->expects($this->once())
+            ->method('getDataCollection')
+            ->will($this->returnValue($dataCollectionMock));
+
+        $dataCollectionMock->expects($this->once())
+            ->method('setOrder')
+            ->with('field', 'FIELD');
+
+        $this->renderContextMock->expects($this->any())
+            ->method('getRequestParam')
+            ->will($this->returnValue('field'));
+
+        $this->renderContextMock->expects($this->any())
+            ->method('getRequestParam')
+            ->will($this->returnValue('direction'));
+
+        $this->assertNull($this->view->prepare());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php b/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php
deleted file mode 100644
index f58a6afd6a4..00000000000
--- a/dev/tests/unit/testsuite/Magento/UrlRedirect/Model/OptionProviderTest.php
+++ /dev/null
@@ -1,37 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\UrlRedirect\Model;
-
-class OptionProviderTest extends \PHPUnit_Framework_TestCase
-{
-    public function testGetAllOptions()
-    {
-        $model = new OptionProvider();
-        $options = $model->getAllOptions();
-        $this->assertInternalType('array', $options);
-        $expectedOptions = array('' => 'No', 'R' => 'Temporary (302)', 'RP' => 'Permanent (301)');
-        $this->assertEquals($expectedOptions, $options);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/App/Request/RewriteServiceTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/App/Request/RewriteServiceTest.php
deleted file mode 100644
index f512ee70e8a..00000000000
--- a/dev/tests/unit/testsuite/Magento/UrlRewrite/App/Request/RewriteServiceTest.php
+++ /dev/null
@@ -1,93 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\App\Request;
-
-class RewriteServiceTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\UrlRewrite\App\Request\RewriteService
-     */
-    protected $_model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_routerListMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_rewriteFactoryMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_configMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_requestMock;
-
-    protected function setUp()
-    {
-        $this->_routerListMock = $this->getMock('\Magento\Framework\App\RouterList', array(), array(), '', false);
-        $this->_configMock = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
-        $this->_requestMock = $this->getMock('\Magento\Framework\App\Request\Http', array(), array(), '', false);
-        $this->_rewriteFactoryMock = $this->getMock(
-            '\Magento\UrlRewrite\Model\UrlRewriteFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-
-        $this->_model = new \Magento\UrlRewrite\App\Request\RewriteService(
-            $this->_routerListMock,
-            $this->_rewriteFactoryMock,
-            $this->_configMock
-        );
-    }
-
-    public function testApplyRewritesWhenRequestIsStraight()
-    {
-        $this->_requestMock->expects($this->once())->method('isStraight')->will($this->returnValue(true));
-        $this->_rewriteFactoryMock->expects($this->never())->method('create')->will($this->returnValue('nodeName'));
-        $this->_model->applyRewrites($this->_requestMock);
-    }
-
-    public function testApplyRewritesWhenRequestIsNotStraight()
-    {
-        $this->_requestMock->expects($this->once())->method('isStraight')->will($this->returnValue(false));
-        $urlRewriteMock = $this->getMock('\Magento\UrlRewrite\Model\UrlRewrite', array(), array(), '', false);
-        $this->_rewriteFactoryMock->expects(
-            $this->once()
-        )->method(
-            'create'
-        )->will(
-            $this->returnValue($urlRewriteMock)
-        );
-        $this->_model->applyRewrites($this->_requestMock);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Controller/RouterTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Controller/RouterTest.php
new file mode 100644
index 00000000000..13776038190
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/UrlRewrite/Controller/RouterTest.php
@@ -0,0 +1,194 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\UrlRewrite\Controller;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\UrlRewrite\Model\OptionProvider;
+
+class RouterTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\UrlRewrite\Controller\Router */
+    protected $router;
+
+    /** @var \Magento\Framework\App\ActionFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $actionFactory;
+
+    /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $url;
+
+    /** @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeManager;
+
+    /** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */
+    protected $store;
+
+    /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $response;
+
+    /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $request;
+
+    /** @var \Magento\UrlRewrite\Model\UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlFinder;
+
+    protected function setUp()
+    {
+        $this->actionFactory = $this->getMock('Magento\Framework\App\ActionFactory', [], [], '', false);
+        $this->url = $this->getMock('Magento\Framework\UrlInterface');
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->response = $this->getMock('Magento\Framework\App\ResponseInterface', ['setRedirect', 'sendResponse']);
+        $this->request = $this->getMockBuilder('\Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()->getMock();
+        $this->urlFinder = $this->getMock('Magento\UrlRewrite\Model\UrlFinderInterface');
+        $this->store = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+
+
+        $this->router = (new ObjectManager($this))->getObject(
+            'Magento\UrlRewrite\Controller\Router',
+            [
+                'actionFactory' => $this->actionFactory,
+                'url' => $this->url,
+                'storeManager' => $this->storeManager,
+                'response' => $this->response,
+                'urlFinder' => $this->urlFinder
+            ]
+        );
+    }
+
+    public function testNoRewriteExist()
+    {
+        $this->urlFinder->expects($this->any())->method('findOneByData')->will($this->returnValue(null));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
+        $this->store->expects($this->any())->method('getId')->will($this->returnValue('current-store-id'));
+
+        $this->assertEquals(null, $this->router->match($this->request));
+    }
+
+    public function testRewriteAfterStoreSwitcher()
+    {
+        $this->request->expects($this->any())->method('getPathInfo')->will($this->returnValue('request-path'));
+        $this->request->expects($this->any())->method('getParam')->with('___from_store')
+            ->will($this->returnValue('old-store'));
+        $oldStore = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $this->storeManager->expects($this->any())->method('getStore')
+            ->will($this->returnValueMap([['old-store', $oldStore], [null, $this->store]]));
+        $oldStore->expects($this->any())->method('getId')->will($this->returnValue('old-store-id'));
+        $this->store->expects($this->any())->method('getId')->will($this->returnValue('current-store-id'));
+        $oldUrlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $oldUrlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('entity-type'));
+        $oldUrlRewrite->expects($this->any())->method('getEntityId')->will($this->returnValue('entity-id'));
+        $oldUrlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('old-request-path'));
+        $urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $urlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('new-request-path'));
+
+        $this->urlFinder->expects($this->any())->method('findOneByData')->will(
+            $this->returnValueMap(
+                [
+                    [
+                        [UrlRewrite::REQUEST_PATH => 'request-path', UrlRewrite::STORE_ID => 'old-store-id'],
+                        $oldUrlRewrite
+                    ],
+                    [
+                        [
+                            UrlRewrite::ENTITY_TYPE => 'entity-type',
+                            UrlRewrite::ENTITY_ID => 'entity-id',
+                            UrlRewrite::STORE_ID => 'current-store-id',
+                            UrlRewrite::IS_AUTOGENERATED => 1,
+                        ],
+                        $urlRewrite
+                    ]
+                ]
+            )
+        );
+        $this->response->expects($this->once())->method('setRedirect')
+            ->with('request-path-302', OptionProvider::TEMPORARY);
+        $this->url->expects($this->once())->method('getUrl')->with('', array('_direct' => 'new-request-path'))
+            ->will($this->returnValue('request-path-302'));
+        $this->request->expects($this->once())->method('setDispatched')->with(true);
+        $this->actionFactory->expects($this->once())->method('create')
+            ->with('Magento\Framework\App\Action\Redirect', ['request' => $this->request]);
+
+        $this->router->match($this->request);
+    }
+
+    public function testNoRewriteAfterStoreSwitcher()
+    {
+        $this->request->expects($this->any())->method('getPathInfo')->will($this->returnValue('request-path'));
+        $this->request->expects($this->any())->method('getParam')->with('___from_store')
+            ->will($this->returnValue('old-store'));
+        $oldStore = $this->getMockBuilder('Magento\Store\Model\Store')->disableOriginalConstructor()->getMock();
+        $this->storeManager->expects($this->any())->method('getStore')
+            ->will($this->returnValueMap([['old-store', $oldStore], [null, $this->store]]));
+        $oldStore->expects($this->any())->method('getId')->will($this->returnValue('old-store-id'));
+        $this->store->expects($this->any())->method('getId')->will($this->returnValue('current-store-id'));
+        $oldUrlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $oldUrlRewrite->expects($this->any())->method('getEntityType')->will($this->returnValue('entity-type'));
+        $oldUrlRewrite->expects($this->any())->method('getEntityId')->will($this->returnValue('entity-id'));
+        $oldUrlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('request-path'));
+        $urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $urlRewrite->expects($this->any())->method('getRequestPath')->will($this->returnValue('request-path'));
+
+        $this->assertEquals(null, $this->router->match($this->request));
+    }
+
+    public function testMatchWithRedirect()
+    {
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
+        $urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue('redirect-code'));
+        $urlRewrite->expects($this->any())->method('getTargetPath')->will($this->returnValue('target-path'));
+        $this->urlFinder->expects($this->any())->method('findOneByData')->will($this->returnValue($urlRewrite));
+        $this->response->expects($this->once())->method('setRedirect')
+            ->with('new-target-path', 'redirect-code');
+        $this->url->expects($this->once())->method('getUrl')->with('', array('_direct' => 'target-path'))
+            ->will($this->returnValue('new-target-path'));
+        $this->request->expects($this->once())->method('setDispatched')->with(true);
+        $this->actionFactory->expects($this->once())->method('create')
+            ->with('Magento\Framework\App\Action\Redirect', ['request' => $this->request]);
+
+        $this->router->match($this->request);
+    }
+
+    public function testMatch()
+    {
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
+        $urlRewrite = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewrite')
+            ->disableOriginalConstructor()->getMock();
+        $urlRewrite->expects($this->any())->method('getRedirectType')->will($this->returnValue(0));
+        $urlRewrite->expects($this->any())->method('getTargetPath')->will($this->returnValue('target-path'));
+        $this->urlFinder->expects($this->any())->method('findOneByData')->will($this->returnValue($urlRewrite));
+        $this->request->expects($this->once())->method('setPathInfo')->with('/target-path');
+        $this->actionFactory->expects($this->once())->method('create')
+            ->with('Magento\Framework\App\Action\Forward', ['request' => $this->request]);
+
+        $this->router->match($this->request);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
index 94adce72111..8f1334cf110 100644
--- a/dev/tests/unit/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
+++ b/dev/tests/unit/testsuite/Magento/UrlRewrite/Helper/UrlRewriteTest.php
@@ -23,41 +23,68 @@
  */
 namespace Magento\UrlRewrite\Helper;
 
+use Magento\TestFramework\Helper\ObjectManager;
+
 class UrlRewriteTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * Test hasRedirectOptions
-     *
-     * @dataProvider redirectOptionsDataProvider
+     * @var \Magento\UrlRewrite\Helper\UrlRewrite
      */
-    public function testHasRedirectOptions($option, $expected)
+    protected $_helper;
+
+    protected function setUp()
     {
-        $optionsMock = $this->getMock(
-            'Magento\UrlRewrite\Model\UrlRewrite\OptionProvider',
-            array('getRedirectOptions'),
-            array(),
-            '',
-            false,
-            false
-        );
-        $optionsMock->expects($this->any())->method('getRedirectOptions')->will($this->returnValue(array('R', 'RP')));
-        $helper = new \Magento\UrlRewrite\Helper\UrlRewrite(
-            $this->getMock('Magento\Framework\App\Helper\Context', array(), array(), '', false, false),
-            $optionsMock
-        );
-        $mockObject = new \Magento\Framework\Object();
-        $mockObject->setOptions($option);
-        $this->assertEquals($expected, $helper->hasRedirectOptions($mockObject));
+        $this->_helper = (new ObjectManager($this))->getObject('Magento\UrlRewrite\Helper\UrlRewrite');
+    }
+
+    /**
+     * @dataProvider requestPathDataProvider
+     */
+    public function testValidateRequestPath($requestPath)
+    {
+        $this->assertTrue($this->_helper->validateRequestPath($requestPath));
+    }
+
+    /**
+     * @dataProvider requestPathExceptionDataProvider
+     * @expectedException \Magento\Framework\Model\Exception
+     */
+    public function testValidateRequestPathException($requestPath)
+    {
+        $this->_helper->validateRequestPath($requestPath);
     }
 
     /**
-     * Data provider for redirect options
-     *
-     * @static
-     * @return array
+     * @dataProvider requestPathDataProvider
      */
-    public static function redirectOptionsDataProvider()
+    public function testValidateSuffix($suffix)
     {
-        return array(array('', false), array('R', true), array('RP', true));
+        $this->assertTrue($this->_helper->validateSuffix($suffix));
+    }
+
+    /**
+     * @dataProvider requestPathExceptionDataProvider
+     * @expectedException \Magento\Framework\Model\Exception
+     */
+    public function testValidateSuffixException($suffix)
+    {
+        $this->_helper->validateSuffix($suffix);
+    }
+
+    public function requestPathDataProvider()
+    {
+        return array(
+            'no leading slash' => array('correct/request/path'),
+            'leading slash' => array('another/good/request/path/')
+        );
+    }
+
+    public function requestPathExceptionDataProvider()
+    {
+        return array(
+            'two slashes' => array('request/path/with/two//slashes'),
+            'three slashes' => array('request/path/with/three///slashes'),
+            'anchor' => array('request/path/with#anchor')
+        );
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Resource/UrlRewriteCollectionTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Resource/UrlRewriteCollectionTest.php
new file mode 100644
index 00000000000..8dd432179ff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Resource/UrlRewriteCollectionTest.php
@@ -0,0 +1,167 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model\Resource;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class UrlRewriteCollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\Model\Resource\Db\AbstractDb|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resource;
+
+    /**
+     * @var \Zend_Db_Select|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $select;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $adapter;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $connection;
+
+    /**
+     * @var \Magento\UrlRewrite\Model\Resource\UrlRewriteCollection
+     */
+    protected $collection;
+
+    protected function setUp()
+    {
+        $this->storeManager = $this->getMock('Magento\Framework\StoreManagerInterface');
+        $this->select = $this->getMock('Zend_Db_Select', ['from', 'where'], [], '', false);
+        $this->adapter = $this->getMock(
+            'Magento\Framework\DB\Adapter\Pdo\Mysql',
+            ['select', 'prepareSqlCondition', 'quoteIdentifier'],
+            [],
+            '',
+            false
+        );
+        $this->resource = $this->getMockForAbstractClass(
+            'Magento\Framework\Model\Resource\Db\AbstractDb',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getReadConnection', '__wakeup', 'getMainTable', 'getTable']
+        );
+
+        $this->select->expects($this->any())
+            ->method('where')
+            ->will($this->returnSelf());
+        $this->adapter->expects($this->any())
+            ->method('select')
+            ->will($this->returnValue($this->select));
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+        $this->resource->expects($this->any())
+            ->method('getReadConnection')
+            ->will($this->returnValue($this->adapter));
+        $this->resource->expects($this->any())
+            ->method('getMainTable')
+            ->will($this->returnValue('test_main_table'));
+        $this->resource->expects($this->any())
+            ->method('getTable')
+            ->with('test_main_table')
+            ->will($this->returnValue('test_main_table'));
+
+        $this->collection = (new ObjectManager($this))->getObject(
+            'Magento\UrlRewrite\Model\Resource\UrlRewriteCollection',
+            [
+                'storeManager' => $this->storeManager,
+                'resource' => $this->resource,
+            ]
+        );
+    }
+
+    /**
+     * @param array $storeId
+     * @param bool $withAdmin
+     * @param array $condition
+     * @dataProvider dataProviderForTestAddStoreIfStoreIsArray
+     * @covers \Magento\UrlRewrite\Model\Resource\UrlRewriteCollection
+     */
+    public function testAddStoreFilterIfStoreIsArray($storeId, $withAdmin, $condition)
+    {
+        $this->adapter->expects($this->once())
+            ->method('prepareSqlCondition')
+            ->with('store_id', ['in' => $condition]);
+
+        $this->collection->addStoreFilter($storeId, $withAdmin);
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderForTestAddStoreIfStoreIsArray()
+    {
+        return [
+            [[112, 113], false, [112, 113]],
+            [[112, 113], true, [112, 113, 0]],
+        ];
+    }
+
+    /**
+     * @param int $storeId
+     * @param bool $withAdmin
+     * @param array $condition
+     * @dataProvider dataProviderForTestAddStoreFilterIfStoreIsInt
+     * @covers \Magento\UrlRewrite\Model\Resource\UrlRewriteCollection
+     */
+    public function testAddStoreFilterIfStoreIsInt($storeId, $withAdmin, $condition)
+    {
+        $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $store->expects($this->once())->method('getId')->will($this->returnValue($storeId));
+        $this->storeManager->expects($this->once())->method('getStore')->will($this->returnValue($store));
+
+        $this->adapter->expects($this->once())
+            ->method('prepareSqlCondition')
+            ->with('store_id', ['in' => $condition]);
+
+        $this->collection->addStoreFilter($storeId, $withAdmin);
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderForTestAddStoreFilterIfStoreIsInt()
+    {
+        return [
+            [112, false, [112]],
+            [112, true, [112, 0]],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/AbstractStorageTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/AbstractStorageTest.php
new file mode 100644
index 00000000000..b82dda44cf0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/AbstractStorageTest.php
@@ -0,0 +1,152 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model\Storage;
+
+class AbstractStorageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @var \Magento\UrlRewrite\Model\Storage\AbstractStorage|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storage;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMockBuilder('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder')
+            ->disableOriginalConstructor()->getMock();
+
+        $this->storage = $this->getMockForAbstractClass(
+            'Magento\UrlRewrite\Model\Storage\AbstractStorage',
+            [$this->urlRewriteBuilder],
+            '',
+            true,
+            true,
+            true
+        );
+    }
+
+    public function testFindAllByData()
+    {
+        $data = [['field1' => 'value1']];
+        $rows = [['row1'], ['row2']];
+        $urlRewrites = [['urlRewrite1'], ['urlRewrite2']];
+
+        $this->storage->expects($this->once())
+            ->method('doFindAllByData')
+            ->with($data)
+            ->will($this->returnValue($rows));
+
+        $this->urlRewriteBuilder->expects($this->at(0))
+            ->method('populateWithArray')
+            ->with($rows[0])
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->at(1))
+            ->method('create')
+            ->will($this->returnValue($urlRewrites[0]));
+
+        $this->urlRewriteBuilder->expects($this->at(2))
+            ->method('populateWithArray')
+            ->with($rows[1])
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->at(3))
+            ->method('create')
+            ->will($this->returnValue($urlRewrites[1]));
+
+        $this->assertEquals($urlRewrites, $this->storage->findAllByData($data));
+    }
+
+    public function testFindOneByDataIfNotFound()
+    {
+        $data = [['field1' => 'value1']];
+
+        $this->storage->expects($this->once())
+            ->method('doFindOneByData')
+            ->with($data)
+            ->will($this->returnValue(null));
+
+        $this->assertNull($this->storage->findOneByData($data));
+    }
+
+    public function testFindOneByDataIfFound()
+    {
+        $data = [['field1' => 'value1']];
+        $row = ['row1'];
+        $urlRewrite = ['urlRewrite1'];
+
+        $this->storage->expects($this->once())
+            ->method('doFindOneByData')
+            ->with($data)
+            ->will($this->returnValue($row));
+
+        $this->urlRewriteBuilder->expects($this->once())
+            ->method('populateWithArray')
+            ->with($row)
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($urlRewrite));
+
+        $this->assertEquals($urlRewrite, $this->storage->findOneByData($data));
+    }
+
+    public function testReplaceIfUrlsAreEmpty()
+    {
+        $this->storage->expects($this->never())->method('doReplace');
+
+        $this->storage->replace([]);
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     * @expectedExceptionMessage URL key for specified store already exists.
+     */
+    public function testReplaceIfThrewDuplicateEntryExceptionWithCustomMessage()
+    {
+        $this->storage
+            ->expects($this->once())
+            ->method('doReplace')
+            ->will($this->throwException(new DuplicateEntryException('Custom storage message')));
+
+        $this->storage->replace([['UrlRewrite1']]);
+    }
+
+    public function testReplace()
+    {
+        $urls = [['UrlRewrite1'], ['UrlRewrite2']];
+
+        $this->storage
+            ->expects($this->once())
+            ->method('doReplace')
+            ->with($urls);
+
+        $this->storage->replace($urls);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/DbStorageTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/DbStorageTest.php
new file mode 100644
index 00000000000..c6f21bd684b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/Storage/DbStorageTest.php
@@ -0,0 +1,324 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\UrlRewrite\Model\Storage;
+
+use Magento\Framework\App\Resource;
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\UrlRewrite\Model\Storage\DbStorage;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+
+class DbStorageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlRewriteBuilder;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $adapter;
+
+    /**
+     * @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $select;
+
+    /**
+     * @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resource;
+
+    /**
+     * @var \Magento\UrlRewrite\Model\Storage\DbStorage
+     */
+    protected $storage;
+
+    protected function setUp()
+    {
+        $this->urlRewriteBuilder = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewriteBuilder', [], [], '',
+            false);
+        $this->adapter = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface');
+        $this->select = $this->getMock('Magento\Framework\DB\Select', ['from', 'where', 'deleteFromSelect'], [], '',
+            false);
+        $this->resource = $this->getMock('Magento\Framework\App\Resource', [], [], '', false);
+
+        $this->resource->expects($this->any())
+            ->method('getConnection')
+            ->with(Resource::DEFAULT_WRITE_RESOURCE)
+            ->will($this->returnValue($this->adapter));
+        $this->adapter->expects($this->any())
+            ->method('select')
+            ->will($this->returnValue($this->select));
+
+        $this->storage = (new ObjectManager($this))->getObject(
+            'Magento\UrlRewrite\Model\Storage\DbStorage',
+            [
+                'urlRewriteBuilder' => $this->urlRewriteBuilder,
+                'resource' => $this->resource,
+            ]
+        );
+    }
+
+    public function testFindAllByData()
+    {
+        $data = ['col1' => 'val1', 'col2' => 'val2'];
+
+        $this->select->expects($this->at(1))
+            ->method('where')
+            ->with('col1 IN (?)', 'val1');
+
+        $this->select->expects($this->at(2))
+            ->method('where')
+            ->with('col2 IN (?)', 'val2');
+
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+
+        $this->adapter->expects($this->once())
+            ->method('fetchAll')
+            ->with($this->select)
+            ->will($this->returnValue([['row1'], ['row2']]));
+
+        $this->urlRewriteBuilder->expects($this->at(0))
+            ->method('populateWithArray')
+            ->with(['row1'])
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->at(1))
+            ->method('create')
+            ->will($this->returnValue(['urlRewrite1']));
+
+        $this->urlRewriteBuilder->expects($this->at(2))
+            ->method('populateWithArray')
+            ->with(['row2'])
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->at(3))
+            ->method('create')
+            ->will($this->returnValue(['urlRewrite2']));
+
+        $this->assertEquals([['urlRewrite1'], ['urlRewrite2']], $this->storage->findAllByData($data));
+    }
+
+    public function testFindOneByData()
+    {
+        $data = ['col1' => 'val1', 'col2' => 'val2'];
+
+        $this->select->expects($this->at(1))
+            ->method('where')
+            ->with('col1 IN (?)', 'val1');
+
+        $this->select->expects($this->at(2))
+            ->method('where')
+            ->with('col2 IN (?)', 'val2');
+
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+
+        $this->adapter->expects($this->once())
+            ->method('fetchRow')
+            ->with($this->select)
+            ->will($this->returnValue(['row1']));
+
+        $this->urlRewriteBuilder->expects($this->at(0))
+            ->method('populateWithArray')
+            ->with(['row1'])
+            ->will($this->returnSelf());
+
+        $this->urlRewriteBuilder->expects($this->at(1))
+            ->method('create')
+            ->will($this->returnValue(['urlRewrite1']));
+
+        $this->assertEquals(['urlRewrite1'], $this->storage->findOneByData($data));
+    }
+
+    public function testReplace()
+    {
+        $urlFirst = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewrite', [], [], '', false);
+        $urlSecond = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewrite', [], [], '', false);
+
+        // delete
+
+        $urlFirst->expects($this->any())
+            ->method('getByKey')
+            ->will($this->returnValueMap([
+                [UrlRewrite::ENTITY_TYPE, 'product'],
+                [UrlRewrite::ENTITY_ID, 'entity_1'],
+                [UrlRewrite::STORE_ID, 'store_id_1']
+            ]));
+        $urlFirst->expects($this->any())->method('getEntityType')->willReturn('product');
+        $urlSecond->expects($this->any())
+            ->method('getByKey')
+            ->will($this->returnValueMap([
+                [UrlRewrite::ENTITY_TYPE, 'category'],
+                [UrlRewrite::ENTITY_ID, 'entity_2'],
+                [UrlRewrite::STORE_ID, 'store_id_2']
+            ]));
+        $urlSecond->expects($this->any())->method('getEntityType')->willReturn('category');
+
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+
+        $this->select->expects($this->at(1))
+            ->method('where')
+            ->with('entity_id IN (?)', ['entity_1']);
+
+        $this->select->expects($this->at(2))
+            ->method('where')
+            ->with('store_id IN (?)', ['store_id_1']);
+
+        $this->select->expects($this->at(3))
+            ->method('where')
+            ->with('entity_type IN (?)', 'product');
+
+        $this->select->expects($this->at(4))
+            ->method('deleteFromSelect')
+            ->with('table_name')
+            ->will($this->returnValue('sql delete query'));
+
+        $this->select->expects($this->at(6))
+            ->method('where')
+            ->with('entity_id IN (?)', ['entity_2']);
+
+        $this->select->expects($this->at(7))
+            ->method('where')
+            ->with('store_id IN (?)', ['store_id_2']);
+
+        $this->select->expects($this->at(8))
+            ->method('where')
+            ->with('entity_type IN (?)', 'category');
+
+
+        $this->select->expects($this->at(9))
+            ->method('deleteFromSelect')
+            ->with('table_name')
+            ->will($this->returnValue('sql delete query'));
+
+        $this->resource->expects($this->any())
+            ->method('getTableName')
+            ->with(DbStorage::TABLE_NAME)
+            ->will($this->returnValue('table_name'));
+
+        $this->adapter->expects($this->any())
+            ->method('query')
+            ->with('sql delete query');
+
+        // insert
+
+        $urlFirst->expects($this->any())
+            ->method('toArray')
+            ->will($this->returnValue(['row1']));
+        $urlSecond->expects($this->any())
+            ->method('toArray')
+            ->will($this->returnValue(['row2']));
+
+        $this->resource->expects($this->any())
+            ->method('getTableName')
+            ->with(DbStorage::TABLE_NAME)
+            ->will($this->returnValue('table_name'));
+
+        $this->adapter->expects($this->once())
+            ->method('insertMultiple')
+            ->with('table_name', [['row1'], ['row2']]);
+
+        $this->storage->replace([$urlFirst, $urlSecond]);
+    }
+
+    /**
+     * @expectedException \Magento\UrlRewrite\Model\Storage\DuplicateEntryException
+     */
+    public function testReplaceIfThrewDuplicateEntryException()
+    {
+        $url = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewrite', [], [], '', false);
+
+        $url->expects($this->any())
+            ->method('toArray')
+            ->will($this->returnValue(['row1']));
+
+        $this->adapter->expects($this->once())
+            ->method('insertMultiple')
+            ->will(
+                $this->throwException(
+                    new \Exception('SQLSTATE[23000]: test: 1062 test', DbStorage::ERROR_CODE_DUPLICATE_ENTRY)
+                )
+            );
+
+        $this->storage->replace([$url]);
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testReplaceIfThrewCustomException()
+    {
+        $url = $this->getMock('Magento\UrlRewrite\Service\V1\Data\UrlRewrite', [], [], '', false);
+
+        $url->expects($this->any())
+            ->method('toArray')
+            ->will($this->returnValue(['row1']));
+
+        $this->adapter->expects($this->once())
+            ->method('insertMultiple')
+            ->will($this->throwException(new \RuntimeException()));
+
+        $this->storage->replace([$url]);
+    }
+
+    public function testDeleteByData()
+    {
+        $data = ['col1' => 'val1', 'col2' => 'val2'];
+
+        $this->adapter->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+
+        $this->select->expects($this->at(1))
+            ->method('where')
+            ->with('col1 IN (?)', 'val1');
+
+        $this->select->expects($this->at(2))
+            ->method('where')
+            ->with('col2 IN (?)', 'val2');
+
+        $this->select->expects($this->at(3))
+            ->method('deleteFromSelect')
+            ->with('table_name')
+            ->will($this->returnValue('sql delete query'));
+
+        $this->resource->expects($this->any())
+            ->method('getTableName')
+            ->with(DbStorage::TABLE_NAME)
+            ->will($this->returnValue('table_name'));
+
+        $this->adapter->expects($this->once())
+            ->method('query')
+            ->with('sql delete query');
+
+        $this->storage->deleteByData($data);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/OptionProviderTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/OptionProviderTest.php
deleted file mode 100644
index ec89f682b80..00000000000
--- a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/OptionProviderTest.php
+++ /dev/null
@@ -1,43 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Test class for \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider.
- */
-namespace Magento\UrlRewrite\Model\UrlRewrite;
-
-class OptionProviderTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @covers \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider::getAllOptions
-     */
-    public function testGetAllOptions()
-    {
-        $model = new \Magento\UrlRewrite\Model\UrlRewrite\OptionProvider();
-        $options = $model->getAllOptions();
-        $this->assertInternalType('array', $options);
-        $expectedOptions = array('' => 'No', 'R' => 'Temporary (302)', 'RP' => 'Permanent (301)');
-        $this->assertEquals($expectedOptions, $options);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/TypeProviderTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/TypeProviderTest.php
deleted file mode 100644
index 7e13ef7e204..00000000000
--- a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewrite/TypeProviderTest.php
+++ /dev/null
@@ -1,39 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\UrlRewrite\Model\UrlRewrite;
-
-class TypeProviderTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @covers \Magento\UrlRewrite\Model\UrlRewrite\TypeProvider::getAllOptions
-     */
-    public function testGetAllOptions()
-    {
-        $model = new \Magento\UrlRewrite\Model\UrlRewrite\TypeProvider();
-        $options = $model->getAllOptions();
-        $this->assertInternalType('array', $options);
-        $expectedOptions = array(1 => 'System', 0 => 'Custom');
-        $this->assertEquals($expectedOptions, $options);
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php b/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
deleted file mode 100644
index 404171484c1..00000000000
--- a/dev/tests/unit/testsuite/Magento/UrlRewrite/Model/UrlRewriteTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/**
- * Test class for /Magento/UrlRewrite/Model/UrlRewrite
- *
- * 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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\UrlRewrite\Model;
-
-use Magento\TestFramework\Helper\ObjectManager as ObjectManager;
-use Magento\UrlRewrite\Model\UrlRewrite as UrlRewrite;
-
-class UrlRewriteTest extends \PHPUnit_Framework_TestCase
-{
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewrite
-     */
-    private $model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $resourceMock;
-    
-    /**
-     * @var \Magento\TestFramework\Helper\ObjectManager
-     */
-    private $objectManager;
-
-    public function setUp()
-    {
-
-        $resourceMethods = ['getIdFieldName', 'loadByRequestPath', 'load',];
-        $this->resourceMock = $this->getMockForAbstractClass('\Magento\Framework\Model\Resource\AbstractResource',
-            [], '', false, true, true, $resourceMethods
-
-        );
-
-        $this->objectManager= new ObjectManager($this);
-
-        $this->model = $this->objectManager->getObject('\Magento\UrlRewrite\Model\UrlRewrite',
-        [
-            'resource' => $this->resourceMock,
-        ]
-        );
-    }
-
-    public function testLoadByRequestPath()
-    {
-        $path = 'path';
-
-        $this->resourceMock->expects($this->once())
-            ->method('loadByRequestPath')
-            ->with($this->model, $path);
-
-        $this->model->loadByRequestPath($path);
-
-    }
-
-    public function testLoadByIdPath()
-    {
-        $path = 'path';
-
-        $this->resourceMock->expects($this->once())
-            ->method('load')
-            ->with($this->model, $path, UrlRewrite::PATH_FIELD);
-
-        $this->model->loadByIdPath($path);
-    }
-
-    public function testHasOption()
-    {
-        $searchOption = 'option2';
-        $options='option1,' . $searchOption . ',option3';
-        $this->assertTrue($this->model->setOptions($options)->hasOption('option2'));
-    }
-
-    public function testGetStoreId()
-    {
-        $id = 42;
-        $this->assertEquals($id, $this->model->setStoreId($id)->getStoreId());
-    }
-} 
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php b/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
index a698b79d63b..605ee12b019 100644
--- a/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
+++ b/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Unit test for model \Magento\User\Model\User
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -24,11 +22,13 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\User\Model;
+
 /**
  * Test class for \Magento\User\Model\User testing
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-namespace Magento\User\Model;
-
 class UserTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\User\Model\User */
@@ -40,30 +40,33 @@ class UserTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Core\Helper\Data */
     protected $_coreData;
 
-    /** @var \Magento\Framework\Mail\Template\TransportBuilder|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */
     protected $_transportBuilderMock;
 
-    /** @var \Magento\Framework\Model\Context|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */
     protected $_contextMock;
 
-    /** @var \Magento\User\Model\Resource\User|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\User\Model\Resource\User|\PHPUnit_Framework_MockObject_MockObject */
     protected $_resourceMock;
 
-    /** @var \Magento\Framework\Data\Collection\Db|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Framework\Data\Collection\Db|\PHPUnit_Framework_MockObject_MockObject */
     protected $_collectionMock;
 
-    /** @var \Magento\Framework\Mail\TransportInterface|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Framework\Mail\TransportInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $_transportMock;
 
     /** @var \Magento\Framework\StoreManagerInterface|PHPUnit_Framework_MockObject_MockObject */
     protected $_storeManagerMock;
 
-    /** @var \Magento\Store\Model\Store|PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */
     protected $_storetMock;
 
     /** @var \Magento\Backend\App\ConfigInterface */
     protected $_configMock;
 
+    /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $_encryptorMock;
+
     /**
      * Set required values
      */
@@ -141,6 +144,10 @@ class UserTest extends \PHPUnit_Framework_TestCase
             array()
         )->getMock();
 
+        $this->_encryptorMock = $this->getMockBuilder('Magento\Framework\Encryption\EncryptorInterface')
+            ->setMethods(['validateHash'])
+            ->getMockForAbstractClass();
+
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->_model = $helper->getObject(
             'Magento\User\Model\User',
@@ -156,7 +163,8 @@ class UserTest extends \PHPUnit_Framework_TestCase
                 'roleFactory' => $roleFactoryMock,
                 'transportBuilder' => $this->_transportBuilderMock,
                 'storeManager' => $this->_storeManagerMock,
-                'config' => $this->_configMock
+                'config' => $this->_configMock,
+                'encryptor' => $this->_encryptorMock
             )
         );
     }
@@ -339,4 +347,61 @@ class UserTest extends \PHPUnit_Framework_TestCase
 
         $this->assertInstanceOf('\Magento\User\Model\User', $this->_model->sendPasswordResetConfirmationEmail());
     }
+
+    public function testVerifyIdentity()
+    {
+        $password = 'password';
+        $this->_encryptorMock
+            ->expects($this->once())
+            ->method('validateHash')
+            ->with($password, $this->_model->getPassword())
+            ->will($this->returnValue(true));
+        $this->_model->setIsActive(true);
+        $this->_resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(true));
+        $this->assertTrue(
+            $this->_model->verifyIdentity($password),
+            'Identity verification failed while should have passed.'
+        );
+    }
+
+    public function testVerifyIdentityFailure()
+    {
+        $password = 'password';
+        $this->_encryptorMock
+            ->expects($this->once())
+            ->method('validateHash')
+            ->with($password, $this->_model->getPassword())
+            ->will($this->returnValue(false));
+        $this->assertFalse(
+            $this->_model->verifyIdentity($password),
+            'Identity verification passed while should have failed.'
+        );
+    }
+
+    public function testVerifyIdentityInactiveRecord()
+    {
+        $password = 'password';
+        $this->_encryptorMock
+            ->expects($this->once())
+            ->method('validateHash')
+            ->with($password, $this->_model->getPassword())
+            ->will($this->returnValue(true));
+        $this->_model->setIsActive(false);
+        $this->setExpectedException('Magento\Backend\Model\Auth\Exception', 'This account is inactive.');
+        $this->_model->verifyIdentity($password);
+    }
+
+    public function testVerifyIdentityNoAssignedRoles()
+    {
+        $password = 'password';
+        $this->_encryptorMock
+            ->expects($this->once())
+            ->method('validateHash')
+            ->with($password, $this->_model->getPassword())
+            ->will($this->returnValue(true));
+        $this->_model->setIsActive(true);
+        $this->_resourceMock->expects($this->once())->method('hasAssigned2Role')->will($this->returnValue(false));
+        $this->setExpectedException('Magento\Backend\Model\Auth\Exception', 'Access denied.');
+        $this->_model->verifyIdentity($password);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/_files/webapi.php b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
index a96970f7d57..436f7f61dbc 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/_files/webapi.php
@@ -26,40 +26,23 @@ return [
         'Magento\Customer\Service\V1\CustomerServiceInterface' => [
             'getCustomer' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Customer::customer_self'
-                    ],
-                    1 => [
-                        'Magento_Customer::customer_self'
-                    ],
-                    2 => [
-                        'Magento_Customer::read'
-                    ],
+                    'Magento_Customer::customer_self',
+                    'Magento_Customer::read',
                 ],
                 'secure' => false,
             ],
             'updateCustomer' => [
-                'resources' => [
-                    0 => [
-                        'Magento_Customer::customer_self'
-                    ]
-                ],
+                'resources' => ['Magento_Customer::customer_self'],
                 'secure' => true,
             ],
             'createCustomer' => [
-                'resources' => [
-                    0 => [
-                        'Magento_Customer::manage'
-                    ]
-                ],
+                'resources' => ['Magento_Customer::manage'],
                 'secure' => false,
             ],
             'deleteCustomer' => [
                 'resources' => [
-                    0 => [
-                        'Magento_Customer::manage',
-                        'Magento_Customer::delete'
-                    ]
+                    'Magento_Customer::manage',
+                    'Magento_Customer::delete'
                 ],
                 'secure' => false,
             ],
diff --git a/dev/tests/unit/testsuite/Magento/Weee/Pricing/Render/AdjustmentTest.php b/dev/tests/unit/testsuite/Magento/Weee/Pricing/Render/AdjustmentTest.php
index 31b46fc960e..5639bef7298 100644
--- a/dev/tests/unit/testsuite/Magento/Weee/Pricing/Render/AdjustmentTest.php
+++ b/dev/tests/unit/testsuite/Magento/Weee/Pricing/Render/AdjustmentTest.php
@@ -332,11 +332,11 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
     public function getWeeeTaxAttributesDataProvider()
     {
         return [
-            [\Magento\Weee\Model\Tax::DISPLAY_INCL, [1,2,3], []],
-            [\Magento\Weee\Model\Tax::DISPLAY_INCL_DESCR, [1,2,3], [1,2,3]],
-            [\Magento\Weee\Model\Tax::DISPLAY_EXCL_DESCR_INCL, [1,2,3], [1,2,3]],
-            [\Magento\Weee\Model\Tax::DISPLAY_EXCL, [1,2,3], []],
-            [4, [1,2,3], []],
+            [\Magento\Weee\Model\Tax::DISPLAY_INCL, [1, 2, 3], []],
+            [\Magento\Weee\Model\Tax::DISPLAY_INCL_DESCR, [1, 2, 3], [1, 2, 3]],
+            [\Magento\Weee\Model\Tax::DISPLAY_EXCL_DESCR_INCL, [1, 2, 3], [1, 2, 3]],
+            [\Magento\Weee\Model\Tax::DISPLAY_EXCL, [1, 2, 3], []],
+            [4, [1, 2, 3], []],
         ];
     }
 
@@ -345,9 +345,9 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
      *
      * @param \Magento\Framework\Object $attribute
      * @param string $expectedResult
-     * @dataProvider renderWeeeTaxAttributeDataProvider
+     * @dataProvider renderWeeeTaxAttributeAmountDataProvider
      */
-    public function testRenderWeeeTaxAttribute($attribute, $expectedResult)
+    public function testRenderWeeeTaxAttributeAmount($attribute, $expectedResult)
     {
         $this->priceCurrencyMock->expects($this->any())->method('convertAndFormat')->will($this->returnArgument(0));
 
@@ -356,17 +356,43 @@ class AdjustmentTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Data provider for testRenderWeeeTaxAttribute
+     * Data provider for testRenderWeeeTaxAttributeAmount
      *
      * @return array
      */
-    public function renderWeeeTaxAttributeDataProvider()
+    public function renderWeeeTaxAttributeAmountDataProvider()
     {
         return [
-            [new \Magento\Framework\Object(['name' => 'name1', 'amount' => 51]), 'name1: 51'],
-            [new \Magento\Framework\Object(['name' => 'name1', 'amount' => false]), 'name1: '],
-            [new \Magento\Framework\Object(['name' => false, 'amount' => 51]), ': 51'],
-            [new \Magento\Framework\Object(['name' => false, 'amount' => false]), ': '],
+            [new \Magento\Framework\Object(['amount' => 51]), 51],
+            [new \Magento\Framework\Object(['amount' => false]), false],
+        ];
+    }
+
+    /**
+     * Test for method renderWeeeTaxAttributeName
+     *
+     * @param \Magento\Framework\Object $attribute
+     * @param string $expectedResult
+     * @dataProvider renderWeeeTaxAttributeNameDataProvider
+     */
+    public function testRenderWeeeTaxAttributeName($attribute, $expectedResult)
+    {
+        $this->priceCurrencyMock->expects($this->any())->method('convertAndFormat')->will($this->returnArgument(0));
+
+        $result = $this->model->renderWeeeTaxAttributeName($attribute);
+        $this->assertEquals($expectedResult, $result);
+    }
+
+    /**
+     * Data provider for testRenderWeeeTaxAttributeName
+     *
+     * @return array
+     */
+    public function renderWeeeTaxAttributeNameDataProvider()
+    {
+        return [
+            [new \Magento\Framework\Object(['name' => 51]), 51],
+            [new \Magento\Framework\Object(['name' => false]), false],
         ];
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Block/Rss/LinkTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Block/Rss/LinkTest.php
new file mode 100644
index 00000000000..8bc5d349f4c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Block/Rss/LinkTest.php
@@ -0,0 +1,101 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Wishlist\Block\Rss;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class LinkTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Wishlist\Block\Rss\Link */
+    protected $link;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Wishlist\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $wishlistHelper;
+
+    /** @var \Magento\Framework\App\Rss\UrlBuilderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlBuilder;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    protected function setUp()
+    {
+        $wishlist = $this->getMock('Magento\Wishlist\Model\Wishlist', [], [], '', false);
+        $wishlist->expects($this->any())->method('getId')->will($this->returnValue(5));
+
+        $customer = $this->getMock('Magento\Customer\Service\V1\Data\Customer', [], [], '', false);
+        $customer->expects($this->any())->method('getId')->will($this->returnValue(8));
+        $customer->expects($this->any())->method('getEmail')->will($this->returnValue('test@example.com'));
+
+        $this->wishlistHelper = $this->getMock(
+            'Magento\Wishlist\Helper\Data',
+            ['getWishlist', 'getCustomer'],
+            [],
+            '',
+            false
+        );
+        $this->wishlistHelper->expects($this->any())->method('getWishlist')->will($this->returnValue($wishlist));
+        $this->wishlistHelper->expects($this->any())->method('getCustomer')->will($this->returnValue($customer));
+
+        $this->urlBuilder = $this->getMock('Magento\Framework\App\Rss\UrlBuilderInterface');
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->link = $this->objectManagerHelper->getObject(
+            'Magento\Wishlist\Block\Rss\Link',
+            [
+                'wishlistHelper' => $this->wishlistHelper,
+                'rssUrlBuilder' => $this->urlBuilder,
+                'scopeConfig' => $this->scopeConfig
+            ]
+        );
+    }
+
+    public function testGetLink()
+    {
+        $this->urlBuilder->expects($this->atLeastOnce())->method('getUrl')
+            ->with($this->equalTo(array(
+                'type' => 'wishlist',
+                'data' => 'OCx0ZXN0QGV4YW1wbGUuY29t',
+                '_secure' => false,
+                'wishlist_id' => 5
+            )))
+            ->will($this->returnValue('http://url.com/rss/feed/index/type/wishlist/wishlist_id/5'));
+        $this->assertEquals('http://url.com/rss/feed/index/type/wishlist/wishlist_id/5', $this->link->getLink());
+    }
+
+    public function testIsRssAllowed()
+    {
+        $this->scopeConfig
+            ->expects($this->atLeastOnce())
+            ->method('isSetFlag')
+            ->with('rss/wishlist/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertEquals(true, $this->link->isRssAllowed());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php
new file mode 100644
index 00000000000..56658a74b1d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller;
+
+class WishlistProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProvider
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Wishlist\Model\WishlistFactory
+     */
+    protected $wishlistFactory;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * Set up mock objects for tested class
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->request = $this->getMock(
+            '\Magento\Framework\App\RequestInterface',
+            ['getModuleName', 'setModuleName', 'getActionName', 'setActionName', 'getCookie', 'getParam'],
+            [],
+            '',
+            false
+        );
+
+        $this->wishlistFactory = $this->getMock(
+            '\Magento\Wishlist\Model\WishlistFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+
+        $this->customerSession = $this->getMock(
+            '\Magento\Customer\Model\Session',
+            ['getCustomerId'],
+            [],
+            '',
+            false
+        );
+
+        $this->messageManager = $this->getMock(
+            '\Magento\Framework\Message\ManagerInterface',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->wishlistProvider = $objectManager->getObject(
+            '\Magento\Wishlist\Controller\WishlistProvider',
+            [
+                'request' => $this->request,
+                'wishlistFactory' => $this->wishlistFactory,
+                'customerSession' => $this->customerSession,
+                'messageManager' => $this->messageManager
+            ]
+        );
+    }
+
+    public function testGetWishlist()
+    {
+        $wishlist = $this->getMock('\Magento\Wishlist\Model\Wishlist', [], [], '', false);
+
+        $this->wishlistFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($wishlist));
+
+        $this->assertEquals($wishlist, $this->wishlistProvider->getWishlist());
+    }
+
+    public function testGetWishlistWithCustomer()
+    {
+        $wishlist = $this->getMock(
+            '\Magento\Wishlist\Model\Wishlist',
+            ['loadByCustomerId', 'getId', 'getCustomerId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $wishlist->expects($this->once())
+            ->method('loadByCustomerId')
+            ->will($this->returnSelf());
+        $wishlist->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $wishlist->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue(1));
+
+        $this->wishlistFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($wishlist));
+
+        $this->customerSession->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue(1));
+
+        $this->assertEquals($wishlist, $this->wishlistProvider->getWishlist());
+    }
+
+    public function testGetWishlistWithIdAndCustomer()
+    {
+        $wishlist = $this->getMock(
+            '\Magento\Wishlist\Model\Wishlist',
+            ['loadByCustomerId', 'load', 'getId', 'getCustomerId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $wishlist->expects($this->once())
+            ->method('load')
+            ->will($this->returnSelf());
+        $wishlist->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $wishlist->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue(1));
+
+        $this->wishlistFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($wishlist));
+
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->will($this->returnValue(1));
+
+        $this->customerSession->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue(1));
+
+        $this->assertEquals($wishlist, $this->wishlistProvider->getWishlist());
+    }
+
+    public function testGetWishlistWithIdWithoutCustomer()
+    {
+        $wishlist = $this->getMock(
+            '\Magento\Wishlist\Model\Wishlist',
+            ['loadByCustomerId', 'load', 'getId', 'getCustomerId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $wishlist->expects($this->once())
+            ->method('load')
+            ->will($this->returnSelf());
+        $wishlist->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $wishlist->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue(1));
+
+        $this->wishlistFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($wishlist));
+
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->will($this->returnValue(1));
+
+        $this->assertEquals(false, $this->wishlistProvider->getWishlist());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Helper/DataTest.php
index 70b58ed5e57..c71af89bd7e 100644
--- a/dev/tests/unit/testsuite/Magento/Wishlist/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Helper/DataTest.php
@@ -25,47 +25,118 @@ namespace Magento\Wishlist\Helper;
 
 class DataTest extends \PHPUnit_Framework_TestCase
 {
-    public function testGetAddToCartUrl()
+    /**
+     * @var \Magento\Wishlist\Helper\Data
+     */
+    protected $wishlistHelper;
+
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $coreRegistry;
+
+    /**
+     * @var string
+     */
+    protected $url;
+
+    /**
+     * Set up mock objects for tested class
+     *
+     * @return void
+     */
+    public function setUp()
     {
-        $url = 'http://magento.com/wishlist/index/index/wishlist_id/1/?___store=default';
+        $this->url = 'http://magento.com/wishlist/index/index/wishlist_id/1/?___store=default';
         $encoded = 'encodedUrl';
 
-        $coreData = $this->getMock('Magento\Core\Helper\Data', array(), array(), '', false);
+        $coreData = $this->getMock('Magento\Core\Helper\Data', [], [], '', false);
         $coreData->expects($this->any())
             ->method('urlEncode')
-            ->with($url)
+            ->with($this->url)
             ->will($this->returnValue($encoded));
 
-        $store = $this->getMock('Magento\Store\Model\Store', array(), array(), '', false);
+        $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
         $store->expects($this->any())
             ->method('getUrl')
-            ->with('wishlist/index/cart', array('item' => '%item%', 'uenc' => $encoded))
-            ->will($this->returnValue($url));
+            ->with('wishlist/index/cart', ['item' => '%item%', 'uenc' => $encoded])
+            ->will($this->returnValue($this->url));
 
-        $storeManager = $this->getMock('Magento\Framework\StoreManagerInterface', array(), array(), '', false);
+        $storeManager = $this->getMockBuilder('Magento\Framework\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
         $storeManager->expects($this->any())
             ->method('getStore')
             ->will($this->returnValue($store));
 
-        $urlBuilder = $this->getMock('Magento\Framework\UrlInterface\Proxy', array('getUrl'), array(), '', false);
+        $urlBuilder = $this->getMock('Magento\Framework\UrlInterface\Proxy', ['getUrl'], [], '', false);
         $urlBuilder->expects($this->any())
             ->method('getUrl')
-            ->with('*/*/*', array('_current' => true, '_use_rewrite' => true, '_scope_to_url' => true))
-            ->will($this->returnValue($url));
+            ->with('*/*/*', ['_current' => true, '_use_rewrite' => true, '_scope_to_url' => true])
+            ->will($this->returnValue($this->url));
 
-        $context = $this->getMock('Magento\Framework\App\Helper\Context', array(), array(), '', false);
+        $context = $this->getMock('Magento\Framework\App\Helper\Context', [], [], '', false);
         $context->expects($this->once())
             ->method('getUrlBuilder')
             ->will($this->returnValue($urlBuilder));
 
+        $this->wishlistProvider = $this->getMock(
+            'Magento\Wishlist\Controller\WishlistProviderInterface',
+            ['getWishlist'],
+            [],
+            '',
+            false
+        );
+
+        $this->coreRegistry = $this->getMock(
+            '\Magento\Framework\Registry',
+            ['registry'],
+            [],
+            '',
+            false
+        );
+
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
 
-        /** @var \Magento\Wishlist\Helper\Data $wishlistHelper */
-        $wishlistHelper = $objectManager->getObject(
+        $this->wishlistHelper = $objectManager->getObject(
             'Magento\Wishlist\Helper\Data',
-            array('context' => $context, 'storeManager' => $storeManager, 'coreData' => $coreData)
+            [
+                'context' => $context,
+                'storeManager' => $storeManager,
+                'coreData' => $coreData,
+                'wishlistProvider' => $this->wishlistProvider,
+                'coreRegistry' => $this->coreRegistry
+            ]
         );
+    }
+
+    public function testGetAddToCartUrl()
+    {
+        $this->assertEquals($this->url, $this->wishlistHelper->getAddToCartUrl('%item%'));
+    }
+
+    public function testGetWishlist()
+    {
+        $wishlist = $this->getMock('\Magento\Wishlist\Model\Wishlist', [], [], '', false);
+        $this->wishlistProvider->expects($this->once())
+            ->method('getWishlist')
+            ->will($this->returnValue($wishlist));
+
+        $this->assertEquals($wishlist, $this->wishlistHelper->getWishlist());
+    }
+
+    public function testGetWishlistWithCoreRegistry()
+    {
+        $wishlist = $this->getMock('\Magento\Wishlist\Model\Wishlist', [], [], '', false);
+        $this->coreRegistry->expects($this->any())
+            ->method('registry')
+            ->will($this->returnValue($wishlist));
 
-        $this->assertEquals($url, $wishlistHelper->getAddToCartUrl('%item%'));
+        $this->assertEquals($wishlist, $this->wishlistHelper->getWishlist());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Model/ObserverTest.php
index 54c346b2fb1..0d3ebe7c808 100644
--- a/dev/tests/unit/testsuite/Magento/Wishlist/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Model/ObserverTest.php
@@ -142,6 +142,10 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     public function testProcessCartUpdateBefore()
     {
         $customerId = 1;
@@ -158,12 +162,12 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $eventObserver->expects($this->any())
+        $eventObserver->expects($this->exactly(2))
             ->method('getEvent')
             ->willReturn($event);
 
         $quoteItem = $this->getMockBuilder('Magento\Sales\Model\Quote\Item')
-            ->setMethods(['getProductId', 'getBuyRequest'])
+            ->setMethods(['getProductId', 'getBuyRequest', '__wakeup'])
             ->disableOriginalConstructor()
             ->getMock();
 
@@ -172,9 +176,18 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
+        $infoData = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['toArray'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $infoData->expects($this->once())
+            ->method('toArray')
+            ->willReturn([$itemId => ['qty' => $itemQty, 'wishlist' => true]]);
+
         $cart = $this->getMockBuilder('Magento\Checkout\Model\Cart')->disableOriginalConstructor()->getMock();
         $quote = $this->getMockBuilder('Magento\Sales\Model\Quote')
-            ->setMethods(['getCustomerId', 'getItemById', 'removeItem'])
+            ->setMethods(['getCustomerId', 'getItemById', 'removeItem', '__wakeup'])
             ->disableOriginalConstructor()
             ->getMock();
 
@@ -184,7 +197,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
 
         $event->expects($this->once())
             ->method('getInfo')
-            ->willReturn([$itemId => ['qty' => $itemQty, 'wishlist' => true]]);
+            ->willReturn($infoData);
 
         $cart->expects($this->any())
             ->method('getQuote')
@@ -231,8 +244,8 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             ->method('calculate');
 
         /** @var $eventObserver \Magento\Framework\Event\Observer */
-        $this->assertInstanceOf(
-            'Magento\Wishlist\Model\Observer',
+        $this->assertSame(
+            $this->observer,
             $this->observer->processCartUpdateBefore($eventObserver)
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Block/RssTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Model/Rss/WishlistTest.php
similarity index 56%
rename from dev/tests/unit/testsuite/Magento/Wishlist/Block/RssTest.php
rename to dev/tests/unit/testsuite/Magento/Wishlist/Model/Rss/WishlistTest.php
index d58267781d4..943592bb062 100644
--- a/dev/tests/unit/testsuite/Magento/Wishlist/Block/RssTest.php
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Model/Rss/WishlistTest.php
@@ -22,23 +22,19 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Wishlist\Block;
+namespace Magento\Wishlist\Model\Rss;
 
-/**
- * Test for rendering price html in rss templates
- *
- */
-class RssTest extends \PHPUnit_Framework_TestCase
+class WishlistTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Wishlist\Block\Rss
+     * @var \Magento\Wishlist\Model\Rss\Wishlist
      */
-    protected $block;
+    protected $model;
 
     /**
-     * @var \Magento\Catalog\Model\ProductFactory
+     * @var \Magento\Wishlist\Block\Customer\Wishlist
      */
-    protected $productFactoryMock;
+    protected $wishlistBlock;
 
     /**
      * @var \Magento\Rss\Model\RssFactory
@@ -51,19 +47,14 @@ class RssTest extends \PHPUnit_Framework_TestCase
     protected $urlBuilderMock;
 
     /**
-     * @var \Magento\Core\Helper\Data
-     */
-    protected $coreHelperMock;
-
-    /**
-     * @var \Magento\Wishlist\Helper\Data
+     * @var \Magento\Wishlist\Helper\Rss
      */
     protected $wishlistHelperMock;
 
     /**
      * @var \Magento\Framework\App\Config\ScopeConfigInterface
      */
-    protected $storeConfigMock;
+    protected $scopeConfig;
 
     /**
      * @var \Magento\Catalog\Helper\Image
@@ -75,6 +66,11 @@ class RssTest extends \PHPUnit_Framework_TestCase
      */
     protected $catalogOutputMock;
 
+    /**
+     * @var \Magento\Catalog\Helper\Output
+     */
+    protected $layoutMock;
+
     /**
      * Set up mock objects for tested class
      *
@@ -82,22 +78,11 @@ class RssTest extends \PHPUnit_Framework_TestCase
      */
     public function setUp()
     {
-        $templateContextMock = $this->getMock('Magento\Catalog\Block\Product\Context', [], [], '', false);
-        $this->coreHelperMock = $this->getMock('Magento\Core\Helper\Data', [], [], '', false);
         $this->catalogOutputMock = $this->getMock('Magento\Catalog\Helper\Output', [], [], '', false);
-        $wishlistFactoryMock = $this->getMock('Magento\Wishlist\Model\WishlistFactory', [], [], '', false);
         $this->rssFactoryMock = $this->getMock('Magento\Rss\Model\RssFactory', ['create'], [], '', false);
-        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
-        $cacheStateMock = $this->getMock('Magento\Framework\App\Cache\StateInterface', [], [], '', false);
-        $this->productFactoryMock = $this->getMock(
-            'Magento\Catalog\Model\ProductFactory',
-            ['create', '__wakeup'],
-            [],
-            '',
-            false
-        );
+        $this->wishlistBlock = $this->getMock('\Magento\Wishlist\Block\Customer\Wishlist', [], [], '', false);
         $this->wishlistHelperMock = $this->getMock(
-            'Magento\Wishlist\Helper\Data',
+            'Magento\Wishlist\Helper\Rss',
             ['getWishlist', 'getCustomer', 'getCustomerName'],
             [],
             '',
@@ -112,7 +97,7 @@ class RssTest extends \PHPUnit_Framework_TestCase
             true,
             ['getUrl']
         );
-        $this->storeConfigMock = $this->getMockForAbstractClass(
+        $this->scopeConfig = $this->getMockForAbstractClass(
             'Magento\Framework\App\Config\ScopeConfigInterface',
             [],
             '',
@@ -123,48 +108,37 @@ class RssTest extends \PHPUnit_Framework_TestCase
         );
         $this->imageHelperMock = $this->getMock('Magento\Catalog\Helper\Image', [], [], '', false);
 
-        $templateContextMock->expects($this->once())
-            ->method('getEventManager')
-            ->will($this->returnValue($eventManagerMock));
-        $templateContextMock->expects($this->once())
-            ->method('getCacheState')
-            ->will($this->returnValue($cacheStateMock));
-        $templateContextMock->expects($this->once())
-            ->method('getImageHelper')
-            ->will($this->returnValue($this->imageHelperMock));
-        $templateContextMock->expects($this->once())
-            ->method('getWishlistHelper')
-            ->will($this->returnValue($this->wishlistHelperMock));
-        $templateContextMock->expects($this->once())
-            ->method('getScopeConfig')
-            ->will($this->returnValue($this->storeConfigMock));
-        $templateContextMock->expects($this->once())
-            ->method('getUrlBuilder')
-            ->will($this->returnValue($this->urlBuilderMock));
+        $this->layoutMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\LayoutInterface',
+            [],
+            '',
+            true,
+            true,
+            true,
+            ['getBlock']
+        );
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $objectManager->getObject(
-            'Magento\Wishlist\Block\Rss',
+        $this->model = $objectManager->getObject(
+            'Magento\Wishlist\Model\Rss\Wishlist',
             [
-                'context' => $templateContextMock,
-                'productFactory' => $this->productFactoryMock,
-                'coreData' => $this->coreHelperMock,
-                'wishlistFactory' => $wishlistFactoryMock,
+                'wishlistHelper' => $this->wishlistHelperMock,
+                'wishlistBlock' => $this->wishlistBlock,
+                'outputHelper' => $this->catalogOutputMock,
+                'imageHelper'=> $this->imageHelperMock,
+                'urlBuilder' => $this->urlBuilderMock,
+                'scopeConfig' => $this->scopeConfig,
                 'rssFactory' => $this->rssFactoryMock,
-                'outputHelper' => $this->catalogOutputMock
+                'layout' => $this->layoutMock,
             ]
         );
     }
 
-    /**
-     * Test for method _toHtml
-     */
-    public function testToHtml()
+    public function testGetRssData()
     {
         $wishlistId = 1;
         $customerName = 'Customer Name';
         $title = "$customerName's Wishlist";
-        $rssObjMock = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
         $wishlistModelMock = $this->getMock(
             'Magento\Wishlist\Model\Wishlist',
             ['getId', '__wakeup', 'getCustomerId', 'getItemCollection'],
@@ -177,22 +151,11 @@ class RssTest extends \PHPUnit_Framework_TestCase
         $locale = 'en_US';
         $productUrl = 'http://product.url/';
         $productName = 'Product name';
-        $expectedHeaders = [
-            'title' => $title,
-            'description' => $title,
-            'link' => $wishlistSharingUrl,
-            'charset' => 'UTF-8',
-            'language' => $locale
-        ];
 
-
-        $this->rssFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($rssObjMock));
-        $this->wishlistHelperMock->expects($this->once())
+        $this->wishlistHelperMock->expects($this->any())
             ->method('getWishlist')
             ->will($this->returnValue($wishlistModelMock));
-        $this->wishlistHelperMock->expects($this->once())
+        $this->wishlistHelperMock->expects($this->any())
             ->method('getCustomer')
             ->will($this->returnValue($customerServiceMock));
         $this->wishlistHelperMock->expects($this->once())
@@ -204,7 +167,7 @@ class RssTest extends \PHPUnit_Framework_TestCase
         $this->urlBuilderMock->expects($this->once())
             ->method('getUrl')
             ->will($this->returnValue($wishlistSharingUrl));
-        $this->storeConfigMock->expects($this->any())
+        $this->scopeConfig->expects($this->any())
             ->method('getValue')
             ->will($this->returnValueMap(
                     [
@@ -215,7 +178,7 @@ class RssTest extends \PHPUnit_Framework_TestCase
                             null
                         ],
                         [
-                            'general/locale/code',
+                            \Magento\Core\Helper\Data::XML_PATH_DEFAULT_LOCALE,
                             \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
                             null,
                             $locale
@@ -229,25 +192,23 @@ class RssTest extends \PHPUnit_Framework_TestCase
             'productUrl' => $productUrl
         ];
         $description = $this->processWishlistItemDescription($wishlistModelMock, $staticArgs);
-        $expectedEntry = [
-            'title' => $productName,
-            'link' => $productUrl,
-            'description' => $description
-        ];
-        $rssString = '';
 
-        $rssObjMock->expects($this->once())
-            ->method('_addHeader')
-            ->with($expectedHeaders)
-            ->will($this->returnSelf());
-        $rssObjMock->expects($this->once())
-            ->method('_addEntry')
-            ->with($expectedEntry);
-        $rssObjMock->expects($this->once())
-            ->method('createRssXml')
-            ->will($this->returnValue($rssString));
+        $expectedResult = array(
+            'title' => $title,
+            'description' => $title,
+            'link' => $wishlistSharingUrl,
+            'charset' => 'UTF-8',
+            'entries' => array(
+                0 => array(
+                    'title' => $productName,
+                    'link' => $productUrl,
+                    'description' => $description
+                )
+            )
+        );
+
 
-        $this->assertEquals($rssString, $this->block->toHtml());
+        $this->assertEquals($expectedResult, $this->model->getRssData());
     }
 
     /**
@@ -276,24 +237,12 @@ class RssTest extends \PHPUnit_Framework_TestCase
                 'getDescription',
                 'getShortDescription',
                 'getName',
-                'getVisibleInSiteVisibilities',
-                'getUrlModel',
                 '__wakeup'
             ],
             [],
             '',
             false
         );
-        $urlModelMock = $this->getMock('Magento\Catalog\Model\Product\Url', [], [], '', false);
-        $layoutMock = $this->getMockForAbstractClass(
-            'Magento\Framework\View\LayoutInterface',
-            [],
-            '',
-            true,
-            true,
-            true,
-            ['getBlock']
-        );
 
         $wishlistModelMock->expects($this->once())
             ->method('getItemCollection')
@@ -301,24 +250,15 @@ class RssTest extends \PHPUnit_Framework_TestCase
         $wishlistItem->expects($this->once())
             ->method('getProduct')
             ->will($this->returnValue($productMock));
-        $productMock->expects($this->once())
-            ->method('getUrlModel')
-            ->will($this->returnValue($urlModelMock));
         $productMock->expects($this->once())
             ->method('getAllowedPriceInRss')
-            ->will($this->returnValue($urlModelMock));
-        $urlModelMock->expects($this->once())
-            ->method('getUrl')
-            ->will($this->returnValue($staticArgs['productUrl']));
+            ->will($this->returnValue(true));
         $productMock->expects($this->once())
             ->method('getName')
             ->will($this->returnValue($staticArgs['productName']));
         $productMock->expects($this->once())
             ->method('getAllowedInRss')
             ->will($this->returnValue(true));
-        $productMock->expects($this->once())
-            ->method('getVisibleInSiteVisibilities')
-            ->will($this->returnValue(true));
         $this->imageHelperMock->expects($this->once())
             ->method('init')
             ->will($this->returnSelf());
@@ -327,7 +267,7 @@ class RssTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($imgThumbSrc));
         $priceRendererMock = $this->getMock('Magento\Framework\Pricing\Render', ['render'], [], '', false);
 
-        $layoutMock->expects($this->once())
+        $this->layoutMock->expects($this->once())
             ->method('getBlock')
             ->will($this->returnValue($priceRendererMock));
         $priceRendererMock->expects($this->once())
@@ -342,8 +282,12 @@ class RssTest extends \PHPUnit_Framework_TestCase
         $this->catalogOutputMock->expects($this->any())
             ->method('productAttribute')
             ->will($this->returnArgument(1));
+        $this->wishlistBlock
+            ->expects($this->any())
+            ->method('getProductUrl')
+            ->with($productMock, ['_rss' => true])
+            ->will($this->returnValue($staticArgs['productUrl']));
 
-        $this->block->setLayout($layoutMock);
         $description = '<table><tr><td><a href="' . $staticArgs['productUrl'] . '"><img src="' . $imgThumbSrc .
             '" border="0" align="left" height="75" width="75"></a></td><td style="text-decoration:none;">' .
             $productShortDescription . '<p>' . $priceHtmlForTest . '</p><p>Comment: ' . $productDescription . '<p>' .
@@ -352,52 +296,21 @@ class RssTest extends \PHPUnit_Framework_TestCase
         return $description;
     }
 
-    /**
-     * Test for method _toHtml for the case, when wishlist is absent
-     */
-    public function testToHtmlWithoutWishlist()
+    public function testIsAllowed()
     {
-        $url = 'http://base.url/index';
-        $rssString = '<xml>Some empty xml</xml>';
-        $rssObjMock = $this->getMock('Magento\Rss\Model\Rss', [], [], '', false);
-        $customerServiceMock = $this->getMock('Magento\Customer\Service\V1\Data\Customer', [], [], '', false);
-        $wishlistModelMock = $this->getMock(
-            'Magento\Wishlist\Model\Wishlist',
-            ['getId', '__wakeup', 'getCustomerId'],
-            [],
-            '',
-            false
-        );
-        $expectedHeaders = [
-            'title' => __('We cannot retrieve the wish list.'),
-            'description' => __('We cannot retrieve the wish list.'),
-            'link' => $url,
-            'charset' => 'UTF-8'
-        ];
+        $this->scopeConfig->expects($this->once())->method('getValue')
+            ->with('rss/wishlist/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue(true));
+        $this->assertTrue($this->model->isAllowed());
+    }
 
-        $this->rssFactoryMock->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($rssObjMock));
-        $this->wishlistHelperMock->expects($this->once())
-            ->method('getWishlist')
-            ->will($this->returnValue($wishlistModelMock));
-        $wishlistModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue(false));
-        $this->urlBuilderMock->expects($this->once())
-            ->method('getUrl')
-            ->will($this->returnValue($url));
-        $this->wishlistHelperMock->expects($this->once())
-            ->method('getCustomer')
-            ->will($this->returnValue($customerServiceMock));
-        $rssObjMock->expects($this->once())
-            ->method('_addHeader')
-            ->with($expectedHeaders)
-            ->will($this->returnSelf());
-        $rssObjMock->expects($this->once())
-            ->method('createRssXml')
-            ->will($this->returnValue($rssString));
+    public function testGetCacheKey()
+    {
+        $this->assertEquals('rss_wishlist_data', $this->model->getCacheKey());
+    }
 
-        $this->assertEquals($rssString, $this->block->toHtml());
+    public function testGetCacheLifetime()
+    {
+        $this->assertEquals(60, $this->model->getCacheLifetime());
     }
 }
diff --git a/dev/tools/Magento/Tools/Migration/Acl/log/AclXPathToAclId.log b/dev/tools/Magento/Tools/Migration/Acl/log/AclXPathToAclId.log
index c3479226d7d..558cb0580c5 100644
--- a/dev/tools/Magento/Tools/Migration/Acl/log/AclXPathToAclId.log
+++ b/dev/tools/Magento/Tools/Migration/Acl/log/AclXPathToAclId.log
@@ -1 +1 @@
-{"config\/acl\/resources\/admin\/cms\/magento_banner":"Magento_Banner::magento_banner","config\/acl\/resources\/admin\/catalog\/events":"Magento_CatalogEvent::events","config\/acl\/resources\/admin\/system\/config\/magento_catalogpermissions":"Magento_CatalogPermissions::magento_catalogpermissions","config\/acl\/resources\/admin\/catalog\/magento_catalogpermissions":"Magento_CatalogPermissions::catalog_magento_catalogpermissions","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout":"Magento_AdvancedCheckout::magento_advancedcheckout","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout\/view":"Magento_AdvancedCheckout::view","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout\/update":"Magento_AdvancedCheckout::update","config\/acl\/resources\/admin\/cms\/page\/save_revision":"Magento_VersionsCms::save_revision","config\/acl\/resources\/admin\/cms\/page\/delete_revision":"Magento_VersionsCms::delete_revision","config\/acl\/resources\/admin\/cms\/page\/publish_revision":"Magento_VersionsCms::publish_revision","config\/acl\/resources\/admin\/cms\/hierarchy":"Magento_VersionsCms::hierarchy","config\/acl\/resources\/admin\/customer\/customersegment":"Magento_CustomerSegment::customersegment","config\/acl\/resources\/admin\/report\/customers\/segment":"Magento_CustomerSegment::segment","config\/acl\/resources\/admin\/customer\/attributes":"Magento_CustomerCustomAttributes::attributes","config\/acl\/resources\/admin\/customer\/attributes\/customer_attributes":"Magento_CustomerCustomAttributes::customer_attributes","config\/acl\/resources\/admin\/customer\/attributes\/customer_address_attributes":"Magento_CustomerCustomAttributes::customer_address_attributes","config\/acl\/resources\/admin\/system\/config\/giftcardaccount":"Magento_GiftCardAccount::giftcardaccount","config\/acl\/resources\/admin\/customer\/giftcardaccount":"Magento_GiftCardAccount::customer_giftcardaccount","config\/acl\/resources\/admin\/system\/config\/giftcard":"Magento_GiftCard::giftcard","config\/acl\/resources\/admin\/system\/config\/magento_giftregistry":"Magento_GiftRegistry::magento_giftregistry","config\/acl\/resources\/admin\/customer\/magento_giftregistry":"Magento_GiftRegistry::customer_magento_giftregistry","config\/acl\/resources\/admin\/sales\/magento_giftwrapping":"Magento_GiftWrapping::magento_giftwrapping","config\/acl\/resources\/admin\/system\/convert\/enterprise_scheduled_operation":"Magento_ScheduledImportExport::enterprise_scheduled_operation","config\/acl\/resources\/admin\/customer\/magento_invitation":"Magento_Invitation::magento_invitation","config\/acl\/resources\/admin\/report\/magento_invitation":"Magento_Invitation::report_magento_invitation","config\/acl\/resources\/admin\/report\/magento_invitation\/general":"Magento_Invitation::general","config\/acl\/resources\/admin\/report\/magento_invitation\/customer":"Magento_Invitation::magento_invitation_customer","config\/acl\/resources\/admin\/report\/magento_invitation\/order":"Magento_Invitation::order","config\/acl\/resources\/admin\/system\/config\/magento_invitation":"Magento_Invitation::config_magento_invitation","config\/acl\/resources\/admin\/system\/config\/logging":"Magento_Logging::logging","config\/acl\/resources\/admin\/system\/magento_logging":"Magento_Logging::magento_logging","config\/acl\/resources\/admin\/system\/magento_logging\/events":"Magento_Logging::magento_logging_events","config\/acl\/resources\/admin\/system\/magento_logging\/backups":"Magento_Logging::backups","config\/acl\/resources\/admin\/system\/crypt_key":"Magento_Pci::crypt_key","config\/acl\/resources\/admin\/system\/acl\/locks":"Magento_Pci::locks","config\/acl\/resources\/admin\/catalog\/products\/read_product_price":"Magento_PricePermissions::read_product_price","config\/acl\/resources\/admin\/catalog\/products\/read_product_price\/edit_product_price":"Magento_PricePermissions::edit_product_price","config\/acl\/resources\/admin\/catalog\/products\/edit_product_status":"Magento_PricePermissions::edit_product_status","config\/acl\/resources\/admin\/promo\/catalog\/edit":"Magento_PromotionPermissions::edit","config\/acl\/resources\/admin\/promo\/quote\/edit":"Magento_PromotionPermissions::quote_edit","config\/acl\/resources\/admin\/promo\/magento_reminder\/edit":"Magento_PromotionPermissions::magento_reminder_edit","config\/acl\/resources\/admin\/promo\/magento_reminder":"Magento_Reminder::magento_reminder","config\/acl\/resources\/admin\/system\/config\/promo":"Magento_SalesRule::config_promo","config\/acl\/resources\/admin\/customer\/manage\/reward_balance":"Magento_Reward::reward_balance","config\/acl\/resources\/admin\/sales\/order\/actions\/create\/reward_spend":"Magento_Reward::reward_spend","config\/acl\/resources\/admin\/customer\/rates":"Magento_Reward::rates","config\/acl\/resources\/admin\/system\/config\/magento_reward":"Magento_Reward::magento_reward","config\/acl\/resources\/admin\/sales\/magento_rma":"Magento_Rma::magento_rma","config\/acl\/resources\/admin\/sales\/magento_rma\/rma_manage":"Magento_Rma::rma_manage","config\/acl\/resources\/admin\/sales\/magento_rma\/rma_attribute":"Magento_Rma::rma_attribute","config\/acl\/resources\/admin\/sales\/archive":"Magento_SalesArchive::archive","config\/acl\/resources\/admin\/sales\/archive\/orders":"Magento_SalesArchive::orders","config\/acl\/resources\/admin\/sales\/archive\/orders\/add":"Magento_SalesArchive::add","config\/acl\/resources\/admin\/sales\/archive\/orders\/remove":"Magento_SalesArchive::remove","config\/acl\/resources\/admin\/sales\/archive\/invoices":"Magento_SalesArchive::invoices","config\/acl\/resources\/admin\/sales\/archive\/shipments":"Magento_SalesArchive::shipments","config\/acl\/resources\/admin\/sales\/archive\/creditmemos":"Magento_SalesArchive::creditmemos","config\/acl\/resources\/admin\/catalog\/targetrule":"Magento_TargetRule::targetrule","config\/acl\/resources\/admin\/report\/customers\/wishlist":"Magento_MultipleWishlist::wishlist","config\/acl\/resources\/admin\/system\/adminnotification":"Magento_AdminNotification::adminnotification","config\/acl\/resources\/admin\/system\/adminnotification\/show_toolbar":"Magento_AdminNotification::show_toolbar","config\/acl\/resources\/admin\/system\/adminnotification\/show_list":"Magento_AdminNotification::show_list","config\/acl\/resources\/admin\/system\/adminnotification\/mark_as_read":"Magento_AdminNotification::mark_as_read","config\/acl\/resources\/admin\/system\/adminnotification\/remove":"Magento_AdminNotification::adminnotification_remove","config\/acl\/resources\/all":"Magento_Adminhtml::all","config\/acl\/resources\/admin":"Magento_Adminhtml::admin","config\/acl\/resources\/admin\/dashboard":"Magento_Adminhtml::dashboard","config\/acl\/resources\/admin\/system":"Magento_Adminhtml::system","config\/acl\/resources\/admin\/system\/store":"Magento_Adminhtml::store","config\/acl\/resources\/admin\/system\/design":"Magento_Adminhtml::design","config\/acl\/resources\/admin\/system\/design\/schedule":"Magento_Adminhtml::schedule","config\/acl\/resources\/admin\/system\/config":"Magento_Adminhtml::config","config\/acl\/resources\/admin\/system\/config\/general":"Magento_Adminhtml::config_general","config\/acl\/resources\/admin\/system\/config\/web":"Magento_Adminhtml::web","config\/acl\/resources\/admin\/system\/config\/design":"Magento_Adminhtml::config_design","config\/acl\/resources\/admin\/system\/config\/system":"Magento_Adminhtml::config_system","config\/acl\/resources\/admin\/system\/config\/advanced":"Magento_Adminhtml::advanced","config\/acl\/resources\/admin\/system\/config\/trans_email":"Magento_Adminhtml::trans_email","config\/acl\/resources\/admin\/system\/config\/dev":"Magento_Adminhtml::dev","config\/acl\/resources\/admin\/system\/config\/currency":"Magento_Adminhtml::currency","config\/acl\/resources\/admin\/system\/config\/sendfriend":"Magento_Adminhtml::sendfriend","config\/acl\/resources\/admin\/system\/config\/admin":"Magento_Adminhtml::config_admin","config\/acl\/resources\/admin\/system\/currency":"Magento_CurrencySymbol::system_currency","config\/acl\/resources\/admin\/system\/email_template":"Magento_Email::template","config\/acl\/resources\/admin\/system\/variable":"Magento_Adminhtml::variable","config\/acl\/resources\/admin\/system\/myaccount":"Magento_Adminhtml::myaccount","config\/acl\/resources\/admin\/system\/tools":"Magento_Adminhtml::tools","config\/acl\/resources\/admin\/system\/convert":"Magento_Adminhtml::convert","config\/acl\/resources\/admin\/system\/cache":"Magento_Adminhtml::cache","config\/acl\/resources\/admin\/system\/extensions":"Magento_Adminhtml::extensions","config\/acl\/resources\/admin\/system\/extensions\/local":"Magento_Adminhtml::local","config\/acl\/resources\/admin\/system\/extensions\/custom":"Magento_Adminhtml::custom","config\/acl\/resources\/admin\/global_search":"Magento_Adminhtml::global_search","config\/acl\/resources\/admin\/system\/tools\/backup":"Magento_Backup::backup","config\/acl\/resources\/admin\/system\/tools\/backup\/rollback":"Magento_Backup::rollback","config\/acl\/resources\/admin\/system\/config\/cataloginventory":"Magento_CatalogInventory::cataloginventory","config\/acl\/resources\/admin\/promo":"Magento_CatalogRule::promo","config\/acl\/resources\/admin\/promo\/catalog":"Magento_CatalogRule::promo_catalog","config\/acl\/resources\/admin\/catalog\/search":"Magento_CatalogSearch::search","config\/acl\/resources\/admin\/system\/config\/catalog":"Magento_Catalog::config_catalog","config\/acl\/resources\/admin\/catalog":"Magento_Catalog::catalog","config\/acl\/resources\/admin\/catalog\/attributes":"Magento_Catalog::catalog_attributes","config\/acl\/resources\/admin\/catalog\/attributes\/attributes":"Magento_Catalog::attributes_attributes","config\/acl\/resources\/admin\/catalog\/attributes\/sets":"Magento_Catalog::sets","config\/acl\/resources\/admin\/catalog\/categories":"Magento_Catalog::categories","config\/acl\/resources\/admin\/catalog\/products":"Magento_Catalog::products","config\/acl\/resources\/admin\/catalog\/update_attributes":"Magento_Catalog::update_attributes","config\/acl\/resources\/admin\/catalog\/urlrewrite":"Magento_Catalog::urlrewrite","config\/acl\/resources\/admin\/sales\/checkoutagreement":"Magento_Checkout::checkoutagreement","config\/acl\/resources\/admin\/system\/config\/checkout":"Magento_Checkout::checkout","config\/acl\/resources\/admin\/cms":"Magento_Cms::cms","config\/acl\/resources\/admin\/cms\/block":"Magento_Cms::block","config\/acl\/resources\/admin\/cms\/page":"Magento_Cms::page","config\/acl\/resources\/admin\/cms\/page\/save":"Magento_Cms::save","config\/acl\/resources\/admin\/cms\/page\/delete":"Magento_Cms::page_delete","config\/acl\/resources\/admin\/cms\/media_gallery":"Magento_Cms::media_gallery","config\/acl\/resources\/admin\/system\/config\/cms":"Magento_Cms::config_cms","config\/acl\/resources\/admin\/system\/config\/contacts":"Magento_Contact::contact","config\/acl\/resources\/admin\/system\/currency\/rates":"Magento_CurrencySymbol::currency_rates","config\/acl\/resources\/admin\/system\/currency\/symbols":"Magento_CurrencySymbol::symbols","config\/acl\/resources\/admin\/customer":"Magento_Customer::customer","config\/acl\/resources\/admin\/customer\/group":"Magento_Customer::group","config\/acl\/resources\/admin\/customer\/manage":"Magento_Customer::manage","config\/acl\/resources\/admin\/customer\/online":"Magento_Customer::online","config\/acl\/resources\/admin\/system\/config\/customer":"Magento_Customer::config_customer","config\/acl\/resources\/admin\/system\/design\/editor":"Magento_DesignEditor::editor","config\/acl\/resources\/admin\/system\/config\/downloadable":"Magento_Downloadable::downloadable","config\/acl\/resources\/admin\/system\/config\/google":"Magento_GoogleAnalytics::google","config\/acl\/resources\/admin\/catalog\/googleshopping":"Magento_GoogleShopping::googleshopping","config\/acl\/resources\/admin\/catalog\/googleshopping\/types":"Magento_GoogleShopping::types","config\/acl\/resources\/admin\/catalog\/googleshopping\/items":"Magento_GoogleShopping::items","config\/acl\/resources\/admin\/system\/convert\/import":"Magento_ImportExport::import","config\/acl\/resources\/admin\/system\/convert\/export":"Magento_ImportExport::export","config\/acl\/resources\/admin\/system\/index":"Magento_Index::index","config\/acl\/resources\/admin\/system\/config\/newsletter":"Magento_Newsletter::newsletter","config\/acl\/resources\/admin\/newsletter":"Magento_Newsletter::admin_newsletter","config\/acl\/resources\/admin\/newsletter\/problem":"Magento_Newsletter::problem","config\/acl\/resources\/admin\/newsletter\/queue":"Magento_Newsletter::queue","config\/acl\/resources\/admin\/newsletter\/subscriber":"Magento_Newsletter::subscriber","config\/acl\/resources\/admin\/newsletter\/template":"Magento_Newsletter::template","config\/acl\/resources\/admin\/system\/config\/oauth":"Magento_Oauth::oauth","config\/acl\/resources\/admin\/system\/config\/payment":"Magento_Payment::payment","config\/acl\/resources\/admin\/system\/config\/payment_services":"Magento_Payment::payment_services","config\/acl\/resources\/admin\/system\/config\/paypal":"Magento_Paypal::paypal","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports":"Magento_Paypal::paypal_settlement_reports","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports\/view":"Magento_Paypal::paypal_settlement_reports_view","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports\/fetch":"Magento_Paypal::fetch","config\/acl\/resources\/admin\/system\/config\/persistent":"Magento_Persistent::persistent","config\/acl\/resources\/admin\/cms\/poll":"Magento_Poll::poll","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/ratings":"Magento_Rating::ratings","config\/acl\/resources\/admin\/report":"Magento_Reports::report","config\/acl\/resources\/admin\/report\/salesroot":"Magento_Reports::salesroot","config\/acl\/resources\/admin\/report\/salesroot\/sales":"Magento_Reports::salesroot_sales","config\/acl\/resources\/admin\/report\/salesroot\/tax":"Magento_Reports::tax","config\/acl\/resources\/admin\/report\/salesroot\/shipping":"Magento_Reports::shipping","config\/acl\/resources\/admin\/report\/salesroot\/invoiced":"Magento_Reports::invoiced","config\/acl\/resources\/admin\/report\/salesroot\/refunded":"Magento_Reports::refunded","config\/acl\/resources\/admin\/report\/salesroot\/coupons":"Magento_Reports::coupons","config\/acl\/resources\/admin\/report\/shopcart":"Magento_Reports::shopcart","config\/acl\/resources\/admin\/report\/shopcart\/product":"Magento_Reports::product","config\/acl\/resources\/admin\/report\/shopcart\/abandoned":"Magento_Reports::abandoned","config\/acl\/resources\/admin\/report\/products":"Magento_Reports::report_products","config\/acl\/resources\/admin\/report\/products\/bestsellers":"Magento_Reports::bestsellers","config\/acl\/resources\/admin\/report\/products\/sold":"Magento_Reports::sold","config\/acl\/resources\/admin\/report\/products\/viewed":"Magento_Reports::viewed","config\/acl\/resources\/admin\/report\/products\/lowstock":"Magento_Reports::lowstock","config\/acl\/resources\/admin\/report\/products\/downloads":"Magento_Reports::downloads","config\/acl\/resources\/admin\/report\/customers":"Magento_Reports::customers","config\/acl\/resources\/admin\/report\/customers\/accounts":"Magento_Reports::accounts","config\/acl\/resources\/admin\/report\/customers\/totals":"Magento_Reports::totals","config\/acl\/resources\/admin\/report\/customers\/orders":"Magento_Reports::customers_orders","config\/acl\/resources\/admin\/report\/review":"Magento_Reports::review","config\/acl\/resources\/admin\/report\/review\/customer":"Magento_Reports::review_customer","config\/acl\/resources\/admin\/report\/review\/product":"Magento_Reports::review_product","config\/acl\/resources\/admin\/report\/tags":"Magento_Reports::tags","config\/acl\/resources\/admin\/report\/tags\/customer":"Magento_Reports::tags_customer","config\/acl\/resources\/admin\/report\/tags\/popular":"Magento_Reports::popular","config\/acl\/resources\/admin\/report\/tags\/product":"Magento_Reports::tags_product","config\/acl\/resources\/admin\/report\/search":"Magento_Reports::report_search","config\/acl\/resources\/admin\/report\/statistics":"Magento_Reports::statistics","config\/acl\/resources\/admin\/system\/config\/reports":"Magento_Reports::reports","config\/acl\/resources\/admin\/catalog\/reviews_ratings":"Magento_Review::reviews_ratings","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews":"Magento_Review::reviews","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews\/all":"Magento_Review::reviews_all","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews\/pending":"Magento_Review::pending","config\/acl\/resources\/admin\/system\/config\/rss":"Magento_Rss::rss","config\/acl\/resources\/admin\/promo\/quote":"Magento_SalesRule::quote","config\/acl\/resources\/admin\/sales":"Magento_Sales::sales","config\/acl\/resources\/admin\/sales\/order":"Magento_Sales::sales_order","config\/acl\/resources\/admin\/sales\/order\/actions":"Magento_Sales::actions","config\/acl\/resources\/admin\/sales\/order\/actions\/create":"Magento_Sales::create","config\/acl\/resources\/admin\/sales\/order\/actions\/view":"Magento_Sales::actions_view","config\/acl\/resources\/admin\/sales\/order\/actions\/email":"Magento_Sales::email","config\/acl\/resources\/admin\/sales\/order\/actions\/reorder":"Magento_Sales::reorder","config\/acl\/resources\/admin\/sales\/order\/actions\/edit":"Magento_Sales::actions_edit","config\/acl\/resources\/admin\/sales\/order\/actions\/cancel":"Magento_Sales::cancel","config\/acl\/resources\/admin\/sales\/order\/actions\/review_payment":"Magento_Sales::review_payment","config\/acl\/resources\/admin\/sales\/order\/actions\/capture":"Magento_Sales::capture","config\/acl\/resources\/admin\/sales\/order\/actions\/invoice":"Magento_Sales::invoice","config\/acl\/resources\/admin\/sales\/order\/actions\/creditmemo":"Magento_Sales::creditmemo","config\/acl\/resources\/admin\/sales\/order\/actions\/hold":"Magento_Sales::hold","config\/acl\/resources\/admin\/sales\/order\/actions\/unhold":"Magento_Sales::unhold","config\/acl\/resources\/admin\/sales\/order\/actions\/ship":"Magento_Sales::ship","config\/acl\/resources\/admin\/sales\/order\/actions\/comment":"Magento_Sales::comment","config\/acl\/resources\/admin\/sales\/order\/actions\/emails":"Magento_Sales::emails","config\/acl\/resources\/admin\/sales\/invoice":"Magento_Sales::sales_invoice","config\/acl\/resources\/admin\/sales\/shipment":"Magento_Sales::shipment","config\/acl\/resources\/admin\/sales\/creditmemo":"Magento_Sales::sales_creditmemo","config\/acl\/resources\/admin\/sales\/transactions":"Magento_Sales::transactions","config\/acl\/resources\/admin\/sales\/transactions\/fetch":"Magento_Sales::transactions_fetch","config\/acl\/resources\/admin\/sales\/recurring_payment":"Magento_Sales::recurring_payment","config\/acl\/resources\/admin\/sales\/billing_agreement":"Magento_Sales::billing_agreement","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions":"Magento_Sales::billing_agreement_actions","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/view":"Magento_Sales::billing_agreement_actions_view","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/manage":"Magento_Sales::actions_manage","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/use":"Magento_Sales::use","config\/acl\/resources\/admin\/system\/order_statuses":"Magento_Sales::order_statuses","config\/acl\/resources\/admin\/system\/config\/sales":"Magento_Sales::config_sales","config\/acl\/resources\/admin\/system\/config\/sales_email":"Magento_Sales::sales_email","config\/acl\/resources\/admin\/system\/config\/sales_pdf":"Magento_Sales::sales_pdf","config\/acl\/resources\/admin\/system\/config\/shipping":"Magento_Shipping::config_shipping","config\/acl\/resources\/admin\/system\/config\/carriers":"Magento_Shipping::carriers","config\/acl\/resources\/admin\/catalog\/sitemap":"Magento_Sitemap::sitemap","config\/acl\/resources\/admin\/system\/config\/sitemap":"Magento_Sitemap::config_sitemap","config\/acl\/resources\/admin\/sales\/tax":"Magento_Tax::sales_tax","config\/acl\/resources\/admin\/sales\/tax\/classes_customer":"Magento_Tax::classes_customer","config\/acl\/resources\/admin\/sales\/tax\/classes_product":"Magento_Tax::classes_product","config\/acl\/resources\/admin\/sales\/tax\/import_export":"Magento_Tax::import_export","config\/acl\/resources\/admin\/sales\/tax\/rates":"Magento_Tax::tax_rates","config\/acl\/resources\/admin\/sales\/tax\/rules":"Magento_Tax::rules","config\/acl\/resources\/admin\/system\/config\/tax":"Magento_Tax::config_tax","config\/acl\/resources\/admin\/system\/acl":"Magento_User::acl","config\/acl\/resources\/admin\/system\/acl\/roles":"Magento_User::acl_roles","config\/acl\/resources\/admin\/system\/acl\/users":"Magento_User::acl_users","config\/acl\/resources\/admin\/cms\/widget_instance":"Magento_Widget::widget_instance","config\/acl\/resources\/admin\/system\/config\/wishlist":"Magento_Wishlist::config_wishlist"}
+{"config\/acl\/resources\/admin\/cms\/magento_banner":"Magento_Banner::magento_banner","config\/acl\/resources\/admin\/catalog\/events":"Magento_CatalogEvent::events","config\/acl\/resources\/admin\/system\/config\/magento_catalogpermissions":"Magento_CatalogPermissions::magento_catalogpermissions","config\/acl\/resources\/admin\/catalog\/magento_catalogpermissions":"Magento_CatalogPermissions::catalog_magento_catalogpermissions","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout":"Magento_AdvancedCheckout::magento_advancedcheckout","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout\/view":"Magento_AdvancedCheckout::view","config\/acl\/resources\/admin\/sales\/magento_advancedcheckout\/update":"Magento_AdvancedCheckout::update","config\/acl\/resources\/admin\/cms\/page\/save_revision":"Magento_VersionsCms::save_revision","config\/acl\/resources\/admin\/cms\/page\/delete_revision":"Magento_VersionsCms::delete_revision","config\/acl\/resources\/admin\/cms\/page\/publish_revision":"Magento_VersionsCms::publish_revision","config\/acl\/resources\/admin\/cms\/hierarchy":"Magento_VersionsCms::hierarchy","config\/acl\/resources\/admin\/customer\/customersegment":"Magento_CustomerSegment::customersegment","config\/acl\/resources\/admin\/report\/customers\/segment":"Magento_CustomerSegment::segment","config\/acl\/resources\/admin\/customer\/attributes":"Magento_CustomerCustomAttributes::attributes","config\/acl\/resources\/admin\/customer\/attributes\/customer_attributes":"Magento_CustomerCustomAttributes::customer_attributes","config\/acl\/resources\/admin\/customer\/attributes\/customer_address_attributes":"Magento_CustomerCustomAttributes::customer_address_attributes","config\/acl\/resources\/admin\/system\/config\/giftcardaccount":"Magento_GiftCardAccount::giftcardaccount","config\/acl\/resources\/admin\/customer\/giftcardaccount":"Magento_GiftCardAccount::customer_giftcardaccount","config\/acl\/resources\/admin\/system\/config\/giftcard":"Magento_GiftCard::giftcard","config\/acl\/resources\/admin\/system\/config\/magento_giftregistry":"Magento_GiftRegistry::magento_giftregistry","config\/acl\/resources\/admin\/customer\/magento_giftregistry":"Magento_GiftRegistry::customer_magento_giftregistry","config\/acl\/resources\/admin\/sales\/magento_giftwrapping":"Magento_GiftWrapping::magento_giftwrapping","config\/acl\/resources\/admin\/system\/convert\/enterprise_scheduled_operation":"Magento_ScheduledImportExport::enterprise_scheduled_operation","config\/acl\/resources\/admin\/customer\/magento_invitation":"Magento_Invitation::magento_invitation","config\/acl\/resources\/admin\/report\/magento_invitation":"Magento_Invitation::report_magento_invitation","config\/acl\/resources\/admin\/report\/magento_invitation\/general":"Magento_Invitation::general","config\/acl\/resources\/admin\/report\/magento_invitation\/customer":"Magento_Invitation::magento_invitation_customer","config\/acl\/resources\/admin\/report\/magento_invitation\/order":"Magento_Invitation::order","config\/acl\/resources\/admin\/system\/config\/magento_invitation":"Magento_Invitation::config_magento_invitation","config\/acl\/resources\/admin\/system\/config\/logging":"Magento_Logging::logging","config\/acl\/resources\/admin\/system\/magento_logging":"Magento_Logging::magento_logging","config\/acl\/resources\/admin\/system\/magento_logging\/events":"Magento_Logging::magento_logging_events","config\/acl\/resources\/admin\/system\/magento_logging\/backups":"Magento_Logging::backups","config\/acl\/resources\/admin\/system\/crypt_key":"Magento_Pci::crypt_key","config\/acl\/resources\/admin\/system\/acl\/locks":"Magento_Pci::locks","config\/acl\/resources\/admin\/catalog\/products\/read_product_price":"Magento_PricePermissions::read_product_price","config\/acl\/resources\/admin\/catalog\/products\/read_product_price\/edit_product_price":"Magento_PricePermissions::edit_product_price","config\/acl\/resources\/admin\/catalog\/products\/edit_product_status":"Magento_PricePermissions::edit_product_status","config\/acl\/resources\/admin\/promo\/catalog\/edit":"Magento_PromotionPermissions::edit","config\/acl\/resources\/admin\/promo\/quote\/edit":"Magento_PromotionPermissions::quote_edit","config\/acl\/resources\/admin\/promo\/magento_reminder\/edit":"Magento_PromotionPermissions::magento_reminder_edit","config\/acl\/resources\/admin\/promo\/magento_reminder":"Magento_Reminder::magento_reminder","config\/acl\/resources\/admin\/system\/config\/promo":"Magento_SalesRule::config_promo","config\/acl\/resources\/admin\/customer\/manage\/reward_balance":"Magento_Reward::reward_balance","config\/acl\/resources\/admin\/sales\/order\/actions\/create\/reward_spend":"Magento_Reward::reward_spend","config\/acl\/resources\/admin\/customer\/rates":"Magento_Reward::rates","config\/acl\/resources\/admin\/system\/config\/magento_reward":"Magento_Reward::magento_reward","config\/acl\/resources\/admin\/sales\/magento_rma":"Magento_Rma::magento_rma","config\/acl\/resources\/admin\/sales\/magento_rma\/rma_manage":"Magento_Rma::rma_manage","config\/acl\/resources\/admin\/sales\/magento_rma\/rma_attribute":"Magento_Rma::rma_attribute","config\/acl\/resources\/admin\/sales\/archive":"Magento_SalesArchive::archive","config\/acl\/resources\/admin\/sales\/archive\/orders":"Magento_SalesArchive::orders","config\/acl\/resources\/admin\/sales\/archive\/orders\/add":"Magento_SalesArchive::add","config\/acl\/resources\/admin\/sales\/archive\/orders\/remove":"Magento_SalesArchive::remove","config\/acl\/resources\/admin\/sales\/archive\/invoices":"Magento_SalesArchive::invoices","config\/acl\/resources\/admin\/sales\/archive\/shipments":"Magento_SalesArchive::shipments","config\/acl\/resources\/admin\/sales\/archive\/creditmemos":"Magento_SalesArchive::creditmemos","config\/acl\/resources\/admin\/catalog\/targetrule":"Magento_TargetRule::targetrule","config\/acl\/resources\/admin\/report\/customers\/wishlist":"Magento_MultipleWishlist::wishlist","config\/acl\/resources\/admin\/system\/adminnotification":"Magento_AdminNotification::adminnotification","config\/acl\/resources\/admin\/system\/adminnotification\/show_toolbar":"Magento_AdminNotification::show_toolbar","config\/acl\/resources\/admin\/system\/adminnotification\/show_list":"Magento_AdminNotification::show_list","config\/acl\/resources\/admin\/system\/adminnotification\/mark_as_read":"Magento_AdminNotification::mark_as_read","config\/acl\/resources\/admin\/system\/adminnotification\/remove":"Magento_AdminNotification::adminnotification_remove","config\/acl\/resources\/all":"Magento_Adminhtml::all","config\/acl\/resources\/admin":"Magento_Adminhtml::admin","config\/acl\/resources\/admin\/dashboard":"Magento_Adminhtml::dashboard","config\/acl\/resources\/admin\/system":"Magento_Adminhtml::system","config\/acl\/resources\/admin\/system\/store":"Magento_Adminhtml::store","config\/acl\/resources\/admin\/system\/design":"Magento_Adminhtml::design","config\/acl\/resources\/admin\/system\/design\/schedule":"Magento_Adminhtml::schedule","config\/acl\/resources\/admin\/system\/config":"Magento_Adminhtml::config","config\/acl\/resources\/admin\/system\/config\/general":"Magento_Adminhtml::config_general","config\/acl\/resources\/admin\/system\/config\/web":"Magento_Adminhtml::web","config\/acl\/resources\/admin\/system\/config\/design":"Magento_Adminhtml::config_design","config\/acl\/resources\/admin\/system\/config\/system":"Magento_Adminhtml::config_system","config\/acl\/resources\/admin\/system\/config\/advanced":"Magento_Adminhtml::advanced","config\/acl\/resources\/admin\/system\/config\/trans_email":"Magento_Adminhtml::trans_email","config\/acl\/resources\/admin\/system\/config\/dev":"Magento_Adminhtml::dev","config\/acl\/resources\/admin\/system\/config\/currency":"Magento_Adminhtml::currency","config\/acl\/resources\/admin\/system\/config\/sendfriend":"Magento_Adminhtml::sendfriend","config\/acl\/resources\/admin\/system\/config\/admin":"Magento_Adminhtml::config_admin","config\/acl\/resources\/admin\/system\/currency":"Magento_CurrencySymbol::system_currency","config\/acl\/resources\/admin\/system\/email_template":"Magento_Email::template","config\/acl\/resources\/admin\/system\/variable":"Magento_Adminhtml::variable","config\/acl\/resources\/admin\/system\/myaccount":"Magento_Adminhtml::myaccount","config\/acl\/resources\/admin\/system\/tools":"Magento_Adminhtml::tools","config\/acl\/resources\/admin\/system\/convert":"Magento_Adminhtml::convert","config\/acl\/resources\/admin\/system\/cache":"Magento_Adminhtml::cache","config\/acl\/resources\/admin\/system\/extensions":"Magento_Adminhtml::extensions","config\/acl\/resources\/admin\/system\/extensions\/local":"Magento_Adminhtml::local","config\/acl\/resources\/admin\/system\/extensions\/custom":"Magento_Adminhtml::custom","config\/acl\/resources\/admin\/global_search":"Magento_Adminhtml::global_search","config\/acl\/resources\/admin\/system\/tools\/backup":"Magento_Backup::backup","config\/acl\/resources\/admin\/system\/tools\/backup\/rollback":"Magento_Backup::rollback","config\/acl\/resources\/admin\/system\/config\/cataloginventory":"Magento_CatalogInventory::cataloginventory","config\/acl\/resources\/admin\/promo":"Magento_CatalogRule::promo","config\/acl\/resources\/admin\/promo\/catalog":"Magento_CatalogRule::promo_catalog","config\/acl\/resources\/admin\/catalog\/search":"Magento_CatalogSearch::search","config\/acl\/resources\/admin\/system\/config\/catalog":"Magento_Catalog::config_catalog","config\/acl\/resources\/admin\/catalog":"Magento_Catalog::catalog","config\/acl\/resources\/admin\/catalog\/attributes":"Magento_Catalog::catalog_attributes","config\/acl\/resources\/admin\/catalog\/attributes\/attributes":"Magento_Catalog::attributes_attributes","config\/acl\/resources\/admin\/catalog\/attributes\/sets":"Magento_Catalog::sets","config\/acl\/resources\/admin\/catalog\/categories":"Magento_Catalog::categories","config\/acl\/resources\/admin\/catalog\/products":"Magento_Catalog::products","config\/acl\/resources\/admin\/catalog\/update_attributes":"Magento_Catalog::update_attributes","config\/acl\/resources\/admin\/catalog\/urlrewrite":"Magento_Catalog::urlrewrite","config\/acl\/resources\/admin\/sales\/checkoutagreement":"Magento_Checkout::checkoutagreement","config\/acl\/resources\/admin\/system\/config\/checkout":"Magento_Checkout::checkout","config\/acl\/resources\/admin\/cms":"Magento_Cms::cms","config\/acl\/resources\/admin\/cms\/block":"Magento_Cms::block","config\/acl\/resources\/admin\/cms\/page":"Magento_Cms::page","config\/acl\/resources\/admin\/cms\/page\/save":"Magento_Cms::save","config\/acl\/resources\/admin\/cms\/page\/delete":"Magento_Cms::page_delete","config\/acl\/resources\/admin\/cms\/media_gallery":"Magento_Cms::media_gallery","config\/acl\/resources\/admin\/system\/config\/cms":"Magento_Cms::config_cms","config\/acl\/resources\/admin\/system\/config\/contacts":"Magento_Contact::contact","config\/acl\/resources\/admin\/system\/currency\/rates":"Magento_CurrencySymbol::currency_rates","config\/acl\/resources\/admin\/system\/currency\/symbols":"Magento_CurrencySymbol::symbols","config\/acl\/resources\/admin\/customer":"Magento_Customer::customer","config\/acl\/resources\/admin\/customer\/group":"Magento_Customer::group","config\/acl\/resources\/admin\/customer\/manage":"Magento_Customer::manage","config\/acl\/resources\/admin\/customer\/online":"Magento_Customer::online","config\/acl\/resources\/admin\/system\/config\/customer":"Magento_Customer::config_customer","config\/acl\/resources\/admin\/system\/design\/editor":"Magento_DesignEditor::editor","config\/acl\/resources\/admin\/system\/config\/downloadable":"Magento_Downloadable::downloadable","config\/acl\/resources\/admin\/system\/config\/google":"Magento_GoogleAnalytics::google","config\/acl\/resources\/admin\/catalog\/googleshopping":"Magento_GoogleShopping::googleshopping","config\/acl\/resources\/admin\/catalog\/googleshopping\/types":"Magento_GoogleShopping::types","config\/acl\/resources\/admin\/catalog\/googleshopping\/items":"Magento_GoogleShopping::items","config\/acl\/resources\/admin\/system\/convert\/import":"Magento_ImportExport::import","config\/acl\/resources\/admin\/system\/convert\/export":"Magento_ImportExport::export","config\/acl\/resources\/admin\/system\/config\/newsletter":"Magento_Newsletter::newsletter","config\/acl\/resources\/admin\/newsletter":"Magento_Newsletter::admin_newsletter","config\/acl\/resources\/admin\/newsletter\/problem":"Magento_Newsletter::problem","config\/acl\/resources\/admin\/newsletter\/queue":"Magento_Newsletter::queue","config\/acl\/resources\/admin\/newsletter\/subscriber":"Magento_Newsletter::subscriber","config\/acl\/resources\/admin\/newsletter\/template":"Magento_Newsletter::template","config\/acl\/resources\/admin\/system\/config\/oauth":"Magento_Oauth::oauth","config\/acl\/resources\/admin\/system\/config\/payment":"Magento_Payment::payment","config\/acl\/resources\/admin\/system\/config\/payment_services":"Magento_Payment::payment_services","config\/acl\/resources\/admin\/system\/config\/paypal":"Magento_Paypal::paypal","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports":"Magento_Paypal::paypal_settlement_reports","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports\/view":"Magento_Paypal::paypal_settlement_reports_view","config\/acl\/resources\/admin\/report\/salesroot\/paypal_settlement_reports\/fetch":"Magento_Paypal::fetch","config\/acl\/resources\/admin\/system\/config\/persistent":"Magento_Persistent::persistent","config\/acl\/resources\/admin\/cms\/poll":"Magento_Poll::poll","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/ratings":"Magento_Rating::ratings","config\/acl\/resources\/admin\/report":"Magento_Reports::report","config\/acl\/resources\/admin\/report\/salesroot":"Magento_Reports::salesroot","config\/acl\/resources\/admin\/report\/salesroot\/sales":"Magento_Reports::salesroot_sales","config\/acl\/resources\/admin\/report\/salesroot\/tax":"Magento_Reports::tax","config\/acl\/resources\/admin\/report\/salesroot\/shipping":"Magento_Reports::shipping","config\/acl\/resources\/admin\/report\/salesroot\/invoiced":"Magento_Reports::invoiced","config\/acl\/resources\/admin\/report\/salesroot\/refunded":"Magento_Reports::refunded","config\/acl\/resources\/admin\/report\/salesroot\/coupons":"Magento_Reports::coupons","config\/acl\/resources\/admin\/report\/shopcart":"Magento_Reports::shopcart","config\/acl\/resources\/admin\/report\/shopcart\/product":"Magento_Reports::product","config\/acl\/resources\/admin\/report\/shopcart\/abandoned":"Magento_Reports::abandoned","config\/acl\/resources\/admin\/report\/products":"Magento_Reports::report_products","config\/acl\/resources\/admin\/report\/products\/bestsellers":"Magento_Reports::bestsellers","config\/acl\/resources\/admin\/report\/products\/sold":"Magento_Reports::sold","config\/acl\/resources\/admin\/report\/products\/viewed":"Magento_Reports::viewed","config\/acl\/resources\/admin\/report\/products\/lowstock":"Magento_Reports::lowstock","config\/acl\/resources\/admin\/report\/products\/downloads":"Magento_Reports::downloads","config\/acl\/resources\/admin\/report\/customers":"Magento_Reports::customers","config\/acl\/resources\/admin\/report\/customers\/accounts":"Magento_Reports::accounts","config\/acl\/resources\/admin\/report\/customers\/totals":"Magento_Reports::totals","config\/acl\/resources\/admin\/report\/customers\/orders":"Magento_Reports::customers_orders","config\/acl\/resources\/admin\/report\/review":"Magento_Reports::review","config\/acl\/resources\/admin\/report\/review\/customer":"Magento_Reports::review_customer","config\/acl\/resources\/admin\/report\/review\/product":"Magento_Reports::review_product","config\/acl\/resources\/admin\/report\/tags":"Magento_Reports::tags","config\/acl\/resources\/admin\/report\/tags\/customer":"Magento_Reports::tags_customer","config\/acl\/resources\/admin\/report\/tags\/popular":"Magento_Reports::popular","config\/acl\/resources\/admin\/report\/tags\/product":"Magento_Reports::tags_product","config\/acl\/resources\/admin\/report\/search":"Magento_Reports::report_search","config\/acl\/resources\/admin\/report\/statistics":"Magento_Reports::statistics","config\/acl\/resources\/admin\/system\/config\/reports":"Magento_Reports::reports","config\/acl\/resources\/admin\/catalog\/reviews_ratings":"Magento_Review::reviews_ratings","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews":"Magento_Review::reviews","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews\/all":"Magento_Review::reviews_all","config\/acl\/resources\/admin\/catalog\/reviews_ratings\/reviews\/pending":"Magento_Review::pending","config\/acl\/resources\/admin\/system\/config\/rss":"Magento_Rss::rss","config\/acl\/resources\/admin\/promo\/quote":"Magento_SalesRule::quote","config\/acl\/resources\/admin\/sales":"Magento_Sales::sales","config\/acl\/resources\/admin\/sales\/order":"Magento_Sales::sales_order","config\/acl\/resources\/admin\/sales\/order\/actions":"Magento_Sales::actions","config\/acl\/resources\/admin\/sales\/order\/actions\/create":"Magento_Sales::create","config\/acl\/resources\/admin\/sales\/order\/actions\/view":"Magento_Sales::actions_view","config\/acl\/resources\/admin\/sales\/order\/actions\/email":"Magento_Sales::email","config\/acl\/resources\/admin\/sales\/order\/actions\/reorder":"Magento_Sales::reorder","config\/acl\/resources\/admin\/sales\/order\/actions\/edit":"Magento_Sales::actions_edit","config\/acl\/resources\/admin\/sales\/order\/actions\/cancel":"Magento_Sales::cancel","config\/acl\/resources\/admin\/sales\/order\/actions\/review_payment":"Magento_Sales::review_payment","config\/acl\/resources\/admin\/sales\/order\/actions\/capture":"Magento_Sales::capture","config\/acl\/resources\/admin\/sales\/order\/actions\/invoice":"Magento_Sales::invoice","config\/acl\/resources\/admin\/sales\/order\/actions\/creditmemo":"Magento_Sales::creditmemo","config\/acl\/resources\/admin\/sales\/order\/actions\/hold":"Magento_Sales::hold","config\/acl\/resources\/admin\/sales\/order\/actions\/unhold":"Magento_Sales::unhold","config\/acl\/resources\/admin\/sales\/order\/actions\/ship":"Magento_Sales::ship","config\/acl\/resources\/admin\/sales\/order\/actions\/comment":"Magento_Sales::comment","config\/acl\/resources\/admin\/sales\/order\/actions\/emails":"Magento_Sales::emails","config\/acl\/resources\/admin\/sales\/invoice":"Magento_Sales::sales_invoice","config\/acl\/resources\/admin\/sales\/shipment":"Magento_Sales::shipment","config\/acl\/resources\/admin\/sales\/creditmemo":"Magento_Sales::sales_creditmemo","config\/acl\/resources\/admin\/sales\/transactions":"Magento_Sales::transactions","config\/acl\/resources\/admin\/sales\/transactions\/fetch":"Magento_Sales::transactions_fetch","config\/acl\/resources\/admin\/sales\/recurring_payment":"Magento_Sales::recurring_payment","config\/acl\/resources\/admin\/sales\/billing_agreement":"Magento_Sales::billing_agreement","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions":"Magento_Sales::billing_agreement_actions","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/view":"Magento_Sales::billing_agreement_actions_view","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/manage":"Magento_Sales::actions_manage","config\/acl\/resources\/admin\/sales\/billing_agreement\/actions\/use":"Magento_Sales::use","config\/acl\/resources\/admin\/system\/order_statuses":"Magento_Sales::order_statuses","config\/acl\/resources\/admin\/system\/config\/sales":"Magento_Sales::config_sales","config\/acl\/resources\/admin\/system\/config\/sales_email":"Magento_Sales::sales_email","config\/acl\/resources\/admin\/system\/config\/sales_pdf":"Magento_Sales::sales_pdf","config\/acl\/resources\/admin\/system\/config\/shipping":"Magento_Shipping::config_shipping","config\/acl\/resources\/admin\/system\/config\/carriers":"Magento_Shipping::carriers","config\/acl\/resources\/admin\/catalog\/sitemap":"Magento_Sitemap::sitemap","config\/acl\/resources\/admin\/system\/config\/sitemap":"Magento_Sitemap::config_sitemap","config\/acl\/resources\/admin\/sales\/tax":"Magento_Tax::sales_tax","config\/acl\/resources\/admin\/sales\/tax\/classes_customer":"Magento_Tax::classes_customer","config\/acl\/resources\/admin\/sales\/tax\/classes_product":"Magento_Tax::classes_product","config\/acl\/resources\/admin\/sales\/tax\/import_export":"Magento_Tax::import_export","config\/acl\/resources\/admin\/sales\/tax\/rates":"Magento_Tax::tax_rates","config\/acl\/resources\/admin\/sales\/tax\/rules":"Magento_Tax::rules","config\/acl\/resources\/admin\/system\/config\/tax":"Magento_Tax::config_tax","config\/acl\/resources\/admin\/system\/acl":"Magento_User::acl","config\/acl\/resources\/admin\/system\/acl\/roles":"Magento_User::acl_roles","config\/acl\/resources\/admin\/system\/acl\/users":"Magento_User::acl_users","config\/acl\/resources\/admin\/cms\/widget_instance":"Magento_Widget::widget_instance","config\/acl\/resources\/admin\/system\/config\/wishlist":"Magento_Wishlist::config_wishlist"}
diff --git a/dev/tools/Magento/Tools/Migration/Acl/log/MenuIdToAclId.log b/dev/tools/Magento/Tools/Migration/Acl/log/MenuIdToAclId.log
index 7a075d40e27..7f9ef8e178f 100644
--- a/dev/tools/Magento/Tools/Migration/Acl/log/MenuIdToAclId.log
+++ b/dev/tools/Magento/Tools/Migration/Acl/log/MenuIdToAclId.log
@@ -1 +1 @@
-{"Magento_Banner::cms_magento_banner":"Magento_Banner::magento_banner","Magento_CatalogEvent::catalog_magento_catalogevent":"Magento_Catalog::categories","Magento_CatalogEvent::catalog_magento_catalogevent_events":"Magento_CatalogEvent::events","Magento_VersionsCms::cms_enterprise_page":"Magento_Cms::page","Magento_VersionsCms::cms_enterprise_page_page":"Magento_Cms::page","Magento_VersionsCms::cms_enterprise_page_hierarchy":"Magento_VersionsCms::hierarchy","Magento_CustomerSegment::customer_customersegment":"Magento_CustomerSegment::customersegment","Magento_CustomerSegment::report_customers_segment":"Magento_CustomerSegment::segment","Magento_CustomerCustomAttributes::customer_attributes":"Magento_CustomerCustomAttributes::attributes","Magento_CustomerCustomAttributes::customer_attributes_customer_attributes":"Magento_CustomerCustomAttributes::customer_attributes","Magento_CustomerCustomAttributes::customer_attributes_customer_address_attributes":"Magento_CustomerCustomAttributes::customer_address_attributes","Magento_GiftCardAccount::customer_giftcardaccount":"Magento_GiftCardAccount::customer_giftcardaccount","Magento_GiftRegistry::customer_magento_giftregistry":"Magento_GiftRegistry::customer_magento_giftregistry","Magento_GiftWrapping::sales_magento_giftwrapping":"Magento_GiftWrapping::magento_giftwrapping","Magento_ScheduledImportExport::system_convert_enterprise_scheduled_operation":"Magento_ScheduledImportExport::enterprise_scheduled_operation","Magento_Invitation::customer_magento_invitation":"Magento_Invitation::magento_invitation","Magento_Invitation::report_magento_invitation":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_general":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_customer":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_order":"Magento_Invitation::report_magento_invitation","Magento_Logging::system_magento_logging":"Magento_Logging::magento_logging","Magento_Logging::system_magento_logging_events":"Magento_Logging::magento_logging_events","Magento_Logging::system_magento_logging_backups":"Magento_Logging::backups","Magento_Pci::system_crypt_key":"Magento_Pci::crypt_key","Magento_Pci::system_acl_locks":"Magento_Pci::locks","Magento_Reminder::promo_reminder":"Magento_Reminder::magento_reminder","Magento_Reward::customer_reward":"Magento_Reward::rates","Magento_Rma::sales_magento_rma":"Magento_Rma::magento_rma","Magento_Rma::sales_magento_rma_rma":"Magento_Rma::magento_rma","Magento_Rma::sales_magento_rma_rma_item_attribute":"Magento_Rma::magento_rma","Magento_SalesArchive::sales_archive":"Magento_SalesArchive::archive","Magento_SalesArchive::sales_archive_orders":"Magento_SalesArchive::orders","Magento_SalesArchive::sales_archive_invoices":"Magento_SalesArchive::invoices","Magento_SalesArchive::sales_archive_shipments":"Magento_SalesArchive::shipments","Magento_SalesArchive::sales_archive_creditmemos":"Magento_SalesArchive::creditmemos","Magento_TargetRule::catalog_targetrule":"Magento_TargetRule::targetrule","Magento_MultipleWishlist::report_customers_wishlist":"Magento_MultipleWishlist::wishlist","Magento_AdminNotification::system_adminnotification":"Magento_AdminNotification::adminnotification","Magento_Adminhtml::dashboard":"Magento_Adminhtml::dashboard","Magento_Adminhtml::system":"Magento_Adminhtml::system","Magento_Adminhtml::system_myaccount":"Magento_Adminhtml::myaccount","Magento_Adminhtml::system_tools":"Magento_Adminhtml::tools","Magento_Adminhtml::system_design":"Magento_Adminhtml::design","Magento_Adminhtml::system_design_schedule":"Magento_Adminhtml::schedule","Magento_Adminhtml::system_currency":"Magento_CurrencySymbol::system_currency","Magento_Adminhtml::system_email_template":"Magento_Email::template","Magento_Adminhtml::system_variable":"Magento_Adminhtml::variable","Magento_Adminhtml::system_cache":"Magento_Adminhtml::cache","Magento_Adminhtml::system_store":"Magento_Adminhtml::store","Magento_Adminhtml::system_config":"Magento_Adminhtml::config","Magento_Backup::system_tools_backup":"Magento_Backup::backup","Magento_CatalogRule::promo":"Magento_CatalogRule::promo","Magento_CatalogRule::promo_catalog":"Magento_CatalogRule::promo_catalog","Magento_CatalogSearch::catalog_search":"Magento_CatalogSearch::search","Magento_Catalog::catalog":"Magento_Catalog::catalog","Magento_Catalog::catalog_products":"Magento_Catalog::products","Magento_Catalog::catalog_categories":"Magento_Catalog::categories","Magento_Catalog::catalog_attributes":"Magento_Catalog::catalog_attributes","Magento_Catalog::catalog_attributes_attributes":"Magento_Catalog::attributes_attributes","Magento_Catalog::catalog_attributes_sets":"Magento_Catalog::sets","Magento_Catalog::catalog_urlrewrite":"Magento_Catalog::urlrewrite","Magento_Checkout::sales_checkoutagreement":"Magento_Checkout::checkoutagreement","Magento_Cms::cms":"Magento_Cms::cms","Magento_Cms::cms_page":"Magento_Cms::page","Magento_Cms::cms_block":"Magento_Cms::block","Magento_Connect::system_extensions":"Magento_Adminhtml::extensions","Magento_Connect::system_extensions_local":"Magento_Adminhtml::local","Magento_Connect::system_extensions_custom":"Magento_Adminhtml::custom","Magento_CurrencySymbol::system_currency_rates":"Magento_CurrencySymbol::currency_rates","Magento_CurrencySymbol::system_currency_symbols":"Magento_CurrencySymbol::symbols","Magento_Customer::customer":"Magento_Customer::customer","Magento_Customer::customer_manage":"Magento_Customer::manage","Magento_Customer::customer_group":"Magento_Customer::group","Magento_Customer::customer_online":"Magento_Customer::online","Magento_DesignEditor::system_design_editor":"Magento_DesignEditor::editor","Magento_Downloadable::report_products_downloads":"Magento_Reports::downloads","Magento_GoogleShopping::catalog_googleshopping":"Magento_GoogleShopping::googleshopping","Magento_GoogleShopping::catalog_googleshopping_types":"Magento_GoogleShopping::types","Magento_GoogleShopping::catalog_googleshopping_items":"Magento_GoogleShopping::items","Magento_ImportExport::system_convert_import":"Magento_ImportExport::import","Magento_ImportExport::system_convert_export":"Magento_ImportExport::export","Magento_Index::system_index":"Magento_Index::index","Magento_Newsletter::newsletter":"Magento_Newsletter::admin_newsletter","Magento_Newsletter::newsletter_template":"Magento_Newsletter::template","Magento_Newsletter::newsletter_queue":"Magento_Newsletter::queue","Magento_Newsletter::newsletter_subscriber":"Magento_Newsletter::subscriber","Magento_Newsletter::newsletter_problem":"Magento_Newsletter::problem","Magento_Paypal::report_salesroot_paypal_settlement_reports":"Magento_Paypal::paypal_settlement_reports","Magento_Poll::cms_poll":"Magento_Poll::poll","Magento_Reports::report":"Magento_Reports::report","Magento_Reports::report_salesroot":"Magento_Reports::salesroot","Magento_Reports::report_salesroot_sales":"Magento_Reports::salesroot_sales","Magento_Reports::report_salesroot_tax":"Magento_Reports::tax","Magento_Reports::report_salesroot_invoiced":"Magento_Reports::invoiced","Magento_Reports::report_salesroot_shipping":"Magento_Reports::shipping","Magento_Reports::report_salesroot_refunded":"Magento_Reports::refunded","Magento_Reports::report_salesroot_coupons":"Magento_Reports::coupons","Magento_Reports::report_shopcart":"Magento_Reports::shopcart","Magento_Reports::report_shopcart_product":"Magento_Reports::product","Magento_Reports::report_shopcart_abandoned":"Magento_Reports::abandoned","Magento_Reports::report_products":"Magento_Reports::report_products","Magento_Reports::report_products_bestsellers":"Magento_Reports::bestsellers","Magento_Reports::report_products_sold":"Magento_Reports::sold","Magento_Reports::report_products_viewed":"Magento_Reports::viewed","Magento_Reports::report_products_lowstock":"Magento_Reports::lowstock","Magento_Reports::report_customers":"Magento_Reports::customers","Magento_Reports::report_customers_accounts":"Magento_Reports::accounts","Magento_Reports::report_customers_totals":"Magento_Reports::totals","Magento_Reports::report_customers_orders":"Magento_Reports::customers_orders","Magento_Reports::report_search":"Magento_Reports::report_search","Magento_Reports::report_statistics":"Magento_Reports::statistics","Magento_Review::catalog_reviews_ratings":"Magento_Review::reviews_ratings","Magento_Review::catalog_reviews_ratings_reviews":"Magento_Review::reviews","Magento_Review::catalog_reviews_ratings_ratings":"Magento_Rating::ratings","Magento_Review::catalog_reviews_ratings_reviews_pending":"Magento_Review::pending","Magento_Review::catalog_reviews_ratings_reviews_all":"Magento_Review::reviews_all","Magento_Review::report_review":"Magento_Reports::review","Magento_Review::report_review_customer":"Magento_Reports::review_customer","Magento_Review::report_review_product":"Magento_Reports::review_product","Magento_SalesRule::promo_quote":"Magento_SalesRule::quote","Magento_Sales::sales":"Magento_Sales::sales","Magento_Sales::sales_order":"Magento_Sales::sales_order","Magento_Sales::sales_invoice":"Magento_Sales::sales_invoice","Magento_Sales::sales_shipment":"Magento_Sales::shipment","Magento_Sales::sales_creditmemo":"Magento_Sales::sales_creditmemo","Magento_Sales::sales_transactions":"Magento_Sales::transactions","Magento_Sales::sales_recurring_payment":"Magento_Sales::recurring_payment","Magento_Paypal::paypal_billing_agreement":"Magento_Paypal::billing_agreement","Magento_Sales::system_order_statuses":"Magento_Sales::order_statuses","Magento_Sitemap::catalog_sitemap":"Magento_Sitemap::sitemap","Magento_Tax::sales_tax":"Magento_Tax::sales_tax","Magento_Tax::sales_tax_rules":"Magento_Tax::rules","Magento_Tax::sales_tax_rates":"Magento_Tax::tax_rates","Magento_Tax::sales_tax_import_export":"Magento_Tax::import_export","Magento_Tax::sales_tax_classes_customer":"Magento_Tax::classes_customer","Magento_Tax::sales_tax_classes_product":"Magento_Tax::classes_product","Magento_User::system_acl":"Magento_User::acl","Magento_User::system_acl_users":"Magento_User::acl_users","Magento_User::system_acl_roles":"Magento_User::acl_roles","Magento_Widget::cms_widget_instance":"Magento_Widget::widget_instance"}
+{"Magento_Banner::cms_magento_banner":"Magento_Banner::magento_banner","Magento_CatalogEvent::catalog_magento_catalogevent":"Magento_Catalog::categories","Magento_CatalogEvent::catalog_magento_catalogevent_events":"Magento_CatalogEvent::events","Magento_VersionsCms::cms_enterprise_page":"Magento_Cms::page","Magento_VersionsCms::cms_enterprise_page_page":"Magento_Cms::page","Magento_VersionsCms::cms_enterprise_page_hierarchy":"Magento_VersionsCms::hierarchy","Magento_CustomerSegment::customer_customersegment":"Magento_CustomerSegment::customersegment","Magento_CustomerSegment::report_customers_segment":"Magento_CustomerSegment::segment","Magento_CustomerCustomAttributes::customer_attributes":"Magento_CustomerCustomAttributes::attributes","Magento_CustomerCustomAttributes::customer_attributes_customer_attributes":"Magento_CustomerCustomAttributes::customer_attributes","Magento_CustomerCustomAttributes::customer_attributes_customer_address_attributes":"Magento_CustomerCustomAttributes::customer_address_attributes","Magento_GiftCardAccount::customer_giftcardaccount":"Magento_GiftCardAccount::customer_giftcardaccount","Magento_GiftRegistry::customer_magento_giftregistry":"Magento_GiftRegistry::customer_magento_giftregistry","Magento_GiftWrapping::sales_magento_giftwrapping":"Magento_GiftWrapping::magento_giftwrapping","Magento_ScheduledImportExport::system_convert_enterprise_scheduled_operation":"Magento_ScheduledImportExport::enterprise_scheduled_operation","Magento_Invitation::customer_magento_invitation":"Magento_Invitation::magento_invitation","Magento_Invitation::report_magento_invitation":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_general":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_customer":"Magento_Invitation::report_magento_invitation","Magento_Invitation::report_magento_invitation_order":"Magento_Invitation::report_magento_invitation","Magento_Logging::system_magento_logging":"Magento_Logging::magento_logging","Magento_Logging::system_magento_logging_events":"Magento_Logging::magento_logging_events","Magento_Logging::system_magento_logging_backups":"Magento_Logging::backups","Magento_Pci::system_crypt_key":"Magento_Pci::crypt_key","Magento_Pci::system_acl_locks":"Magento_Pci::locks","Magento_Reminder::promo_reminder":"Magento_Reminder::magento_reminder","Magento_Reward::customer_reward":"Magento_Reward::rates","Magento_Rma::sales_magento_rma":"Magento_Rma::magento_rma","Magento_Rma::sales_magento_rma_rma":"Magento_Rma::magento_rma","Magento_Rma::sales_magento_rma_rma_item_attribute":"Magento_Rma::magento_rma","Magento_SalesArchive::sales_archive":"Magento_SalesArchive::archive","Magento_SalesArchive::sales_archive_orders":"Magento_SalesArchive::orders","Magento_SalesArchive::sales_archive_invoices":"Magento_SalesArchive::invoices","Magento_SalesArchive::sales_archive_shipments":"Magento_SalesArchive::shipments","Magento_SalesArchive::sales_archive_creditmemos":"Magento_SalesArchive::creditmemos","Magento_TargetRule::catalog_targetrule":"Magento_TargetRule::targetrule","Magento_MultipleWishlist::report_customers_wishlist":"Magento_MultipleWishlist::wishlist","Magento_AdminNotification::system_adminnotification":"Magento_AdminNotification::adminnotification","Magento_Adminhtml::dashboard":"Magento_Adminhtml::dashboard","Magento_Adminhtml::system":"Magento_Adminhtml::system","Magento_Adminhtml::system_myaccount":"Magento_Adminhtml::myaccount","Magento_Adminhtml::system_tools":"Magento_Adminhtml::tools","Magento_Adminhtml::system_design":"Magento_Adminhtml::design","Magento_Adminhtml::system_design_schedule":"Magento_Adminhtml::schedule","Magento_Adminhtml::system_currency":"Magento_CurrencySymbol::system_currency","Magento_Adminhtml::system_email_template":"Magento_Email::template","Magento_Adminhtml::system_variable":"Magento_Adminhtml::variable","Magento_Adminhtml::system_cache":"Magento_Adminhtml::cache","Magento_Adminhtml::system_store":"Magento_Adminhtml::store","Magento_Adminhtml::system_config":"Magento_Adminhtml::config","Magento_Backup::system_tools_backup":"Magento_Backup::backup","Magento_CatalogRule::promo":"Magento_CatalogRule::promo","Magento_CatalogRule::promo_catalog":"Magento_CatalogRule::promo_catalog","Magento_CatalogSearch::catalog_search":"Magento_CatalogSearch::search","Magento_Catalog::catalog":"Magento_Catalog::catalog","Magento_Catalog::catalog_products":"Magento_Catalog::products","Magento_Catalog::catalog_categories":"Magento_Catalog::categories","Magento_Catalog::catalog_attributes":"Magento_Catalog::catalog_attributes","Magento_Catalog::catalog_attributes_attributes":"Magento_Catalog::attributes_attributes","Magento_Catalog::catalog_attributes_sets":"Magento_Catalog::sets","Magento_Catalog::catalog_urlrewrite":"Magento_Catalog::urlrewrite","Magento_Checkout::sales_checkoutagreement":"Magento_Checkout::checkoutagreement","Magento_Cms::cms":"Magento_Cms::cms","Magento_Cms::cms_page":"Magento_Cms::page","Magento_Cms::cms_block":"Magento_Cms::block","Magento_Connect::system_extensions":"Magento_Adminhtml::extensions","Magento_Connect::system_extensions_local":"Magento_Adminhtml::local","Magento_Connect::system_extensions_custom":"Magento_Adminhtml::custom","Magento_CurrencySymbol::system_currency_rates":"Magento_CurrencySymbol::currency_rates","Magento_CurrencySymbol::system_currency_symbols":"Magento_CurrencySymbol::symbols","Magento_Customer::customer":"Magento_Customer::customer","Magento_Customer::customer_manage":"Magento_Customer::manage","Magento_Customer::customer_group":"Magento_Customer::group","Magento_Customer::customer_online":"Magento_Customer::online","Magento_DesignEditor::system_design_editor":"Magento_DesignEditor::editor","Magento_Downloadable::report_products_downloads":"Magento_Reports::downloads","Magento_GoogleShopping::catalog_googleshopping":"Magento_GoogleShopping::googleshopping","Magento_GoogleShopping::catalog_googleshopping_types":"Magento_GoogleShopping::types","Magento_GoogleShopping::catalog_googleshopping_items":"Magento_GoogleShopping::items","Magento_ImportExport::system_convert_import":"Magento_ImportExport::import","Magento_ImportExport::system_convert_export":"Magento_ImportExport::export","Magento_Newsletter::newsletter":"Magento_Newsletter::admin_newsletter","Magento_Newsletter::newsletter_template":"Magento_Newsletter::template","Magento_Newsletter::newsletter_queue":"Magento_Newsletter::queue","Magento_Newsletter::newsletter_subscriber":"Magento_Newsletter::subscriber","Magento_Newsletter::newsletter_problem":"Magento_Newsletter::problem","Magento_Paypal::report_salesroot_paypal_settlement_reports":"Magento_Paypal::paypal_settlement_reports","Magento_Poll::cms_poll":"Magento_Poll::poll","Magento_Reports::report":"Magento_Reports::report","Magento_Reports::report_salesroot":"Magento_Reports::salesroot","Magento_Reports::report_salesroot_sales":"Magento_Reports::salesroot_sales","Magento_Reports::report_salesroot_tax":"Magento_Reports::tax","Magento_Reports::report_salesroot_invoiced":"Magento_Reports::invoiced","Magento_Reports::report_salesroot_shipping":"Magento_Reports::shipping","Magento_Reports::report_salesroot_refunded":"Magento_Reports::refunded","Magento_Reports::report_salesroot_coupons":"Magento_Reports::coupons","Magento_Reports::report_shopcart":"Magento_Reports::shopcart","Magento_Reports::report_shopcart_product":"Magento_Reports::product","Magento_Reports::report_shopcart_abandoned":"Magento_Reports::abandoned","Magento_Reports::report_products":"Magento_Reports::report_products","Magento_Reports::report_products_bestsellers":"Magento_Reports::bestsellers","Magento_Reports::report_products_sold":"Magento_Reports::sold","Magento_Reports::report_products_viewed":"Magento_Reports::viewed","Magento_Reports::report_products_lowstock":"Magento_Reports::lowstock","Magento_Reports::report_customers":"Magento_Reports::customers","Magento_Reports::report_customers_accounts":"Magento_Reports::accounts","Magento_Reports::report_customers_totals":"Magento_Reports::totals","Magento_Reports::report_customers_orders":"Magento_Reports::customers_orders","Magento_Reports::report_search":"Magento_Reports::report_search","Magento_Reports::report_statistics":"Magento_Reports::statistics","Magento_Review::catalog_reviews_ratings":"Magento_Review::reviews_ratings","Magento_Review::catalog_reviews_ratings_reviews":"Magento_Review::reviews","Magento_Review::catalog_reviews_ratings_ratings":"Magento_Rating::ratings","Magento_Review::catalog_reviews_ratings_reviews_pending":"Magento_Review::pending","Magento_Review::catalog_reviews_ratings_reviews_all":"Magento_Review::reviews_all","Magento_Review::report_review":"Magento_Reports::review","Magento_Review::report_review_customer":"Magento_Reports::review_customer","Magento_Review::report_review_product":"Magento_Reports::review_product","Magento_SalesRule::promo_quote":"Magento_SalesRule::quote","Magento_Sales::sales":"Magento_Sales::sales","Magento_Sales::sales_order":"Magento_Sales::sales_order","Magento_Sales::sales_invoice":"Magento_Sales::sales_invoice","Magento_Sales::sales_shipment":"Magento_Sales::shipment","Magento_Sales::sales_creditmemo":"Magento_Sales::sales_creditmemo","Magento_Sales::sales_transactions":"Magento_Sales::transactions","Magento_Sales::sales_recurring_payment":"Magento_Sales::recurring_payment","Magento_Paypal::paypal_billing_agreement":"Magento_Paypal::billing_agreement","Magento_Sales::system_order_statuses":"Magento_Sales::order_statuses","Magento_Sitemap::catalog_sitemap":"Magento_Sitemap::sitemap","Magento_Tax::sales_tax":"Magento_Tax::sales_tax","Magento_Tax::sales_tax_rules":"Magento_Tax::rules","Magento_Tax::sales_tax_rates":"Magento_Tax::tax_rates","Magento_Tax::sales_tax_import_export":"Magento_Tax::import_export","Magento_Tax::sales_tax_classes_customer":"Magento_Tax::classes_customer","Magento_Tax::sales_tax_classes_product":"Magento_Tax::classes_product","Magento_User::system_acl":"Magento_User::acl","Magento_User::system_acl_users":"Magento_User::acl_users","Magento_User::system_acl_roles":"Magento_User::acl_roles","Magento_Widget::cms_widget_instance":"Magento_Widget::widget_instance"}
diff --git a/dev/tools/Magento/Tools/Migration/factory_table_names/replace_ce.php b/dev/tools/Magento/Tools/Migration/factory_table_names/replace_ce.php
index 66abe867592..2e42f97bdfa 100644
--- a/dev/tools/Magento/Tools/Migration/factory_table_names/replace_ce.php
+++ b/dev/tools/Magento/Tools/Migration/factory_table_names/replace_ce.php
@@ -158,8 +158,6 @@ return array(
     'core/store' => 'store',
     'core/store_group' => 'store_group',
     'core/translate' => 'core_translate',
-    'core/url_rewrite' => 'core_url_rewrite',
-    'core/url_rewrite_tag' => 'core_url_rewrite_tag',
     'core/variable' => 'core_variable',
     'core/variable_value' => 'core_variable_value',
     'core/website' => 'store_website',
diff --git a/lib/internal/Magento/Framework/App/Action/Action.php b/lib/internal/Magento/Framework/App/Action/Action.php
index 750c9a42ac7..2cb090f6264 100644
--- a/lib/internal/Magento/Framework/App/Action/Action.php
+++ b/lib/internal/Magento/Framework/App/Action/Action.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Default implementation of application action controller
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -28,6 +26,11 @@ namespace Magento\Framework\App\Action;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\App\ResponseInterface;
 
+/**
+ * Default implementation of application action controller
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class Action extends AbstractAction
 {
     /**
diff --git a/lib/internal/Magento/Framework/App/Action/Context.php b/lib/internal/Magento/Framework/App/Action/Context.php
index 37f1c15d33b..23250cb3379 100644
--- a/lib/internal/Magento/Framework/App/Action/Context.php
+++ b/lib/internal/Magento/Framework/App/Action/Context.php
@@ -80,6 +80,8 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      * @param \Magento\Framework\App\ActionFlag $actionFlag
      * @param \Magento\Framework\App\ViewInterface $view
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         \Magento\Framework\App\RequestInterface $request,
diff --git a/lib/internal/Magento/Framework/App/ActionFactory.php b/lib/internal/Magento/Framework/App/ActionFactory.php
index 297c5fe3707..4f8ecbefd5e 100644
--- a/lib/internal/Magento/Framework/App/ActionFactory.php
+++ b/lib/internal/Magento/Framework/App/ActionFactory.php
@@ -25,8 +25,6 @@
  */
 namespace Magento\Framework\App;
 
-use Magento\Framework\App\ActionInterface;
-
 class ActionFactory
 {
     /**
diff --git a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
index 76f026d1fb4..7bd5ccebdc5 100644
--- a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
+++ b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
@@ -102,19 +102,20 @@ class ObjectManagerFactory
             $diConfig->extend($configData);
         }
 
-        $this->factory = new \Magento\Framework\ObjectManager\Factory\Factory(
+        $factoryClass = $diConfig->getPreference('Magento\Framework\ObjectManager\Factory\Factory');
+        $this->factory = new $factoryClass(
             $diConfig,
             null,
             $definitions,
             $appArguments->get()
         );
+
         if ($appArguments->get('MAGE_PROFILER') == 2) {
             $this->factory = new \Magento\Framework\ObjectManager\Profiler\FactoryDecorator(
                 $this->factory,
                 \Magento\Framework\ObjectManager\Profiler\Log::getInstance()
             );
         }
-        $className = $this->_locatorClassName;
 
         $sharedInstances = [
             'Magento\Framework\App\Arguments' => $appArguments,
@@ -129,6 +130,7 @@ class ObjectManagerFactory
             $configClass => $diConfig
         ];
 
+        $className = $this->_locatorClassName;
         /** @var \Magento\Framework\ObjectManager $objectManager */
         $objectManager = new $className($this->factory, $diConfig, $sharedInstances);
 
diff --git a/lib/internal/Magento/Framework/App/Rss/DataProviderInterface.php b/lib/internal/Magento/Framework/App/Rss/DataProviderInterface.php
new file mode 100644
index 00000000000..4adb19b7225
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Rss/DataProviderInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App\Rss;
+
+/**
+ * Interface DataProviderInterface
+ * @package Magento\Framework\App\Rss
+ */
+interface DataProviderInterface
+{
+    /**
+     * Check if RSS feed allowed
+     *
+     * @return mixed
+     */
+    public function isAllowed();
+
+    /**
+     * Get RSS feed items
+     *
+     * @return array
+     */
+    public function getRssData();
+
+    /**
+     * @return string
+     */
+    public function getCacheKey();
+
+    /**
+     * @return int
+     */
+    public function getCacheLifetime();
+
+    /**
+     * Get information about all feeds this Data Provider is responsible for
+     *
+     * @return array
+     */
+    public function getFeeds();
+}
diff --git a/app/code/Magento/Index/Model/Indexer/ConfigInterface.php b/lib/internal/Magento/Framework/App/Rss/RssManagerInterface.php
similarity index 73%
rename from app/code/Magento/Index/Model/Indexer/ConfigInterface.php
rename to lib/internal/Magento/Framework/App/Rss/RssManagerInterface.php
index e61723e79da..9f6be5d9011 100644
--- a/app/code/Magento/Index/Model/Indexer/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/App/Rss/RssManagerInterface.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Indexer configuration interface
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,22 +21,25 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Model\Indexer;
+namespace Magento\Framework\App\Rss;
 
-interface ConfigInterface
+/**
+ * Interface RssManagerInterface
+ * @package Magento\Framework\App\Rss
+ */
+interface RssManagerInterface
 {
     /**
-     * Get indexer data by name
-     *
-     * @param string $name
-     * @return array
+     * Get Data Provider by type
+     * @param string $type
+     * @return DataProviderInterface
      */
-    public function getIndexer($name);
+    public function getProvider($type);
 
     /**
-     * Get indexers configuration
+     * Get all registered providers
      *
      * @return array
      */
-    public function getAll();
+    public function getProviders();
 }
diff --git a/app/code/Magento/Catalog/Model/Config/Backend/Seo/Product.php b/lib/internal/Magento/Framework/App/Rss/UrlBuilder.php
similarity index 77%
rename from app/code/Magento/Catalog/Model/Config/Backend/Seo/Product.php
rename to lib/internal/Magento/Framework/App/Rss/UrlBuilder.php
index 240374fae1f..007634f11c6 100644
--- a/app/code/Magento/Catalog/Model/Config/Backend/Seo/Product.php
+++ b/lib/internal/Magento/Framework/App/Rss/UrlBuilder.php
@@ -21,19 +21,20 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Model\Config\Backend\Seo;
+namespace Magento\Framework\App\Rss;
 
-use Magento\Framework\App\Config\Value;
-
-class Product extends Value
+/**
+ * Class UrlBuilder
+ * @package Magento\Rss\Model
+ */
+class UrlBuilder implements UrlBuilderInterface
 {
     /**
-     * Refresh category url rewrites if configuration was changed
-     *
-     * @return $this
+     * @param array $queryParams
+     * @return string
      */
-    protected function _afterSave()
+    public function getUrl(array $queryParams = array())
     {
-        return $this;
+        return '';
     }
 }
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php b/lib/internal/Magento/Framework/App/Rss/UrlBuilderInterface.php
similarity index 78%
rename from app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php
rename to lib/internal/Magento/Framework/App/Rss/UrlBuilderInterface.php
index 0c8fd557897..d703130d763 100644
--- a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php
+++ b/lib/internal/Magento/Framework/App/Rss/UrlBuilderInterface.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,16 +21,17 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Controller\Adminhtml\Process;
+namespace Magento\Framework\App\Rss;
 
-class ReindexEvents extends \Magento\Index\Controller\Adminhtml\Process
+/**
+ * Interface UrlBuilderInterface
+ * @package Magento\Framework\App\Rss
+ */
+interface UrlBuilderInterface
 {
     /**
-     * Reindex pending events for index process
-     *
-     * @return void
+     * @param array $queryParams
+     * @return mixed
      */
-    public function execute()
-    {
-    }
+    public function getUrl(array $queryParams = array());
 }
diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php
index 16217a38d2c..00474eef4ad 100644
--- a/lib/internal/Magento/Framework/App/State.php
+++ b/lib/internal/Magento/Framework/App/State.php
@@ -174,6 +174,16 @@ class State
         $this->_installDate = $date;
     }
 
+    /**
+     * Get install date
+     *
+     * @return int
+     */
+    public function getInstallDate()
+    {
+        return $this->_installDate;
+    }
+
     /**
      * Set area code
      *
diff --git a/lib/internal/Magento/Framework/App/View.php b/lib/internal/Magento/Framework/App/View.php
index 73baafce443..7aa31f6ab1e 100644
--- a/lib/internal/Magento/Framework/App/View.php
+++ b/lib/internal/Magento/Framework/App/View.php
@@ -120,14 +120,15 @@ class View implements ViewInterface
         if ($this->_isLayoutLoaded) {
             throw new \RuntimeException('Layout must be loaded only once.');
         }
-        if ($addActionHandles) {
-            // add default layout handles for this action
-            $this->page->initLayout();
-        }
         // if handles were specified in arguments load them first
         if (!empty($handles)) {
             $this->getLayout()->getUpdate()->addHandle($handles);
         }
+
+        if ($addActionHandles) {
+            // add default layout handles for this action
+            $this->page->initLayout();
+        }
         $this->loadLayoutUpdates();
 
         if (!$generateXml) {
@@ -161,9 +162,7 @@ class View implements ViewInterface
      */
     public function addActionLayoutHandles()
     {
-        if (!$this->addPageLayoutHandles()) {
-            $this->getLayout()->getUpdate()->addHandle($this->getDefaultLayoutHandle());
-        }
+        $this->getLayout()->getUpdate()->addHandle($this->getDefaultLayoutHandle());
         return $this;
     }
 
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index dce0e23d1c1..99077829922 100644
--- a/lib/internal/Magento/Framework/AppInterface.php
+++ b/lib/internal/Magento/Framework/AppInterface.php
@@ -35,7 +35,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '0.1.0-alpha96';
+    const VERSION = '0.1.0-alpha97';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/Config/Data.php b/lib/internal/Magento/Framework/Config/Data.php
index 9e2cbaa72e4..06ccd9720a5 100644
--- a/lib/internal/Magento/Framework/Config/Data.php
+++ b/lib/internal/Magento/Framework/Config/Data.php
@@ -30,14 +30,14 @@ class Data implements \Magento\Framework\Config\DataInterface
     /**
      * Configuration reader model
      *
-     * @var \Magento\Framework\Config\ReaderInterface
+     * @var ReaderInterface
      */
     protected $_reader;
 
     /**
      * Configuration cache model
      *
-     * @var \Magento\Framework\Config\CacheInterface
+     * @var CacheInterface
      */
     protected $_cache;
 
@@ -53,24 +53,51 @@ class Data implements \Magento\Framework\Config\DataInterface
      *
      * @var array
      */
-    protected $_data = array();
+    protected $_data = [];
+
+    /**
+     * @var ReaderInterface
+     */
+    private $reader;
+
+    /**
+     * @var CacheInterface
+     */
+    private $cache;
+
+    /**
+     * @var string
+     */
+    private $cacheId;
 
     /**
      * Constructor
      *
-     * @param \Magento\Framework\Config\ReaderInterface $reader
-     * @param \Magento\Framework\Config\CacheInterface $cache
+     * @param ReaderInterface $reader
+     * @param CacheInterface $cache
      * @param string $cacheId
      */
     public function __construct(
-        \Magento\Framework\Config\ReaderInterface $reader,
-        \Magento\Framework\Config\CacheInterface $cache,
+        ReaderInterface $reader,
+        CacheInterface $cache,
         $cacheId
     ) {
-        $data = $cache->load($cacheId);
+        $this->reader = $reader;
+        $this->cache = $cache;
+        $this->cacheId = $cacheId;
+        $this->initData();
+    }
+
+    /**
+     * Initialise data for configuration
+     * @return void
+     */
+    protected function initData()
+    {
+        $data = $this->cache->load($this->cacheId);
         if (false === $data) {
-            $data = $reader->read();
-            $cache->save(serialize($data), $cacheId);
+            $data = $this->reader->read();
+            $this->cache->save(serialize($data), $this->cacheId);
         } else {
             $data = unserialize($data);
         }
@@ -111,4 +138,13 @@ class Data implements \Magento\Framework\Config\DataInterface
         }
         return $data;
     }
+
+    /**
+     * Clear cache data
+     * @return void
+     */
+    public function reset()
+    {
+        $this->cache->remove($this->cacheId);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Event/etc/events.xsd b/lib/internal/Magento/Framework/Event/etc/events.xsd
index 239cb2f8b1d..19846b8dea1 100644
--- a/lib/internal/Magento/Framework/Event/etc/events.xsd
+++ b/lib/internal/Magento/Framework/Event/etc/events.xsd
@@ -79,7 +79,7 @@
     <xs:simpleType name="methodName">
         <xs:annotation>
             <xs:documentation>
-                Method name can contain only [a-zA-Z].
+                Method name can contain only English letters.
             </xs:documentation>
         </xs:annotation>
         <xs:restriction base="xs:string">
diff --git a/lib/internal/Magento/Framework/Search/AbstractKeyValuePair.php b/lib/internal/Magento/Framework/Search/AbstractKeyValuePair.php
index a93d6f7c690..2c1cef61112 100644
--- a/lib/internal/Magento/Framework/Search/AbstractKeyValuePair.php
+++ b/lib/internal/Magento/Framework/Search/AbstractKeyValuePair.php
@@ -62,7 +62,7 @@ class AbstractKeyValuePair
     /**
      * Get field values
      *
-     * @return array
+     * @return mixed
      */
     public function getValue()
     {
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php
new file mode 100644
index 00000000000..99e721e18b6
--- /dev/null
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Adapter\Mysql;
+
+use Magento\Framework\App\Resource;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+
+class ConditionManager
+{
+    const CONDITION_PATTERN_SIMPLE = '%s %s %s';
+    const CONDITION_PATTERN_ARRAY = '%s %s (%s)';
+    /**
+     * @var AdapterInterface
+     */
+    private $adapter;
+
+    /**
+     * @param \Magento\Framework\App\Resource $resource
+     */
+    public function __construct(Resource $resource)
+    {
+        $this->adapter = $resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
+    }
+
+    /**
+     * @param string $query
+     * @return string
+     */
+    public function wrapBrackets($query)
+    {
+        return empty($query)
+            ? $query
+            : '(' . $query . ')';
+    }
+
+    /**
+     * @param string[] $queries
+     * @param string $unionOperator
+     * @return string
+     */
+    public function combineQueries(array $queries, $unionOperator)
+    {
+        return implode(
+            ' ' . $unionOperator . ' ',
+            array_filter($queries, 'strlen')
+        );
+    }
+
+    /**
+     * @param string $field
+     * @param string $operator
+     * @param mixed $value
+     * @return string
+     */
+    public function generateCondition($field, $operator, $value)
+    {
+        return sprintf(
+            is_array($value) ? self::CONDITION_PATTERN_ARRAY :self::CONDITION_PATTERN_SIMPLE,
+            $this->adapter->quoteIdentifier($field),
+            $operator,
+            $this->adapter->quote($value)
+        );
+    }
+}
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Dimensions.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Dimensions.php
index 520975451b3..578e8a34bd3 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Dimensions.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Dimensions.php
@@ -33,25 +33,25 @@ class Dimensions
 
     const STORE_FIELD_NAME = 'store_id';
 
-    /**
-     * @var \Magento\Framework\App\Resource
-     */
-    private $resource;
     /**
      * @var ScopeResolverInterface
      */
     private $scopeResolver;
+    /**
+     * @var ConditionManager
+     */
+    private $conditionManager;
 
     /**
-     * @param \Magento\Framework\App\Resource $resource
      * @param ScopeResolverInterface $scopeResolver
+     * @param ConditionManager $conditionManager
      */
     public function __construct(
-        \Magento\Framework\App\Resource $resource,
-        ScopeResolverInterface $scopeResolver
+        ScopeResolverInterface $scopeResolver,
+        ConditionManager $conditionManager
     ) {
-        $this->resource = $resource;
         $this->scopeResolver = $scopeResolver;
+        $this->conditionManager = $conditionManager;
     }
 
     /**
@@ -60,31 +60,23 @@ class Dimensions
      */
     public function build(Dimension $dimension)
     {
-        /** @var AdapterInterface $adapter */
-        $adapter = $this->resource->getConnection(\Magento\Framework\App\Resource::DEFAULT_READ_RESOURCE);
-
-        return $this->generateExpression($dimension, $adapter);
+        return $this->generateExpression($dimension);
     }
 
     /**
      * @param Dimension $dimension
-     * @param AdapterInterface $adapter
      * @return string
      */
-    private function generateExpression(Dimension $dimension, AdapterInterface $adapter)
+    private function generateExpression(Dimension $dimension)
     {
-        $identifier = $dimension->getName();
+        $field = $dimension->getName();
         $value = $dimension->getValue();
 
-        if (self::DEFAULT_DIMENSION_NAME === $identifier) {
-            $identifier = self::STORE_FIELD_NAME;
+        if (self::DEFAULT_DIMENSION_NAME === $field) {
+            $field = self::STORE_FIELD_NAME;
             $value = $this->scopeResolver->getScope($value)->getId();
         }
 
-        return sprintf(
-            '%s = %s',
-            $adapter->quoteIdentifier($identifier),
-            $adapter->quote($value)
-        );
+        return $this->conditionManager->generateCondition($field, '=', $value);
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php
index 117849c1af6..aa665eb216e 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php
@@ -26,7 +26,10 @@ namespace Magento\Framework\Search\Adapter\Mysql\Filter;
 use Magento\Framework\DB\Select;
 use Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Range;
 use Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Term;
+use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
+use Magento\Framework\Search\Adapter\Mysql\Filter\Builder\Wildcard;
 use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface;
+use Magento\Framework\Search\Request\Query\Bool;
 
 class Builder implements BuilderInterface
 {
@@ -34,96 +37,140 @@ class Builder implements BuilderInterface
      * @var Range
      */
     private $range;
+
     /**
      * @var Term
      */
     private $term;
 
+    /**
+     * @var ConditionManager
+     */
+    private $conditionManager;
+
+    /**
+     * @var Wildcard
+     */
+    private $wildcard;
+
     /**
      * @param Range $range
      * @param Term $term
+     * @param Wildcard $wildcard
+     * @param ConditionManager $conditionManager
      */
     public function __construct(
         Range $range,
-        Term $term
+        Term $term,
+        Wildcard $wildcard,
+        ConditionManager $conditionManager
     ) {
         $this->range = $range;
         $this->term = $term;
+        $this->conditionManager = $conditionManager;
+        $this->wildcard = $wildcard;
     }
 
     /**
      * {@inheritdoc}
      */
-    public function build(RequestFilterInterface $filter)
+    public function build(RequestFilterInterface $filter, $conditionType)
+    {
+        return $this->processFilter($filter, $this->isNegation($conditionType));
+    }
+
+    /**
+     * @param RequestFilterInterface $filter
+     * @param bool $isNegation
+     * @return string
+     */
+    private function processFilter(RequestFilterInterface $filter, $isNegation)
     {
         switch ($filter->getType()) {
             case RequestFilterInterface::TYPE_BOOL:
-                /** @var \Magento\Framework\Search\Request\Filter\Bool $filter */
-                $queries = [];
-                $must = $this->buildFilters($filter->getMust(), Select::SQL_AND);
-                if (!empty($must)) {
-                    $queries[] = $must;
-                }
-                $should = $this->buildFilters($filter->getShould(), Select::SQL_OR);
-                if (!empty($should)) {
-                    $queries[] = $this->wrapBrackets($should);
-                }
-                $mustNot = $this->buildFilters($filter->getMustNot(), Select::SQL_AND);
-                if (!empty($mustNot)) {
-                    $queries[] = '!' . $this->wrapBrackets($mustNot);
-                }
-                $query = $this->generateQuery($queries, Select::SQL_AND);
+                $query = $this->processBoolFilter($filter, $isNegation);
                 break;
             case RequestFilterInterface::TYPE_TERM:
-                /** @var \Magento\Framework\Search\Request\Filter\Term $filter */
-                $query = $this->term->buildFilter($filter);
+                $query = $this->processTermFilter($filter, $isNegation);
                 break;
             case RequestFilterInterface::TYPE_RANGE:
-                /** @var \Magento\Framework\Search\Request\Filter\Range $filter */
-                $query = $this->range->buildFilter($filter);
+                $query = $this->processRangeFilter($filter, $isNegation);
+                break;
+            case RequestFilterInterface::TYPE_WILDCARD:
+                /** @var \Magento\Framework\Search\Request\Filter\Wildcard $filter */
+                $query = $this->wildcard->buildFilter($filter, $isNegation);
                 break;
             default:
                 throw new \InvalidArgumentException(sprintf('Unknown filter type \'%s\'', $filter->getType()));
         }
-        return $this->wrapBrackets($query);
+        return $this->conditionManager->wrapBrackets($query);
     }
 
     /**
-     * @param \Magento\Framework\Search\Request\FilterInterface[] $filters
-     * @param string $unionOperator
-     * @return string
+     * @param string $conditionType
+     * @return bool
      */
-    private function buildFilters(array $filters, $unionOperator)
+    private function isNegation($conditionType)
     {
-        $queries = [];
-        foreach ($filters as $filter) {
-            $queries[] = $this->build($filter);
-        }
-        return $this->generateQuery($queries, $unionOperator);
+        return Bool::QUERY_CONDITION_NOT === $conditionType;
     }
 
     /**
-     * @param string[] $queries
-     * @param string $unionOperator
+     * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Bool $filter
+     * @param bool $isNegation
      * @return string
      */
-    private function generateQuery(array $queries, $unionOperator)
+    private function processBoolFilter(RequestFilterInterface $filter, $isNegation)
     {
-        $query = implode(
-            ' ' . $unionOperator . ' ',
-            $queries
+        $must = $this->buildFilters($filter->getMust(), Select::SQL_AND, $isNegation);
+        $should = $this->buildFilters($filter->getShould(), Select::SQL_OR, $isNegation);
+        $mustNot = $this->buildFilters(
+            $filter->getMustNot(),
+            Select::SQL_AND,
+            !$isNegation
         );
-        return $query;
+
+        $queries = [
+            $must,
+            $this->conditionManager->wrapBrackets($should),
+            $this->conditionManager->wrapBrackets($mustNot),
+        ];
+
+        return $this->conditionManager->combineQueries($queries, Select::SQL_AND);
+    }
+
+    /**
+     * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Term $filter
+     * @param bool $isNegation
+     * @return string
+     */
+    private function processTermFilter(RequestFilterInterface $filter, $isNegation)
+    {
+        return $this->term->buildFilter($filter, $isNegation);
+    }
+
+    /**
+     * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Range $filter
+     * @param bool $isNegation
+     * @return string
+     */
+    private function processRangeFilter(RequestFilterInterface $filter, $isNegation)
+    {
+        return $this->range->buildFilter($filter, $isNegation);
     }
 
     /**
-     * @param string $query
+     * @param \Magento\Framework\Search\Request\FilterInterface[] $filters
+     * @param string $unionOperator
+     * @param bool $isNegation
      * @return string
      */
-    private function wrapBrackets($query)
+    private function buildFilters(array $filters, $unionOperator, $isNegation)
     {
-        return empty($query)
-            ? $query
-            : '(' . $query . ')';
+        $queries = [];
+        foreach ($filters as $filter) {
+            $queries[] = $this->processFilter($filter, $isNegation);
+        }
+        return $this->conditionManager->combineQueries($queries, $unionOperator);
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php
index aa987061745..5958e425aaf 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php
@@ -23,13 +23,17 @@
  */
 namespace Magento\Framework\Search\Adapter\Mysql\Filter\Builder;
 
+use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface;
+
 interface FilterInterface
 {
     /**
-     * @param \Magento\Framework\Search\Request\FilterInterface $filter
-     * @return \Magento\Framework\DB\Select
+     * @param RequestFilterInterface $filter
+     * @param bool $isNegation
+     * @return string
      */
     public function buildFilter(
-        \Magento\Framework\Search\Request\FilterInterface $filter
+        RequestFilterInterface $filter,
+        $isNegation
     );
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php
index 19637d02d64..635a259e507 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php
@@ -24,64 +24,93 @@
 namespace Magento\Framework\Search\Adapter\Mysql\Filter\Builder;
 
 use Magento\Framework\App\Resource;
-use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
+use Magento\Framework\Search\Request\Filter\Range as RangeFilterRequest;
+use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface;
 
 class Range implements FilterInterface
 {
+    const CONDITION_PART_GREATER_THAN = '>=';
+    const CONDITION_PART_LOWER_THAN = '<';
+
     /**
-     * @var \Magento\Framework\App\Resource
+     * @var ConditionManager
      */
-    private $resource;
+    private $conditionManager;
 
     /**
-     * @param \Magento\Framework\App\Resource $resource
+     * @param ConditionManager $conditionManager
      */
-    public function __construct(\Magento\Framework\App\Resource $resource)
-    {
-        $this->resource = $resource;
+    public function __construct(
+        ConditionManager $conditionManager
+    ) {
+        $this->conditionManager = $conditionManager;
     }
 
     /**
-     * @param \Magento\Framework\Search\Request\FilterInterface $filter
-     * @return \Magento\Framework\DB\Select
+     * {@inheritdoc}
      */
     public function buildFilter(
-        \Magento\Framework\Search\Request\FilterInterface $filter
+        RequestFilterInterface $filter,
+        $isNegation
     ) {
-        $adapter = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
-        /** @var \Magento\Framework\Search\Request\Filter\Range $filter */
-        return $this->generateCondition($filter->getField(), $filter->getFrom(), $filter->getTo(), $adapter);
+        /** @var RangeFilterRequest $filter */
+        $queries = [
+            $this->getLeftConditionPart($filter, $isNegation),
+            $this->getRightConditionPart($filter, $isNegation),
+        ];
+        $unionOperator = $this->getConditionUnionOperator($isNegation);
+
+        return $this->conditionManager->combineQueries($queries, $unionOperator);
     }
 
-    private function generateCondition($field, $from, $to, AdapterInterface $adapter)
+    /**
+     * @param RequestFilterInterface|RangeFilterRequest $filter
+     * @param bool $isNegation
+     * @return string
+     */
+    private function getLeftConditionPart(RequestFilterInterface $filter, $isNegation)
     {
-        $hasFromValue = !is_null($from);
-        $hasToValue = !is_null($to);
+        return $this->getPart(
+            $filter->getField(),
+            ($isNegation ? self::CONDITION_PART_LOWER_THAN : self::CONDITION_PART_GREATER_THAN),
+            $filter->getFrom()
+        );
+    }
 
-        $condition = '';
+    /**
+     * @param RequestFilterInterface|RangeFilterRequest $filter
+     * @param bool $isNegation
+     * @return string
+     */
+    private function getRightConditionPart(RequestFilterInterface $filter, $isNegation)
+    {
+        return $this->getPart(
+            $filter->getField(),
+            ($isNegation ? self::CONDITION_PART_GREATER_THAN : self::CONDITION_PART_LOWER_THAN),
+            $filter->getTo()
+        );
+    }
 
-        if ($hasFromValue and $hasToValue) {
-            $condition = sprintf(
-                '%s >= %s %s %s < %s',
-                $field,
-                $adapter->quote($from),
-                \Zend_Db_Select::SQL_AND,
-                $field,
-                $adapter->quote($to)
-            );
-        } elseif ($hasFromValue and !$hasToValue) {
-            $condition = sprintf(
-                '%s >= %s',
-                $field,
-                $adapter->quote($from)
-            );
-        } elseif (!$hasFromValue and $hasToValue) {
-            $condition = sprintf(
-                '%s < %s',
-                $field,
-                $adapter->quote($to)
-            );
-        }
-        return $condition;
+    /**
+     * @param string $field
+     * @param string $operator
+     * @param string $value
+     * @return string
+     */
+    private function getPart($field, $operator, $value)
+    {
+        return is_null($value)
+            ? ''
+            : $this->conditionManager->generateCondition($field, $operator, $value);
+    }
+
+    /**
+     * @param bool $isNegation
+     * @return string
+     */
+    private function getConditionUnionOperator($isNegation)
+    {
+        return $isNegation ? \Zend_Db_Select::SQL_OR : \Zend_Db_Select::SQL_AND;
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php
index 940e4aef6b4..3dbb897668f 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php
@@ -24,36 +24,58 @@
 namespace Magento\Framework\Search\Adapter\Mysql\Filter\Builder;
 
 use Magento\Framework\App\Resource;
+use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
+use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface;
 
 class Term implements FilterInterface
 {
+    const CONDITION_OPERATOR_EQUALS = '=';
+    const CONDITION_OPERATOR_NOT_EQUALS = '!=';
+    const CONDITION_OPERATOR_IN = 'IN';
+    const CONDITION_OPERATOR_NOT_IN = 'NOT IN';
+
     /**
-     * @var \Magento\Framework\App\Resource
+     * @var ConditionManager
      */
-    private $resource;
+    private $conditionManager;
 
     /**
-     * @param \Magento\Framework\App\Resource $resource
+     * @param ConditionManager $conditionManager
      */
-    public function __construct(\Magento\Framework\App\Resource $resource)
-    {
-        $this->resource = $resource;
+    public function __construct(
+        ConditionManager $conditionManager
+    ) {
+        $this->conditionManager = $conditionManager;
     }
 
     /**
      * {@inheritdoc}
      */
     public function buildFilter(
-        \Magento\Framework\Search\Request\FilterInterface $filter
+        RequestFilterInterface $filter,
+        $isNegation
     ) {
-        $adapter = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
-
         /** @var \Magento\Framework\Search\Request\Filter\Term $filter */
-        $condition = sprintf(
-            '%s = %s',
+
+        return $this->conditionManager->generateCondition(
             $filter->getField(),
-            $adapter->quote($filter->getValue())
+            $this->getConditionOperator($filter->getValue(), $isNegation),
+            $filter->getValue()
         );
-        return $condition;
+    }
+
+    /**
+     * @param string|array $value
+     * @param bool $isNegation
+     * @return string
+     */
+    private function getConditionOperator($value, $isNegation)
+    {
+        if (is_array($value)) {
+            $operator = $isNegation ? self::CONDITION_OPERATOR_NOT_IN : self::CONDITION_OPERATOR_IN;
+        } else {
+            $operator = $isNegation ? self::CONDITION_OPERATOR_NOT_EQUALS : self::CONDITION_OPERATOR_EQUALS;
+        }
+        return $operator;
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php
new file mode 100644
index 00000000000..82db2851bd7
--- /dev/null
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php
@@ -0,0 +1,65 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Adapter\Mysql\Filter\Builder;
+
+use Magento\Framework\App\Resource;
+use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
+
+class Wildcard implements FilterInterface
+{
+
+    const CONDITION_LIKE = 'LIKE';
+    const CONDITION_NOT_LIKE = 'NOT LIKE';
+
+    /**
+     * @var ConditionManager
+     */
+    private $conditionManager;
+
+    /**
+     * @param ConditionManager $conditionManager
+     */
+    public function __construct(
+        ConditionManager $conditionManager
+    ) {
+        $this->conditionManager = $conditionManager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function buildFilter(
+        \Magento\Framework\Search\Request\FilterInterface $filter,
+        $isNegation
+    ) {
+        /** @var \Magento\Framework\Search\Request\Filter\Wildcard $filter */
+
+        $searchValue = '%' . $filter->getValue() . '%';
+        return $this->conditionManager->generateCondition(
+            $filter->getField(),
+            ($isNegation ? self::CONDITION_NOT_LIKE : self::CONDITION_LIKE),
+            $searchValue
+        );
+    }
+}
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php
index 1b21f97e170..0af13c9d803 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php
@@ -29,7 +29,8 @@ interface BuilderInterface
 {
     /**
      * @param RequestFilterInterface $filter
+     * @param string $conditionType
      * @return string
      */
-    public function build(RequestFilterInterface $filter);
+    public function build(RequestFilterInterface $filter, $conditionType);
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php
index 818b9d061b9..26ba3aa6f22 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php
@@ -38,9 +38,6 @@ use Magento\Framework\Search\RequestInterface;
  */
 class Mapper
 {
-    const BOOL_MUST_NOT = true;
-    const BOOL_MUST = false;
-
     /**
      * @var \Magento\Framework\App\Resource
      */
@@ -55,34 +52,44 @@ class Mapper
      * @var \Magento\Framework\Search\Adapter\Mysql\Query\Builder\Match
      */
     private $matchQueryBuilder;
+
     /**
      * @var Filter\Builder
      */
     private $filterBuilder;
+
     /**
      * @var Dimensions
      */
     private $dimensionsBuilder;
 
+    /**
+     * @var ConditionManager
+     */
+    private $conditionManager;
+
     /**
      * @param \Magento\Framework\App\Resource $resource
      * @param ScoreBuilderFactory $scoreBuilderFactory
      * @param MatchQueryBuilder $matchQueryBuilder
      * @param Builder $filterBuilder
      * @param Dimensions $dimensionsBuilder
+     * @param ConditionManager $conditionManager
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
         ScoreBuilderFactory $scoreBuilderFactory,
         MatchQueryBuilder $matchQueryBuilder,
         Builder $filterBuilder,
-        Dimensions $dimensionsBuilder
+        Dimensions $dimensionsBuilder,
+        ConditionManager $conditionManager
     ) {
         $this->resource = $resource;
         $this->scoreBuilderFactory = $scoreBuilderFactory;
         $this->matchQueryBuilder = $matchQueryBuilder;
         $this->filterBuilder = $filterBuilder;
         $this->dimensionsBuilder = $dimensionsBuilder;
+        $this->conditionManager = $conditionManager;
     }
 
     /**
@@ -95,7 +102,12 @@ class Mapper
     {
         /** @var ScoreBuilder $scoreBuilder */
         $scoreBuilder = $this->scoreBuilderFactory->create();
-        $select = $this->processQuery($scoreBuilder, $request->getQuery(), $this->getSelect(), self::BOOL_MUST);
+        $select = $this->processQuery(
+            $scoreBuilder,
+            $request->getQuery(),
+            $this->getSelect(),
+            BoolQuery::QUERY_CONDITION_MUST
+        );
         $select = $this->processDimensions($request, $select);
         $tableName = $this->resource->getTableName($request->getIndex());
         $select->from($tableName)
@@ -110,7 +122,7 @@ class Mapper
      * @param ScoreBuilder $scoreBuilder
      * @param RequestQueryInterface $query
      * @param Select $select
-     * @param bool $isNot
+     * @param string $conditionType
      * @return Select
      * @throws \InvalidArgumentException
      */
@@ -118,19 +130,17 @@ class Mapper
         ScoreBuilder $scoreBuilder,
         RequestQueryInterface $query,
         Select $select,
-        $isNot
+        $conditionType
     ) {
         switch ($query->getType()) {
             case RequestQueryInterface::TYPE_MATCH:
                 /** @var MatchQuery $query */
-                $scoreBuilder->startQuery();
                 $select = $this->matchQueryBuilder->build(
                     $scoreBuilder,
                     $select,
                     $query,
-                    $isNot
+                    $conditionType
                 );
-                $scoreBuilder->endQuery($query->getBoost());
                 break;
             case RequestQueryInterface::TYPE_BOOL:
                 /** @var BoolQuery $query */
@@ -138,7 +148,7 @@ class Mapper
                 break;
             case RequestQueryInterface::TYPE_FILTER:
                 /** @var FilterQuery $query */
-                $select = $this->processFilterQuery($scoreBuilder, $query, $select, $isNot);
+                $select = $this->processFilterQuery($scoreBuilder, $query, $select, $conditionType);
                 break;
             default:
                 throw new \InvalidArgumentException(sprintf('Unknown query type \'%s\'', $query->getType()));
@@ -162,21 +172,21 @@ class Mapper
             $scoreBuilder,
             $query->getMust(),
             $select,
-            self::BOOL_MUST
+            BoolQuery::QUERY_CONDITION_MUST
         );
 
         $select = $this->processBoolQueryCondition(
             $scoreBuilder,
             $query->getShould(),
             $select,
-            self::BOOL_MUST
+            BoolQuery::QUERY_CONDITION_SHOULD
         );
 
         $select = $this->processBoolQueryCondition(
             $scoreBuilder,
             $query->getMustNot(),
             $select,
-            self::BOOL_MUST_NOT
+            BoolQuery::QUERY_CONDITION_NOT
         );
 
         $scoreBuilder->endQuery($query->getBoost());
@@ -190,17 +200,17 @@ class Mapper
      * @param ScoreBuilder $scoreBuilder
      * @param RequestQueryInterface[] $subQueryList
      * @param Select $select
-     * @param bool $isNot
+     * @param string $conditionType
      * @return Select
      */
     private function processBoolQueryCondition(
         ScoreBuilder $scoreBuilder,
         array $subQueryList,
         Select $select,
-        $isNot
+        $conditionType
     ) {
         foreach ($subQueryList as $subQuery) {
-            $select = $this->processQuery($scoreBuilder, $subQuery, $select, $isNot);
+            $select = $this->processQuery($scoreBuilder, $subQuery, $select, $conditionType);
         }
         return $select;
     }
@@ -211,22 +221,19 @@ class Mapper
      * @param ScoreBuilder $scoreBuilder
      * @param FilterQuery $query
      * @param Select $select
-     * @param bool $isNot
+     * @param string $conditionType
      * @return Select
      */
-    private function processFilterQuery(ScoreBuilder $scoreBuilder, FilterQuery $query, Select $select, $isNot)
+    private function processFilterQuery(ScoreBuilder $scoreBuilder, FilterQuery $query, Select $select, $conditionType)
     {
         switch ($query->getReferenceType()) {
             case FilterQuery::REFERENCE_QUERY:
                 $scoreBuilder->startQuery();
-                $select = $this->processQuery($scoreBuilder, $query->getReference(), $select, $isNot);
+                $select = $this->processQuery($scoreBuilder, $query->getReference(), $select, $conditionType);
                 $scoreBuilder->endQuery($query->getBoost());
                 break;
             case FilterQuery::REFERENCE_FILTER:
-                $filterCondition = $this->filterBuilder->build($query->getReference());
-                if ($isNot === true) {
-                    $filterCondition = '!' . $filterCondition;
-                }
+                $filterCondition = $this->filterBuilder->build($query->getReference(), $conditionType);
                 $select->where($filterCondition);
                 $scoreBuilder->addCondition(1, $query->getBoost());
                 break;
@@ -258,12 +265,9 @@ class Mapper
             $dimensions[] = $this->dimensionsBuilder->build($dimension);
         }
 
-        if (!empty($dimensions)) {
-            $query = sprintf(
-                '(%s)',
-                implode(' ' . Select::SQL_OR . ' ', $dimensions)
-            );
-            $select->where($query);
+        $query = $this->conditionManager->combineQueries($dimensions, \Zend_Db_Select::SQL_OR);
+        if (!empty($query)) {
+            $select->where($this->conditionManager->wrapBrackets($query));
         }
 
         return $select;
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php
index 2c57d1bc522..04c347d8dec 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php
@@ -40,20 +40,25 @@ class Match implements QueryInterface
         $conditionType
     ) {
         /** @var $query \Magento\Framework\Search\Request\Query\Match */
+        $queryValue = $query->getValue();
+        if ($conditionType === Bool::QUERY_CONDITION_MUST) {
+            $queryValue = '+' . $queryValue;
+        } elseif ($conditionType === Bool::QUERY_CONDITION_NOT) {
+            $queryValue = '-' . $queryValue;
+        }
+
+        $fieldList = [];
         foreach ($query->getMatches() as $match) {
-            $mode = Select::FULLTEXT_MODE_NATURAL;
-            if ($conditionType === Bool::QUERY_CONDITION_NOT) {
-                $match['value'] = '-' . $match['value'];
-                $mode = Select::FULLTEXT_MODE_BOOLEAN;
-            }
+            $fieldList[] = $match['field'];
+        }
 
-            $scoreBuilder->addCondition(
-                $select->getMatchQuery($match['field'], $match['value'], $mode),
-                isset($match['boost']) ? $match['boost'] : 1
-            );
+        $queryBoost = $query->getBoost();
+        $scoreBuilder->addCondition(
+            $select->getMatchQuery($fieldList, $queryValue, Select::FULLTEXT_MODE_BOOLEAN),
+            !is_null($queryBoost) ? $queryBoost : 1
+        );
+        $select->match($fieldList, $queryValue, true, Select::FULLTEXT_MODE_BOOLEAN);
 
-            $select->match($match['field'], $match['value'], true, $mode);
-        }
         return $select;
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php
index 98107060318..e52f0c395c3 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php
@@ -31,13 +31,13 @@ interface QueryInterface
      * @param \Magento\Framework\Search\Adapter\Mysql\ScoreBuilder $scoreBuilder
      * @param \Magento\Framework\DB\Select $select
      * @param \Magento\Framework\Search\Request\QueryInterface $query
-     * @param bool $isNot
+     * @param string $conditionType
      * @return \Magento\Framework\DB\Select
      */
     public function build(
         ScoreBuilder $scoreBuilder,
         \Magento\Framework\DB\Select $select,
         \Magento\Framework\Search\Request\QueryInterface $query,
-        $isNot
+        $conditionType
     );
 }
diff --git a/lib/internal/Magento/Framework/Search/Request/Binder.php b/lib/internal/Magento/Framework/Search/Request/Binder.php
new file mode 100644
index 00000000000..776b5ef2bb1
--- /dev/null
+++ b/lib/internal/Magento/Framework/Search/Request/Binder.php
@@ -0,0 +1,96 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Request;
+
+class Binder
+{
+    /**
+     * Bind data to request data
+     *
+     * @param array $requestData
+     * @param array $bindData
+     * @return array
+     */
+    public function bind(array $requestData, array $bindData)
+    {
+        $data = $this->processLimits($requestData, $bindData);
+        $data['dimensions'] = $this->processDimensions($requestData['dimensions'], $bindData['dimensions']);
+        $data['queries'] = $this->processData($requestData['queries'], $bindData['placeholder']);
+        $data['filters'] = $this->processData($requestData['filters'], $bindData['placeholder']);
+
+        return $data;
+    }
+
+    /**
+     * Replace bind limits
+     *
+     * @param array $data
+     * @param array $bindData
+     * @return array
+     */
+    private function processLimits($data, $bindData)
+    {
+        $limitList = ['from', 'size'];
+        foreach ($limitList as $limit) {
+            if (isset($bindData[$limit])) {
+                $data[$limit] = $bindData[$limit];
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * @param array $data
+     * @param array $bindData
+     * @return array
+     */
+    private function processDimensions($data, $bindData)
+    {
+        foreach ($data as $name => $value) {
+            if (isset($bindData[$name])) {
+                $data[$name]['value'] = $bindData[$name];
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Replace data recursive
+     *
+     * @param array $data
+     * @param array $bindData
+     * @return array
+     */
+    private function processData($data, $bindData)
+    {
+        foreach ($data as $key => $value) {
+            if (is_array($value)) {
+                $data[$key] = $this->processData($value, $bindData);
+            } elseif (!empty($bindData[$value])) {
+                $data[$key] = $bindData[$value];
+            }
+        }
+        return $data;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Search/RequestFactory.php b/lib/internal/Magento/Framework/Search/Request/Builder.php
similarity index 52%
rename from lib/internal/Magento/Framework/Search/RequestFactory.php
rename to lib/internal/Magento/Framework/Search/Request/Builder.php
index 0846e0e7488..304003e2c8d 100644
--- a/lib/internal/Magento/Framework/Search/RequestFactory.php
+++ b/lib/internal/Magento/Framework/Search/Request/Builder.php
@@ -21,84 +21,164 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Framework\Search;
 
-/**
- * Search Request Pool
- */
-class RequestFactory
+namespace Magento\Framework\Search\Request;
+
+
+use Magento\Framework\ObjectManager;
+use Magento\Framework\Search\RequestInterface;
+
+class Builder
 {
-    const CACHE_PREFIX = 'search_request::';
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
 
     /**
-     * @var Request\Config
+     * @var Config
      */
     private $config;
 
     /**
-     * @var \Magento\Framework\ObjectManager
+     * @var Binder
      */
-    private $objectManager;
+    private $binder;
+
+    /**
+     * @var array
+     */
+    private $data = [
+        'dimensions' => [],
+        'placeholder' => []
+    ];
+    /**
+     * @var Cleaner
+     */
+    private $cleaner;
 
     /**
-     * Request Pool constructor
+     * Request Builder constructor
      *
-     * @param \Magento\Framework\ObjectManager $objectManager
-     * @param \Magento\Framework\Search\Request\Config $config
+     * @param ObjectManager $objectManager
+     * @param Config $config
+     * @param Binder $binder
+     * @param Cleaner $cleaner
      */
-    public function __construct(
-        \Magento\Framework\ObjectManager $objectManager,
-        \Magento\Framework\Search\Request\Config $config
-    ) {
+    public function __construct(ObjectManager $objectManager, Config $config, Binder $binder, Cleaner $cleaner)
+    {
         $this->objectManager = $objectManager;
         $this->config = $config;
+        $this->binder = $binder;
+        $this->cleaner = $cleaner;
     }
 
     /**
-     * Create Request instance with specified parameters
+     * Set request name
      *
      * @param string $requestName
-     * @param array $bindValues
-     * @return \Magento\Framework\Search\Request
-     * @throws \InvalidArgumentException
+     * @return $this
      */
-    public function create($requestName, array $bindValues = array())
+    public function setRequestName($requestName)
     {
+        $this->data['requestName'] = $requestName;
+        return $this;
+    }
+
+    /**
+     * Set size
+     *
+     * @param int $size
+     * @return $this
+     */
+    public function setSize($size)
+    {
+        $this->data['size'] = $size;
+        return $this;
+    }
+
+    /**
+     * Set from
+     *
+     * @param int $from
+     * @return $this
+     */
+    public function setFrom($from)
+    {
+        $this->data['from'] = $from;
+        return $this;
+    }
+
+    /**
+     * Bind dimension data by name
+     *
+     * @param string $name
+     * @param string $value
+     * @return $this
+     */
+    public function bindDimension($name, $value)
+    {
+        $this->data['dimensions'][$name] = $value;
+        return $this;
+    }
+
+    /**
+     * Bind data to placeholder
+     *
+     * @param string $placeholder
+     * @param string $value
+     * @return $this
+     */
+    public function bind($placeholder, $value)
+    {
+        $this->data['placeholder']['$' . $placeholder . '$'] = $value;
+        return $this;
+    }
+
+    /**
+     * Create request object
+     *
+     * @return RequestInterface
+     */
+    public function create()
+    {
+        if (!isset($this->data['requestName'])) {
+            throw new \InvalidArgumentException("Request name not defined.");
+        }
+        $requestName = $this->data['requestName'];
+        /** @var array $data */
         $data = $this->config->get($requestName);
         if (is_null($data)) {
             throw new \InvalidArgumentException("Request name '{$requestName}' doesn't exist.");
         }
-        $data = $this->replaceBinds((array)$data, array_keys($bindValues), array_values($bindValues));
+
+        $data = $this->binder->bind($data, $this->data);
+        $data = $this->cleaner->clean($data);
+
+        $this->clear();
+
         return $this->convert($data);
     }
 
     /**
-     * @param string|array $data
-     * @param string[] $bindKeys
-     * @param string[] $bindValues
-     * @return string|array
+     * Clear data
+     *
+     * @return void
      */
-    private function replaceBinds($data, $bindKeys, $bindValues)
+    private function clear()
     {
-        if (is_scalar($data)) {
-            return str_replace($bindKeys, $bindValues, $data);
-        } else {
-            foreach ($data as $key => $value) {
-                $data[$key] = $this->replaceBinds($value, $bindKeys, $bindValues);
-            }
-            return $data;
-        }
+        $this->data = [];
     }
 
     /**
      * Convert array to Request instance
      *
      * @param array $data
-     * @return \Magento\Framework\Search\Request
+     * @return RequestInterface
      */
     private function convert($data)
     {
-        /** @var \Magento\Framework\Search\Request\Mapper $mapper */
+        /** @var Mapper $mapper */
         $mapper = $this->objectManager->create(
             'Magento\Framework\Search\Request\Mapper',
             [
diff --git a/lib/internal/Magento/Framework/Search/Request/Cleaner.php b/lib/internal/Magento/Framework/Search/Request/Cleaner.php
new file mode 100644
index 00000000000..b2e26b76f81
--- /dev/null
+++ b/lib/internal/Magento/Framework/Search/Request/Cleaner.php
@@ -0,0 +1,206 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\Search\Request;
+
+use Magento\Framework\Exception\StateException;
+
+class Cleaner
+{
+    /**
+     * @var array
+     */
+    private $requestData;
+
+    /**
+     * @var array
+     */
+    private $mappedQueries;
+
+    /**
+     * @var array
+     */
+    private $mappedFilters;
+
+    /**
+     * Clean not binder queries and filters
+     *
+     * @param array $requestData
+     * @return array
+     */
+    public function clean(array $requestData)
+    {
+        $this->clear();
+        $this->requestData = $requestData;
+        $this->cleanQuery($requestData['query']);
+        $requestData = $this->requestData;
+        $this->clear();
+
+        return $requestData;
+    }
+
+    /**
+     * Clear don't bind queries
+     *
+     * @param string $queryName
+     * @return void
+     * @throws StateException
+     * @throws \Exception
+     */
+    private function cleanQuery($queryName)
+    {
+        if (!isset($this->requestData['queries'][$queryName])) {
+            throw new \Exception('Query ' . $queryName . ' does not exist');
+        } elseif (in_array($queryName, $this->mappedQueries)) {
+            throw new StateException('Cycle found. Query %1 already used in request hierarchy', [$queryName]);
+        }
+        $this->mappedQueries[] = $queryName;
+        $query = $this->requestData['queries'][$queryName];
+        switch ($query['type']) {
+            case QueryInterface::TYPE_BOOL:
+                $queryReference = $this->processQueryReference($query['queryReference']);
+                if (empty($queryReference)) {
+                    unset($this->requestData['queries'][$queryName]);
+                } else {
+                    $this->requestData['queries'][$queryName]['queryReference'] = array_values($queryReference);
+                }
+                break;
+            case QueryInterface::TYPE_MATCH:
+                if (preg_match('/\$(.+)\$/si', $query['value'], $matches)) {
+                    unset($this->requestData['queries'][$queryName]);
+                }
+                break;
+            case QueryInterface::TYPE_FILTER:
+                if (isset($query['queryReference'][0])) {
+                    $fQueryName = $query['queryReference'][0]['ref'];
+                    $this->cleanQuery($fQueryName);
+                    if (!isset($this->requestData['queries'][$fQueryName])) {
+                        unset($this->requestData['queries'][$queryName]);
+                    }
+                } elseif (isset($query['filterReference'][0])) {
+                    $filterName = $query['filterReference'][0]['ref'];
+                    $this->cleanFilter($filterName);
+                    if (!isset($this->requestData['filters'][$filterName])) {
+                        unset($this->requestData['queries'][$queryName]);
+                    }
+                } else {
+                    throw new \Exception('Reference is not provided');
+                }
+                break;
+            default:
+                throw new \InvalidArgumentException('Invalid query type');
+        }
+    }
+
+    /**
+     * Clear don't bind filters
+     *
+     * @param string $filterName
+     * @return void
+     * @throws StateException
+     * @throws \Exception
+     */
+    private function cleanFilter($filterName)
+    {
+        if (!isset($this->requestData['filters'][$filterName])) {
+            throw new \Exception('Filter ' . $filterName . ' does not exist');
+        } elseif (in_array($filterName, $this->mappedFilters)) {
+            throw new StateException('Cycle found. Filter %1 already used in request hierarchy', [$filterName]);
+        }
+        $this->mappedFilters[] = $filterName;
+        $filter = $this->requestData['filters'][$filterName];
+        switch ($filter['type']) {
+            case FilterInterface::TYPE_WILDCARD:
+            case FilterInterface::TYPE_TERM:
+                if (is_string($filter['value']) && preg_match('/\$(.+)\$/si', $filter['value'], $matches)) {
+                    unset($this->requestData['filters'][$filterName]);
+                }
+                break;
+            case FilterInterface::TYPE_RANGE:
+                $keys = ['from', 'to'];
+                foreach ($keys as $key) {
+                    if (isset($filter[$key]) && preg_match('/\$(.+)\$/si', $filter[$key], $matches)) {
+                        unset($this->requestData['filters'][$filterName]);
+                        break;
+                    }
+                }
+                break;
+            case FilterInterface::TYPE_BOOL:
+                $filterReference = $this->processFilterReference($filter['filterReference']);
+                if (empty($filterReference)) {
+                    unset($this->requestData['filters'][$filterName]);
+                } else {
+                    $this->requestData['filters'][$filterName]['filterReference'] = array_values($filterReference);
+                }
+                break;
+            default:
+                throw new \InvalidArgumentException('Invalid filter type');
+        }
+    }
+
+    /**
+     * Aggregate Queries by clause
+     *
+     * @param array $queryReference
+     * @return array
+     */
+    private function processQueryReference($queryReference)
+    {
+        foreach ($queryReference as $key => $value) {
+            $this->cleanQuery($value['ref']);
+            if (!isset($this->requestData['queries'][$value['ref']])) {
+                unset($queryReference[$key]);
+            }
+        }
+        return $queryReference;
+    }
+
+    /**
+     * Aggregate Filters by clause
+     *
+     * @param array $filterReference
+     * @return array
+     */
+    private function processFilterReference($filterReference)
+    {
+        foreach ($filterReference as $key => $value) {
+            $this->cleanFilter($value['ref']);
+            if (!isset($this->requestData['filters'][$value['ref']])) {
+                unset($filterReference[$key]);
+            }
+        }
+        return $filterReference;
+    }
+
+    /**
+     * Clear variables to default status
+     *
+     * @return void
+     */
+    private function clear()
+    {
+        $this->mappedQueries = [];
+        $this->mappedFilters = [];
+        $this->requestData = [];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Search/Request/Config.php b/lib/internal/Magento/Framework/Search/Request/Config.php
index 1bf6a976e66..f5479cf88df 100644
--- a/lib/internal/Magento/Framework/Search/Request/Config.php
+++ b/lib/internal/Magento/Framework/Search/Request/Config.php
@@ -25,15 +25,18 @@ namespace Magento\Framework\Search\Request;
 
 class Config extends \Magento\Framework\Config\Data
 {
+    /** Cache ID for Search Request*/
+    const CACHE_ID = 'request_declaration';
+
     /**
-     * @param \Magento\Framework\Config\ReaderInterface $reader
+     * @param \Magento\Framework\Search\Request\Config\FilesystemReader $reader
      * @param \Magento\Framework\Config\CacheInterface $cache
      * @param string $cacheId
      */
     public function __construct(
-        \Magento\Framework\Config\ReaderInterface $reader,
+        \Magento\Framework\Search\Request\Config\FilesystemReader $reader,
         \Magento\Framework\Config\CacheInterface $cache,
-        $cacheId = 'request_declaration'
+        $cacheId = self::CACHE_ID
     ) {
         parent::__construct($reader, $cache, $cacheId);
     }
diff --git a/app/code/Magento/Index/Model/Indexer/Config/Reader.php b/lib/internal/Magento/Framework/Search/Request/Config/FilesystemReader.php
similarity index 70%
rename from app/code/Magento/Index/Model/Indexer/Config/Reader.php
rename to lib/internal/Magento/Framework/Search/Request/Config/FilesystemReader.php
index 3768d10bbb7..48ed453a5c6 100644
--- a/app/code/Magento/Index/Model/Indexer/Config/Reader.php
+++ b/lib/internal/Magento/Framework/Search/Request/Config/FilesystemReader.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Indexer configuration reader
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,21 +21,27 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Model\Indexer\Config;
+namespace Magento\Framework\Search\Request\Config;
 
-class Reader extends \Magento\Framework\Config\Reader\Filesystem
+class FilesystemReader extends \Magento\Framework\Config\Reader\Filesystem
 {
     /**
-     * List of id attributes for merge
+     * List of identifier attributes for merging
      *
      * @var array
      */
-    protected $_idAttributes = array('/config/indexer' => 'name', '/config/indexer/depends' => 'name');
+    protected $_idAttributes = array(
+        '/requests/request' => '@name',
+        '/requests/request/queries/query' => '@name',
+        '/requests/request/filters/filter' => '@name',
+        '/requests/request/aggregation/bucket' => '@name',
+        '/requests/request/dimensions/dimension' => '@name',
+    );
 
     /**
      * @param \Magento\Framework\Config\FileResolverInterface $fileResolver
-     * @param \Magento\Index\Model\Indexer\Config\Converter $converter
-     * @param \Magento\Index\Model\Indexer\Config\SchemaLocator $schemaLocator
+     * @param Converter $converter
+     * @param SchemaLocator $schemaLocator
      * @param \Magento\Framework\Config\ValidationStateInterface $validationState
      * @param string $fileName
      * @param array $idAttributes
@@ -46,10 +50,10 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem
      */
     public function __construct(
         \Magento\Framework\Config\FileResolverInterface $fileResolver,
-        \Magento\Index\Model\Indexer\Config\Converter $converter,
-        \Magento\Index\Model\Indexer\Config\SchemaLocator $schemaLocator,
+        \Magento\Framework\Search\Request\Config\Converter $converter,
+        \Magento\Framework\Search\Request\Config\SchemaLocator $schemaLocator,
         \Magento\Framework\Config\ValidationStateInterface $validationState,
-        $fileName = 'indexers.xml',
+        $fileName = 'search_request.xml',
         $idAttributes = array(),
         $domDocumentClass = 'Magento\Framework\Config\Dom',
         $defaultScope = 'global'
diff --git a/lib/internal/Magento/Framework/Search/Request/Filter/Term.php b/lib/internal/Magento/Framework/Search/Request/Filter/Term.php
index 98518dee352..a91396861d9 100644
--- a/lib/internal/Magento/Framework/Search/Request/Filter/Term.php
+++ b/lib/internal/Magento/Framework/Search/Request/Filter/Term.php
@@ -23,38 +23,28 @@
  */
 namespace Magento\Framework\Search\Request\Filter;
 
+use Magento\Framework\Search\AbstractKeyValuePair;
 use Magento\Framework\Search\Request\FilterInterface;
 
 /**
  * Term Filter
  */
-class Term implements FilterInterface
+class Term extends AbstractKeyValuePair implements FilterInterface
 {
-    /**
-     * @var string
-     */
-    protected $name;
-
     /**
      * @var string
      */
     protected $field;
 
-    /**
-     * @var string
-     */
-    protected $value;
-
     /**
      * @param string $name
+     * @param string|array $value
      * @param string $field
-     * @param string $value
      */
-    public function __construct($name, $field, $value)
+    public function __construct($name, $value, $field)
     {
-        $this->name = $name;
+        parent::__construct($name, $value);
         $this->field = $field;
-        $this->value = $value;
     }
 
     /**
@@ -65,14 +55,6 @@ class Term implements FilterInterface
         return FilterInterface::TYPE_TERM;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
     /**
      * Get Field
      *
@@ -82,14 +64,4 @@ class Term implements FilterInterface
     {
         return $this->field;
     }
-
-    /**
-     * Get Value
-     *
-     * @return string
-     */
-    public function getValue()
-    {
-        return $this->value;
-    }
 }
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Form.php b/lib/internal/Magento/Framework/Search/Request/Filter/Wildcard.php
similarity index 57%
rename from app/code/Magento/Index/Block/Adminhtml/Process/Edit/Form.php
rename to lib/internal/Magento/Framework/Search/Request/Filter/Wildcard.php
index 02fe591e11b..6a2fb1ce09c 100644
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Form.php
+++ b/lib/internal/Magento/Framework/Search/Request/Filter/Wildcard.php
@@ -21,35 +21,47 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Block\Adminhtml\Process\Edit;
+namespace Magento\Framework\Search\Request\Filter;
 
-use Magento\Backend\Block\Widget\Form as WidgetForm;
+use Magento\Framework\Search\AbstractKeyValuePair;
+use Magento\Framework\Search\Request\FilterInterface;
 
-class Form extends \Magento\Backend\Block\Widget\Form\Generic
+/**
+ * Wildcard Filter
+ */
+class Wildcard extends AbstractKeyValuePair implements FilterInterface
 {
     /**
-     * Prepare form
-     *
-     * @return WidgetForm
+     * @var string
+     */
+    protected $field;
+
+    /**
+     * @param string $name
+     * @param string|array $value
+     * @param string $field
+     */
+    public function __construct($name, $value, $field)
+    {
+        parent::__construct($name, $value);
+        $this->field = $field;
+    }
+
+    /**
+     * {@inheritdoc}
      */
-    protected function _prepareForm()
+    public function getType()
     {
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create(
-            array('data' => array('id' => 'edit_form', 'action' => $this->getActionUrl(), 'method' => 'post'))
-        );
-        $form->setUseContainer(true);
-        $this->setForm($form);
-        return parent::_prepareForm();
+        return FilterInterface::TYPE_WILDCARD;
     }
 
     /**
-     * Get action url
+     * Get Field
      *
      * @return string
      */
-    public function getActionUrl()
+    public function getField()
     {
-        return $this->getUrl('adminhtml/process/save');
+        return $this->field;
     }
 }
diff --git a/lib/internal/Magento/Framework/Search/Request/FilterInterface.php b/lib/internal/Magento/Framework/Search/Request/FilterInterface.php
index d1b594594b4..fa4898dd59a 100644
--- a/lib/internal/Magento/Framework/Search/Request/FilterInterface.php
+++ b/lib/internal/Magento/Framework/Search/Request/FilterInterface.php
@@ -37,6 +37,8 @@ interface FilterInterface
 
     const TYPE_RANGE = 'rangeFilter';
 
+    const TYPE_WILDCARD = 'wildcardFilter';
+
     /**#@-*/
 
     /**
diff --git a/lib/internal/Magento/Framework/Search/Request/Mapper.php b/lib/internal/Magento/Framework/Search/Request/Mapper.php
index 6a35bbae6fa..0fc5ca6623c 100644
--- a/lib/internal/Magento/Framework/Search/Request/Mapper.php
+++ b/lib/internal/Magento/Framework/Search/Request/Mapper.php
@@ -23,8 +23,8 @@
  */
 namespace Magento\Framework\Search\Request;
 
-use Magento\Framework\Search\Request\Query\Filter;
 use Magento\Framework\Exception\StateException;
+use Magento\Framework\Search\Request\Query\Filter;
 
 class Mapper
 {
@@ -88,14 +88,6 @@ class Mapper
         $this->rootQuery = $this->get($rootQueryName);
     }
 
-    /**
-     * @return QueryInterface
-     */
-    public function getRootQuery()
-    {
-        return $this->rootQuery;
-    }
-
     /**
      * Get Query Interface by name
      *
@@ -138,6 +130,7 @@ class Mapper
                     'Magento\Framework\Search\Request\Query\Match',
                     [
                         'name' => $query['name'],
+                        'value' => $query['value'],
                         'boost' => isset($query['boost']) ? $query['boost'] : 1,
                         'matches' => $query['match']
                     ]
@@ -179,36 +172,6 @@ class Mapper
         return $query;
     }
 
-    /**
-     * Aggregate Queries by clause
-     *
-     * @param array $data
-     * @return array
-     */
-    private function aggregateQueriesByType($data)
-    {
-        $list = [];
-        foreach ($data as $value) {
-            $list[$value['clause']][$value['ref']] = $this->mapQuery($value['ref']);
-        }
-        return $list;
-    }
-
-    /**
-     * Aggregate Filters by clause
-     *
-     * @param array $data
-     * @return array
-     */
-    private function aggregateFiltersByType($data)
-    {
-        $list = [];
-        foreach ($data as $value) {
-            $list[$value['clause']][$value['ref']] = $this->mapFilter($value['ref']);
-        }
-        return $list;
-    }
-
     /**
      * Convert array to Filter instance
      *
@@ -246,10 +209,19 @@ class Mapper
                         'name' => $filter['name'],
                         'field' => $filter['field'],
                         'from' => isset($filter['from']) ? $filter['from'] : null,
-                        'to' => isset($filter['to']) ? $filter['to'] : null,
+                        'to' => isset($filter['to']) ? $filter['to'] : null
+                    ]
+                );
+                break;
+            case FilterInterface::TYPE_WILDCARD:
+                $filter = $this->objectManager->create(
+                    'Magento\Framework\Search\Request\Filter\Wildcard',
+                    [
+                        'name' => $filter['name'],
+                        'field' => $filter['field'],
+                        'value' => $filter['value']
                     ]
                 );
-
                 break;
             case FilterInterface::TYPE_BOOL:
                 $aggregatedByType = $this->aggregateFiltersByType($filter['filterReference']);
@@ -268,31 +240,52 @@ class Mapper
     }
 
     /**
-     * @return void
-     * @throws StateException
+     * Aggregate Filters by clause
+     *
+     * @param array $data
+     * @return array
      */
-    private function validate()
+    private function aggregateFiltersByType($data)
     {
-        $this->validateQueries();
-        $this->validateFilters();
+        $list = [];
+        foreach ($data as $value) {
+            $list[$value['clause']][$value['ref']] = $this->mapFilter($value['ref']);
+        }
+        return $list;
+    }
+
+    /**
+     * Aggregate Queries by clause
+     *
+     * @param array $data
+     * @return array
+     */
+    private function aggregateQueriesByType($data)
+    {
+        $list = [];
+        foreach ($data as $value) {
+            $list[$value['clause']][$value['ref']] = $this->mapQuery($value['ref']);
+        }
+        return $list;
     }
 
     /**
      * @return void
      * @throws StateException
      */
-    private function validateQueries()
+    private function validate()
     {
-        $this->validateNotUsed($this->queries, $this->mappedQueries, 'Query %1 is not used in request hierarchy');
+        $this->validateQueries();
+        $this->validateFilters();
     }
 
     /**
      * @return void
      * @throws StateException
      */
-    private function validateFilters()
+    private function validateQueries()
     {
-        $this->validateNotUsed($this->filters, $this->mappedFilters, 'Filter %1 is not used in request hierarchy');
+        $this->validateNotUsed($this->queries, $this->mappedQueries, 'Query %1 is not used in request hierarchy');
     }
 
     /**
@@ -311,6 +304,23 @@ class Mapper
         }
     }
 
+    /**
+     * @return void
+     * @throws StateException
+     */
+    private function validateFilters()
+    {
+        $this->validateNotUsed($this->filters, $this->mappedFilters, 'Filter %1 is not used in request hierarchy');
+    }
+
+    /**
+     * @return QueryInterface
+     */
+    public function getRootQuery()
+    {
+        return $this->rootQuery;
+    }
+
     /**
      * Build BucketInterface[] from array
      *
@@ -322,11 +332,11 @@ class Mapper
         $buckets = array();
         foreach ($this->aggregations as $bucketData) {
             $arguments =
-            [
-                'name' => $bucketData['name'],
-                'field' => $bucketData['field'],
-                'metrics' => $this->mapMetrics($bucketData['metric'])
-            ];
+                [
+                    'name' => $bucketData['name'],
+                    'field' => $bucketData['field'],
+                    'metrics' => $this->mapMetrics($bucketData['metric'])
+                ];
             switch ($bucketData['type']) {
                 case BucketInterface::TYPE_TERM:
                     $bucket = $this->objectManager->create(
diff --git a/lib/internal/Magento/Framework/Search/Request/Query/Match.php b/lib/internal/Magento/Framework/Search/Request/Query/Match.php
index e32b458a435..c7ea624c56b 100644
--- a/lib/internal/Magento/Framework/Search/Request/Query/Match.php
+++ b/lib/internal/Magento/Framework/Search/Request/Query/Match.php
@@ -31,10 +31,19 @@ use Magento\Framework\Search\Request\QueryInterface;
 class Match implements QueryInterface
 {
     /**
+     * Name
+     *
      * @var string
      */
     protected $name;
 
+    /**
+     * Value
+     *
+     * @var string
+     */
+    protected $value;
+
     /**
      * Boost
      *
@@ -46,8 +55,8 @@ class Match implements QueryInterface
      * Match query array
      * Possible structure:
      * array(
-     *     ['field' => 'some_field', 'value' => 'some_value', 'boost' => 'some_boost'],
-     *     ['field' => 'some_field', 'value' => 'some_value', 'boost' => 'some_boost'],
+     *     ['field' => 'some_field', 'boost' => 'some_boost'],
+     *     ['field' => 'some_field', 'boost' => 'some_boost'],
      * )
      *
      * @var array
@@ -56,16 +65,26 @@ class Match implements QueryInterface
 
     /**
      * @param string $name
+     * @param string $value
      * @param int|null $boost
      * @param array $matches
      */
-    public function __construct($name, $boost, array $matches)
+    public function __construct($name, $value, $boost, array $matches)
     {
         $this->name = $name;
+        $this->value = $value;
         $this->boost = $boost;
         $this->matches = $matches;
     }
 
+    /**
+     * @return string
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
     /**
      * {@inheritdoc}
      */
diff --git a/lib/internal/Magento/Framework/Search/etc/requests.xsd b/lib/internal/Magento/Framework/Search/etc/requests.xsd
index f24cbc813f3..34efc893da9 100644
--- a/lib/internal/Magento/Framework/Search/etc/requests.xsd
+++ b/lib/internal/Magento/Framework/Search/etc/requests.xsd
@@ -121,6 +121,7 @@
         <xs:sequence>
           <xs:element type="match" name="match" minOccurs="1" maxOccurs="unbounded" />
         </xs:sequence>
+        <xs:attribute type="xs:string" name="value" use="required" />
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
@@ -155,6 +156,7 @@
   <xs:complexType name="filter" abstract="true">
     <xs:attribute type="xs:string" name="name" use="required" />
   </xs:complexType>
+
   <xs:complexType name="termFilter">
     <xs:complexContent>
       <xs:extension base="filter">
@@ -234,7 +236,6 @@
     <xs:simpleContent>
       <xs:extension base="xs:string">
         <xs:attribute type="xs:string" name="field" use="required" />
-        <xs:attribute type="xs:string" name="value" use="required" />
         <xs:attribute type="xs:byte" name="boost" use="optional" />
       </xs:extension>
     </xs:simpleContent>
diff --git a/lib/internal/Magento/Framework/Session/Config.php b/lib/internal/Magento/Framework/Session/Config.php
index 289fc2e25be..0e3e3e9d266 100644
--- a/lib/internal/Magento/Framework/Session/Config.php
+++ b/lib/internal/Magento/Framework/Session/Config.php
@@ -118,7 +118,11 @@ class Config implements ConfigInterface
      */
     protected $_scopeType;
 
+    /** @var  \Magento\Framework\ValidatorFactory */
+    protected $_validatorFactory;
+
     /**
+     * @param \Magento\Framework\ValidatorFactory $validatorFactory
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\Stdlib\String $stringHelper
      * @param \Magento\Framework\App\RequestInterface $request
@@ -130,6 +134,7 @@ class Config implements ConfigInterface
      * @param string $lifetimePath
      */
     public function __construct(
+        \Magento\Framework\ValidatorFactory $validatorFactory,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\Stdlib\String $stringHelper,
         \Magento\Framework\App\RequestInterface $request,
@@ -140,6 +145,7 @@ class Config implements ConfigInterface
         $cacheLimiter = null,
         $lifetimePath = self::XML_PATH_COOKIE_LIFETIME
     ) {
+        $this->_validatorFactory = $validatorFactory;
         $this->_scopeConfig = $scopeConfig;
         $this->_stringHelper = $stringHelper;
         $this->_httpRequest = $request;
@@ -158,18 +164,15 @@ class Config implements ConfigInterface
         }
 
         $lifetime = $this->_scopeConfig->getValue($lifetimePath, $this->_scopeType);
-        $lifetime = is_numeric($lifetime) ? $lifetime : self::COOKIE_LIFETIME_DEFAULT;
-        $this->setCookieLifetime($lifetime);
+        $this->setCookieLifetime($lifetime, self::COOKIE_LIFETIME_DEFAULT);
 
         $path = $this->_scopeConfig->getValue(self::XML_PATH_COOKIE_PATH, $this->_scopeType);
-        if (empty($path)) {
-            $path = $this->_httpRequest->getBasePath();
-        }
-        $this->setCookiePath($path);
+        $path = empty($path) ? $this->_httpRequest->getBasePath() : $path;
+        $this->setCookiePath($path, $this->_httpRequest->getBasePath());
 
         $domain = $this->_scopeConfig->getValue(self::XML_PATH_COOKIE_DOMAIN, $this->_scopeType);
         $domain = empty($domain) ? $this->_httpRequest->getHttpHost() : $domain;
-        $this->setCookieDomain((string)$domain);
+        $this->setCookieDomain((string)$domain, $this->_httpRequest->getHttpHost());
 
         $this->setCookieHttpOnly(
             $this->_scopeConfig->getValue(self::XML_PATH_COOKIE_HTTPONLY, $this->_scopeType)
@@ -180,26 +183,22 @@ class Config implements ConfigInterface
      * Set many options at once
      *
      * @param array $options
+     * @param array $default
      * @return $this
-     * @throws \InvalidArgumentException
      */
-    public function setOptions($options)
+    public function setOptions($options, $default = [])
     {
-        if (!is_array($options) && !$options instanceof \Traversable) {
-            throw new \InvalidArgumentException(
-                sprintf('Parameter provided to %s must be an array or Traversable', __METHOD__)
-            );
-        }
-
-        foreach ($options as $option => $value) {
-            $setter = 'set' . $this->_stringHelper->upperCaseWords($option, '_', '');
-            if (method_exists($this, $setter)) {
-                $this->{$setter}($value);
-            } else {
-                $this->setOption($option, $value);
+        $options = (!is_array($options) && !$options instanceof \Traversable) ? $default : $options;
+        if (is_array($options) || $options instanceof \Traversable) {
+            foreach ($options as $option => $value) {
+                $setter = 'set' . $this->_stringHelper->upperCaseWords($option, '_', '');
+                if (method_exists($this, $setter)) {
+                    $this->{$setter}($value);
+                } else {
+                    $this->setOption($option, $value);
+                }
             }
         }
-
         return $this;
     }
 
@@ -264,16 +263,17 @@ class Config implements ConfigInterface
      * Set session.name
      *
      * @param string $name
+     * @param string|null $default
      * @return $this
-     * @throws \InvalidArgumentException
      */
-    public function setName($name)
+    public function setName($name, $default = null)
     {
         $name = (string)$name;
-        if (empty($name)) {
-            throw new \InvalidArgumentException('Invalid session name; cannot be empty');
+        $name = empty($name) ? $default : $name;
+        if (!empty($name)) {
+            $this->setOption('session.name', $name);
         }
-        $this->setOption('session.name', $name);
+
         return $this;
     }
 
@@ -313,20 +313,21 @@ class Config implements ConfigInterface
      * Set session.cookie_lifetime
      *
      * @param int $cookieLifetime
+     * @param int|null $default
      * @return $this
-     * @throws \InvalidArgumentException
      */
-    public function setCookieLifetime($cookieLifetime)
+    public function setCookieLifetime($cookieLifetime, $default = null)
     {
-        if (!is_numeric($cookieLifetime)) {
-            throw new \InvalidArgumentException('Invalid cookie_lifetime; must be numeric');
-        }
-        if ($cookieLifetime < 0) {
-            throw new \InvalidArgumentException('Invalid cookie_lifetime; must be a positive integer or zero');
+        $validator = $this->_validatorFactory->create(
+            [],
+            'Magento\Framework\Session\Config\Validator\CookieLifetimeValidator'
+        );
+        if ($validator->isValid($cookieLifetime)) {
+            $this->setOption('session.cookie_lifetime', (int)$cookieLifetime);
+        } elseif (null !== $default && $validator->isValid($default)) {
+            $this->setOption('session.cookie_lifetime', (int)$default);
         }
 
-        $cookieLifetime = (int)$cookieLifetime;
-        $this->setOption('session.cookie_lifetime', $cookieLifetime);
         return $this;
     }
 
@@ -344,19 +345,22 @@ class Config implements ConfigInterface
      * Set session.cookie_path
      *
      * @param string $cookiePath
+     * @param string|null $default
      * @return $this
-     * @throws \InvalidArgumentException
      */
-    public function setCookiePath($cookiePath)
+    public function setCookiePath($cookiePath, $default = null)
     {
         $cookiePath = (string)$cookiePath;
-
-        $test = parse_url($cookiePath, PHP_URL_PATH);
-        if ($test != $cookiePath || '/' != $test[0]) {
-            throw new \InvalidArgumentException('Invalid cookie path');
+        $validator = $this->_validatorFactory->create(
+            [],
+            'Magento\Framework\Session\Config\Validator\CookiePathValidator'
+        );
+        if ($validator->isValid($cookiePath)) {
+            $this->setOption('session.cookie_path', $cookiePath);
+        } elseif (null !== $default && $validator->isValid($default)) {
+            $this->setOption('session.cookie_path', $default);
         }
 
-        $this->setOption('session.cookie_path', $cookiePath);
         return $this;
     }
 
@@ -374,22 +378,21 @@ class Config implements ConfigInterface
      * Set session.cookie_domain
      *
      * @param string $cookieDomain
+     * @param string|null $default
      * @return $this
-     * @throws \InvalidArgumentException
      */
-    public function setCookieDomain($cookieDomain)
+    public function setCookieDomain($cookieDomain, $default = null)
     {
-        if (!is_string($cookieDomain)) {
-            throw new \InvalidArgumentException('Invalid cookie domain: must be a string');
-        }
-
-        $validator = new \Zend\Validator\Hostname(\Zend\Validator\Hostname::ALLOW_ALL);
-
-        if (!empty($cookieDomain) && !$validator->isValid($cookieDomain)) {
-            throw new \InvalidArgumentException('Invalid cookie domain: ' . join('; ', $validator->getMessages()));
+        $validator = $this->_validatorFactory->create(
+            [],
+            'Magento\Framework\Session\Config\Validator\CookieDomainValidator'
+        );
+        if ($validator->isValid($cookieDomain)) {
+            $this->setOption('session.cookie_domain', $cookieDomain);
+        } elseif (null !== $default && $validator->isValid($default)) {
+            $this->setOption('session.cookie_domain', $default);
         }
 
-        $this->setOption('session.cookie_domain', $cookieDomain);
         return $this;
     }
 
diff --git a/app/code/Magento/Backend/Model/Config/Backend/Domain.php b/lib/internal/Magento/Framework/Session/Config/Validator/CookieDomainValidator.php
similarity index 65%
rename from app/code/Magento/Backend/Model/Config/Backend/Domain.php
rename to lib/internal/Magento/Framework/Session/Config/Validator/CookieDomainValidator.php
index ccc46d9ba9a..29b3705917a 100644
--- a/app/code/Magento/Backend/Model/Config/Backend/Domain.php
+++ b/lib/internal/Magento/Framework/Session/Config/Validator/CookieDomainValidator.php
@@ -21,30 +21,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Model\Config\Backend;
 
-/**
- * Backend model for domain config value
- */
-class Domain extends \Magento\Framework\App\Config\Value
+namespace Magento\Framework\Session\Config\Validator;
+
+class CookieDomainValidator extends \Magento\Framework\Validator\AbstractValidator
 {
     /**
-     * Validate a domain name value
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
+     * {@inheritdoc}
      */
-    protected function _beforeSave()
+    public function isValid($value)
     {
-        $value = $this->getValue();
+        $this->_clearMessages();
+        if (!is_string($value)) {
+            $this->_addMessages(['must be a string']);
+            return false;
+        }
 
         $validator = new \Zend\Validator\Hostname(\Zend\Validator\Hostname::ALLOW_ALL);
 
-        // Empty value is treated valid and will be handled when read the value out
         if (!empty($value) && !$validator->isValid($value)) {
-            throw new \Magento\Framework\Model\Exception(
-                'Invalid domain name: ' . join('; ', $validator->getMessages())
-            );
+            $this->_addMessages($validator->getMessages());
+            return false;
         }
+        return true;
     }
 }
diff --git a/lib/internal/Magento/Framework/Session/Config/Validator/CookieLifetimeValidator.php b/lib/internal/Magento/Framework/Session/Config/Validator/CookieLifetimeValidator.php
new file mode 100644
index 00000000000..116ce1b93fb
--- /dev/null
+++ b/lib/internal/Magento/Framework/Session/Config/Validator/CookieLifetimeValidator.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Session\Config\Validator;
+
+class CookieLifetimeValidator extends \Magento\Framework\Validator\AbstractValidator
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function isValid($value)
+    {
+        $this->_clearMessages();
+        if (!is_numeric($value)) {
+            $this->_addMessages(['must be numeric']);
+            return false;
+        }
+        if ($value < 0) {
+            $this->_addMessages(['must be a positive integer or zero']);
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tabs.php b/lib/internal/Magento/Framework/Session/Config/Validator/CookiePathValidator.php
similarity index 71%
rename from app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tabs.php
rename to lib/internal/Magento/Framework/Session/Config/Validator/CookiePathValidator.php
index 6fec3782a8d..fd393c13833 100644
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Edit/Tabs.php
+++ b/lib/internal/Magento/Framework/Session/Config/Validator/CookiePathValidator.php
@@ -21,18 +21,21 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Index\Block\Adminhtml\Process\Edit;
 
-class Tabs extends \Magento\Backend\Block\Widget\Tabs
+namespace Magento\Framework\Session\Config\Validator;
+
+class CookiePathValidator extends \Magento\Framework\Validator\AbstractValidator
 {
     /**
-     * @return void
+     * {@inheritdoc}
      */
-    protected function _construct()
+    public function isValid($value)
     {
-        parent::_construct();
-        $this->setId('process_tabs');
-        $this->setDestElementId('edit_form');
-        $this->setTitle(__('Index'));
+        $this->_clearMessages();
+        $test = parse_url($value, PHP_URL_PATH);
+        if ($test != $value || '/' != $test[0]) {
+            return false;
+        }
+        return true;
     }
 }
diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php
index 810ad100962..9127258446a 100644
--- a/lib/internal/Magento/Framework/Session/SessionManager.php
+++ b/lib/internal/Magento/Framework/Session/SessionManager.php
@@ -526,7 +526,7 @@ class SessionManager implements SessionManagerInterface
             if ($result === false) {
                 $error = error_get_last();
                 throw new \InvalidArgumentException(
-                    sprintf('"%s" is not a valid sessions-related ini setting. %s', $option, $error['message'])
+                    sprintf('Failed to set ini option "%s" to value "%s". %s', $option, $value, $error['message'])
                 );
             }
         }
diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
index 92b1f1e35ff..d40e3828036 100644
--- a/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
+++ b/lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php
@@ -67,7 +67,7 @@ class DateTime
             $result = date_default_timezone_set($timezone);
         }
         if ($result === true) {
-            $offset = gmmktime(0, 0, 0, 1, 2, 1970) - mktime(0, 0, 0, 1, 2, 1970);
+            $offset = (int)date('Z');
         }
         if ($timezone !== null) {
             date_default_timezone_set($oldZone);
diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php
index 5e611157f03..6282b6d0fa4 100644
--- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php
+++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php
@@ -116,7 +116,7 @@ class Timezone implements TimezoneInterface
      */
     public function getConfigTimezone()
     {
-        return $this->_scopeConfig->getValue('general/locale/timezone', $this->_scopeType);
+        return $this->_scopeConfig->getValue($this->getDefaultTimezonePath(), $this->_scopeType);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/ValidatorFactory.php b/lib/internal/Magento/Framework/ValidatorFactory.php
index 66354555d54..b32a8316a88 100644
--- a/lib/internal/Magento/Framework/ValidatorFactory.php
+++ b/lib/internal/Magento/Framework/ValidatorFactory.php
@@ -28,6 +28,8 @@ namespace Magento\Framework;
  */
 class ValidatorFactory
 {
+    const DEFAULT_INSTANCE_NAME = 'Magento\Framework\Validator';
+
     /**
      * Object Manager instance
      *
@@ -50,7 +52,7 @@ class ValidatorFactory
      */
     public function __construct(
         \Magento\Framework\ObjectManager $objectManager,
-        $instanceName = 'Magento\Framework\Validator'
+        $instanceName = self::DEFAULT_INSTANCE_NAME
     ) {
         $this->_objectManager = $objectManager;
         $this->_instanceName = $instanceName;
@@ -60,10 +62,16 @@ class ValidatorFactory
      * Create class instance with specified parameters
      *
      * @param array $data
+     * @param string $instanceName
      * @return \Magento\Framework\Validator
      */
-    public function create(array $data = array())
+    public function create(array $data = [], $instanceName = null)
     {
-        return $this->_objectManager->create($this->_instanceName, $data);
+        if (null === $instanceName) {
+            return $this->_objectManager->create($this->_instanceName, $data);
+        } else {
+            return $this->_objectManager->create($instanceName, $data);
+        }
+
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Asset/Source.php b/lib/internal/Magento/Framework/View/Asset/Source.php
index 205eb255872..35824fc6af3 100644
--- a/lib/internal/Magento/Framework/View/Asset/Source.php
+++ b/lib/internal/Magento/Framework/View/Asset/Source.php
@@ -71,7 +71,7 @@ class Source
     /**
      * @var \Magento\Framework\View\Design\Theme\ListInterface
      */
-    protected $themeList;
+    private $themeList;
 
     /**
      * @param PreProcessor\Cache $cache
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/File.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/File.php
index 3bef6897e0f..13d8fd610e2 100644
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/File.php
+++ b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/File.php
@@ -53,7 +53,7 @@ class File
      * @param ThemeInterface $themeModel
      * @param string $file
      * @param string|null $module
-     * @return string|bool
+     * @return string|false
      */
     public function getFile($area, ThemeInterface $themeModel, $file, $module = null)
     {
diff --git a/lib/internal/Magento/Framework/View/Element/Template.php b/lib/internal/Magento/Framework/View/Element/Template.php
index 1ea5a982430..549aee5ab82 100644
--- a/lib/internal/Magento/Framework/View/Element/Template.php
+++ b/lib/internal/Magento/Framework/View/Element/Template.php
@@ -28,6 +28,7 @@ use Magento\Framework\App\Filesystem;
 /**
  * Base html block
  * @SuppressWarnings(PHPMD.NumberOfChildren)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Template extends AbstractBlock
 {
@@ -127,6 +128,11 @@ class Template extends AbstractBlock
      */
     protected $templateContext;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
     /**
      * Constructor
      *
@@ -141,6 +147,7 @@ class Template extends AbstractBlock
         $this->_storeManager = $context->getStoreManager();
         $this->_appState = $context->getAppState();
         $this->templateContext = $this;
+        $this->pageConfig = $context->getPageConfig();
         parent::__construct($context, $data);
     }
 
diff --git a/lib/internal/Magento/Framework/View/Element/Template/Context.php b/lib/internal/Magento/Framework/View/Element/Template/Context.php
index dd248e7b8d5..c7c344ff156 100644
--- a/lib/internal/Magento/Framework/View/Element/Template/Context.php
+++ b/lib/internal/Magento/Framework/View/Element/Template/Context.php
@@ -58,6 +58,11 @@ class Context extends \Magento\Framework\View\Element\Context
      */
     protected $_storeManager;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\View\LayoutInterface $layout
@@ -82,6 +87,7 @@ class Context extends \Magento\Framework\View\Element\Context
      * @param \Magento\Framework\View\TemplateEnginePool $enginePool
      * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\View\Page\Config $pageConfig
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -108,7 +114,8 @@ class Context extends \Magento\Framework\View\Element\Context
         \Magento\Framework\View\FileSystem $viewFileSystem,
         \Magento\Framework\View\TemplateEnginePool $enginePool,
         \Magento\Framework\App\State $appState,
-        \Magento\Framework\StoreManagerInterface $storeManager
+        \Magento\Framework\StoreManagerInterface $storeManager,
+        \Magento\Framework\View\Page\Config $pageConfig
     ) {
         parent::__construct(
             $request,
@@ -137,6 +144,7 @@ class Context extends \Magento\Framework\View\Element\Context
         $this->_filesystem = $filesystem;
         $this->_viewFileSystem = $viewFileSystem;
         $this->enginePool = $enginePool;
+        $this->pageConfig = $pageConfig;
     }
 
     /**
@@ -198,4 +206,12 @@ class Context extends \Magento\Framework\View\Element\Context
     {
         return $this->_storeManager;
     }
+
+    /**
+     * @return \Magento\Framework\View\Page\Config
+     */
+    public function getPageConfig()
+    {
+        return $this->pageConfig;
+    }
 }
diff --git a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php
similarity index 76%
rename from app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php
index a1b81e914ce..9e4b38ae752 100644
--- a/app/code/Magento/CmsUrlRewrite/Service/V1/CmsPageUrlGeneratorInterface.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigBuilderInterface.php
@@ -21,18 +21,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CmsUrlRewrite\Service\V1;
+namespace Magento\Framework\View\Element\UiComponent;
 
 /**
- * Product Generator
+ * Interface ConfigBuilderInterface
  */
-interface CmsPageUrlGeneratorInterface
+interface ConfigBuilderInterface
 {
     /**
-     * Generate list of urls
+     * Config data to JSON by output
      *
-     * @param \Magento\Cms\Model\Page $cmsPage
-     * @return \Magento\UrlRedirect\Service\V1\Data\UrlRewrite[]
+     * @param ConfigInterface $configuration
+     * @return string
      */
-    public function generate($cmsPage);
+    public function toJson(ConfigInterface $configuration);
 }
diff --git a/app/code/Magento/Theme/Block/Html/Body.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php
similarity index 55%
rename from app/code/Magento/Theme/Block/Html/Body.php
rename to lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php
index 4fe82bdf159..b738e9798b9 100644
--- a/app/code/Magento/Theme/Block/Html/Body.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigFactory.php
@@ -21,45 +21,51 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Theme\Block\Html;
+namespace Magento\Framework\View\Element\UiComponent;
 
-use \Magento\Framework\View\Element\AbstractBlock;
+use Magento\Framework\ObjectManager;
 
 /**
- * Temporary block to replace some logic from root block
+ * Class ConfigFactory
  */
-class Body extends AbstractBlock
+class ConfigFactory
 {
     /**
-     * @var \Magento\Framework\View\Page\Config
+     * Object Manager instance
+     *
+     * @var ObjectManager
      */
-    protected $pageConfig;
+    protected $objectManager = null;
 
     /**
-     * Construct
+     * Instance name to create
      *
-     * @param \Magento\Framework\View\Element\Context $context
-     * @param \Magento\Framework\View\Page\Config $pageConfig
-     * @param array $data
+     * @var string
+     */
+    protected $instanceName = null;
+
+    /**
+     * Factory constructor
+     *
+     * @param ObjectManager $objectManager
+     * @param string $instanceName
      */
     public function __construct(
-        \Magento\Framework\View\Element\Context $context,
-        \Magento\Framework\View\Page\Config $pageConfig,
-        array $data = array()
+        ObjectManager $objectManager,
+        $instanceName = 'Magento\Framework\View\Element\UiComponent\ConfigInterface'
     ) {
-        $this->pageConfig = $pageConfig;
-        parent::__construct($context, $data);
+        $this->objectManager = $objectManager;
+        $this->instanceName = $instanceName;
     }
 
     /**
-     * Add body class to page configuration api
+     * Create class instance with specified parameters
      *
-     * @param string $bodyClass
-     * @return $this
+     * @param array $data
+     * @return \Magento\Ui\Configuration
      */
-    public function addBodyClass($bodyClass)
+    public function create(array $data = [])
     {
-        $this->pageConfig->addBodyClass($bodyClass);
-        return $this;
+        return $this->objectManager->create($this->instanceName, $data);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php
new file mode 100644
index 00000000000..c8b4c48d503
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigInterface.php
@@ -0,0 +1,70 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+/**
+ * Class ConfigInterface
+ */
+interface ConfigInterface
+{
+    /**
+     * Get configuration data
+     *
+     * @param string|null $key
+     * @return mixed
+     */
+    public function getData($key = null);
+
+    /**
+     * Add configuration data
+     *
+     * @param string $key
+     * @param mixed $data
+     * @return mixed
+     */
+    public function addData($key, $data);
+
+    /**
+     * Update configuration data
+     *
+     * @param string $key
+     * @param mixed $data
+     * @return mixed
+     */
+    public function updateData($key, $data);
+
+    /**
+     * Get owner name
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Get owner parent name
+     *
+     * @return string
+     */
+    public function getParentName();
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.php
new file mode 100644
index 00000000000..51da119ac0a
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageBuilderInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+/**
+ * Interface ConfigStorageBuilderInterface
+ */
+interface ConfigStorageBuilderInterface
+{
+    /**
+     * Config storage data to JSON by output
+     *
+     * @param ConfigStorageInterface $storage
+     * @param string $parentName
+     * @return string
+     */
+    public function toJson(ConfigStorageInterface $storage, $parentName = null);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.php
new file mode 100644
index 00000000000..44e577a07c1
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ConfigStorageInterface.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\Data\Collection as DataCollection;
+
+/**
+ * Class ConfigurationStorageInterface
+ */
+interface ConfigStorageInterface
+{
+    /**
+     * Add components configuration
+     *
+     * @param ConfigInterface $configuration
+     * @return void
+     */
+    public function addComponentsData(ConfigInterface $configuration);
+
+    /**
+     * Remove components configuration
+     *
+     * @param ConfigInterface $configuration
+     * @return void
+     */
+    public function removeComponentsData(ConfigInterface $configuration);
+
+    /**
+     * Get components configuration
+     *
+     * @param string|null $name
+     * @return ConfigInterface|null|array
+     */
+    public function getComponentsData($name = null);
+
+    /**
+     * Add data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function addData($key, array $data);
+
+    /**
+     * Remove data in storage
+     *
+     * @param string $key
+     * @return void
+     */
+    public function removeData($key);
+
+    /**
+     * Get data from storage
+     *
+     * @param string|null $key
+     * @return array|null
+     */
+    public function getData($key = null);
+
+    /**
+     * Update data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function updateData($key, array $data);
+
+    /**
+     * Add meta data
+     *
+     * @param string $key
+     * @param array $data
+     * @return mixed
+     */
+    public function addMeta($key, array $data);
+
+    /**
+     * Remove meta data
+     *
+     * @param string $key
+     * @return array
+     */
+    public function removeMeta($key);
+
+    /**
+     * Get meta data
+     *
+     * @param string|null $key
+     * @return array|null
+     */
+    public function getMeta($key = null);
+
+    /**
+     * Update meta data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function updateMeta($key, array $data);
+
+    /**
+     * Set data collection
+     *
+     * @param string $key
+     * @param DataCollection $dataCollection
+     * @return void
+     */
+    public function addDataCollection($key, DataCollection $dataCollection);
+
+    /**
+     * Get data collection
+     *
+     * @param string|null $key
+     * @return DataCollection
+     */
+    public function getDataCollection($key = null);
+
+    /**
+     * Update data collection in storage
+     *
+     * @param string $key
+     * @param DataCollection $dataCollection
+     * @return mixed
+     */
+    public function updateDataCollection($key, DataCollection $dataCollection);
+
+    /**
+     * Add cloud data in storage
+     *
+     * @param string $key
+     * @param array $data
+     * @return void
+     */
+    public function addGlobalData($key, array $data);
+
+    /**
+     * Remove cloud data in storage
+     *
+     * @param string $key
+     * @return void
+     */
+    public function removeGlobalData($key);
+
+    /**
+     * Get cloud data from storage
+     *
+     * @param string|null $key
+     * @return array|null
+     */
+    public function getGlobalData($key = null);
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
new file mode 100644
index 00000000000..38d55794499
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php
@@ -0,0 +1,230 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element\UiComponent;
+
+use Magento\Framework\Registry;
+use Magento\Framework\View\LayoutInterface;
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
+
+/**
+ * Class Context
+ */
+class Context extends Registry
+{
+    /**
+     * Configuration storage builder
+     *
+     * @var ConfigStorageBuilderInterface
+     */
+    protected $configStorageBuilder;
+
+    /**
+     * Configuration storage
+     *
+     * @var ConfigStorageInterface
+     */
+    protected $configStorage;
+
+    /**
+     * Application request
+     *
+     * @var RequestInterface
+     */
+    protected $request;
+
+    /**
+     * Accept type
+     *
+     * @var string
+     */
+    protected $acceptType;
+
+    /**
+     * @var LayoutInterface
+     */
+    protected $layout;
+
+    /**
+     * @var UiComponentFactory
+     */
+    protected $factory;
+
+    /**
+     * Data Namespace
+     *
+     * @var string
+     */
+    protected $namespace;
+
+    /**
+     * Constructor
+     *
+     * @param ConfigStorageInterface $configStorage
+     * @param ConfigStorageBuilderInterface $configStorageBuilder
+     * @param RequestInterface $request
+     */
+    public function __construct(
+        ConfigStorageInterface $configStorage,
+        ConfigStorageBuilderInterface $configStorageBuilder,
+        RequestInterface $request
+    ) {
+        $this->configStorage = $configStorage;
+        $this->configStorageBuilder = $configStorageBuilder;
+        $this->request = $request;
+        $this->setAcceptType();
+    }
+
+    /**
+     * Getting requested accept type
+     *
+     * @return void
+     */
+    protected function setAcceptType()
+    {
+        $this->acceptType = 'xml';
+
+        $rawAcceptType = $this->request->getHeader('Accept');
+        if (strpos($rawAcceptType, 'json') !== false) {
+            $this->acceptType = 'json';
+        } elseif (strpos($rawAcceptType, 'html') !== false) {
+            $this->acceptType = 'html';
+        }
+    }
+
+    /**
+     * Getting accept type
+     *
+     * @return string
+     */
+    public function getAcceptType()
+    {
+        return $this->acceptType;
+    }
+
+    /**
+     * Set Ui Components Factory
+     *
+     * @param UiComponentFactory $render
+     * @return void
+     */
+    public function setRender(UiComponentFactory $render)
+    {
+        $this->factory = $render;
+    }
+
+    /**
+     * Get Ui Components Factory
+     *
+     * @return UiComponentFactory
+     */
+    public function getRender()
+    {
+        return $this->factory;
+    }
+
+    /**
+     * Set root layout
+     *
+     * @param LayoutInterface $layout
+     * @return void
+     */
+    public function setPageLayout(LayoutInterface $layout)
+    {
+        $this->layout = $layout;
+    }
+
+    /**
+     * Get root layout
+     *
+     * @return LayoutInterface
+     */
+    public function getPageLayout()
+    {
+        return $this->layout;
+    }
+
+    /**
+     * Set root view
+     *
+     * @param string $namespace
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace = $namespace;
+    }
+
+    /**
+     * Get root view
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return $this->namespace;
+    }
+
+    /**
+     * Getting all request data
+     *
+     * @return mixed
+     */
+    public function getRequestParams()
+    {
+        return $this->request->getParams();
+    }
+
+    /**
+     * Getting data according to the key
+     *
+     * @param string $key
+     * @param mixed|null $defaultValue
+     * @return mixed
+     */
+    public function getRequestParam($key, $defaultValue = null)
+    {
+        return $this->request->getParam($key, $defaultValue);
+    }
+
+    /**
+     * Get storage configuration
+     *
+     * @return ConfigStorageInterface
+     */
+    public function getStorage()
+    {
+        return $this->configStorage;
+    }
+
+    /**
+     * Get configuration builder
+     *
+     * @return ConfigStorageBuilderInterface
+     */
+    public function getConfigurationBuilder()
+    {
+        return $this->configStorageBuilder;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
new file mode 100644
index 00000000000..a34bd55eedd
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php
@@ -0,0 +1,215 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element;
+
+
+use Magento\Framework\Object;
+use Magento\Framework\View\LayoutFactory;
+use Magento\Framework\View\LayoutInterface;
+use Magento\Framework\View\Element\Template;
+use Magento\Framework\View\Element\UiComponent\Context as RenderContext;
+
+/**
+ * Class UiComponentFactory
+ */
+class UiComponentFactory extends Object
+{
+    /**
+     * Ui element view
+     *
+     * @var UiComponentInterface
+     */
+    protected $view;
+
+    /**
+     * Render context
+     *
+     * @var RenderContext
+     */
+    protected $renderContext;
+
+    /**
+     * Layout Interface
+     *
+     * @var \Magento\Framework\View\LayoutFactory
+     */
+    protected $layoutFactory;
+
+    /**
+     * @var LayoutInterface
+     */
+    protected $layout;
+
+    /**
+     * @var boolean
+     */
+    protected $layoutLoaded;
+
+    /**
+     * Constructor
+     *
+     * @param RenderContext $renderContext
+     * @param LayoutFactory $layoutFactory
+     * @param array $data
+     */
+    public function __construct(
+        RenderContext $renderContext,
+        LayoutFactory $layoutFactory,
+        array $data = []
+    ) {
+        $this->renderContext = $renderContext;
+        $this->renderContext->setRender($this);
+        $this->layoutFactory = $layoutFactory;
+        parent::__construct($data);
+    }
+
+    /**
+     * Get component name
+     *
+     * @return string
+     */
+    public function getComponent()
+    {
+        return $this->getData('configuration/component');
+    }
+
+    /**
+     * Get layout handle
+     *
+     * @return string
+     */
+    public function getLayoutHandle()
+    {
+        return $this->getData('configuration/name');
+    }
+
+    /**
+     * @param LayoutInterface $layout
+     * @return void
+     */
+    public function setLayout(LayoutInterface $layout)
+    {
+        if (!$this->renderContext->getPageLayout()) {
+            $this->renderContext->setPageLayout($layout);
+        }
+    }
+
+    /**
+     * Create Ui Component instance
+     *
+     * @param string $componentName
+     * @param string $handleName
+     * @param array $arguments
+     * @return UiComponentInterface
+     */
+    public function createUiComponent($componentName, $handleName = '', array $arguments = [])
+    {
+        $root = false;
+        if (!$this->renderContext->getNamespace()) {
+            $root = true;
+            if ($handleName) {
+                $this->renderContext->setNamespace($handleName);
+            }
+        }
+
+        if ($root && $handleName) {
+            if (!$this->layoutLoaded) {
+                $this->layoutLoaded = true;
+                $this->layout = $this->layoutFactory->create();
+                $this->layout->getUpdate()->addHandle('ui_components');
+                $this->layout->getUpdate()->addHandle($handleName);
+                $this->loadLayout();
+            }
+        }
+
+        $view = $this->getUiElementView($componentName);
+
+        $view->update($arguments);
+        if ($root) {
+            // data should be prepared starting from the root element
+            $this->prepare($view);
+            $this->renderContext->setNamespace(null);
+        }
+        return $view;
+    }
+
+    /**
+     * Prepare UI Component data
+     *
+     * @param object $view
+     * @return void
+     */
+    protected function prepare($view)
+    {
+        if ($view instanceof UiComponentInterface) {
+            $view->prepare();
+        }
+        foreach ($view->getLayout()->getChildNames($view->getNameInLayout()) as $childAlias) {
+            $name = $view->getLayout()->getChildName($view->getNameInLayout(), $childAlias);
+            if ($view->getLayout()->isContainer($name)) {
+                foreach ($view->getLayout()->getChildNames($name) as $childName) {
+                    $child = $view->getLayout()->getBlock($childName);
+                    $this->prepare($child);
+                }
+            } else {
+                $child = $view->getChildBlock($childAlias);
+                $this->prepare($child);
+            }
+        }
+    }
+
+    /**
+     * Get UI Element View
+     *
+     * @param string $uiElementName
+     * @return UiComponentInterface
+     * @throws \InvalidArgumentException
+     */
+    protected function getUiElementView($uiElementName)
+    {
+        /** @var UiComponentInterface $view */
+        $view = $this->layout->getBlock($uiElementName);
+        if (!$view instanceof UiComponentInterface) {
+            throw new \InvalidArgumentException(
+                sprintf(
+                    'UI Element "%s" must implement \Magento\Framework\View\Element\UiComponentInterface',
+                    $uiElementName
+                )
+            );
+        }
+        return $view;
+    }
+
+    /**
+     * Load layout
+     *
+     * @return void
+     */
+    protected function loadLayout()
+    {
+        $this->layout->getUpdate()->load();
+        $this->layout->generateXml();
+        $this->layout->generateElements();
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
new file mode 100644
index 00000000000..8df2893132a
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Element/UiComponentInterface.php
@@ -0,0 +1,92 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element;
+
+/**
+ * Class UiComponentInterface
+ */
+interface UiComponentInterface extends BlockInterface
+{
+    /**
+     * Update component data
+     *
+     * @param array $arguments
+     * @return string
+     */
+    public function update(array $arguments = []);
+
+    /**
+     * Prepare component data
+     *
+     * @return string
+     */
+    public function prepare();
+
+    /**
+     * Render component
+     *
+     * @return string
+     */
+    public function render();
+
+    /**
+     * Render label
+     *
+     * @return mixed|string
+     */
+    public function renderLabel();
+
+    /**
+     * Getting template for rendering content
+     *
+     * @return string|false
+     */
+    public function getContentTemplate();
+
+    /**
+     * Getting template for rendering label
+     *
+     * @return string|false
+     */
+    public function getLabelTemplate();
+
+    /**
+     * Getting instance name
+     *
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * Getting parent name component instance
+     *
+     * @return string
+     */
+    public function getParentName();
+
+    /**
+     * @return mixed
+     */
+    public function getRenderContext();
+}
diff --git a/lib/internal/Magento/Framework/View/FileSystem.php b/lib/internal/Magento/Framework/View/FileSystem.php
index 28fed1c4332..654a11040ed 100644
--- a/lib/internal/Magento/Framework/View/FileSystem.php
+++ b/lib/internal/Magento/Framework/View/FileSystem.php
@@ -118,7 +118,7 @@ class FileSystem
      *
      * @param string $fileId
      * @param array $params
-     * @return string
+     * @return string|false
      */
     public function getTemplateFileName($fileId, array $params = array())
     {
diff --git a/lib/internal/Magento/Framework/View/Layout.php b/lib/internal/Magento/Framework/View/Layout.php
index f14b6c5a173..faaf5153434 100644
--- a/lib/internal/Magento/Framework/View/Layout.php
+++ b/lib/internal/Magento/Framework/View/Layout.php
@@ -79,6 +79,11 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
      */
     protected $_update;
 
+    /**
+     * @var \Magento\Framework\View\Element\UiComponentFactory
+     */
+    protected $_uiComponentFactory;
+
     /**
      * @var \Magento\Framework\View\Element\BlockFactory
      */
@@ -214,10 +219,21 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
      */
     protected $cacheable;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config\Reader
+     */
+    protected $pageConfigReader;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config\Generator
+     */
+    protected $pageConfigGenerator;
+
     /**
      * @param \Magento\Framework\View\Layout\ProcessorFactory $processorFactory
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param \Magento\Framework\View\Element\UiComponentFactory $uiElementFactory,
      * @param \Magento\Framework\View\Element\BlockFactory $blockFactory
      * @param \Magento\Framework\Data\Structure $structure
      * @param \Magento\Framework\View\Layout\Argument\Parser $argumentParser
@@ -228,6 +244,8 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
      * @param \Magento\Framework\View\Design\Theme\ResolverInterface $themeResolver
      * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
+     * @param Page\Config\Reader $pageConfigReader
+     * @param Page\Config\Generator $pageConfigGenerator
      * @param string $scopeType
      * @param bool $cacheable
      */
@@ -235,6 +253,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         \Magento\Framework\View\Layout\ProcessorFactory $processorFactory,
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory,
         \Magento\Framework\View\Element\BlockFactory $blockFactory,
         \Magento\Framework\Data\Structure $structure,
         \Magento\Framework\View\Layout\Argument\Parser $argumentParser,
@@ -245,11 +264,15 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         \Magento\Framework\Message\ManagerInterface $messageManager,
         \Magento\Framework\View\Design\Theme\ResolverInterface $themeResolver,
         \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
+        \Magento\Framework\View\Page\Config\Reader $pageConfigReader,
+        \Magento\Framework\View\Page\Config\Generator $pageConfigGenerator,
         $scopeType,
         $cacheable = true
     ) {
         $this->_eventManager = $eventManager;
         $this->_scopeConfig = $scopeConfig;
+        $this->_uiComponentFactory = $uiComponentFactory;
+        $this->_uiComponentFactory->setLayout($this);
         $this->_blockFactory = $blockFactory;
         $this->_appState = $appState;
         $this->_structure = $structure;
@@ -266,6 +289,8 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         $this->themeResolver = $themeResolver;
         $this->scopeResolver = $scopeResolver;
         $this->cacheable = $cacheable;
+        $this->pageConfigReader = $pageConfigReader;
+        $this->pageConfigGenerator = $pageConfigGenerator;
     }
 
     /**
@@ -344,11 +369,15 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
 
         \Magento\Framework\Profiler::start('generate_elements');
 
+        $this->pageConfigGenerator->process();
+
         while (false === $this->_scheduledStructure->isElementsEmpty()) {
             list($type, $node, $actions, $args, $attributes) = current($this->_scheduledStructure->getElements());
             $elementName = key($this->_scheduledStructure->getElements());
 
-            if ($type == Element::TYPE_BLOCK) {
+            if ($type == Element::TYPE_UI_COMPONENT) {
+                $this->_generateUiComponent($elementName);
+            } else if ($type == Element::TYPE_BLOCK) {
                 $this->_generateBlock($elementName);
             } else {
                 $this->_generateContainer($elementName, (string)$node[Element::CONTAINER_OPT_LABEL], $attributes);
@@ -439,6 +468,10 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
                     $this->_readStructure($node);
                     break;
 
+                case Element::TYPE_UI_COMPONENT:
+                    $this->_scheduleStructure($node, $parent);
+                    break;
+
                 case Element::TYPE_REFERENCE_CONTAINER:
                     $this->_mergeContainerAttributes($node);
                     $this->_readStructure($node);
@@ -472,6 +505,18 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
                     $this->_scheduledStructure->setElementToRemoveList((string)$node->getAttribute('name'));
                     break;
 
+                case Page\Config::ELEMENT_TYPE_HTML:
+                    $this->pageConfigReader->readHtml($node);
+                    break;
+
+                case Page\Config::ELEMENT_TYPE_HEAD:
+                    $this->pageConfigReader->readHead($node);
+                    break;
+
+                case Page\Config::ELEMENT_TYPE_BODY:
+                    $this->pageConfigReader->readBody($node);
+                    break;
+
                 default:
                     break;
             }
@@ -846,6 +891,51 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         return $block;
     }
 
+    /**
+     * Creates UI Component object based on xml node data and add it to the layout
+     *
+     * @param string $elementName
+     * @return \Magento\Framework\View\Element\AbstractBlock|void
+     * @throws \Magento\Framework\Exception
+     *
+     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+     */
+    protected function _generateUiComponent($elementName)
+    {
+        list($type, $node, $actions, $args) = $this->_scheduledStructure->getElement($elementName);
+        if ($type !== Element::TYPE_UI_COMPONENT) {
+            throw new \Magento\Framework\Exception(
+                "Unexpected element type specified for generating UI Component: {$type}."
+            );
+        }
+
+        $configPath = (string)$node->getAttribute('ifconfig');
+        if (!empty($configPath)
+            && !$this->_scopeConfig->isSetFlag($configPath, $this->scopeType, $this->scopeResolver->getScope())
+        ) {
+            $this->_scheduledStructure->unsetElement($elementName);
+            return;
+        }
+
+        $group = (string)$node->getAttribute('group');
+        if (!empty($group)) {
+            $this->_structure->addToParentGroup($elementName, $group);
+        }
+
+        $arguments = $this->_evaluateArguments($args);
+
+        // create Ui Component Object
+        $componentName = (string)$node['component'];
+
+        $uiComponent = $this->_uiComponentFactory->createUiComponent($componentName, $elementName, $arguments);
+
+        $this->_blocks[$elementName] = $uiComponent;
+
+        $this->_scheduledStructure->unsetElement($elementName);
+
+        return $uiComponent;
+    }
+
     /**
      * Set container-specific data to structure element
      *
@@ -1093,7 +1183,9 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
     public function renderElement($name, $useCache = true)
     {
         if (!isset($this->_renderElementCache[$name]) || !$useCache) {
-            if ($this->isBlock($name)) {
+            if ($this->isUiComponent($name)) {
+                $result = $this->_renderUiComponent($name);
+            } else if ($this->isBlock($name)) {
                 $result = $this->_renderBlock($name);
             } else {
                 $result = $this->_renderContainer($name);
@@ -1121,6 +1213,19 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         return $block ? $block->toHtml() : '';
     }
 
+    /**
+     * Gets HTML of Ui Component
+     *
+     * @param string $name
+     * @return string
+     * @throws \Magento\Framework\Exception
+     */
+    protected function _renderUiComponent($name)
+    {
+        $uiComponent = $this->getUiComponent($name);
+        return $uiComponent ? $uiComponent->toHtml() : '';
+    }
+
     /**
      * Gets HTML of container element
      *
@@ -1216,6 +1321,20 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         return false;
     }
 
+    /**
+     * Whether specified element is a UI Component
+     *
+     * @param string $name
+     * @return bool
+     */
+    public function isUiComponent($name)
+    {
+        if ($this->_structure->hasElement($name)) {
+            return Element::TYPE_UI_COMPONENT === $this->_structure->getAttribute($name, 'type');
+        }
+        return false;
+    }
+
     /**
      * Checks if element with specified name is container
      *
@@ -1424,6 +1543,24 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
         }
     }
 
+    /**
+     * Get Ui Component object by name
+     *
+     * @param string $name
+     * @return \Magento\Framework\View\Element\AbstractBlock|bool
+     */
+    public function getUiComponent($name)
+    {
+        if ($this->_scheduledStructure->hasElement($name)) {
+            $this->_generateUiComponent($name);
+        }
+        if (isset($this->_blocks[$name])) {
+            return $this->_blocks[$name];
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Gets parent name of an element with specified name
      *
diff --git a/lib/internal/Magento/Framework/View/Layout/Element.php b/lib/internal/Magento/Framework/View/Layout/Element.php
index 477d458bf6f..8fdbed1aa8e 100644
--- a/lib/internal/Magento/Framework/View/Layout/Element.php
+++ b/lib/internal/Magento/Framework/View/Layout/Element.php
@@ -55,6 +55,10 @@ class Element extends \Magento\Framework\Simplexml\Element
 
     const TYPE_MOVE = 'move';
 
+    const TYPE_UI_COMPONENT = 'ui_component';
+
+    const TYPE_HEAD = 'head';
+
     /**#@-*/
 
     /**#@+
@@ -84,6 +88,7 @@ class Element extends \Magento\Framework\Simplexml\Element
             case self::TYPE_RENDERER:
             case self::TYPE_TEMPLATE:
             case self::TYPE_DATA:
+            case self::TYPE_UI_COMPONENT:
                 $this->prepareBlock();
                 break;
             case self::TYPE_REFERENCE_BLOCK:
diff --git a/lib/internal/Magento/Framework/View/Page/Config.php b/lib/internal/Magento/Framework/View/Page/Config.php
index 8262204ed81..825cd66f2b0 100644
--- a/lib/internal/Magento/Framework/View/Page/Config.php
+++ b/lib/internal/Magento/Framework/View/Page/Config.php
@@ -33,6 +33,9 @@ namespace Magento\Framework\View\Page;
  * - meta info
  * - root element properties
  * - etc...
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
  */
 class Config
 {
@@ -41,16 +44,23 @@ class Config
      */
     const ELEMENT_TYPE_BODY = 'body';
     const ELEMENT_TYPE_HTML = 'html';
+    const ELEMENT_TYPE_HEAD = 'head';
     /**#@-*/
 
+    /**
+     * Constant body attribute class
+     */
+    const BODY_ATTRIBUTE_CLASS = 'class';
+
     /**
      * Allowed group of types
      *
      * @var array
      */
-    private $allowedTypes = [
+    protected $allowedTypes = [
         self::ELEMENT_TYPE_BODY,
-        self::ELEMENT_TYPE_HTML
+        self::ELEMENT_TYPE_HTML,
+        self::ELEMENT_TYPE_HEAD
     ];
 
     /**
@@ -59,9 +69,26 @@ class Config
     protected $title;
 
     /**
-     * @var \Magento\Framework\View\Asset\Collection
+     * @var string
+     */
+    protected $titleChunks;
+
+    /**
+     * @var string
+     */
+    protected $pureTitle;
+
+    /**
+     * Asset service
+     *
+     * @var \Magento\Framework\View\Asset\Repository
      */
-    protected $assetCollection;
+    protected $assetRepo;
+
+    /**
+     * @var \Magento\Framework\View\Asset\GroupedCollection
+     */
+    protected $pageAssets;
 
     /**
      * @var string[][]
@@ -74,44 +101,347 @@ class Config
     protected $pageLayout;
 
     /**
-     * Constructor
-     *
-     * @param \Magento\Framework\View\Asset\Collection $assetCollection
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\View\Page\FaviconInterface
+     */
+    protected $favicon;
+
+    /**
+     * @var array
+     */
+    protected $includes;
+
+    /**
+     * @var array
+     */
+    protected $metadata = [
+        'charset' => null,
+        'media_type' => null,
+        'content_type' => null,
+        'description' => null,
+        'keywords' => null,
+        'robots' => null,
+    ];
+
+    /**
+     * @param \Magento\Framework\View\Asset\Repository $assetRepo
+     * @param \Magento\Framework\View\Asset\GroupedCollection $pageAssets
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\View\Page\FaviconInterface $favicon
      */
     public function __construct(
-        \Magento\Framework\View\Asset\Collection $assetCollection
+        \Magento\Framework\View\Asset\Repository $assetRepo,
+        \Magento\Framework\View\Asset\GroupedCollection $pageAssets,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\View\Page\FaviconInterface $favicon
     ) {
-        $this->assetCollection = $assetCollection;
+        $this->assetRepo = $assetRepo;
+        $this->pageAssets = $pageAssets;
+        $this->scopeConfig = $scopeConfig;
+        $this->favicon = $favicon;
     }
 
     /**
      * Set page title
      *
-     * @param string $title
+     * @param string|array $title
      * @return $this
      */
     public function setTitle($title)
     {
-        $this->title = $title;
+        $this->title = $this->scopeConfig->getValue(
+            'design/head/title_prefix',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        ) . ' ' . $this->prepareTitle($title) . ' ' . $this->scopeConfig->getValue(
+            'design/head/title_suffix',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+
         return $this;
     }
 
     /**
-     * Return page title
+     * @param array|string $title
+     * @return string
+     */
+    protected function prepareTitle($title)
+    {
+        $this->titleChunks = '';
+        $this->pureTitle = '';
+
+        if (is_array($title)) {
+            $this->titleChunks = $title;
+            return implode(' / ', $title);
+        }
+        $this->pureTitle = $title;
+        return $this->pureTitle;
+    }
+
+    /**
+     * Retrieve title element text (encoded)
      *
      * @return string
      */
     public function getTitle()
     {
-        return $this->title;
+        if (empty($this->title)) {
+            $this->title = $this->getDefaultTitle();
+        }
+        return htmlspecialchars(html_entity_decode(trim($this->title), ENT_QUOTES, 'UTF-8'));
     }
 
     /**
-     * @return \Magento\Framework\View\Asset\Collection
+     * Same as getTitle(), but return only first item from chunk for backend pages
+     *
+     * @return mixed
+     */
+    public function getShortTitle()
+    {
+        if (!empty($this->titleChunks)) {
+            return reset($this->titleChunks);
+        } else {
+            return $this->pureTitle;
+        }
+    }
+
+    /**
+     * Retrieve default title text
+     *
+     * @return string
+     */
+    public function getDefaultTitle()
+    {
+        return $this->scopeConfig->getValue(
+            'design/head/default_title',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    /**
+     * @param string $name
+     * @param string $content
+     * @return void
+     */
+    public function setMetadata($name, $content)
+    {
+        $this->metadata[$name] = $content;
+    }
+
+    /**
+     * @return array
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * @param string $contentType
+     * @return void
+     */
+    public function setContentType($contentType)
+    {
+        $this->setMetadata('content_type', $contentType);
+    }
+
+    /**
+     * Retrieve Content Type
+     *
+     * @return string
+     */
+    public function getContentType()
+    {
+        if (empty($this->metadata['content_type'])) {
+            $this->metadata['content_type'] = $this->getMediaType() . '; charset=' . $this->getCharset();
+        }
+        return $this->metadata['content_type'];
+    }
+
+    /**
+     * @param string $mediaType
+     * @return void
+     */
+    public function setMediaType($mediaType)
+    {
+        $this->setMetadata('media_type', $mediaType);
+    }
+
+    /**
+     * Retrieve Media Type
+     *
+     * @return string
+     */
+    public function getMediaType()
+    {
+        if (empty($this->metadata['media_type'])) {
+            $this->metadata['media_type'] = $this->scopeConfig->getValue(
+                'design/head/default_media_type',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->metadata['media_type'];
+    }
+
+    /**
+     * @param string $charset
+     * @return void
+     */
+    public function setCharset($charset)
+    {
+        $this->setMetadata('charset', $charset);
+    }
+
+    /**
+     * Retrieve Charset
+     *
+     * @return string
+     */
+    public function getCharset()
+    {
+        if (empty($this->metadata['charset'])) {
+            $this->metadata['charset'] = $this->scopeConfig->getValue(
+                'design/head/default_charset',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->metadata['charset'];
+    }
+
+    /**
+     * @param string $description
+     * @return void
+     */
+    public function setDescription($description)
+    {
+        $this->setMetadata('description', $description);
+    }
+
+    /**
+     * Retrieve content for description tag
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (empty($this->metadata['description'])) {
+            $this->metadata['description'] = $this->scopeConfig->getValue(
+                'design/head/default_description',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->metadata['description'];
+    }
+
+    /**
+     * @param string $keywords
+     * @return void
+     */
+    public function setKeywords($keywords)
+    {
+        $this->setMetadata('keywords', $keywords);
+    }
+
+    /**
+     * Retrieve content for keywords tag
+     *
+     * @return string
+     */
+    public function getKeywords()
+    {
+        if (empty($this->metadata['keywords'])) {
+            $this->metadata['keywords'] = $this->scopeConfig->getValue(
+                'design/head/default_keywords',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->metadata['keywords'];
+    }
+
+    /**
+     * @param string $robots
+     * @return void
+     */
+    public function setRobots($robots)
+    {
+        $this->setMetadata('robots', $robots);
+    }
+
+    /**
+     * Retrieve URL to robots file
+     *
+     * @return string
+     */
+    public function getRobots()
+    {
+        if (empty($this->metadata['robots'])) {
+            $this->metadata['robots'] = $this->scopeConfig->getValue(
+                'design/search_engine_robots/default_robots',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->metadata['robots'];
+    }
+
+    /**
+     * @return \Magento\Framework\View\Asset\GroupedCollection
      */
     public function getAssetCollection()
     {
-        return $this->assetCollection;
+        return $this->pageAssets;
+    }
+
+    /**
+     * @param string $file
+     * @param array $properties
+     * @param string|null $name
+     * @return $this
+     */
+    public function addPageAsset($file, array $properties = [], $name = null)
+    {
+        $asset = $this->assetRepo->createAsset($file);
+        $name = $name ?: $file;
+        $this->pageAssets->add($name, $asset, $properties);
+
+        return $this;
+    }
+
+    /**
+     * @param string $url
+     * @param string $contentType
+     * @param array $properties
+     * @param string|null $name
+     * @return $this
+     */
+    public function addRemotePageAsset($url, $contentType, array $properties = [], $name = null)
+    {
+        $remoteAsset = $this->assetRepo->createRemoteAsset($url, $contentType);
+        $name = $name ?: $url;
+        $this->pageAssets->add($name, $remoteAsset, $properties);
+
+        return $this;
+    }
+
+    /**
+     * Add RSS element
+     *
+     * @param string $title
+     * @param string $href
+     * @return $this
+     */
+    public function addRss($title, $href)
+    {
+        $remoteAsset = $this->assetRepo->createRemoteAsset((string)$href, 'unknown');
+        $this->pageAssets->add(
+            "link/{$href}",
+            $remoteAsset,
+            array('attributes' => 'rel="alternate" type="application/rss+xml" title="' . $title . '"')
+        );
+
+        return $this;
     }
 
     /**
@@ -123,8 +453,15 @@ class Config
     public function addBodyClass($className)
     {
         $className = preg_replace('#[^a-z0-9]+#', '-', strtolower($className));
-        $bodyClasses = $this->getElementAttribute(self::ELEMENT_TYPE_BODY, 'classes');
-        $this->setElementAttribute(self::ELEMENT_TYPE_BODY, 'classes', $bodyClasses . ' ' . $className);
+        $bodyClasses = $this->getElementAttribute(self::ELEMENT_TYPE_BODY, self::BODY_ATTRIBUTE_CLASS);
+        $bodyClasses = $bodyClasses ? explode(' ', $bodyClasses) : [];
+        $bodyClasses[] = $className;
+        $bodyClasses = array_unique($bodyClasses);
+        $this->setElementAttribute(
+            self::ELEMENT_TYPE_BODY,
+            self::BODY_ATTRIBUTE_CLASS,
+            implode(' ', $bodyClasses)
+        );
         return $this;
     }
 
@@ -158,6 +495,15 @@ class Config
         return isset($this->elements[$elementType][$attribute]) ? $this->elements[$elementType][$attribute] : null;
     }
 
+    /**
+     * @param string $elementType
+     * @return string[]
+     */
+    public function getElementAttributes($elementType)
+    {
+        return isset($this->elements[$elementType]) ? $this->elements[$elementType] : [];
+    }
+
     /**
      * Set page layout
      *
@@ -180,4 +526,36 @@ class Config
     {
         return $this->pageLayout;
     }
+
+    /**
+     * @return string
+     */
+    public function getFaviconFile()
+    {
+        return $this->favicon->getFaviconFile();
+    }
+
+    /**
+     * @return string
+     */
+    public function getDefaultFavicon()
+    {
+        return $this->favicon->getDefaultFavicon();
+    }
+
+    /**
+     * Get miscellaneous scripts/styles to be included in head before head closing tag
+     *
+     * @return string
+     */
+    public function getIncludes()
+    {
+        if (empty($this->includes)) {
+            $this->includes = $this->scopeConfig->getValue(
+                'design/head/includes',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            );
+        }
+        return $this->includes;
+    }
 }
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Generator.php b/lib/internal/Magento/Framework/View/Page/Config/Generator.php
new file mode 100644
index 00000000000..033ce3a5730
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Page/Config/Generator.php
@@ -0,0 +1,190 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\Framework\View\Page\Config;
+
+/**
+ * Page config generator model
+ */
+class Generator
+{
+    /**#@+
+     * Available src_type in assets
+     */
+    const SRC_TYPE_RESOURCE = 'resource';
+
+    const SRC_TYPE_CONTROLLER = 'controller';
+
+    const SRC_TYPE_URL = 'url';
+    /**#@-*/
+
+    /**
+     * Virtual content type
+     */
+    const VIRTUAL_CONTENT_TYPE_LINK = 'link';
+
+    /**
+     * @var \Magento\Framework\View\Page\Config\Structure
+     */
+    protected $structure;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
+    /**
+     * @var array
+     */
+    protected $remoteAssetTypes = [
+        self::SRC_TYPE_CONTROLLER => self::SRC_TYPE_CONTROLLER,
+        self::SRC_TYPE_URL => self::SRC_TYPE_URL
+    ];
+
+    /**
+     * @var array
+     */
+    protected $assetProperties = [
+        'ie_condition',
+    ];
+
+    /**
+     * @var array
+     */
+    protected $serviceAssetProperties = [
+        'src',
+        'src_type'
+    ];
+
+    /**
+     * @param \Magento\Framework\View\Page\Config\Structure $structure
+     * @param \Magento\Framework\View\Page\Config $pageConfig
+     */
+    public function __construct(Structure $structure, Config $pageConfig)
+    {
+        $this->structure = $structure;
+        $this->pageConfig = $pageConfig;
+    }
+
+    /**
+     * @return $this
+     */
+    public function process()
+    {
+        $this->structure->processRemoveAssets();
+        $this->processAssets();
+        $this->processTitle();
+        $this->processMetadata();
+        $this->structure->processRemoveElementAttributes();
+        $this->processElementAttributes();
+        $this->processBodyClasses();
+        return $this;
+    }
+
+    /**
+     * Add assets to page config
+     *
+     * @return $this
+     */
+    protected function processAssets()
+    {
+        foreach ($this->structure->getAssets() as $name => $data) {
+            if (isset($data['src_type']) && in_array($data['src_type'], $this->remoteAssetTypes)) {
+                $this->pageConfig->addRemotePageAsset(
+                    $name,
+                    self::VIRTUAL_CONTENT_TYPE_LINK,
+                    $this->getAssetProperties($data)
+                );
+            } else {
+                $this->pageConfig->addPageAsset($name, $this->getAssetProperties($data));
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @param array $data
+     * @return array
+     */
+    protected function getAssetProperties(array $data = [])
+    {
+        $properties = [];
+        $attributes = [];
+        foreach ($data as $name => $value) {
+            if (in_array($name, $this->assetProperties)) {
+                $properties[$name] = $value;
+            } elseif (!in_array($name, $this->serviceAssetProperties)) {
+                $attributes[$name] = $value;
+            }
+        }
+        $properties['attributes'] = $attributes;
+        return $properties;
+    }
+
+    /**
+     * @return $this
+     */
+    protected function processTitle()
+    {
+        $this->pageConfig->setTitle($this->structure->getTitle());
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    protected function processMetadata()
+    {
+        foreach ($this->structure->getMetadata() as $name => $content) {
+            $this->pageConfig->setMetadata($name, $content);
+        }
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    protected function processElementAttributes()
+    {
+        foreach ($this->structure->getElementAttributes() as $element => $attributes) {
+            foreach ($attributes as $name => $value) {
+                $this->pageConfig->setElementAttribute($element, $name, $value);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    protected function processBodyClasses()
+    {
+        foreach ($this->structure->getBodyClasses() as $class) {
+            $this->pageConfig->addBodyClass($class);
+        }
+        return $this;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Reader.php b/lib/internal/Magento/Framework/View/Page/Config/Reader.php
new file mode 100644
index 00000000000..d1957b40967
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Page/Config/Reader.php
@@ -0,0 +1,181 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\Framework\View\Page\Config as PageConfig;
+
+class Reader
+{
+    /**#@+
+     * Supported head elements
+     */
+    const HEAD_CSS = 'css';
+
+    const HEAD_SCRIPT = 'script';
+
+    const HEAD_LINK = 'link';
+
+    const HEAD_REMOVE = 'remove';
+
+    const HEAD_TITLE = 'title';
+
+    const HEAD_META = 'meta';
+    /**#@-*/
+
+    /**
+     * Attribute element
+     */
+    const ATTRIBUTE = 'attribute';
+
+    /**
+     * @var Structure
+     */
+    protected $structure;
+
+    /**
+     * @param \Magento\Framework\View\Page\Config\Structure $structure
+     */
+    public function __construct(Structure $structure)
+    {
+        $this->structure = $structure;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Layout\Element $htmlElement
+     * @return $this
+     */
+    public function readHtml($htmlElement)
+    {
+        /** @var \Magento\Framework\View\Layout\Element $element */
+        foreach ($htmlElement as $element) {
+            switch ($element->getName()) {
+                case self::ATTRIBUTE:
+                    $this->structure->setElementAttribute(
+                        PageConfig::ELEMENT_TYPE_HTML,
+                        $element->getAttribute('name'),
+                        $element->getAttribute('value')
+                    );
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Layout\Element $bodyElement
+     * @return $this
+     */
+    public function readBody($bodyElement)
+    {
+        /** @var \Magento\Framework\View\Layout\Element $element */
+        foreach ($bodyElement as $element) {
+            switch ($element->getName()) {
+                case self::ATTRIBUTE:
+                    $this->setBodyAttributeTosStructure($element);
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Layout\Element $element
+     * @return $this
+     */
+    protected function setBodyAttributeTosStructure($element)
+    {
+        if ($element->getAttribute('name') == PageConfig::BODY_ATTRIBUTE_CLASS) {
+            $this->structure->setBodyClass($element->getAttribute('value'));
+        } else {
+            $this->structure->setElementAttribute(
+                PageConfig::ELEMENT_TYPE_BODY,
+                $element->getAttribute('name'),
+                $element->getAttribute('value')
+            );
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Layout\Element $headElement
+     * @return $this
+     */
+    public function readHead($headElement)
+    {
+        /** @var \Magento\Framework\View\Layout\Element $element */
+        foreach ($headElement as $element) {
+            switch ($element->getName()) {
+                case self::HEAD_CSS:
+                case self::HEAD_SCRIPT:
+                case self::HEAD_LINK:
+                    $this->structure->addAssets($element->getAttribute('src'), $this->getAttributes($element));
+                    break;
+
+                case self::HEAD_REMOVE:
+                    $this->structure->removeAssets($element->getAttribute('src'));
+                    break;
+
+                case self::HEAD_TITLE:
+                    $this->structure->setTitle($element);
+                    break;
+
+                case self::HEAD_META:
+                    $this->structure->setMetaData($element->getAttribute('name'), $element->getAttribute('content'));
+                    break;
+
+                case self::ATTRIBUTE:
+                    $this->structure->setElementAttribute(
+                        PageConfig::ELEMENT_TYPE_HEAD,
+                        $element->getAttribute('name'),
+                        $element->getAttribute('value')
+                    );
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Layout\Element $element
+     * @return array
+     */
+    protected function getAttributes($element)
+    {
+        $attributes = [];
+        foreach ($element->attributes() as $attrName => $attrValue) {
+            $attributes[$attrName] = (string)$attrValue;
+        }
+        return $attributes;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
new file mode 100644
index 00000000000..6998113ea81
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
@@ -0,0 +1,377 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\Framework\View\Page\Config;
+use Magento\Framework\View\Asset\GroupedCollection;
+
+/**
+ * Page config Renderer model
+ */
+class Renderer
+{
+    /**
+     * @var \Magento\Framework\View\Page\Config
+     */
+    protected $pageConfig;
+
+    /**
+     * @var \Magento\Framework\View\Asset\MinifyService
+     */
+    protected $assetMinifyService;
+
+    /**
+     * @var \Magento\Framework\View\Asset\MergeService
+     */
+    protected $assetMergeService;
+
+    /**
+     * @var \Magento\Framework\Escaper
+     */
+    protected $escaper;
+
+    /**
+     * @var \Magento\Framework\Stdlib\String
+     */
+    protected $string;
+
+    /**
+     * @var \Magento\Framework\Logger
+     */
+    protected $logger;
+
+    /**
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * @var \Magento\Framework\App\Action\Title
+     */
+    protected $titles;
+
+    /**
+     * @param \Magento\Framework\View\Page\Config $pageConfig
+     * @param \Magento\Framework\View\Asset\MinifyService $assetMinifyService
+     * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\Escaper $escaper
+     * @param \Magento\Framework\Stdlib\String $string
+     * @param \Magento\Framework\Logger $logger
+     * @param \Magento\Framework\App\Action\Title $titles
+     */
+    public function __construct(
+        Config $pageConfig,
+        \Magento\Framework\View\Asset\MinifyService $assetMinifyService,
+        \Magento\Framework\View\Asset\MergeService $assetMergeService,
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\Escaper $escaper,
+        \Magento\Framework\Stdlib\String $string,
+        \Magento\Framework\Logger $logger,
+        \Magento\Framework\App\Action\Title $titles
+    ) {
+        $this->pageConfig = $pageConfig;
+        $this->assetMinifyService = $assetMinifyService;
+        $this->assetMergeService = $assetMergeService;
+        $this->urlBuilder = $urlBuilder;
+        $this->escaper = $escaper;
+        $this->string = $string;
+        $this->logger = $logger;
+        $this->titles = $titles;
+    }
+
+    /**
+     * @param string $elementType
+     * @return string
+     */
+    public function renderElementAttributes($elementType)
+    {
+        $resultAttributes = [];
+        foreach ($this->pageConfig->getElementAttributes($elementType) as $name => $value) {
+            $resultAttributes[] = sprintf('%s="%s"', $name, $value);
+        }
+        return implode(' ', $resultAttributes);
+    }
+
+    /**
+     * @return string
+     */
+    public function renderHeadContent()
+    {
+        $result = '';
+        $result .= $this->renderMetadata();
+        $result .= $this->renderTitle();
+        $this->prepareFavicon();
+        $result .= $this->renderAssets();
+        $result .= $this->pageConfig->getIncludes();
+        return $result;
+    }
+
+    /**
+     * @return string
+     */
+    public function renderTitle()
+    {
+        $title = $this->pageConfig->getTitle();
+        $this->titles->add($title, true);
+        $this->pageConfig->setTitle(array_reverse($this->titles->get()));
+        return '<title>' . $this->pageConfig->getTitle() . '</title>' . "\n";
+    }
+
+    /**
+     * @return string
+     */
+    public function renderMetadata()
+    {
+        $result = '';
+        foreach ($this->pageConfig->getMetadata() as $name => $content) {
+            $metadataTemplate = $this->getMetadataTemplate($name);
+            if (!$metadataTemplate) {
+                continue;
+            }
+            $content = $this->processMetadataContent($name, $content);
+            if ($content) {
+                $result .= str_replace(['%name', '%content'], [$name, $content], $metadataTemplate);
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * @param string $name
+     * @param string $content
+     * @return mixed
+     */
+    protected function processMetadataContent($name, $content)
+    {
+        $method = 'get' . $this->string->upperCaseWords($name, '_', '');
+        if (method_exists($this->pageConfig, $method)) {
+            $content = $this->pageConfig->$method();
+        }
+        return $content;
+    }
+
+    /**
+     * @param string $name
+     * @return bool|string
+     */
+    protected function getMetadataTemplate($name)
+    {
+        switch($name) {
+            case 'charset':
+                $metadataTemplate = '<meta charset="%content"/>' . "\n";
+                break;
+
+            case 'content_type':
+                $metadataTemplate = '<meta http-equiv="Content-Type" content="%content"/>' . "\n";
+                break;
+
+            case 'x_ua_compatible':
+                $metadataTemplate = '<meta http-equiv="X-UA-Compatible" content="%content"/>' . "\n";
+                break;
+
+            case 'media_type':
+                $metadataTemplate = false;
+                break;
+
+            default:
+                $metadataTemplate = '<meta name="%name" content="%content"/>' . "\n";
+                break;
+        }
+        return $metadataTemplate;
+    }
+
+    /**
+     * @return void
+     */
+    public function prepareFavicon()
+    {
+        if ($this->pageConfig->getFaviconFile()) {
+            $this->pageConfig->addRemotePageAsset(
+                $this->pageConfig->getFaviconFile(),
+                Generator::VIRTUAL_CONTENT_TYPE_LINK,
+                ['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
+                'icon'
+            );
+            $this->pageConfig->addRemotePageAsset(
+                $this->pageConfig->getFaviconFile(),
+                Generator::VIRTUAL_CONTENT_TYPE_LINK,
+                ['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
+                'shortcut-icon'
+            );
+        } else {
+            $this->pageConfig->addPageAsset(
+                $this->pageConfig->getDefaultFavicon(),
+                ['attributes' => ['rel' => 'icon', 'type' => 'image/x-icon']],
+                'icon'
+            );
+            $this->pageConfig->addPageAsset(
+                $this->pageConfig->getDefaultFavicon(),
+                ['attributes' => ['rel' => 'shortcut icon', 'type' => 'image/x-icon']],
+                'shortcut-icon'
+            );
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function renderAssets()
+    {
+        $result = '';
+        /** @var $group \Magento\Framework\View\Asset\PropertyGroup */
+        foreach ($this->pageConfig->getAssetCollection()->getGroups() as $group) {
+            $groupAssets = $this->assetMinifyService->getAssets($group->getAll());
+            $groupAssets = $this->processMerge($groupAssets, $group);
+
+            $attributes = $this->getGroupAttributes($group);
+            $attributes = $this->addDefaultAttributes(
+                $group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE),
+                $attributes
+            );
+
+            $groupTemplate = $this->getAssetTemplate(
+                $group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE),
+                $attributes
+            );
+            $groupHtml = $this->renderAssetHtml($groupTemplate, $groupAssets);
+            $groupHtml = $this->processIeCondition($groupHtml, $group);
+            $result .= $groupHtml;
+        }
+        return $result;
+    }
+
+    /**
+     * @param array $groupAssets
+     * @param \Magento\Framework\View\Asset\PropertyGroup $group
+     * @return array
+     */
+    protected function processMerge($groupAssets, $group)
+    {
+        if ($group->getProperty(GroupedCollection::PROPERTY_CAN_MERGE) && count($groupAssets) > 1) {
+            $groupAssets = $this->assetMergeService->getMergedAssets(
+                $groupAssets,
+                $group->getProperty(GroupedCollection::PROPERTY_CONTENT_TYPE)
+            );
+        }
+        return $groupAssets;
+    }
+
+    /**
+     * @param \Magento\Framework\View\Asset\PropertyGroup $group
+     * @return string|null
+     */
+    protected function getGroupAttributes($group)
+    {
+        $attributes = $group->getProperty('attributes');
+        if (!empty($attributes)) {
+            if (is_array($attributes)) {
+                $attributesString = '';
+                foreach ($attributes as $name => $value) {
+                    $attributesString .= ' ' . $name . '="' . $this->escaper->escapeHtml($value) . '"';
+                }
+                $attributes = $attributesString;
+            } else {
+                $attributes = ' ' . $attributes;
+            }
+        }
+        return $attributes;
+    }
+
+    /**
+     * @param string $contentType
+     * @param string $attributes
+     * @return string
+     */
+    protected function addDefaultAttributes($contentType, $attributes)
+    {
+        switch ($contentType) {
+            case 'js':
+                $attributes = ' type="text/javascript" ' . $attributes;
+                break;
+
+            case 'css':
+                $attributes = ' rel="stylesheet" type="text/css" ' . ($attributes ?: ' media="all"');
+                break;
+        }
+        return $attributes;
+    }
+
+    /**
+     * @param string $contentType
+     * @param string|null $attributes
+     * @return string
+     */
+    protected function getAssetTemplate($contentType, $attributes)
+    {
+        switch ($contentType) {
+            case 'js':
+                $groupTemplate = '<script ' . $attributes . ' src="%s"></script>' . "\n";
+                break;
+
+            case 'css':
+            default:
+                $groupTemplate = '<link ' . $attributes . ' href="%s" />' . "\n";
+                break;
+        }
+        return $groupTemplate;
+    }
+
+    /**
+     * @param string $groupHtml
+     * @param \Magento\Framework\View\Asset\PropertyGroup $group
+     * @return string
+     */
+    protected function processIeCondition($groupHtml, $group)
+    {
+        $ieCondition = $group->getProperty('ie_condition');
+        if (!empty($ieCondition)) {
+            $groupHtml = '<!--[if ' . $ieCondition . ']>' . "\n" . $groupHtml . '<![endif]-->' . "\n";
+        }
+        return $groupHtml;
+    }
+
+    /**
+     * Render HTML tags referencing corresponding URLs
+     *
+     * @param string $template
+     * @param array $assets
+     * @return string
+     */
+    protected function renderAssetHtml($template, $assets)
+    {
+        $result = '';
+        try {
+            /** @var $asset \Magento\Framework\View\Asset\AssetInterface */
+            foreach ($assets as $asset) {
+                $result .= sprintf($template, $asset->getUrl());
+            }
+        } catch (\Magento\Framework\Exception $e) {
+            $this->logger->logException($e);
+            $result .= sprintf($template, $this->urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']));
+        }
+        return $result;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Structure.php b/lib/internal/Magento/Framework/View/Page/Config/Structure.php
new file mode 100644
index 00000000000..eaae439098c
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Page/Config/Structure.php
@@ -0,0 +1,216 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\View\Page\Config;
+
+use Magento\Framework\View\Page\Config as PageConfig;
+
+/**
+ * Page config structure model
+ */
+class Structure
+{
+    /**
+     * Information assets elements on page
+     *
+     * @var array
+     */
+    protected $assets = [];
+
+    /**
+     * List asset which will be removed
+     *
+     * @var array
+     */
+    protected $removeAssets = [];
+
+    /**
+     * @var string
+     */
+    protected $title;
+
+    /**
+     * @var string[]
+     */
+    protected $metadata = [];
+
+    /**
+     * @var array
+     */
+    protected $elementAttributes = [];
+
+    /**
+     * @var array
+     */
+    protected $removeElementAttributes = [];
+
+    /**
+     * @var array
+     */
+    protected $bodyClasses = [];
+
+    /**
+     * @var bool
+     */
+    protected $isBodyClassesDeleted = false;
+
+    /**
+     * @param string $element
+     * @param string $attributeName
+     * @param string $attributeValue
+     * @return $this
+     */
+    public function setElementAttribute($element, $attributeName, $attributeValue)
+    {
+        if (empty($attributeValue)) {
+            $this->removeElementAttributes[$element][] = $attributeName;
+        } else {
+            $this->elementAttributes[$element][$attributeName] = (string)$attributeValue;
+        }
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    public function processRemoveElementAttributes()
+    {
+        foreach ($this->removeElementAttributes as $element => $attributes) {
+            foreach ($attributes as $attributeName) {
+                unset($this->elementAttributes[$element][$attributeName]);
+            }
+            if (empty($this->elementAttributes[$element])) {
+                unset($this->elementAttributes[$element]);
+            }
+        }
+        $this->removeElementAttributes = [];
+        return $this;
+    }
+
+    /**
+     * @param string $value
+     * @return $this
+     */
+    public function setBodyClass($value)
+    {
+        if (empty($value)) {
+            $this->isBodyClassesDeleted = true;
+        } else {
+            $this->bodyClasses[] = $value;
+        }
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getBodyClasses()
+    {
+        return $this->isBodyClassesDeleted ? [] : $this->bodyClasses;
+    }
+
+    /**
+     * @return array
+     */
+    public function getElementAttributes()
+    {
+        return $this->elementAttributes;
+    }
+
+    /**
+     * @param string $title
+     * @return $this
+     */
+    public function setTitle($title)
+    {
+        $this->title = (string)$title;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * @param string $name
+     * @param string $content
+     * @return $this
+     */
+    public function setMetadata($name, $content)
+    {
+        $this->metadata[$name] = (string)$content;
+        return $this;
+    }
+
+    /**
+     * @return string[]
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * @param string $name
+     * @param array $attributes
+     * @return $this
+     */
+    public function addAssets($name, $attributes)
+    {
+        $this->assets[$name] = $attributes;
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     * @return $this
+     */
+    public function removeAssets($name)
+    {
+        $this->removeAssets[$name] = $name;
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    public function processRemoveAssets()
+    {
+        $this->assets = array_diff_key($this->assets, $this->removeAssets);
+        $this->removeAssets = [];
+        return $this;
+    }
+
+    /**
+     * @return array
+     */
+    public function getAssets()
+    {
+        return $this->assets;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Page/FaviconInterface.php b/lib/internal/Magento/Framework/View/Page/FaviconInterface.php
new file mode 100644
index 00000000000..e5255900159
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Page/FaviconInterface.php
@@ -0,0 +1,40 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Page;
+
+/**
+ * Favicon interface
+ */
+interface FaviconInterface
+{
+    /**
+     * @return string
+     */
+    public function getFaviconFile();
+
+    /**
+     * @return string
+     */
+    public function getDefaultFavicon();
+}
diff --git a/lib/internal/Magento/Framework/View/PageLayout/Config.php b/lib/internal/Magento/Framework/View/PageLayout/Config.php
index 08c17422faa..dfbf54de848 100644
--- a/lib/internal/Magento/Framework/View/PageLayout/Config.php
+++ b/lib/internal/Magento/Framework/View/PageLayout/Config.php
@@ -76,6 +76,7 @@ class Config extends \Magento\Framework\Config\AbstractXml
      */
     public function toOptionArray($withEmpty = false)
     {
+        $options = [];
         foreach ($this->getPageLayouts() as $value => $label) {
             $options[] = array('label' => $label, 'value' => $value);
         }
diff --git a/lib/internal/Magento/Framework/View/Result/Layout.php b/lib/internal/Magento/Framework/View/Result/Layout.php
index df7451f13d4..6c0585ab837 100644
--- a/lib/internal/Magento/Framework/View/Result/Layout.php
+++ b/lib/internal/Magento/Framework/View/Result/Layout.php
@@ -97,9 +97,7 @@ class Layout extends View\Element\Template
      */
     public function renderResult(ResponseInterface $response)
     {
-        $layout = $this->getLayout();
-        $output = $layout->getOutput();
-        $response->appendBody($output);
+        $response->appendBody($this->_layout->getOutput());
         return $this;
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Result/Page.php b/lib/internal/Magento/Framework/View/Result/Page.php
index 00d5365d3a3..77f6fb8ac5f 100644
--- a/lib/internal/Magento/Framework/View/Result/Page.php
+++ b/lib/internal/Magento/Framework/View/Result/Page.php
@@ -36,19 +36,12 @@ use Magento\Framework\App\ResponseInterface;
  * and a guaranteed handle that stands for page layout (a wireframe of a page)
  *
  * Page result is a more specific implementation of a generic layout response
+ *
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Page extends Layout
 {
-    /**
-     * Default template
-     */
-    const DEFAULT_ROOT_TEMPLATE = 'Magento_Theme::root.phtml';
-
-    /**
-     * @var string
-     */
-    protected $pageType;
-
     /**
      * @var string
      */
@@ -59,27 +52,32 @@ class Page extends Layout
      */
     protected $pageConfig;
 
+    /**
+     * @var \Magento\Framework\View\Page\Config\Renderer
+     */
+    protected $pageConfigRenderer;
+
     /**
      * Constructor
      *
      * @param View\Element\Template\Context $context
      * @param View\LayoutFactory $layoutFactory
      * @param \Magento\Framework\Translate\InlineInterface $translateInline
-     * @param View\Page\Config $pageConfig
-     * @param string $pageType
+     * @param \Magento\Framework\View\Page\Config\Renderer $pageConfigRenderer
+     * @param string $template
      * @param array $data
      */
     public function __construct(
         View\Element\Template\Context $context,
         View\LayoutFactory $layoutFactory,
         \Magento\Framework\Translate\InlineInterface $translateInline,
-        View\Page\Config $pageConfig,
-        $pageType,
+        View\Page\Config\Renderer $pageConfigRenderer,
+        $template,
         array $data = array()
     ) {
-        $this->pageConfig = $pageConfig;
-        $this->pageType = $pageType;
         parent::__construct($context, $layoutFactory, $translateInline, $data);
+        $this->pageConfigRenderer = $pageConfigRenderer;
+        $this->_template = $template;
     }
 
     /**
@@ -93,7 +91,6 @@ class Page extends Layout
         if ($update->isLayoutDefined()) {
             $update->removeHandle('default');
         }
-        $this->setTemplate(self::DEFAULT_ROOT_TEMPLATE);
         return $this;
     }
 
@@ -120,7 +117,7 @@ class Page extends Layout
             $pageHandles[] = $handle . '_' . $key . '_' . $value;
         }
         // Do not sort array going into add page handles. Ensure default layout handle is added first.
-        return $this->getLayout()->getUpdate()->addPageHandles($pageHandles);
+        return $this->getLayout()->getUpdate()->addHandle($pageHandles);
     }
 
     /**
@@ -140,16 +137,18 @@ class Page extends Layout
     public function renderResult(ResponseInterface $response)
     {
         if ($this->getConfig()->getPageLayout()) {
-            $layout = $this->getLayout();
             $config = $this->getConfig();
 
-            $this->assign('headContent', $layout->getBlock('head')->toHtml());
             $this->addDefaultBodyClasses();
-            $this->assign('bodyClasses', $config->getElementAttribute($config::ELEMENT_TYPE_BODY, 'classes'));
-            $this->assign('bodyAttributes', $config->getElementAttribute($config::ELEMENT_TYPE_BODY, 'attributes'));
-            $this->assign('htmlAttributes', $config->getElementAttribute($config::ELEMENT_TYPE_HTML, 'attributes'));
+            $this->assign([
+                'requireJs' => $this->_layout->getBlock('require.js')->toHtml(),
+                'headContent' => $this->pageConfigRenderer->renderHeadContent(),
+                'htmlAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HTML),
+                'headAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_HEAD),
+                'bodyAttributes' => $this->pageConfigRenderer->renderElementAttributes($config::ELEMENT_TYPE_BODY)
+            ]);
 
-            $output = $layout->getOutput();
+            $output = $this->_layout->getOutput();
             $this->translateInline->processResponseBody($output);
             $this->assign('layoutContent', $output);
             $response->appendBody($this->toHtml());
@@ -166,11 +165,10 @@ class Page extends Layout
      */
     protected function addDefaultBodyClasses()
     {
-        $config = $this->getConfig();
-        $config->addBodyClass($this->_request->getFullActionName('-'));
+        $this->pageConfig->addBodyClass($this->_request->getFullActionName('-'));
         $pageLayout = $this->pageConfig->getPageLayout();
         if ($pageLayout) {
-            $config->addBodyClass('page-layout-' . $pageLayout);
+            $this->pageConfig->addBodyClass('page-layout-' . $pageLayout);
         }
         return $this;
     }
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index fed8d58717c..4d1fc04ca6b 100644
--- a/lib/internal/Magento/Framework/composer.json
+++ b/lib/internal/Magento/Framework/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/framework",
     "description": "N/A",
     "type": "magento2-library",
-    "version": "0.1.0-alpha96",
+    "version": "0.1.0-alpha97",
     "require": {
         "php": "~5.4.11|~5.5.0",
         "ext-spl": "*",
diff --git a/lib/web/app-config.js b/lib/web/app-config.js
index d97b793ecad..b623f8082c1 100644
--- a/lib/web/app-config.js
+++ b/lib/web/app-config.js
@@ -23,8 +23,6 @@
 require.config({
     "waitSeconds":"0",
     "shim": {
-        "jquery/bootstrap-carousel/jquery.bootstrap-carousel": ["jquery"], // no longer used
-        "jquery/bootstrap-carousel/jquery.bootstrap-transition": ["jquery"], // no longer used
         "jquery/jquery.hashchange": ["jquery"],
         "jquery/jquery.mousewheel": ["jquery"],
         "jquery/jquery.popups": ["jquery"],
@@ -38,7 +36,9 @@ require.config({
         "mage/common": ["jquery"],
         "mage/jquery-no-conflict": ["jquery"],
         "mage/requirejs/plugin/id-normalizer": ["jquery"],
-        "mage/webapi": ["jquery"]
+        "mage/webapi": ["jquery"],
+        "ko": { exports: 'ko' },
+        "moment": { exports: 'moment' }
     },
     "paths":{
         "baseImage": 'Magento_Catalog/catalog/base-image-uploader',
@@ -50,7 +50,8 @@ require.config({
         "handlebars": "jquery/handlebars/handlebars-v1.3.0",
         "jquery/jquery.hashchange": "jquery/jquery.ba-hashchange.min",
         "prototype": "prototype/prototype-amd",
-        "_": "underscore"
+        "text": "requirejs/text",
+        "ko": "ko/ko"
     },
     "deps": [
         "bootstrap"
diff --git a/lib/web/css/source/lib/variables.less b/lib/web/css/source/lib/variables.less
index 5165ba7560f..5df5fa888b9 100644
--- a/lib/web/css/source/lib/variables.less
+++ b/lib/web/css/source/lib/variables.less
@@ -53,10 +53,10 @@
 @font-rem-ratio: unit(@font-size-root * 16/100);
 //base font size value in <b>px</b>:
 @font-size-base: unit((@font-size-root / 100) * 16 * @font-size-base-ratio, px); // Also used in: @loader-text-font-size
-@font-size-xl: ceil(1.5 * @font-size-base);
-@font-size-l: ceil(1.25 * @font-size-base);
-@font-size-s: ceil(0.85 * @font-size-base);  // Also used in: Breadcrumbs and in Small button
-@font-size-xs: floor(0.75 * @font-size-base);
+@font-size-xl: ceil(1.5 * @font-size-base);  // 21
+@font-size-l: ceil(1.25 * @font-size-base);  // 18
+@font-size-s: ceil(0.85 * @font-size-base);  // 12 Also used in: Breadcrumbs and in Small button
+@font-size-xs: floor(0.75 * @font-size-base);  // 11
 
 @font-weight-base: 400;
 @font-weight-light: 300;
@@ -281,7 +281,7 @@
 @layout-width: ''; // for the fixed width layout
 @layout-max-width: 1280px;
 @layout-indent: 20px;
-@layout-width-xs-indent: 10px;
+@layout-width-xs-indent: 15px;
 
 // Classnames defining different layouts
 @layout-class-1column: page-layout-1column;
diff --git a/lib/web/date-format-normalizer.js b/lib/web/date-format-normalizer.js
new file mode 100644
index 00000000000..d996f746cfb
--- /dev/null
+++ b/lib/web/date-format-normalizer.js
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([],function(){
+    'use strict';
+
+    var formatCache = {};
+
+    function Formatter() {
+
+        /**
+         * Convert from string-Magento-date-format
+         * to string-moment-js-date-format. Result
+         * stored in internal cache.
+         * @param {String} zendFormat
+         * @return {String}
+         */
+        return function(zendFormat) {
+            var momentFormat = '';
+
+            if(formatCache[zendFormat]) {
+                momentFormat = formatCache[zendFormat];
+            } else {
+                // List of differences. Got from 'MMM d, y h:mm:ss a' -> "MMM D, YYYY h:mm:ss A"
+                momentFormat = String(zendFormat).
+                    replace('D','DDD').
+                    replace('dd','DD').
+                    replace('d','D').
+                    replace('EEEE','dddd').
+                    replace('EEE','ddd').
+                    replace('e','d').
+                    replace('y','YYYY').
+                    replace('a','A').
+                    toString();
+                formatCache[zendFormat] = momentFormat;
+            }
+
+            return momentFormat;
+        }
+    }
+
+    return new Formatter;
+});
\ No newline at end of file
diff --git a/lib/web/jquery/autocomplete/autocomplete.css b/lib/web/jquery/autocomplete/autocomplete.css
new file mode 100644
index 00000000000..4000a35a15c
--- /dev/null
+++ b/lib/web/jquery/autocomplete/autocomplete.css
@@ -0,0 +1,5 @@
+.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; -webkit-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); -moz-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); }
+.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
+.autocomplete-no-suggestion { padding: 2px 5px;}
+.autocomplete-selected { background: #F0F0F0; }
+.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
\ No newline at end of file
diff --git a/lib/web/jquery/autocomplete/jquery.autocomplete.js b/lib/web/jquery/autocomplete/jquery.autocomplete.js
new file mode 100644
index 00000000000..07fa5ca1020
--- /dev/null
+++ b/lib/web/jquery/autocomplete/jquery.autocomplete.js
@@ -0,0 +1,915 @@
+/**
+*  Ajax Autocomplete for jQuery, version 1.2.11
+*  (c) 2014 Tomas Kirda
+*
+*  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
+*  For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
+*
+*/
+
+/*jslint  browser: true, white: true, plusplus: true */
+/*global define, window, document, jQuery, exports */
+
+// Expose plugin as an AMD module if AMD loader is present:
+(function (factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define(['jquery'], factory);
+    } else if (typeof exports === 'object' && typeof require === 'function') {
+        // Browserify
+        factory(require('jquery'));
+    } else {
+        // Browser globals
+        factory(jQuery);
+    }
+}(function ($) {
+    'use strict';
+
+    var
+        utils = (function () {
+            return {
+                escapeRegExChars: function (value) {
+                    return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+                },
+                createNode: function (containerClass) {
+                    var div = document.createElement('div');
+                    div.className = containerClass;
+                    div.style.position = 'absolute';
+                    div.style.display = 'none';
+                    return div;
+                }
+            };
+        }()),
+
+        keys = {
+            ESC: 27,
+            TAB: 9,
+            RETURN: 13,
+            LEFT: 37,
+            UP: 38,
+            RIGHT: 39,
+            DOWN: 40
+        };
+
+    function Autocomplete(el, options) {
+        var noop = function () { },
+            that = this,
+            defaults = {
+                ajaxSettings: {},
+                autoSelectFirst: false,
+                appendTo: document.body,
+                serviceUrl: null,
+                lookup: null,
+                onSelect: null,
+                width: 'auto',
+                minChars: 1,
+                maxHeight: 300,
+                deferRequestBy: 0,
+                params: {},
+                formatResult: Autocomplete.formatResult,
+                delimiter: null,
+                zIndex: 9999,
+                type: 'GET',
+                noCache: false,
+                onSearchStart: noop,
+                onSearchComplete: noop,
+                onSearchError: noop,
+                containerClass: 'autocomplete-suggestions',
+                tabDisabled: false,
+                dataType: 'text',
+                currentRequest: null,
+                triggerSelectOnValidInput: true,
+                preventBadQueries: true,
+                lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
+                    return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
+                },
+                paramName: 'query',
+                transformResult: function (response) {
+                    return typeof response === 'string' ? $.parseJSON(response) : response;
+                },
+                showNoSuggestionNotice: false,
+                noSuggestionNotice: 'No results',
+                orientation: 'bottom',
+                forceFixPosition: false
+            };
+
+        // Shared variables:
+        that.element = el;
+        that.el = $(el);
+        that.suggestions = [];
+        that.badQueries = [];
+        that.selectedIndex = -1;
+        that.currentValue = that.element.value;
+        that.intervalId = 0;
+        that.cachedResponse = {};
+        that.onChangeInterval = null;
+        that.onChange = null;
+        that.isLocal = false;
+        that.suggestionsContainer = null;
+        that.noSuggestionsContainer = null;
+        that.options = $.extend({}, defaults, options);
+        that.classes = {
+            selected: 'autocomplete-selected',
+            suggestion: 'autocomplete-suggestion'
+        };
+        that.hint = null;
+        that.hintValue = '';
+        that.selection = null;
+
+        // Initialize and set options:
+        that.initialize();
+        that.setOptions(options);
+    }
+
+    Autocomplete.utils = utils;
+
+    $.Autocomplete = Autocomplete;
+
+    Autocomplete.formatResult = function (suggestion, currentValue) {
+        var pattern = '(' + utils.escapeRegExChars(currentValue) + ')';
+
+        return suggestion.value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
+    };
+
+    Autocomplete.prototype = {
+
+        killerFn: null,
+
+        initialize: function () {
+            var that = this,
+                suggestionSelector = '.' + that.classes.suggestion,
+                selected = that.classes.selected,
+                options = that.options,
+                container;
+
+            // Remove autocomplete attribute to prevent native suggestions:
+            that.element.setAttribute('autocomplete', 'off');
+
+            that.killerFn = function (e) {
+                if ($(e.target).closest('.' + that.options.containerClass).length === 0) {
+                    that.killSuggestions();
+                    that.disableKillerFn();
+                }
+            };
+
+            // html() deals with many types: htmlString or Element or Array or jQuery
+            that.noSuggestionsContainer = $('<div class="autocomplete-no-suggestion"></div>')
+                                          .html(this.options.noSuggestionNotice).get(0);
+
+            that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
+
+            container = $(that.suggestionsContainer);
+
+            container.appendTo(options.appendTo);
+
+            // Only set width if it was provided:
+            if (options.width !== 'auto') {
+                container.width(options.width);
+            }
+
+            // Listen for mouse over event on suggestions list:
+            container.on('mouseover.autocomplete', suggestionSelector, function () {
+                that.activate($(this).data('index'));
+            });
+
+            // Deselect active element when mouse leaves suggestions container:
+            container.on('mouseout.autocomplete', function () {
+                that.selectedIndex = -1;
+                container.children('.' + selected).removeClass(selected);
+            });
+
+            // Listen for click event on suggestions list:
+            container.on('click.autocomplete', suggestionSelector, function () {
+                that.select($(this).data('index'));
+            });
+
+            that.fixPositionCapture = function () {
+                if (that.visible) {
+                    that.fixPosition();
+                }
+            };
+
+            $(window).on('resize.autocomplete', that.fixPositionCapture);
+
+            that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); });
+            that.el.on('keyup.autocomplete', function (e) { that.onKeyUp(e); });
+            that.el.on('blur.autocomplete', function () { that.onBlur(); });
+            that.el.on('focus.autocomplete', function () { that.onFocus(); });
+            that.el.on('change.autocomplete', function (e) { that.onKeyUp(e); });
+        },
+
+        onFocus: function () {
+            var that = this;
+            that.fixPosition();
+            if (that.options.minChars <= that.el.val().length) {
+                that.onValueChange();
+            }
+        },
+
+        onBlur: function () {
+            this.enableKillerFn();
+        },
+
+        setOptions: function (suppliedOptions) {
+            var that = this,
+                options = that.options;
+
+            $.extend(options, suppliedOptions);
+
+            that.isLocal = $.isArray(options.lookup);
+
+            if (that.isLocal) {
+                options.lookup = that.verifySuggestionsFormat(options.lookup);
+            }
+
+            options.orientation = that.validateOrientation(options.orientation, 'bottom');
+
+            // Adjust height, width and z-index:
+            $(that.suggestionsContainer).css({
+                'max-height': options.maxHeight + 'px',
+                'width': options.width + 'px',
+                'z-index': options.zIndex
+            });
+        },
+
+
+        clearCache: function () {
+            this.cachedResponse = {};
+            this.badQueries = [];
+        },
+
+        clear: function () {
+            this.clearCache();
+            this.currentValue = '';
+            this.suggestions = [];
+        },
+
+        disable: function () {
+            var that = this;
+            that.disabled = true;
+            if (that.currentRequest) {
+                that.currentRequest.abort();
+            }
+        },
+
+        enable: function () {
+            this.disabled = false;
+        },
+
+        fixPosition: function () {
+            // Use only when container has already its content
+
+            var that = this,
+                $container = $(that.suggestionsContainer),
+                containerParent = $container.parent().get(0);
+            // Fix position automatically when appended to body.
+            // In other cases force parameter must be given.
+            if (containerParent !== document.body && !that.options.forceFixPosition)
+                return;
+
+            // Choose orientation
+            var orientation = that.options.orientation,
+                containerHeight = $container.outerHeight(),
+                height = that.el.outerHeight(),
+                offset = that.el.offset(),
+                styles = { 'top': offset.top, 'left': offset.left };
+
+            if (orientation == 'auto') {
+                var viewPortHeight = $(window).height(),
+                    scrollTop = $(window).scrollTop(),
+                    topOverflow = -scrollTop + offset.top - containerHeight,
+                    bottomOverflow = scrollTop + viewPortHeight - (offset.top + height + containerHeight);
+
+                orientation = (Math.max(topOverflow, bottomOverflow) === topOverflow)
+                                ? 'top'
+                                : 'bottom';
+            }
+
+            if (orientation === 'top') {
+                styles.top += -containerHeight;
+            } else {
+                styles.top += height;
+            }
+
+            // If container is not positioned to body,
+            // correct its position using offset parent offset
+            if(containerParent !== document.body) {
+                var opacity = $container.css('opacity'),
+                    parentOffsetDiff;
+
+                    if (!that.visible){
+                        $container.css('opacity', 0).show();
+                    }
+
+                parentOffsetDiff = $container.offsetParent().offset();
+                styles.top -= parentOffsetDiff.top;
+                styles.left -= parentOffsetDiff.left;
+
+                if (!that.visible){
+                    $container.css('opacity', opacity).hide();
+                }
+            }
+
+            // -2px to account for suggestions border.
+            if (that.options.width === 'auto') {
+                styles.width = (that.el.outerWidth() - 2) + 'px';
+            }
+
+            $container.css(styles);
+        },
+
+        enableKillerFn: function () {
+            var that = this;
+            $(document).on('click.autocomplete', that.killerFn);
+        },
+
+        disableKillerFn: function () {
+            var that = this;
+            $(document).off('click.autocomplete', that.killerFn);
+        },
+
+        killSuggestions: function () {
+            var that = this;
+            that.stopKillSuggestions();
+            that.intervalId = window.setInterval(function () {
+                that.hide();
+                that.stopKillSuggestions();
+            }, 50);
+        },
+
+        stopKillSuggestions: function () {
+            window.clearInterval(this.intervalId);
+        },
+
+        isCursorAtEnd: function () {
+            var that = this,
+                valLength = that.el.val().length,
+                selectionStart = that.element.selectionStart,
+                range;
+
+            if (typeof selectionStart === 'number') {
+                return selectionStart === valLength;
+            }
+            if (document.selection) {
+                range = document.selection.createRange();
+                range.moveStart('character', -valLength);
+                return valLength === range.text.length;
+            }
+            return true;
+        },
+
+        onKeyPress: function (e) {
+            var that = this;
+
+            // If suggestions are hidden and user presses arrow down, display suggestions:
+            if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) {
+                that.suggest();
+                return;
+            }
+
+            if (that.disabled || !that.visible) {
+                return;
+            }
+
+            switch (e.which) {
+                case keys.ESC:
+                    that.el.val(that.currentValue);
+                    that.hide();
+                    break;
+                case keys.RIGHT:
+                    if (that.hint && that.options.onHint && that.isCursorAtEnd()) {
+                        that.selectHint();
+                        break;
+                    }
+                    return;
+                case keys.TAB:
+                    if (that.hint && that.options.onHint) {
+                        that.selectHint();
+                        return;
+                    }
+                    // Fall through to RETURN
+                case keys.RETURN:
+                    if (that.selectedIndex === -1) {
+                        that.hide();
+                        return;
+                    }
+                    that.select(that.selectedIndex);
+                    if (e.which === keys.TAB && that.options.tabDisabled === false) {
+                        return;
+                    }
+                    break;
+                case keys.UP:
+                    that.moveUp();
+                    break;
+                case keys.DOWN:
+                    that.moveDown();
+                    break;
+                default:
+                    return;
+            }
+
+            // Cancel event if function did not return:
+            e.stopImmediatePropagation();
+            e.preventDefault();
+        },
+
+        onKeyUp: function (e) {
+            var that = this;
+
+            if (that.disabled) {
+                return;
+            }
+
+            switch (e.which) {
+                case keys.UP:
+                case keys.DOWN:
+                    return;
+            }
+
+            clearInterval(that.onChangeInterval);
+
+            if (that.currentValue !== that.el.val()) {
+                that.findBestHint();
+                if (that.options.deferRequestBy > 0) {
+                    // Defer lookup in case when value changes very quickly:
+                    that.onChangeInterval = setInterval(function () {
+                        that.onValueChange();
+                    }, that.options.deferRequestBy);
+                } else {
+                    that.onValueChange();
+                }
+            }
+        },
+
+        onValueChange: function () {
+            var that = this,
+                options = that.options,
+                value = that.el.val(),
+                query = that.getQuery(value),
+                index;
+
+            if (that.selection && that.currentValue !== query) {
+                that.selection = null;
+                (options.onInvalidateSelection || $.noop).call(that.element);
+            }
+
+            clearInterval(that.onChangeInterval);
+            that.currentValue = value;
+            that.selectedIndex = -1;
+
+            // Check existing suggestion for the match before proceeding:
+            if (options.triggerSelectOnValidInput) {
+                index = that.findSuggestionIndex(query);
+                if (index !== -1) {
+                    that.select(index);
+                    return;
+                }
+            }
+
+            if (query.length < options.minChars) {
+                that.hide();
+            } else {
+                that.getSuggestions(query);
+            }
+        },
+
+        findSuggestionIndex: function (query) {
+            var that = this,
+                index = -1,
+                queryLowerCase = query.toLowerCase();
+
+            $.each(that.suggestions, function (i, suggestion) {
+                if (suggestion.value.toLowerCase() === queryLowerCase) {
+                    index = i;
+                    return false;
+                }
+            });
+
+            return index;
+        },
+
+        getQuery: function (value) {
+            var delimiter = this.options.delimiter,
+                parts;
+
+            if (!delimiter) {
+                return value;
+            }
+            parts = value.split(delimiter);
+            return $.trim(parts[parts.length - 1]);
+        },
+
+        getSuggestionsLocal: function (query) {
+            var that = this,
+                options = that.options,
+                queryLowerCase = query.toLowerCase(),
+                filter = options.lookupFilter,
+                limit = parseInt(options.lookupLimit, 10),
+                data;
+
+            data = {
+                suggestions: $.grep(options.lookup, function (suggestion) {
+                    return filter(suggestion, query, queryLowerCase);
+                })
+            };
+
+            if (limit && data.suggestions.length > limit) {
+                data.suggestions = data.suggestions.slice(0, limit);
+            }
+
+            return data;
+        },
+
+        getSuggestions: function (q) {
+            var response,
+                that = this,
+                options = that.options,
+                serviceUrl = options.serviceUrl,
+                params,
+                cacheKey,
+                ajaxSettings;
+
+            options.params[options.paramName] = q;
+            params = options.ignoreParams ? null : options.params;
+
+            if (that.isLocal) {
+                response = that.getSuggestionsLocal(q);
+            } else {
+                if ($.isFunction(serviceUrl)) {
+                    serviceUrl = serviceUrl.call(that.element, q);
+                }
+                cacheKey = serviceUrl + '?' + $.param(params || {});
+                response = that.cachedResponse[cacheKey];
+            }
+
+            if (response && $.isArray(response.suggestions)) {
+                that.suggestions = response.suggestions;
+                that.suggest();
+            } else if (!that.isBadQuery(q)) {
+                if (options.onSearchStart.call(that.element, options.params) === false) {
+                    return;
+                }
+                if (that.currentRequest) {
+                    that.currentRequest.abort();
+                }
+
+                ajaxSettings = {
+                    url: serviceUrl,
+                    data: params,
+                    type: options.type,
+                    dataType: options.dataType
+                };
+
+                $.extend(ajaxSettings, options.ajaxSettings);
+
+                that.currentRequest = $.ajax(ajaxSettings).done(function (data) {
+                    var result;
+                    that.currentRequest = null;
+                    result = options.transformResult(data);
+                    that.processResponse(result, q, cacheKey);
+                    options.onSearchComplete.call(that.element, q, result.suggestions);
+                }).fail(function (jqXHR, textStatus, errorThrown) {
+                    options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
+                });
+            }
+        },
+
+        isBadQuery: function (q) {
+            if (!this.options.preventBadQueries){
+                return false;
+            }
+
+            var badQueries = this.badQueries,
+                i = badQueries.length;
+
+            while (i--) {
+                if (q.indexOf(badQueries[i]) === 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        },
+
+        hide: function () {
+            var that = this;
+            that.visible = false;
+            that.selectedIndex = -1;
+            $(that.suggestionsContainer).hide();
+            that.signalHint(null);
+        },
+
+        show: function () {
+            this.visible = true;
+            $(this.suggestionsContainer).show();
+        },
+
+        toggle: function () {
+            this.visible ? this.hide() : this.show();
+        },
+
+        suggest: function () {
+            if (this.suggestions.length === 0) {
+                this.options.showNoSuggestionNotice ? this.noSuggestions() : this.hide();               
+                return;
+            }
+
+            var that = this,
+                options = that.options,
+                formatResult = options.formatResult,
+                value = that.getQuery(that.currentValue),
+                className = that.classes.suggestion,
+                classSelected = that.classes.selected,
+                container = $(that.suggestionsContainer),
+                noSuggestionsContainer = $(that.noSuggestionsContainer),
+                beforeRender = options.beforeRender,
+                html = '',
+                index;
+
+            if (options.triggerSelectOnValidInput) {
+                index = that.findSuggestionIndex(value);
+                if (index !== -1) {
+                    that.select(index);
+                    return;
+                }
+            }
+
+            // Build suggestions inner HTML:
+            $.each(that.suggestions, function (i, suggestion) {
+                html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
+            });
+
+            this.adjustContainerWidth();      
+
+            noSuggestionsContainer.detach();
+            container.html(html);
+
+            // Select first value by default:
+            if (options.autoSelectFirst) {
+                that.selectedIndex = 0;
+                container.children().first().addClass(classSelected);
+            }
+
+            if ($.isFunction(beforeRender)) {
+                beforeRender.call(that.element, container);
+            }
+
+            that.fixPosition();
+
+            container.show();
+            that.visible = true;
+
+            that.findBestHint();
+        },
+
+        noSuggestions: function() {
+             var that = this,
+                 container = $(that.suggestionsContainer),
+                 noSuggestionsContainer = $(that.noSuggestionsContainer);
+
+            this.adjustContainerWidth();
+
+            // Some explicit steps. Be careful here as it easy to get
+            // noSuggestionsContainer removed from DOM if not detached properly.
+            noSuggestionsContainer.detach();
+            container.empty(); // clean suggestions if any
+            container.append(noSuggestionsContainer);
+
+            that.fixPosition();
+
+            container.show();
+            that.visible = true;
+        },
+
+        adjustContainerWidth: function() {
+            var that = this,
+                options = that.options,
+                width,
+                container = $(that.suggestionsContainer);
+
+            // If width is auto, adjust width before displaying suggestions,
+            // because if instance was created before input had width, it will be zero.
+            // Also it adjusts if input width has changed.
+            // -2px to account for suggestions border.
+            if (options.width === 'auto') {
+                width = that.el.outerWidth() - 2;
+                container.width(width > 0 ? width : 300);
+            }
+        },
+
+        findBestHint: function () {
+            var that = this,
+                value = that.el.val().toLowerCase(),
+                bestMatch = null;
+
+            if (!value) {
+                return;
+            }
+
+            $.each(that.suggestions, function (i, suggestion) {
+                var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0;
+                if (foundMatch) {
+                    bestMatch = suggestion;
+                }
+                return !foundMatch;
+            });
+
+            that.signalHint(bestMatch);
+        },
+
+        signalHint: function (suggestion) {
+            var hintValue = '',
+                that = this;
+            if (suggestion) {
+                hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length);
+            }
+            if (that.hintValue !== hintValue) {
+                that.hintValue = hintValue;
+                that.hint = suggestion;
+                (this.options.onHint || $.noop)(hintValue);
+            }
+        },
+
+        verifySuggestionsFormat: function (suggestions) {
+            // If suggestions is string array, convert them to supported format:
+            if (suggestions.length && typeof suggestions[0] === 'string') {
+                return $.map(suggestions, function (value) {
+                    return { value: value, data: null };
+                });
+            }
+
+            return suggestions;
+        },
+
+        validateOrientation: function(orientation, fallback) {
+            orientation = $.trim(orientation || '').toLowerCase();
+
+            if($.inArray(orientation, ['auto', 'bottom', 'top']) === -1){
+                orientation = fallback;
+            }
+
+            return orientation;
+        },
+
+        processResponse: function (result, originalQuery, cacheKey) {
+            var that = this,
+                options = that.options;
+
+            result.suggestions = that.verifySuggestionsFormat(result.suggestions);
+
+            // Cache results if cache is not disabled:
+            if (!options.noCache) {
+                that.cachedResponse[cacheKey] = result;
+                if (options.preventBadQueries && result.suggestions.length === 0) {
+                    that.badQueries.push(originalQuery);
+                }
+            }
+
+            // Return if originalQuery is not matching current query:
+            if (originalQuery !== that.getQuery(that.currentValue)) {
+                return;
+            }
+
+            that.suggestions = result.suggestions;
+            that.suggest();
+        },
+
+        activate: function (index) {
+            var that = this,
+                activeItem,
+                selected = that.classes.selected,
+                container = $(that.suggestionsContainer),
+                children = container.children();
+
+            container.children('.' + selected).removeClass(selected);
+
+            that.selectedIndex = index;
+
+            if (that.selectedIndex !== -1 && children.length > that.selectedIndex) {
+                activeItem = children.get(that.selectedIndex);
+                $(activeItem).addClass(selected);
+                return activeItem;
+            }
+
+            return null;
+        },
+
+        selectHint: function () {
+            var that = this,
+                i = $.inArray(that.hint, that.suggestions);
+
+            that.select(i);
+        },
+
+        select: function (i) {
+            var that = this;
+            that.hide();
+            that.onSelect(i);
+        },
+
+        moveUp: function () {
+            var that = this;
+
+            if (that.selectedIndex === -1) {
+                return;
+            }
+
+            if (that.selectedIndex === 0) {
+                $(that.suggestionsContainer).children().first().removeClass(that.classes.selected);
+                that.selectedIndex = -1;
+                that.el.val(that.currentValue);
+                that.findBestHint();
+                return;
+            }
+
+            that.adjustScroll(that.selectedIndex - 1);
+        },
+
+        moveDown: function () {
+            var that = this;
+
+            if (that.selectedIndex === (that.suggestions.length - 1)) {
+                return;
+            }
+
+            that.adjustScroll(that.selectedIndex + 1);
+        },
+
+        adjustScroll: function (index) {
+            var that = this,
+                activeItem = that.activate(index),
+                offsetTop,
+                upperBound,
+                lowerBound,
+                heightDelta = 25;
+
+            if (!activeItem) {
+                return;
+            }
+
+            offsetTop = activeItem.offsetTop;
+            upperBound = $(that.suggestionsContainer).scrollTop();
+            lowerBound = upperBound + that.options.maxHeight - heightDelta;
+
+            if (offsetTop < upperBound) {
+                $(that.suggestionsContainer).scrollTop(offsetTop);
+            } else if (offsetTop > lowerBound) {
+                $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta);
+            }
+
+            that.el.val(that.getValue(that.suggestions[index].value));
+            that.signalHint(null);
+        },
+
+        onSelect: function (index) {
+            var that = this,
+                onSelectCallback = that.options.onSelect,
+                suggestion = that.suggestions[index];
+
+            that.currentValue = that.getValue(suggestion.value);
+
+            if (that.currentValue !== that.el.val()) {
+                that.el.val(that.currentValue);
+            }
+
+            that.signalHint(null);
+            that.suggestions = [];
+            that.selection = suggestion;
+
+            if ($.isFunction(onSelectCallback)) {
+                onSelectCallback.call(that.element, suggestion);
+            }
+        },
+
+        getValue: function (value) {
+            var that = this,
+                delimiter = that.options.delimiter,
+                currentValue,
+                parts;
+
+            if (!delimiter) {
+                return value;
+            }
+
+            currentValue = that.currentValue;
+            parts = currentValue.split(delimiter);
+
+            if (parts.length === 1) {
+                return value;
+            }
+
+            return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value;
+        },
+
+        dispose: function () {
+            var that = this;
+            that.el.off('.autocomplete').removeData('autocomplete');
+            that.disableKillerFn();
+            $(window).off('resize.autocomplete', that.fixPositionCapture);
+            $(that.suggestionsContainer).remove();
+        }
+    };
+
+    return Autocomplete;
+}));
\ No newline at end of file
diff --git a/lib/web/jquery/bootstrap-carousel/css/bootstrap-carousel.css b/lib/web/jquery/bootstrap-carousel/css/bootstrap-carousel.css
deleted file mode 100644
index 11b16c625c7..00000000000
--- a/lib/web/jquery/bootstrap-carousel/css/bootstrap-carousel.css
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Carousel styles START */
-
-.carousel {
-    position: relative;
-}
-
-.carousel-items {
-    position: relative;
-    width: 100%;
-    overflow: hidden;
-}
-
-.carousel-items > .carousel-item {
-    position: relative;
-    display: none;
-    -webkit-transition: .9s linear left;
-    -moz-transition: .9s linear left;
-    -o-transition: .9s linear left;
-    transition: .9s linear left;
-}
-
-
-.carousel-items > .active,
-.carousel-items > .next,
-.carousel-items > .prev {
-    display: block;
-}
-
-.carousel-items > .active {
-    left: 0;
-}
-
-.carousel-items > .next,
-.carousel-items > .prev {
-    position: absolute;
-    top: 0;
-    width: 100%;
-}
-
-.carousel-items > .next {
-    left: 100%;
-}
-
-.carousel-items > .prev {
-    left: -100%;
-}
-
-.carousel-items > .next.left,
-.carousel-items > .prev.right {
-    left: 0;
-}
-
-.carousel-items > .active.left {
-    left: -100%;
-}
-
-.carousel-items > .active.right {
-    left: 100%;
-}
-
-.carousel-previous,
-.carousel-next {
-    position: absolute;
-    top: -35px;
-    width: 24px;
-    height: 32px;
-    text-align: center;
-    text-decoration: none;
-    overflow: hidden;
-    font-size: 0;
-}
-
-.carousel-previous:before,
-.carousel-next:before {
-    font-size: 32px;
-    line-height: 1;
-    font-family: "MUI-Icons";
-    font-style: normal;
-    speak: none;
-    font-weight: normal;
-    -webkit-font-smoothing: antialiased;
-    color: #8E8E8E;
-}
-
-.carousel-previous:hover:before,
-.carousel-previous:active:before,
-.carousel-next:hover:before,
-.carousel-next:active:before{
-    color: #D26C1E;
-}
-
-.carousel-previous {
-    right: 25px;
-}
-
-.carousel-previous:before {
-    content: "\e037";
-}
-
-.carousel-next {
-    right: 1px;
-    background-position: -28px 0;
-}
-
-.carousel-next:before {
-    content: "\e036";
-}
-
-@media screen and (min-width:1400px) {
-    .carousel-previous,
-    .carousel-next {
-        width: 48px;
-        height: 64px;
-        top: 50%;
-        margin-top: -64px;
-    }
-    .carousel-previous {
-        left: -64px;
-        right: auto;
-    }
-    .carousel-next {
-        right: -48px;
-    }
-    .carousel-previous:before,
-    .carousel-next:before {
-        font-size: 64px;
-    }
-}
-
-.carousel-pager {
-    text-align: center;
-    margin: 0;
-    padding: 0;
-    list-style: none;
-}
-
-.carousel-pager li {
-    text-indent: -9999px;
-    display: inline-block;
-    width: 10px;
-    height: 10px;
-    border: 2px solid #8e8e8e;
-    cursor: pointer;
-    margin: 0 5px;
-    border-radius: 15px;
-}
-
-.carousel-pager .active {
-    background: #f37b20;
-    border-color: #d26c1e;
-}
\ No newline at end of file
diff --git a/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-carousel.js b/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-carousel.js
deleted file mode 100644
index a2b61c57537..00000000000
--- a/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-carousel.js
+++ /dev/null
@@ -1,290 +0,0 @@
-/* ==========================================================
- * bootstrap-carousel.js v2.2.2
- * http: //twitter.github.com/bootstrap/javascript.html#carousel
- * ==========================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http: //www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
-    "use strict"; // jshint ;_;
-
-
-    /* CAROUSEL CLASS DEFINITION
-     * ========================= */
-
-    var Carousel = function (element, options) {
-        this.$element = $(element);
-        this.options = options;
-//    this.options.pause == 'hover' && this.$element
-//      .on('mouseenter', $.proxy(this.pause, this))
-//      .on('mouseleave', $.proxy(this.cycle, this))
-    };
-
-    Carousel.prototype = {
-        init: function () {
-            var carousel = this.$element,
-                options = this.options,
-                href = '#' + carousel.context.id,
-                itemClass = options.itemClass,
-                arrowLeft = $('<a/>', {
-                    'class': options.carouselLeftArrowClass,
-                    href: href,
-                    title: options.carouselLeftArrowTitle,
-                    text: options.carouselLeftArrowText,
-                    attr: {'data-slide': 'prev'}
-                }),
-                arrowRight = $('<a/>', {
-                    'class': options.carouselRightArrowClass,
-                    href: href,
-                    title: options.carouselRightArrowTitle,
-                    text: options.carouselRightArrowText,
-                    attr: {'data-slide': 'next'}
-                }),
-                innerWrapper = $('<div/>', {
-                    'class': options.carouselWrapperClass
-                }),
-                carouselSize = carousel.find('.' + itemClass).length,
-                paginator = $('<ul/>', {
-                    'class': options.paginatorClass
-                });
-
-            for (var i = 0; i < carouselSize; i++) {
-                paginator.append($('<li/>', {
-                    text: (i + 1),
-                    title: (i + 1)
-                }));
-            }
-
-            paginator
-                .find('li:first')
-                .addClass(options.activeClass);
-
-            carousel
-                .find('.' + itemClass)
-                .addClass(options.itemClassDefault)
-                .wrapAll(innerWrapper);
-
-            carousel
-                .addClass(options.carouselClass)
-                .find('.' + itemClass + ':first')
-                .addClass(options.activeClass)
-                .end()
-                .append(arrowLeft, paginator, arrowRight);
-
-            return this;
-        }, cycle: function (e) {
-            if (!e) this.paused = false;
-            this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval));
-
-            return this;
-        }, to: function (pos) {
-            var itemClass = this.options.itemClass,
-                $active = this.$element.find('.' + itemClass + '.' + this.options.activeClass),
-                children = $active.parent().children(),
-                activePos = children.index($active),
-                that = this;
-
-            if (pos > (children.length - 1) || pos < 0) return;
-
-            if (this.sliding) {
-                return this.$element.one('slid', function () {
-                    that.to(pos);
-                })
-            }
-
-            if (activePos == pos) {
-                return this.pause().cycle();
-            }
-
-            return this.slide(pos > activePos ? 'next' :  'prev', $(children[pos]));
-        }, pause: function (e) {
-            if (!e) this.paused = true;
-            if (this.$element.find('.next, .prev').length && $.support.transition.end) {
-                this.$element.trigger($.support.transition.end);
-                this.cycle();
-            }
-            clearInterval(this.interval);
-            this.interval = null;
-            return this;
-        }, next: function () {
-            if (this.sliding) return;
-            return this.slide('next');
-        }, prev: function () {
-            if (this.sliding) return;
-            return this.slide('prev');
-        }, slide: function (type, next) {
-            var itemClass = this.options.itemClass,
-                activeClass = this.options.activeClass,
-                $active = this.$element.find('.' + itemClass + '.' + activeClass),
-                $next = next || $active[type](),
-                $paginator = this.$element.find('.' + this.options.paginatorClass),
-                isCycling = this.interval,
-                direction = type == 'next' ? 'left' : 'right',
-                fallback = type == 'next' ? 'first' : 'last',
-                that = this, e;
-
-            this.sliding = true;
-
-            isCycling && this.pause();
-
-            $next = $next.length ? $next :  this.$element.find('.' + itemClass)[fallback]();
-
-            e = $.Event('slide', {
-                relatedTarget: $next[0]
-            });
-
-            if ($next.hasClass(activeClass)) return;
-
-            this.$element.trigger(e);
-            if (e.isDefaultPrevented()) return;
-
-            if ($.support.transition && this.options.effectSlide) {
-                $next.addClass(type);
-                $next[0].offsetWidth; // force reflow
-                $active.addClass(direction);
-                $next.addClass(direction);
-                this.$element.one($.support.transition.end, function () {
-                    $next.removeClass([type, direction].join(' ')).addClass(activeClass);
-                    $active.removeClass([activeClass, direction].join(' '));
-                    that.sliding = false;
-                    setTimeout(function () {
-                        that.$element.trigger('slid');
-                    }, 0);
-                })
-            } else if (!$.support.transition && this.options.effectSlide) {
-                $active.animate({left: (direction == 'right' ? '100%' :  '-100%')}, 600, function () {
-                    $active.removeClass(activeClass);
-                    that.sliding = false;
-                    setTimeout(function () {
-                        that.$element.trigger('slid');
-                    }, 0)
-                });
-                $next.addClass(type).css({left: (direction == 'right' ? '-100%' :  '100%')}).animate({left: '0'}, 600, function () {
-                    $next.removeClass(type).addClass(activeClass);
-                })
-            } else {
-                $active.removeClass(activeClass);
-                $next.addClass(activeClass);
-
-                this.sliding = false;
-                this.$element.trigger('slid');
-            }
-
-            $paginator
-                .find('li')
-                .eq($next.index())
-                .addClass(activeClass)
-                .siblings()
-                .removeClass(activeClass);
-
-            isCycling && this.cycle();
-
-            return this
-        }
-
-    };
-
-
-    /* CAROUSEL PLUGIN DEFINITION
-     * ========================== */
-
-    var old = $.fn.carousel;
-
-    $.fn.carousel = function (option) {
-        return this.each(function () {
-            var $this = $(this),
-                data = $this.data('carousel'),
-                options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option),
-                action = typeof option == 'string' ? option :  options.slide;
-
-            if (!data) {
-                $this.data('carousel', (data = new Carousel(this, options).init()));
-            }
-            if (typeof option == 'number') {
-                data.to(option);
-            } else if (action) {
-                data[action]();
-            } else if (options.interval) {
-                data.cycle();
-            }
-
-            $this.keydown(function (e) {
-                if (e.keyCode == 37) {
-                    data.prev();
-                }
-                if (e.keyCode == 39) {
-                    data.next();
-                }
-            });
-            $this.find('.' + options.paginatorClass + ' li')
-                .on('click.SlideTo', function () {
-                    var elem = $(this),
-                        slideTo = elem.index();
-
-                    elem
-                        .addClass(options.activeClass)
-                        .siblings()
-                        .removeClass(options.activeClass);
-
-                    $this.carousel(slideTo);
-                })
-
-        })
-    };
-
-    $.fn.carousel.defaults = {
-        interval: 5000,
-        pause: 'hover',
-        itemClass: 'item',
-        itemClassDefault: 'carousel-item',
-        activeClass: 'active',
-        carouselClass: 'carousel',
-        paginatorClass: 'carousel-pager',
-        carouselWrapperClass: 'carousel-items',
-        carouselLeftArrowClass: 'carousel-previous',
-        carouselRightArrowClass: 'carousel-next',
-        carouselLeftArrowTitle: 'Previous',
-        carouselRightArrowTitle: 'Next',
-        carouselLeftArrowText: 'Previous',
-        carouselRightArrowText: 'Next',
-        effectSlide: true
-    };
-
-    $.fn.carousel.Constructor = Carousel;
-
-
-    /* CAROUSEL NO CONFLICT
-     * ==================== */
-
-    $.fn.carousel.noConflict = function () {
-        $.fn.carousel = old;
-        return this;
-    };
-
-    /* CAROUSEL DATA-API
-     * ================= */
-
-    $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
-        var $this = $(this),
-            href,
-            $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')),
-            options = $.extend({}, $target.data(), $this.data());
-
-        $target.carousel(options);
-        e.preventDefault();
-    })
-}(window.jQuery);
\ No newline at end of file
diff --git a/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-transition.js b/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-transition.js
deleted file mode 100644
index b0f12c26d32..00000000000
--- a/lib/web/jquery/bootstrap-carousel/jquery.bootstrap-transition.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ===================================================
- * bootstrap-transition.js v2.2.2
- * http://twitter.github.com/bootstrap/javascript.html#transitions
- * ===================================================
- * Copyright 2012 Twitter, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ========================================================== */
-
-
-!function ($) {
-
-  "use strict"; // jshint ;_;
-
-
-  /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
-   * ======================================================= */
-
-  $(function () {
-
-    $.support.transition = (function () {
-
-      var transitionEnd = (function () {
-
-        var el = document.createElement('bootstrap')
-          , transEndEventNames = {
-               'WebkitTransition' : 'webkitTransitionEnd'
-            ,  'MozTransition'    : 'transitionend'
-            ,  'OTransition'      : 'oTransitionEnd otransitionend'
-            ,  'transition'       : 'transitionend'
-            }
-          , name
-
-        for (name in transEndEventNames){
-          if (el.style[name] !== undefined) {
-            return transEndEventNames[name]
-          }
-        }
-
-      }())
-
-      return transitionEnd && {
-        end: transitionEnd
-      }
-
-    })()
-
-  })
-
-}(window.jQuery);
\ No newline at end of file
diff --git a/lib/web/ko/ko.js b/lib/web/ko/ko.js
new file mode 100644
index 00000000000..4ee1701620c
--- /dev/null
+++ b/lib/web/ko/ko.js
@@ -0,0 +1,5299 @@
+/*!
+ * Knockout JavaScript library v3.2.0
+ * (c) Steven Sanderson - http://knockoutjs.com/
+ * License: MIT (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+(function(){
+var DEBUG=true;
+(function(undefined){
+    // (0, eval)('this') is a robust way of getting a reference to the global object
+    // For details, see http://stackoverflow.com/questions/14119988/return-this-0-evalthis/14120023#14120023
+    var window = this || (0, eval)('this'),
+        document = window['document'],
+        navigator = window['navigator'],
+        jQueryInstance = window["jQuery"],
+        JSON = window["JSON"];
+(function(factory) {
+    // Support three module loading scenarios
+    if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
+        // [1] CommonJS/Node.js
+        var target = module['exports'] || exports; // module.exports is for Node.js
+        factory(target, require);
+    } else if (typeof define === 'function' && define['amd']) {
+        // [2] AMD anonymous module
+        define(['exports', 'require'], factory);
+    } else {
+        // [3] No module loader (plain <script> tag) - put directly in global namespace
+        factory(window['ko'] = {});
+    }
+}(function(koExports, require){
+// Internally, all KO objects are attached to koExports (even the non-exported ones whose names will be minified by the closure compiler).
+// In the future, the following "ko" variable may be made distinct from "koExports" so that private objects are not externally reachable.
+var ko = typeof koExports !== 'undefined' ? koExports : {};
+// Google Closure Compiler helpers (used only to make the minified file smaller)
+ko.exportSymbol = function(koPath, object) {
+    var tokens = koPath.split(".");
+
+    // In the future, "ko" may become distinct from "koExports" (so that non-exported objects are not reachable)
+    // At that point, "target" would be set to: (typeof koExports !== "undefined" ? koExports : ko)
+    var target = ko;
+
+    for (var i = 0; i < tokens.length - 1; i++)
+        target = target[tokens[i]];
+    target[tokens[tokens.length - 1]] = object;
+};
+ko.exportProperty = function(owner, publicName, object) {
+    owner[publicName] = object;
+};
+ko.version = "3.2.0";
+
+ko.exportSymbol('version', ko.version);
+ko.utils = (function () {
+    function objectForEach(obj, action) {
+        for (var prop in obj) {
+            if (obj.hasOwnProperty(prop)) {
+                action(prop, obj[prop]);
+            }
+        }
+    }
+
+    function extend(target, source) {
+        if (source) {
+            for(var prop in source) {
+                if(source.hasOwnProperty(prop)) {
+                    target[prop] = source[prop];
+                }
+            }
+        }
+        return target;
+    }
+
+    function setPrototypeOf(obj, proto) {
+        obj.__proto__ = proto;
+        return obj;
+    }
+
+    var canSetPrototype = ({ __proto__: [] } instanceof Array);
+
+    // Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup)
+    var knownEvents = {}, knownEventTypesByEventName = {};
+    var keyEventTypeName = (navigator && /Firefox\/2/i.test(navigator.userAgent)) ? 'KeyboardEvent' : 'UIEvents';
+    knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress'];
+    knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave'];
+    objectForEach(knownEvents, function(eventType, knownEventsForType) {
+        if (knownEventsForType.length) {
+            for (var i = 0, j = knownEventsForType.length; i < j; i++)
+                knownEventTypesByEventName[knownEventsForType[i]] = eventType;
+        }
+    });
+    var eventsThatMustBeRegisteredUsingAttachEvent = { 'propertychange': true }; // Workaround for an IE9 issue - https://github.com/SteveSanderson/knockout/issues/406
+
+    // Detect IE versions for bug workarounds (uses IE conditionals, not UA string, for robustness)
+    // Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10.
+    // Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser.
+    // If there is a future need to detect specific versions of IE10+, we will amend this.
+    var ieVersion = document && (function() {
+        var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i');
+
+        // Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment
+        while (
+            div.innerHTML = '<!--[if gt IE ' + (++version) + ']><i></i><![endif]-->',
+            iElems[0]
+        ) {}
+        return version > 4 ? version : undefined;
+    }());
+    var isIe6 = ieVersion === 6,
+        isIe7 = ieVersion === 7;
+
+    function isClickOnCheckableElement(element, eventType) {
+        if ((ko.utils.tagNameLower(element) !== "input") || !element.type) return false;
+        if (eventType.toLowerCase() != "click") return false;
+        var inputType = element.type;
+        return (inputType == "checkbox") || (inputType == "radio");
+    }
+
+    return {
+        fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/],
+
+        arrayForEach: function (array, action) {
+            for (var i = 0, j = array.length; i < j; i++)
+                action(array[i], i);
+        },
+
+        arrayIndexOf: function (array, item) {
+            if (typeof Array.prototype.indexOf == "function")
+                return Array.prototype.indexOf.call(array, item);
+            for (var i = 0, j = array.length; i < j; i++)
+                if (array[i] === item)
+                    return i;
+            return -1;
+        },
+
+        arrayFirst: function (array, predicate, predicateOwner) {
+            for (var i = 0, j = array.length; i < j; i++)
+                if (predicate.call(predicateOwner, array[i], i))
+                    return array[i];
+            return null;
+        },
+
+        arrayRemoveItem: function (array, itemToRemove) {
+            var index = ko.utils.arrayIndexOf(array, itemToRemove);
+            if (index > 0) {
+                array.splice(index, 1);
+            }
+            else if (index === 0) {
+                array.shift();
+            }
+        },
+
+        arrayGetDistinctValues: function (array) {
+            array = array || [];
+            var result = [];
+            for (var i = 0, j = array.length; i < j; i++) {
+                if (ko.utils.arrayIndexOf(result, array[i]) < 0)
+                    result.push(array[i]);
+            }
+            return result;
+        },
+
+        arrayMap: function (array, mapping) {
+            array = array || [];
+            var result = [];
+            for (var i = 0, j = array.length; i < j; i++)
+                result.push(mapping(array[i], i));
+            return result;
+        },
+
+        arrayFilter: function (array, predicate) {
+            array = array || [];
+            var result = [];
+            for (var i = 0, j = array.length; i < j; i++)
+                if (predicate(array[i], i))
+                    result.push(array[i]);
+            return result;
+        },
+
+        arrayPushAll: function (array, valuesToPush) {
+            if (valuesToPush instanceof Array)
+                array.push.apply(array, valuesToPush);
+            else
+                for (var i = 0, j = valuesToPush.length; i < j; i++)
+                    array.push(valuesToPush[i]);
+            return array;
+        },
+
+        addOrRemoveItem: function(array, value, included) {
+            var existingEntryIndex = ko.utils.arrayIndexOf(ko.utils.peekObservable(array), value);
+            if (existingEntryIndex < 0) {
+                if (included)
+                    array.push(value);
+            } else {
+                if (!included)
+                    array.splice(existingEntryIndex, 1);
+            }
+        },
+
+        canSetPrototype: canSetPrototype,
+
+        extend: extend,
+
+        setPrototypeOf: setPrototypeOf,
+
+        setPrototypeOfOrExtend: canSetPrototype ? setPrototypeOf : extend,
+
+        objectForEach: objectForEach,
+
+        objectMap: function(source, mapping) {
+            if (!source)
+                return source;
+            var target = {};
+            for (var prop in source) {
+                if (source.hasOwnProperty(prop)) {
+                    target[prop] = mapping(source[prop], prop, source);
+                }
+            }
+            return target;
+        },
+
+        emptyDomNode: function (domNode) {
+            while (domNode.firstChild) {
+                ko.removeNode(domNode.firstChild);
+            }
+        },
+
+        moveCleanedNodesToContainerElement: function(nodes) {
+            // Ensure it's a real array, as we're about to reparent the nodes and
+            // we don't want the underlying collection to change while we're doing that.
+            var nodesArray = ko.utils.makeArray(nodes);
+
+            var container = document.createElement('div');
+            for (var i = 0, j = nodesArray.length; i < j; i++) {
+                container.appendChild(ko.cleanNode(nodesArray[i]));
+            }
+            return container;
+        },
+
+        cloneNodes: function (nodesArray, shouldCleanNodes) {
+            for (var i = 0, j = nodesArray.length, newNodesArray = []; i < j; i++) {
+                var clonedNode = nodesArray[i].cloneNode(true);
+                newNodesArray.push(shouldCleanNodes ? ko.cleanNode(clonedNode) : clonedNode);
+            }
+            return newNodesArray;
+        },
+
+        setDomNodeChildren: function (domNode, childNodes) {
+            ko.utils.emptyDomNode(domNode);
+            if (childNodes) {
+                for (var i = 0, j = childNodes.length; i < j; i++)
+                    domNode.appendChild(childNodes[i]);
+            }
+        },
+
+        replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) {
+            var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray;
+            if (nodesToReplaceArray.length > 0) {
+                var insertionPoint = nodesToReplaceArray[0];
+                var parent = insertionPoint.parentNode;
+                for (var i = 0, j = newNodesArray.length; i < j; i++)
+                    parent.insertBefore(newNodesArray[i], insertionPoint);
+                for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) {
+                    ko.removeNode(nodesToReplaceArray[i]);
+                }
+            }
+        },
+
+        fixUpContinuousNodeArray: function(continuousNodeArray, parentNode) {
+            // Before acting on a set of nodes that were previously outputted by a template function, we have to reconcile
+            // them against what is in the DOM right now. It may be that some of the nodes have already been removed, or that
+            // new nodes might have been inserted in the middle, for example by a binding. Also, there may previously have been
+            // leading comment nodes (created by rewritten string-based templates) that have since been removed during binding.
+            // So, this function translates the old "map" output array into its best guess of the set of current DOM nodes.
+            //
+            // Rules:
+            //   [A] Any leading nodes that have been removed should be ignored
+            //       These most likely correspond to memoization nodes that were already removed during binding
+            //       See https://github.com/SteveSanderson/knockout/pull/440
+            //   [B] We want to output a continuous series of nodes. So, ignore any nodes that have already been removed,
+            //       and include any nodes that have been inserted among the previous collection
+
+            if (continuousNodeArray.length) {
+                // The parent node can be a virtual element; so get the real parent node
+                parentNode = (parentNode.nodeType === 8 && parentNode.parentNode) || parentNode;
+
+                // Rule [A]
+                while (continuousNodeArray.length && continuousNodeArray[0].parentNode !== parentNode)
+                    continuousNodeArray.shift();
+
+                // Rule [B]
+                if (continuousNodeArray.length > 1) {
+                    var current = continuousNodeArray[0], last = continuousNodeArray[continuousNodeArray.length - 1];
+                    // Replace with the actual new continuous node set
+                    continuousNodeArray.length = 0;
+                    while (current !== last) {
+                        continuousNodeArray.push(current);
+                        current = current.nextSibling;
+                        if (!current) // Won't happen, except if the developer has manually removed some DOM elements (then we're in an undefined scenario)
+                            return;
+                    }
+                    continuousNodeArray.push(last);
+                }
+            }
+            return continuousNodeArray;
+        },
+
+        setOptionNodeSelectionState: function (optionNode, isSelected) {
+            // IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser.
+            if (ieVersion < 7)
+                optionNode.setAttribute("selected", isSelected);
+            else
+                optionNode.selected = isSelected;
+        },
+
+        stringTrim: function (string) {
+            return string === null || string === undefined ? '' :
+                string.trim ?
+                    string.trim() :
+                    string.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
+        },
+
+        stringStartsWith: function (string, startsWith) {
+            string = string || "";
+            if (startsWith.length > string.length)
+                return false;
+            return string.substring(0, startsWith.length) === startsWith;
+        },
+
+        domNodeIsContainedBy: function (node, containedByNode) {
+            if (node === containedByNode)
+                return true;
+            if (node.nodeType === 11)
+                return false; // Fixes issue #1162 - can't use node.contains for document fragments on IE8
+            if (containedByNode.contains)
+                return containedByNode.contains(node.nodeType === 3 ? node.parentNode : node);
+            if (containedByNode.compareDocumentPosition)
+                return (containedByNode.compareDocumentPosition(node) & 16) == 16;
+            while (node && node != containedByNode) {
+                node = node.parentNode;
+            }
+            return !!node;
+        },
+
+        domNodeIsAttachedToDocument: function (node) {
+            return ko.utils.domNodeIsContainedBy(node, node.ownerDocument.documentElement);
+        },
+
+        anyDomNodeIsAttachedToDocument: function(nodes) {
+            return !!ko.utils.arrayFirst(nodes, ko.utils.domNodeIsAttachedToDocument);
+        },
+
+        tagNameLower: function(element) {
+            // For HTML elements, tagName will always be upper case; for XHTML elements, it'll be lower case.
+            // Possible future optimization: If we know it's an element from an XHTML document (not HTML),
+            // we don't need to do the .toLowerCase() as it will always be lower case anyway.
+            return element && element.tagName && element.tagName.toLowerCase();
+        },
+
+        registerEventHandler: function (element, eventType, handler) {
+            var mustUseAttachEvent = ieVersion && eventsThatMustBeRegisteredUsingAttachEvent[eventType];
+            if (!mustUseAttachEvent && jQueryInstance) {
+                jQueryInstance(element)['bind'](eventType, handler);
+            } else if (!mustUseAttachEvent && typeof element.addEventListener == "function")
+                element.addEventListener(eventType, handler, false);
+            else if (typeof element.attachEvent != "undefined") {
+                var attachEventHandler = function (event) { handler.call(element, event); },
+                    attachEventName = "on" + eventType;
+                element.attachEvent(attachEventName, attachEventHandler);
+
+                // IE does not dispose attachEvent handlers automatically (unlike with addEventListener)
+                // so to avoid leaks, we have to remove them manually. See bug #856
+                ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+                    element.detachEvent(attachEventName, attachEventHandler);
+                });
+            } else
+                throw new Error("Browser doesn't support addEventListener or attachEvent");
+        },
+
+        triggerEvent: function (element, eventType) {
+            if (!(element && element.nodeType))
+                throw new Error("element must be a DOM node when calling triggerEvent");
+
+            // For click events on checkboxes and radio buttons, jQuery toggles the element checked state *after* the
+            // event handler runs instead of *before*. (This was fixed in 1.9 for checkboxes but not for radio buttons.)
+            // IE doesn't change the checked state when you trigger the click event using "fireEvent".
+            // In both cases, we'll use the click method instead.
+            var useClickWorkaround = isClickOnCheckableElement(element, eventType);
+
+            if (jQueryInstance && !useClickWorkaround) {
+                jQueryInstance(element)['trigger'](eventType);
+            } else if (typeof document.createEvent == "function") {
+                if (typeof element.dispatchEvent == "function") {
+                    var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents";
+                    var event = document.createEvent(eventCategory);
+                    event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
+                    element.dispatchEvent(event);
+                }
+                else
+                    throw new Error("The supplied element doesn't support dispatchEvent");
+            } else if (useClickWorkaround && element.click) {
+                element.click();
+            } else if (typeof element.fireEvent != "undefined") {
+                element.fireEvent("on" + eventType);
+            } else {
+                throw new Error("Browser doesn't support triggering events");
+            }
+        },
+
+        unwrapObservable: function (value) {
+            return ko.isObservable(value) ? value() : value;
+        },
+
+        peekObservable: function (value) {
+            return ko.isObservable(value) ? value.peek() : value;
+        },
+
+        toggleDomNodeCssClass: function (node, classNames, shouldHaveClass) {
+            if (classNames) {
+                var cssClassNameRegex = /\S+/g,
+                    currentClassNames = node.className.match(cssClassNameRegex) || [];
+                ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) {
+                    ko.utils.addOrRemoveItem(currentClassNames, className, shouldHaveClass);
+                });
+                node.className = currentClassNames.join(" ");
+            }
+        },
+
+        setTextContent: function(element, textContent) {
+            var value = ko.utils.unwrapObservable(textContent);
+            if ((value === null) || (value === undefined))
+                value = "";
+
+            // We need there to be exactly one child: a text node.
+            // If there are no children, more than one, or if it's not a text node,
+            // we'll clear everything and create a single text node.
+            var innerTextNode = ko.virtualElements.firstChild(element);
+            if (!innerTextNode || innerTextNode.nodeType != 3 || ko.virtualElements.nextSibling(innerTextNode)) {
+                ko.virtualElements.setDomNodeChildren(element, [element.ownerDocument.createTextNode(value)]);
+            } else {
+                innerTextNode.data = value;
+            }
+
+            ko.utils.forceRefresh(element);
+        },
+
+        setElementName: function(element, name) {
+            element.name = name;
+
+            // Workaround IE 6/7 issue
+            // - https://github.com/SteveSanderson/knockout/issues/197
+            // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/
+            if (ieVersion <= 7) {
+                try {
+                    element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false);
+                }
+                catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View"
+            }
+        },
+
+        forceRefresh: function(node) {
+            // Workaround for an IE9 rendering bug - https://github.com/SteveSanderson/knockout/issues/209
+            if (ieVersion >= 9) {
+                // For text nodes and comment nodes (most likely virtual elements), we will have to refresh the container
+                var elem = node.nodeType == 1 ? node : node.parentNode;
+                if (elem.style)
+                    elem.style.zoom = elem.style.zoom;
+            }
+        },
+
+        ensureSelectElementIsRenderedCorrectly: function(selectElement) {
+            // Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width.
+            // (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option)
+            // Also fixes IE7 and IE8 bug that causes selects to be zero width if enclosed by 'if' or 'with'. (See issue #839)
+            if (ieVersion) {
+                var originalWidth = selectElement.style.width;
+                selectElement.style.width = 0;
+                selectElement.style.width = originalWidth;
+            }
+        },
+
+        range: function (min, max) {
+            min = ko.utils.unwrapObservable(min);
+            max = ko.utils.unwrapObservable(max);
+            var result = [];
+            for (var i = min; i <= max; i++)
+                result.push(i);
+            return result;
+        },
+
+        makeArray: function(arrayLikeObject) {
+            var result = [];
+            for (var i = 0, j = arrayLikeObject.length; i < j; i++) {
+                result.push(arrayLikeObject[i]);
+            };
+            return result;
+        },
+
+        isIe6 : isIe6,
+        isIe7 : isIe7,
+        ieVersion : ieVersion,
+
+        getFormFields: function(form, fieldName) {
+            var fields = ko.utils.makeArray(form.getElementsByTagName("input")).concat(ko.utils.makeArray(form.getElementsByTagName("textarea")));
+            var isMatchingField = (typeof fieldName == 'string')
+                ? function(field) { return field.name === fieldName }
+                : function(field) { return fieldName.test(field.name) }; // Treat fieldName as regex or object containing predicate
+            var matches = [];
+            for (var i = fields.length - 1; i >= 0; i--) {
+                if (isMatchingField(fields[i]))
+                    matches.push(fields[i]);
+            };
+            return matches;
+        },
+
+        parseJson: function (jsonString) {
+            if (typeof jsonString == "string") {
+                jsonString = ko.utils.stringTrim(jsonString);
+                if (jsonString) {
+                    if (JSON && JSON.parse) // Use native parsing where available
+                        return JSON.parse(jsonString);
+                    return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers
+                }
+            }
+            return null;
+        },
+
+        stringifyJson: function (data, replacer, space) {   // replacer and space are optional
+            if (!JSON || !JSON.stringify)
+                throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
+            return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space);
+        },
+
+        postJson: function (urlOrForm, data, options) {
+            options = options || {};
+            var params = options['params'] || {};
+            var includeFields = options['includeFields'] || this.fieldsIncludedWithJsonPost;
+            var url = urlOrForm;
+
+            // If we were given a form, use its 'action' URL and pick out any requested field values
+            if((typeof urlOrForm == 'object') && (ko.utils.tagNameLower(urlOrForm) === "form")) {
+                var originalForm = urlOrForm;
+                url = originalForm.action;
+                for (var i = includeFields.length - 1; i >= 0; i--) {
+                    var fields = ko.utils.getFormFields(originalForm, includeFields[i]);
+                    for (var j = fields.length - 1; j >= 0; j--)
+                        params[fields[j].name] = fields[j].value;
+                }
+            }
+
+            data = ko.utils.unwrapObservable(data);
+            var form = document.createElement("form");
+            form.style.display = "none";
+            form.action = url;
+            form.method = "post";
+            for (var key in data) {
+                // Since 'data' this is a model object, we include all properties including those inherited from its prototype
+                var input = document.createElement("input");
+                input.type = "hidden";
+                input.name = key;
+                input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key]));
+                form.appendChild(input);
+            }
+            objectForEach(params, function(key, value) {
+                var input = document.createElement("input");
+                input.type = "hidden";
+                input.name = key;
+                input.value = value;
+                form.appendChild(input);
+            });
+            document.body.appendChild(form);
+            options['submitter'] ? options['submitter'](form) : form.submit();
+            setTimeout(function () { form.parentNode.removeChild(form); }, 0);
+        }
+    }
+}());
+
+ko.exportSymbol('utils', ko.utils);
+ko.exportSymbol('utils.arrayForEach', ko.utils.arrayForEach);
+ko.exportSymbol('utils.arrayFirst', ko.utils.arrayFirst);
+ko.exportSymbol('utils.arrayFilter', ko.utils.arrayFilter);
+ko.exportSymbol('utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues);
+ko.exportSymbol('utils.arrayIndexOf', ko.utils.arrayIndexOf);
+ko.exportSymbol('utils.arrayMap', ko.utils.arrayMap);
+ko.exportSymbol('utils.arrayPushAll', ko.utils.arrayPushAll);
+ko.exportSymbol('utils.arrayRemoveItem', ko.utils.arrayRemoveItem);
+ko.exportSymbol('utils.extend', ko.utils.extend);
+ko.exportSymbol('utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost);
+ko.exportSymbol('utils.getFormFields', ko.utils.getFormFields);
+ko.exportSymbol('utils.peekObservable', ko.utils.peekObservable);
+ko.exportSymbol('utils.postJson', ko.utils.postJson);
+ko.exportSymbol('utils.parseJson', ko.utils.parseJson);
+ko.exportSymbol('utils.registerEventHandler', ko.utils.registerEventHandler);
+ko.exportSymbol('utils.stringifyJson', ko.utils.stringifyJson);
+ko.exportSymbol('utils.range', ko.utils.range);
+ko.exportSymbol('utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass);
+ko.exportSymbol('utils.triggerEvent', ko.utils.triggerEvent);
+ko.exportSymbol('utils.unwrapObservable', ko.utils.unwrapObservable);
+ko.exportSymbol('utils.objectForEach', ko.utils.objectForEach);
+ko.exportSymbol('utils.addOrRemoveItem', ko.utils.addOrRemoveItem);
+ko.exportSymbol('unwrap', ko.utils.unwrapObservable); // Convenient shorthand, because this is used so commonly
+
+if (!Function.prototype['bind']) {
+    // Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf)
+    // In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js
+    Function.prototype['bind'] = function (object) {
+        var originalFunction = this, args = Array.prototype.slice.call(arguments), object = args.shift();
+        return function () {
+            return originalFunction.apply(object, args.concat(Array.prototype.slice.call(arguments)));
+        };
+    };
+}
+
+ko.utils.domData = new (function () {
+    var uniqueId = 0;
+    var dataStoreKeyExpandoPropertyName = "__ko__" + (new Date).getTime();
+    var dataStore = {};
+
+    function getAll(node, createIfNotFound) {
+        var dataStoreKey = node[dataStoreKeyExpandoPropertyName];
+        var hasExistingDataStore = dataStoreKey && (dataStoreKey !== "null") && dataStore[dataStoreKey];
+        if (!hasExistingDataStore) {
+            if (!createIfNotFound)
+                return undefined;
+            dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++;
+            dataStore[dataStoreKey] = {};
+        }
+        return dataStore[dataStoreKey];
+    }
+
+    return {
+        get: function (node, key) {
+            var allDataForNode = getAll(node, false);
+            return allDataForNode === undefined ? undefined : allDataForNode[key];
+        },
+        set: function (node, key, value) {
+            if (value === undefined) {
+                // Make sure we don't actually create a new domData key if we are actually deleting a value
+                if (getAll(node, false) === undefined)
+                    return;
+            }
+            var allDataForNode = getAll(node, true);
+            allDataForNode[key] = value;
+        },
+        clear: function (node) {
+            var dataStoreKey = node[dataStoreKeyExpandoPropertyName];
+            if (dataStoreKey) {
+                delete dataStore[dataStoreKey];
+                node[dataStoreKeyExpandoPropertyName] = null;
+                return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended
+            }
+            return false;
+        },
+
+        nextKey: function () {
+            return (uniqueId++) + dataStoreKeyExpandoPropertyName;
+        }
+    };
+})();
+
+ko.exportSymbol('utils.domData', ko.utils.domData);
+ko.exportSymbol('utils.domData.clear', ko.utils.domData.clear); // Exporting only so specs can clear up after themselves fully
+
+ko.utils.domNodeDisposal = new (function () {
+    var domDataKey = ko.utils.domData.nextKey();
+    var cleanableNodeTypes = { 1: true, 8: true, 9: true };       // Element, Comment, Document
+    var cleanableNodeTypesWithDescendants = { 1: true, 9: true }; // Element, Document
+
+    function getDisposeCallbacksCollection(node, createIfNotFound) {
+        var allDisposeCallbacks = ko.utils.domData.get(node, domDataKey);
+        if ((allDisposeCallbacks === undefined) && createIfNotFound) {
+            allDisposeCallbacks = [];
+            ko.utils.domData.set(node, domDataKey, allDisposeCallbacks);
+        }
+        return allDisposeCallbacks;
+    }
+    function destroyCallbacksCollection(node) {
+        ko.utils.domData.set(node, domDataKey, undefined);
+    }
+
+    function cleanSingleNode(node) {
+        // Run all the dispose callbacks
+        var callbacks = getDisposeCallbacksCollection(node, false);
+        if (callbacks) {
+            callbacks = callbacks.slice(0); // Clone, as the array may be modified during iteration (typically, callbacks will remove themselves)
+            for (var i = 0; i < callbacks.length; i++)
+                callbacks[i](node);
+        }
+
+        // Erase the DOM data
+        ko.utils.domData.clear(node);
+
+        // Perform cleanup needed by external libraries (currently only jQuery, but can be extended)
+        ko.utils.domNodeDisposal["cleanExternalData"](node);
+
+        // Clear any immediate-child comment nodes, as these wouldn't have been found by
+        // node.getElementsByTagName("*") in cleanNode() (comment nodes aren't elements)
+        if (cleanableNodeTypesWithDescendants[node.nodeType])
+            cleanImmediateCommentTypeChildren(node);
+    }
+
+    function cleanImmediateCommentTypeChildren(nodeWithChildren) {
+        var child, nextChild = nodeWithChildren.firstChild;
+        while (child = nextChild) {
+            nextChild = child.nextSibling;
+            if (child.nodeType === 8)
+                cleanSingleNode(child);
+        }
+    }
+
+    return {
+        addDisposeCallback : function(node, callback) {
+            if (typeof callback != "function")
+                throw new Error("Callback must be a function");
+            getDisposeCallbacksCollection(node, true).push(callback);
+        },
+
+        removeDisposeCallback : function(node, callback) {
+            var callbacksCollection = getDisposeCallbacksCollection(node, false);
+            if (callbacksCollection) {
+                ko.utils.arrayRemoveItem(callbacksCollection, callback);
+                if (callbacksCollection.length == 0)
+                    destroyCallbacksCollection(node);
+            }
+        },
+
+        cleanNode : function(node) {
+            // First clean this node, where applicable
+            if (cleanableNodeTypes[node.nodeType]) {
+                cleanSingleNode(node);
+
+                // ... then its descendants, where applicable
+                if (cleanableNodeTypesWithDescendants[node.nodeType]) {
+                    // Clone the descendants list in case it changes during iteration
+                    var descendants = [];
+                    ko.utils.arrayPushAll(descendants, node.getElementsByTagName("*"));
+                    for (var i = 0, j = descendants.length; i < j; i++)
+                        cleanSingleNode(descendants[i]);
+                }
+            }
+            return node;
+        },
+
+        removeNode : function(node) {
+            ko.cleanNode(node);
+            if (node.parentNode)
+                node.parentNode.removeChild(node);
+        },
+
+        "cleanExternalData" : function (node) {
+            // Special support for jQuery here because it's so commonly used.
+            // Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData
+            // so notify it to tear down any resources associated with the node & descendants here.
+            if (jQueryInstance && (typeof jQueryInstance['cleanData'] == "function"))
+                jQueryInstance['cleanData']([node]);
+        }
+    }
+})();
+ko.cleanNode = ko.utils.domNodeDisposal.cleanNode; // Shorthand name for convenience
+ko.removeNode = ko.utils.domNodeDisposal.removeNode; // Shorthand name for convenience
+ko.exportSymbol('cleanNode', ko.cleanNode);
+ko.exportSymbol('removeNode', ko.removeNode);
+ko.exportSymbol('utils.domNodeDisposal', ko.utils.domNodeDisposal);
+ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisposal.addDisposeCallback);
+ko.exportSymbol('utils.domNodeDisposal.removeDisposeCallback', ko.utils.domNodeDisposal.removeDisposeCallback);
+(function () {
+    var leadingCommentRegex = /^(\s*)<!--(.*?)-->/;
+
+    function simpleHtmlParse(html) {
+        // Based on jQuery's "clean" function, but only accounting for table-related elements.
+        // If you have referenced jQuery, this won't be used anyway - KO will use jQuery's "clean" function directly
+
+        // Note that there's still an issue in IE < 9 whereby it will discard comment nodes that are the first child of
+        // a descendant node. For example: "<div><!-- mycomment -->abc</div>" will get parsed as "<div>abc</div>"
+        // This won't affect anyone who has referenced jQuery, and there's always the workaround of inserting a dummy node
+        // (possibly a text node) in front of the comment. So, KO does not attempt to workaround this IE issue automatically at present.
+
+        // Trim whitespace, otherwise indexOf won't work as expected
+        var tags = ko.utils.stringTrim(html).toLowerCase(), div = document.createElement("div");
+
+        // Finds the first match from the left column, and returns the corresponding "wrap" data from the right column
+        var wrap = tags.match(/^<(thead|tbody|tfoot)/)              && [1, "<table>", "</table>"] ||
+                   !tags.indexOf("<tr")                             && [2, "<table><tbody>", "</tbody></table>"] ||
+                   (!tags.indexOf("<td") || !tags.indexOf("<th"))   && [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+                   /* anything else */                                 [0, "", ""];
+
+        // Go to html and back, then peel off extra wrappers
+        // Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness.
+        var markup = "ignored<div>" + wrap[1] + html + wrap[2] + "</div>";
+        if (typeof window['innerShiv'] == "function") {
+            div.appendChild(window['innerShiv'](markup));
+        } else {
+            div.innerHTML = markup;
+        }
+
+        // Move to the right depth
+        while (wrap[0]--)
+            div = div.lastChild;
+
+        return ko.utils.makeArray(div.lastChild.childNodes);
+    }
+
+    function jQueryHtmlParse(html) {
+        // jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API.
+        if (jQueryInstance['parseHTML']) {
+            return jQueryInstance['parseHTML'](html) || []; // Ensure we always return an array and never null
+        } else {
+            // For jQuery < 1.8.0, we fall back on the undocumented internal "clean" function.
+            var elems = jQueryInstance['clean']([html]);
+
+            // As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment.
+            // Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time.
+            // Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment.
+            if (elems && elems[0]) {
+                // Find the top-most parent element that's a direct child of a document fragment
+                var elem = elems[0];
+                while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */)
+                    elem = elem.parentNode;
+                // ... then detach it
+                if (elem.parentNode)
+                    elem.parentNode.removeChild(elem);
+            }
+
+            return elems;
+        }
+    }
+
+    ko.utils.parseHtmlFragment = function(html) {
+        return jQueryInstance ? jQueryHtmlParse(html)   // As below, benefit from jQuery's optimisations where possible
+                              : simpleHtmlParse(html);  // ... otherwise, this simple logic will do in most common cases.
+    };
+
+    ko.utils.setHtml = function(node, html) {
+        ko.utils.emptyDomNode(node);
+
+        // There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap it
+        html = ko.utils.unwrapObservable(html);
+
+        if ((html !== null) && (html !== undefined)) {
+            if (typeof html != 'string')
+                html = html.toString();
+
+            // jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments,
+            // for example <tr> elements which are not normally allowed to exist on their own.
+            // If you've referenced jQuery we'll use that rather than duplicating its code.
+            if (jQueryInstance) {
+                jQueryInstance(node)['html'](html);
+            } else {
+                // ... otherwise, use KO's own parsing logic.
+                var parsedNodes = ko.utils.parseHtmlFragment(html);
+                for (var i = 0; i < parsedNodes.length; i++)
+                    node.appendChild(parsedNodes[i]);
+            }
+        }
+    };
+})();
+
+ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment);
+ko.exportSymbol('utils.setHtml', ko.utils.setHtml);
+
+ko.memoization = (function () {
+    var memos = {};
+
+    function randomMax8HexChars() {
+        return (((1 + Math.random()) * 0x100000000) | 0).toString(16).substring(1);
+    }
+    function generateRandomId() {
+        return randomMax8HexChars() + randomMax8HexChars();
+    }
+    function findMemoNodes(rootNode, appendToArray) {
+        if (!rootNode)
+            return;
+        if (rootNode.nodeType == 8) {
+            var memoId = ko.memoization.parseMemoText(rootNode.nodeValue);
+            if (memoId != null)
+                appendToArray.push({ domNode: rootNode, memoId: memoId });
+        } else if (rootNode.nodeType == 1) {
+            for (var i = 0, childNodes = rootNode.childNodes, j = childNodes.length; i < j; i++)
+                findMemoNodes(childNodes[i], appendToArray);
+        }
+    }
+
+    return {
+        memoize: function (callback) {
+            if (typeof callback != "function")
+                throw new Error("You can only pass a function to ko.memoization.memoize()");
+            var memoId = generateRandomId();
+            memos[memoId] = callback;
+            return "<!--[ko_memo:" + memoId + "]-->";
+        },
+
+        unmemoize: function (memoId, callbackParams) {
+            var callback = memos[memoId];
+            if (callback === undefined)
+                throw new Error("Couldn't find any memo with ID " + memoId + ". Perhaps it's already been unmemoized.");
+            try {
+                callback.apply(null, callbackParams || []);
+                return true;
+            }
+            finally { delete memos[memoId]; }
+        },
+
+        unmemoizeDomNodeAndDescendants: function (domNode, extraCallbackParamsArray) {
+            var memos = [];
+            findMemoNodes(domNode, memos);
+            for (var i = 0, j = memos.length; i < j; i++) {
+                var node = memos[i].domNode;
+                var combinedParams = [node];
+                if (extraCallbackParamsArray)
+                    ko.utils.arrayPushAll(combinedParams, extraCallbackParamsArray);
+                ko.memoization.unmemoize(memos[i].memoId, combinedParams);
+                node.nodeValue = ""; // Neuter this node so we don't try to unmemoize it again
+                if (node.parentNode)
+                    node.parentNode.removeChild(node); // If possible, erase it totally (not always possible - someone else might just hold a reference to it then call unmemoizeDomNodeAndDescendants again)
+            }
+        },
+
+        parseMemoText: function (memoText) {
+            var match = memoText.match(/^\[ko_memo\:(.*?)\]$/);
+            return match ? match[1] : null;
+        }
+    };
+})();
+
+ko.exportSymbol('memoization', ko.memoization);
+ko.exportSymbol('memoization.memoize', ko.memoization.memoize);
+ko.exportSymbol('memoization.unmemoize', ko.memoization.unmemoize);
+ko.exportSymbol('memoization.parseMemoText', ko.memoization.parseMemoText);
+ko.exportSymbol('memoization.unmemoizeDomNodeAndDescendants', ko.memoization.unmemoizeDomNodeAndDescendants);
+ko.extenders = {
+    'throttle': function(target, timeout) {
+        // Throttling means two things:
+
+        // (1) For dependent observables, we throttle *evaluations* so that, no matter how fast its dependencies
+        //     notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate
+        target['throttleEvaluation'] = timeout;
+
+        // (2) For writable targets (observables, or writable dependent observables), we throttle *writes*
+        //     so the target cannot change value synchronously or faster than a certain rate
+        var writeTimeoutInstance = null;
+        return ko.dependentObservable({
+            'read': target,
+            'write': function(value) {
+                clearTimeout(writeTimeoutInstance);
+                writeTimeoutInstance = setTimeout(function() {
+                    target(value);
+                }, timeout);
+            }
+        });
+    },
+
+    'rateLimit': function(target, options) {
+        var timeout, method, limitFunction;
+
+        if (typeof options == 'number') {
+            timeout = options;
+        } else {
+            timeout = options['timeout'];
+            method = options['method'];
+        }
+
+        limitFunction = method == 'notifyWhenChangesStop' ?  debounce : throttle;
+        target.limit(function(callback) {
+            return limitFunction(callback, timeout);
+        });
+    },
+
+    'notify': function(target, notifyWhen) {
+        target["equalityComparer"] = notifyWhen == "always" ?
+            null :  // null equalityComparer means to always notify
+            valuesArePrimitiveAndEqual;
+    }
+};
+
+var primitiveTypes = { 'undefined':1, 'boolean':1, 'number':1, 'string':1 };
+function valuesArePrimitiveAndEqual(a, b) {
+    var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes);
+    return oldValueIsPrimitive ? (a === b) : false;
+}
+
+function throttle(callback, timeout) {
+    var timeoutInstance;
+    return function () {
+        if (!timeoutInstance) {
+            timeoutInstance = setTimeout(function() {
+                timeoutInstance = undefined;
+                callback();
+            }, timeout);
+        }
+    };
+}
+
+function debounce(callback, timeout) {
+    var timeoutInstance;
+    return function () {
+        clearTimeout(timeoutInstance);
+        timeoutInstance = setTimeout(callback, timeout);
+    };
+}
+
+function applyExtenders(requestedExtenders) {
+    var target = this;
+    if (requestedExtenders) {
+        ko.utils.objectForEach(requestedExtenders, function(key, value) {
+            var extenderHandler = ko.extenders[key];
+            if (typeof extenderHandler == 'function') {
+                target = extenderHandler(target, value) || target;
+            }
+        });
+    }
+    return target;
+}
+
+ko.exportSymbol('extenders', ko.extenders);
+
+ko.subscription = function (target, callback, disposeCallback) {
+    this.target = target;
+    this.callback = callback;
+    this.disposeCallback = disposeCallback;
+    this.isDisposed = false;
+    ko.exportProperty(this, 'dispose', this.dispose);
+};
+ko.subscription.prototype.dispose = function () {
+    this.isDisposed = true;
+    this.disposeCallback();
+};
+
+ko.subscribable = function () {
+    ko.utils.setPrototypeOfOrExtend(this, ko.subscribable['fn']);
+    this._subscriptions = {};
+}
+
+var defaultEvent = "change";
+
+var ko_subscribable_fn = {
+    subscribe: function (callback, callbackTarget, event) {
+        var self = this;
+
+        event = event || defaultEvent;
+        var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
+
+        var subscription = new ko.subscription(self, boundCallback, function () {
+            ko.utils.arrayRemoveItem(self._subscriptions[event], subscription);
+            if (self.afterSubscriptionRemove)
+                self.afterSubscriptionRemove(event);
+        });
+
+        if (self.beforeSubscriptionAdd)
+            self.beforeSubscriptionAdd(event);
+
+        if (!self._subscriptions[event])
+            self._subscriptions[event] = [];
+        self._subscriptions[event].push(subscription);
+
+        return subscription;
+    },
+
+    "notifySubscribers": function (valueToNotify, event) {
+        event = event || defaultEvent;
+        if (this.hasSubscriptionsForEvent(event)) {
+            try {
+                ko.dependencyDetection.begin(); // Begin suppressing dependency detection (by setting the top frame to undefined)
+                for (var a = this._subscriptions[event].slice(0), i = 0, subscription; subscription = a[i]; ++i) {
+                    // In case a subscription was disposed during the arrayForEach cycle, check
+                    // for isDisposed on each subscription before invoking its callback
+                    if (!subscription.isDisposed)
+                        subscription.callback(valueToNotify);
+                }
+            } finally {
+                ko.dependencyDetection.end(); // End suppressing dependency detection
+            }
+        }
+    },
+
+    limit: function(limitFunction) {
+        var self = this, selfIsObservable = ko.isObservable(self),
+            isPending, previousValue, pendingValue, beforeChange = 'beforeChange';
+
+        if (!self._origNotifySubscribers) {
+            self._origNotifySubscribers = self["notifySubscribers"];
+            self["notifySubscribers"] = function(value, event) {
+                if (!event || event === defaultEvent) {
+                    self._rateLimitedChange(value);
+                } else if (event === beforeChange) {
+                    self._rateLimitedBeforeChange(value);
+                } else {
+                    self._origNotifySubscribers(value, event);
+                }
+            };
+        }
+
+        var finish = limitFunction(function() {
+            // If an observable provided a reference to itself, access it to get the latest value.
+            // This allows computed observables to delay calculating their value until needed.
+            if (selfIsObservable && pendingValue === self) {
+                pendingValue = self();
+            }
+            isPending = false;
+            if (self.isDifferent(previousValue, pendingValue)) {
+                self._origNotifySubscribers(previousValue = pendingValue);
+            }
+        });
+
+        self._rateLimitedChange = function(value) {
+            isPending = true;
+            pendingValue = value;
+            finish();
+        };
+        self._rateLimitedBeforeChange = function(value) {
+            if (!isPending) {
+                previousValue = value;
+                self._origNotifySubscribers(value, beforeChange);
+            }
+        };
+    },
+
+    hasSubscriptionsForEvent: function(event) {
+        return this._subscriptions[event] && this._subscriptions[event].length;
+    },
+
+    getSubscriptionsCount: function () {
+        var total = 0;
+        ko.utils.objectForEach(this._subscriptions, function(eventName, subscriptions) {
+            total += subscriptions.length;
+        });
+        return total;
+    },
+
+    isDifferent: function(oldValue, newValue) {
+        return !this['equalityComparer'] || !this['equalityComparer'](oldValue, newValue);
+    },
+
+    extend: applyExtenders
+};
+
+ko.exportProperty(ko_subscribable_fn, 'subscribe', ko_subscribable_fn.subscribe);
+ko.exportProperty(ko_subscribable_fn, 'extend', ko_subscribable_fn.extend);
+ko.exportProperty(ko_subscribable_fn, 'getSubscriptionsCount', ko_subscribable_fn.getSubscriptionsCount);
+
+// For browsers that support proto assignment, we overwrite the prototype of each
+// observable instance. Since observables are functions, we need Function.prototype
+// to still be in the prototype chain.
+if (ko.utils.canSetPrototype) {
+    ko.utils.setPrototypeOf(ko_subscribable_fn, Function.prototype);
+}
+
+ko.subscribable['fn'] = ko_subscribable_fn;
+
+
+ko.isSubscribable = function (instance) {
+    return instance != null && typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function";
+};
+
+ko.exportSymbol('subscribable', ko.subscribable);
+ko.exportSymbol('isSubscribable', ko.isSubscribable);
+
+ko.computedContext = ko.dependencyDetection = (function () {
+    var outerFrames = [],
+        currentFrame,
+        lastId = 0;
+
+    // Return a unique ID that can be assigned to an observable for dependency tracking.
+    // Theoretically, you could eventually overflow the number storage size, resulting
+    // in duplicate IDs. But in JavaScript, the largest exact integral value is 2^53
+    // or 9,007,199,254,740,992. If you created 1,000,000 IDs per second, it would
+    // take over 285 years to reach that number.
+    // Reference http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
+    function getId() {
+        return ++lastId;
+    }
+
+    function begin(options) {
+        outerFrames.push(currentFrame);
+        currentFrame = options;
+    }
+
+    function end() {
+        currentFrame = outerFrames.pop();
+    }
+
+    return {
+        begin: begin,
+
+        end: end,
+
+        registerDependency: function (subscribable) {
+            if (currentFrame) {
+                if (!ko.isSubscribable(subscribable))
+                    throw new Error("Only subscribable things can act as dependencies");
+                currentFrame.callback(subscribable, subscribable._id || (subscribable._id = getId()));
+            }
+        },
+
+        ignore: function (callback, callbackTarget, callbackArgs) {
+            try {
+                begin();
+                return callback.apply(callbackTarget, callbackArgs || []);
+            } finally {
+                end();
+            }
+        },
+
+        getDependenciesCount: function () {
+            if (currentFrame)
+                return currentFrame.computed.getDependenciesCount();
+        },
+
+        isInitial: function() {
+            if (currentFrame)
+                return currentFrame.isInitial;
+        }
+    };
+})();
+
+ko.exportSymbol('computedContext', ko.computedContext);
+ko.exportSymbol('computedContext.getDependenciesCount', ko.computedContext.getDependenciesCount);
+ko.exportSymbol('computedContext.isInitial', ko.computedContext.isInitial);
+ko.exportSymbol('computedContext.isSleeping', ko.computedContext.isSleeping);
+ko.observable = function (initialValue) {
+    var _latestValue = initialValue;
+
+    function observable() {
+        if (arguments.length > 0) {
+            // Write
+
+            // Ignore writes if the value hasn't changed
+            if (observable.isDifferent(_latestValue, arguments[0])) {
+                observable.valueWillMutate();
+                _latestValue = arguments[0];
+                if (DEBUG) observable._latestValue = _latestValue;
+                observable.valueHasMutated();
+            }
+            return this; // Permits chained assignments
+        }
+        else {
+            // Read
+            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
+            return _latestValue;
+        }
+    }
+    ko.subscribable.call(observable);
+    ko.utils.setPrototypeOfOrExtend(observable, ko.observable['fn']);
+
+    if (DEBUG) observable._latestValue = _latestValue;
+    observable.peek = function() { return _latestValue };
+    observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); }
+    observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }
+
+    ko.exportProperty(observable, 'peek', observable.peek);
+    ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated);
+    ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate);
+
+    return observable;
+}
+
+ko.observable['fn'] = {
+    "equalityComparer": valuesArePrimitiveAndEqual
+};
+
+var protoProperty = ko.observable.protoProperty = "__ko_proto__";
+ko.observable['fn'][protoProperty] = ko.observable;
+
+// Note that for browsers that don't support proto assignment, the
+// inheritance chain is created manually in the ko.observable constructor
+if (ko.utils.canSetPrototype) {
+    ko.utils.setPrototypeOf(ko.observable['fn'], ko.subscribable['fn']);
+}
+
+ko.hasPrototype = function(instance, prototype) {
+    if ((instance === null) || (instance === undefined) || (instance[protoProperty] === undefined)) return false;
+    if (instance[protoProperty] === prototype) return true;
+    return ko.hasPrototype(instance[protoProperty], prototype); // Walk the prototype chain
+};
+
+ko.isObservable = function (instance) {
+    return ko.hasPrototype(instance, ko.observable);
+}
+ko.isWriteableObservable = function (instance) {
+    // Observable
+    if ((typeof instance == "function") && instance[protoProperty] === ko.observable)
+        return true;
+    // Writeable dependent observable
+    if ((typeof instance == "function") && (instance[protoProperty] === ko.dependentObservable) && (instance.hasWriteFunction))
+        return true;
+    // Anything else
+    return false;
+}
+
+
+ko.exportSymbol('observable', ko.observable);
+ko.exportSymbol('isObservable', ko.isObservable);
+ko.exportSymbol('isWriteableObservable', ko.isWriteableObservable);
+ko.exportSymbol('isWritableObservable', ko.isWriteableObservable);
+ko.observableArray = function (initialValues) {
+    initialValues = initialValues || [];
+
+    if (typeof initialValues != 'object' || !('length' in initialValues))
+        throw new Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");
+
+    var result = ko.observable(initialValues);
+    ko.utils.setPrototypeOfOrExtend(result, ko.observableArray['fn']);
+    return result.extend({'trackArrayChanges':true});
+};
+
+ko.observableArray['fn'] = {
+    'remove': function (valueOrPredicate) {
+        var underlyingArray = this.peek();
+        var removedValues = [];
+        var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
+        for (var i = 0; i < underlyingArray.length; i++) {
+            var value = underlyingArray[i];
+            if (predicate(value)) {
+                if (removedValues.length === 0) {
+                    this.valueWillMutate();
+                }
+                removedValues.push(value);
+                underlyingArray.splice(i, 1);
+                i--;
+            }
+        }
+        if (removedValues.length) {
+            this.valueHasMutated();
+        }
+        return removedValues;
+    },
+
+    'removeAll': function (arrayOfValues) {
+        // If you passed zero args, we remove everything
+        if (arrayOfValues === undefined) {
+            var underlyingArray = this.peek();
+            var allValues = underlyingArray.slice(0);
+            this.valueWillMutate();
+            underlyingArray.splice(0, underlyingArray.length);
+            this.valueHasMutated();
+            return allValues;
+        }
+        // If you passed an arg, we interpret it as an array of entries to remove
+        if (!arrayOfValues)
+            return [];
+        return this['remove'](function (value) {
+            return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
+        });
+    },
+
+    'destroy': function (valueOrPredicate) {
+        var underlyingArray = this.peek();
+        var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
+        this.valueWillMutate();
+        for (var i = underlyingArray.length - 1; i >= 0; i--) {
+            var value = underlyingArray[i];
+            if (predicate(value))
+                underlyingArray[i]["_destroy"] = true;
+        }
+        this.valueHasMutated();
+    },
+
+    'destroyAll': function (arrayOfValues) {
+        // If you passed zero args, we destroy everything
+        if (arrayOfValues === undefined)
+            return this['destroy'](function() { return true });
+
+        // If you passed an arg, we interpret it as an array of entries to destroy
+        if (!arrayOfValues)
+            return [];
+        return this['destroy'](function (value) {
+            return ko.utils.arrayIndexOf(arrayOfValues, value) >= 0;
+        });
+    },
+
+    'indexOf': function (item) {
+        var underlyingArray = this();
+        return ko.utils.arrayIndexOf(underlyingArray, item);
+    },
+
+    'replace': function(oldItem, newItem) {
+        var index = this['indexOf'](oldItem);
+        if (index >= 0) {
+            this.valueWillMutate();
+            this.peek()[index] = newItem;
+            this.valueHasMutated();
+        }
+    }
+};
+
+// Populate ko.observableArray.fn with read/write functions from native arrays
+// Important: Do not add any additional functions here that may reasonably be used to *read* data from the array
+// because we'll eval them without causing subscriptions, so ko.computed output could end up getting stale
+ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) {
+    ko.observableArray['fn'][methodName] = function () {
+        // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of
+        // (for consistency with mutating regular observables)
+        var underlyingArray = this.peek();
+        this.valueWillMutate();
+        this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments);
+        var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments);
+        this.valueHasMutated();
+        return methodCallResult;
+    };
+});
+
+// Populate ko.observableArray.fn with read-only functions from native arrays
+ko.utils.arrayForEach(["slice"], function (methodName) {
+    ko.observableArray['fn'][methodName] = function () {
+        var underlyingArray = this();
+        return underlyingArray[methodName].apply(underlyingArray, arguments);
+    };
+});
+
+// Note that for browsers that don't support proto assignment, the
+// inheritance chain is created manually in the ko.observableArray constructor
+if (ko.utils.canSetPrototype) {
+    ko.utils.setPrototypeOf(ko.observableArray['fn'], ko.observable['fn']);
+}
+
+ko.exportSymbol('observableArray', ko.observableArray);
+var arrayChangeEventName = 'arrayChange';
+ko.extenders['trackArrayChanges'] = function(target) {
+    // Only modify the target observable once
+    if (target.cacheDiffForKnownOperation) {
+        return;
+    }
+    var trackingChanges = false,
+        cachedDiff = null,
+        pendingNotifications = 0,
+        underlyingSubscribeFunction = target.subscribe;
+
+    // Intercept "subscribe" calls, and for array change events, ensure change tracking is enabled
+    target.subscribe = target['subscribe'] = function(callback, callbackTarget, event) {
+        if (event === arrayChangeEventName) {
+            trackChanges();
+        }
+        return underlyingSubscribeFunction.apply(this, arguments);
+    };
+
+    function trackChanges() {
+        // Calling 'trackChanges' multiple times is the same as calling it once
+        if (trackingChanges) {
+            return;
+        }
+
+        trackingChanges = true;
+
+        // Intercept "notifySubscribers" to track how many times it was called.
+        var underlyingNotifySubscribersFunction = target['notifySubscribers'];
+        target['notifySubscribers'] = function(valueToNotify, event) {
+            if (!event || event === defaultEvent) {
+                ++pendingNotifications;
+            }
+            return underlyingNotifySubscribersFunction.apply(this, arguments);
+        };
+
+        // Each time the array changes value, capture a clone so that on the next
+        // change it's possible to produce a diff
+        var previousContents = [].concat(target.peek() || []);
+        cachedDiff = null;
+        target.subscribe(function(currentContents) {
+            // Make a copy of the current contents and ensure it's an array
+            currentContents = [].concat(currentContents || []);
+
+            // Compute the diff and issue notifications, but only if someone is listening
+            if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
+                var changes = getChanges(previousContents, currentContents);
+                if (changes.length) {
+                    target['notifySubscribers'](changes, arrayChangeEventName);
+                }
+            }
+
+            // Eliminate references to the old, removed items, so they can be GCed
+            previousContents = currentContents;
+            cachedDiff = null;
+            pendingNotifications = 0;
+        });
+    }
+
+    function getChanges(previousContents, currentContents) {
+        // We try to re-use cached diffs.
+        // The scenarios where pendingNotifications > 1 are when using rate-limiting or the Deferred Updates
+        // plugin, which without this check would not be compatible with arrayChange notifications. Normally,
+        // notifications are issued immediately so we wouldn't be queueing up more than one.
+        if (!cachedDiff || pendingNotifications > 1) {
+            cachedDiff = ko.utils.compareArrays(previousContents, currentContents, { 'sparse': true });
+        }
+
+        return cachedDiff;
+    }
+
+    target.cacheDiffForKnownOperation = function(rawArray, operationName, args) {
+        // Only run if we're currently tracking changes for this observable array
+        // and there aren't any pending deferred notifications.
+        if (!trackingChanges || pendingNotifications) {
+            return;
+        }
+        var diff = [],
+            arrayLength = rawArray.length,
+            argsLength = args.length,
+            offset = 0;
+
+        function pushDiff(status, value, index) {
+            return diff[diff.length] = { 'status': status, 'value': value, 'index': index };
+        }
+        switch (operationName) {
+            case 'push':
+                offset = arrayLength;
+            case 'unshift':
+                for (var index = 0; index < argsLength; index++) {
+                    pushDiff('added', args[index], offset + index);
+                }
+                break;
+
+            case 'pop':
+                offset = arrayLength - 1;
+            case 'shift':
+                if (arrayLength) {
+                    pushDiff('deleted', rawArray[offset], offset);
+                }
+                break;
+
+            case 'splice':
+                // Negative start index means 'from end of array'. After that we clamp to [0...arrayLength].
+                // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
+                var startIndex = Math.min(Math.max(0, args[0] < 0 ? arrayLength + args[0] : args[0]), arrayLength),
+                    endDeleteIndex = argsLength === 1 ? arrayLength : Math.min(startIndex + (args[1] || 0), arrayLength),
+                    endAddIndex = startIndex + argsLength - 2,
+                    endIndex = Math.max(endDeleteIndex, endAddIndex),
+                    additions = [], deletions = [];
+                for (var index = startIndex, argsIndex = 2; index < endIndex; ++index, ++argsIndex) {
+                    if (index < endDeleteIndex)
+                        deletions.push(pushDiff('deleted', rawArray[index], index));
+                    if (index < endAddIndex)
+                        additions.push(pushDiff('added', args[argsIndex], index));
+                }
+                ko.utils.findMovesInArrayComparison(deletions, additions);
+                break;
+
+            default:
+                return;
+        }
+        cachedDiff = diff;
+    };
+};
+ko.computed = ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) {
+    var _latestValue,
+        _needsEvaluation = true,
+        _isBeingEvaluated = false,
+        _suppressDisposalUntilDisposeWhenReturnsFalse = false,
+        _isDisposed = false,
+        readFunction = evaluatorFunctionOrOptions,
+        pure = false,
+        isSleeping = false;
+
+    if (readFunction && typeof readFunction == "object") {
+        // Single-parameter syntax - everything is on this "options" param
+        options = readFunction;
+        readFunction = options["read"];
+    } else {
+        // Multi-parameter syntax - construct the options according to the params passed
+        options = options || {};
+        if (!readFunction)
+            readFunction = options["read"];
+    }
+    if (typeof readFunction != "function")
+        throw new Error("Pass a function that returns the value of the ko.computed");
+
+    function addSubscriptionToDependency(subscribable, id) {
+        if (!_subscriptionsToDependencies[id]) {
+            _subscriptionsToDependencies[id] = subscribable.subscribe(evaluatePossiblyAsync);
+            ++_dependenciesCount;
+        }
+    }
+
+    function disposeAllSubscriptionsToDependencies() {
+        ko.utils.objectForEach(_subscriptionsToDependencies, function (id, subscription) {
+            subscription.dispose();
+        });
+        _subscriptionsToDependencies = {};
+    }
+
+    function disposeComputed() {
+        disposeAllSubscriptionsToDependencies();
+        _dependenciesCount = 0;
+        _isDisposed = true;
+        _needsEvaluation = false;
+    }
+
+    function evaluatePossiblyAsync() {
+        var throttleEvaluationTimeout = dependentObservable['throttleEvaluation'];
+        if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) {
+            clearTimeout(evaluationTimeoutInstance);
+            evaluationTimeoutInstance = setTimeout(evaluateImmediate, throttleEvaluationTimeout);
+        } else if (dependentObservable._evalRateLimited) {
+            dependentObservable._evalRateLimited();
+        } else {
+            evaluateImmediate();
+        }
+    }
+
+    function evaluateImmediate(suppressChangeNotification) {
+        if (_isBeingEvaluated) {
+            if (pure) {
+                throw Error("A 'pure' computed must not be called recursively");
+            }
+            // If the evaluation of a ko.computed causes side effects, it's possible that it will trigger its own re-evaluation.
+            // This is not desirable (it's hard for a developer to realise a chain of dependencies might cause this, and they almost
+            // certainly didn't intend infinite re-evaluations). So, for predictability, we simply prevent ko.computeds from causing
+            // their own re-evaluation. Further discussion at https://github.com/SteveSanderson/knockout/pull/387
+            return;
+        }
+
+        // Do not evaluate (and possibly capture new dependencies) if disposed
+        if (_isDisposed) {
+            return;
+        }
+
+        if (disposeWhen && disposeWhen()) {
+            // See comment below about _suppressDisposalUntilDisposeWhenReturnsFalse
+            if (!_suppressDisposalUntilDisposeWhenReturnsFalse) {
+                dispose();
+                return;
+            }
+        } else {
+            // It just did return false, so we can stop suppressing now
+            _suppressDisposalUntilDisposeWhenReturnsFalse = false;
+        }
+
+        _isBeingEvaluated = true;
+
+        // When sleeping, recalculate the value and return.
+        if (isSleeping) {
+            try {
+                var dependencyTracking = {};
+                ko.dependencyDetection.begin({
+                    callback: function (subscribable, id) {
+                        if (!dependencyTracking[id]) {
+                            dependencyTracking[id] = 1;
+                            ++_dependenciesCount;
+                        }
+                    },
+                    computed: dependentObservable,
+                    isInitial: undefined
+                });
+                _dependenciesCount = 0;
+                _latestValue = readFunction.call(evaluatorFunctionTarget);
+            } finally {
+                ko.dependencyDetection.end();
+                _isBeingEvaluated = false;
+            }
+        } else {
+            try {
+                // Initially, we assume that none of the subscriptions are still being used (i.e., all are candidates for disposal).
+                // Then, during evaluation, we cross off any that are in fact still being used.
+                var disposalCandidates = _subscriptionsToDependencies, disposalCount = _dependenciesCount;
+                ko.dependencyDetection.begin({
+                    callback: function(subscribable, id) {
+                        if (!_isDisposed) {
+                            if (disposalCount && disposalCandidates[id]) {
+                                // Don't want to dispose this subscription, as it's still being used
+                                _subscriptionsToDependencies[id] = disposalCandidates[id];
+                                ++_dependenciesCount;
+                                delete disposalCandidates[id];
+                                --disposalCount;
+                            } else {
+                                // Brand new subscription - add it
+                                addSubscriptionToDependency(subscribable, id);
+                            }
+                        }
+                    },
+                    computed: dependentObservable,
+                    isInitial: pure ? undefined : !_dependenciesCount        // If we're evaluating when there are no previous dependencies, it must be the first time
+                });
+
+                _subscriptionsToDependencies = {};
+                _dependenciesCount = 0;
+
+                try {
+                    var newValue = evaluatorFunctionTarget ? readFunction.call(evaluatorFunctionTarget) : readFunction();
+
+                } finally {
+                    ko.dependencyDetection.end();
+
+                    // For each subscription no longer being used, remove it from the active subscriptions list and dispose it
+                    if (disposalCount) {
+                        ko.utils.objectForEach(disposalCandidates, function(id, toDispose) {
+                            toDispose.dispose();
+                        });
+                    }
+
+                    _needsEvaluation = false;
+                }
+
+                if (dependentObservable.isDifferent(_latestValue, newValue)) {
+                    dependentObservable["notifySubscribers"](_latestValue, "beforeChange");
+
+                    _latestValue = newValue;
+                    if (DEBUG) dependentObservable._latestValue = _latestValue;
+
+                    if (suppressChangeNotification !== true) {  // Check for strict true value since setTimeout in Firefox passes a numeric value to the function
+                        dependentObservable["notifySubscribers"](_latestValue);
+                    }
+                }
+            } finally {
+                _isBeingEvaluated = false;
+            }
+        }
+
+        if (!_dependenciesCount)
+            dispose();
+    }
+
+    function dependentObservable() {
+        if (arguments.length > 0) {
+            if (typeof writeFunction === "function") {
+                // Writing a value
+                writeFunction.apply(evaluatorFunctionTarget, arguments);
+            } else {
+                throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
+            }
+            return this; // Permits chained assignments
+        } else {
+            // Reading the value
+            ko.dependencyDetection.registerDependency(dependentObservable);
+            if (_needsEvaluation)
+                evaluateImmediate(true /* suppressChangeNotification */);
+            return _latestValue;
+        }
+    }
+
+    function peek() {
+        // Peek won't re-evaluate, except to get the initial value when "deferEvaluation" is set, or while the computed is sleeping.
+        // Those are the only times that both of these conditions will be satisfied.
+        if (_needsEvaluation && !_dependenciesCount)
+            evaluateImmediate(true /* suppressChangeNotification */);
+        return _latestValue;
+    }
+
+    function isActive() {
+        return _needsEvaluation || _dependenciesCount > 0;
+    }
+
+    // By here, "options" is always non-null
+    var writeFunction = options["write"],
+        disposeWhenNodeIsRemoved = options["disposeWhenNodeIsRemoved"] || options.disposeWhenNodeIsRemoved || null,
+        disposeWhenOption = options["disposeWhen"] || options.disposeWhen,
+        disposeWhen = disposeWhenOption,
+        dispose = disposeComputed,
+        _subscriptionsToDependencies = {},
+        _dependenciesCount = 0,
+        evaluationTimeoutInstance = null;
+
+    if (!evaluatorFunctionTarget)
+        evaluatorFunctionTarget = options["owner"];
+
+    ko.subscribable.call(dependentObservable);
+    ko.utils.setPrototypeOfOrExtend(dependentObservable, ko.dependentObservable['fn']);
+
+    dependentObservable.peek = peek;
+    dependentObservable.getDependenciesCount = function () { return _dependenciesCount; };
+    dependentObservable.hasWriteFunction = typeof options["write"] === "function";
+    dependentObservable.dispose = function () { dispose(); };
+    dependentObservable.isActive = isActive;
+
+    // Replace the limit function with one that delays evaluation as well.
+    var originalLimit = dependentObservable.limit;
+    dependentObservable.limit = function(limitFunction) {
+        originalLimit.call(dependentObservable, limitFunction);
+        dependentObservable._evalRateLimited = function() {
+            dependentObservable._rateLimitedBeforeChange(_latestValue);
+
+            _needsEvaluation = true;    // Mark as dirty
+
+            // Pass the observable to the rate-limit code, which will access it when
+            // it's time to do the notification.
+            dependentObservable._rateLimitedChange(dependentObservable);
+        }
+    };
+
+    if (options['pure']) {
+        pure = true;
+        isSleeping = true;     // Starts off sleeping; will awake on the first subscription
+        dependentObservable.beforeSubscriptionAdd = function () {
+            // If asleep, wake up the computed and evaluate to register any dependencies.
+            if (isSleeping) {
+                isSleeping = false;
+                evaluateImmediate(true /* suppressChangeNotification */);
+            }
+        }
+        dependentObservable.afterSubscriptionRemove = function () {
+            if (!dependentObservable.getSubscriptionsCount()) {
+                disposeAllSubscriptionsToDependencies();
+                isSleeping = _needsEvaluation = true;
+            }
+        }
+    } else if (options['deferEvaluation']) {
+        // This will force a computed with deferEvaluation to evaluate when the first subscriptions is registered.
+        dependentObservable.beforeSubscriptionAdd = function () {
+            peek();
+            delete dependentObservable.beforeSubscriptionAdd;
+        }
+    }
+
+    ko.exportProperty(dependentObservable, 'peek', dependentObservable.peek);
+    ko.exportProperty(dependentObservable, 'dispose', dependentObservable.dispose);
+    ko.exportProperty(dependentObservable, 'isActive', dependentObservable.isActive);
+    ko.exportProperty(dependentObservable, 'getDependenciesCount', dependentObservable.getDependenciesCount);
+
+    // Add a "disposeWhen" callback that, on each evaluation, disposes if the node was removed without using ko.removeNode.
+    if (disposeWhenNodeIsRemoved) {
+        // Since this computed is associated with a DOM node, and we don't want to dispose the computed
+        // until the DOM node is *removed* from the document (as opposed to never having been in the document),
+        // we'll prevent disposal until "disposeWhen" first returns false.
+        _suppressDisposalUntilDisposeWhenReturnsFalse = true;
+
+        // Only watch for the node's disposal if the value really is a node. It might not be,
+        // e.g., { disposeWhenNodeIsRemoved: true } can be used to opt into the "only dispose
+        // after first false result" behaviour even if there's no specific node to watch. This
+        // technique is intended for KO's internal use only and shouldn't be documented or used
+        // by application code, as it's likely to change in a future version of KO.
+        if (disposeWhenNodeIsRemoved.nodeType) {
+            disposeWhen = function () {
+                return !ko.utils.domNodeIsAttachedToDocument(disposeWhenNodeIsRemoved) || (disposeWhenOption && disposeWhenOption());
+            };
+        }
+    }
+
+    // Evaluate, unless sleeping or deferEvaluation is true
+    if (!isSleeping && !options['deferEvaluation'])
+        evaluateImmediate();
+
+    // Attach a DOM node disposal callback so that the computed will be proactively disposed as soon as the node is
+    // removed using ko.removeNode. But skip if isActive is false (there will never be any dependencies to dispose).
+    if (disposeWhenNodeIsRemoved && isActive() && disposeWhenNodeIsRemoved.nodeType) {
+        dispose = function() {
+            ko.utils.domNodeDisposal.removeDisposeCallback(disposeWhenNodeIsRemoved, dispose);
+            disposeComputed();
+        };
+        ko.utils.domNodeDisposal.addDisposeCallback(disposeWhenNodeIsRemoved, dispose);
+    }
+
+    return dependentObservable;
+};
+
+ko.isComputed = function(instance) {
+    return ko.hasPrototype(instance, ko.dependentObservable);
+};
+
+var protoProp = ko.observable.protoProperty; // == "__ko_proto__"
+ko.dependentObservable[protoProp] = ko.observable;
+
+ko.dependentObservable['fn'] = {
+    "equalityComparer": valuesArePrimitiveAndEqual
+};
+ko.dependentObservable['fn'][protoProp] = ko.dependentObservable;
+
+// Note that for browsers that don't support proto assignment, the
+// inheritance chain is created manually in the ko.dependentObservable constructor
+if (ko.utils.canSetPrototype) {
+    ko.utils.setPrototypeOf(ko.dependentObservable['fn'], ko.subscribable['fn']);
+}
+
+ko.exportSymbol('dependentObservable', ko.dependentObservable);
+ko.exportSymbol('computed', ko.dependentObservable); // Make "ko.computed" an alias for "ko.dependentObservable"
+ko.exportSymbol('isComputed', ko.isComputed);
+
+ko.pureComputed = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget) {
+    if (typeof evaluatorFunctionOrOptions === 'function') {
+        return ko.computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget, {'pure':true});
+    } else {
+        evaluatorFunctionOrOptions = ko.utils.extend({}, evaluatorFunctionOrOptions);   // make a copy of the parameter object
+        evaluatorFunctionOrOptions['pure'] = true;
+        return ko.computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget);
+    }
+}
+ko.exportSymbol('pureComputed', ko.pureComputed);
+
+(function() {
+    var maxNestedObservableDepth = 10; // Escape the (unlikely) pathalogical case where an observable's current value is itself (or similar reference cycle)
+
+    ko.toJS = function(rootObject) {
+        if (arguments.length == 0)
+            throw new Error("When calling ko.toJS, pass the object you want to convert.");
+
+        // We just unwrap everything at every level in the object graph
+        return mapJsObjectGraph(rootObject, function(valueToMap) {
+            // Loop because an observable's value might in turn be another observable wrapper
+            for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++)
+                valueToMap = valueToMap();
+            return valueToMap;
+        });
+    };
+
+    ko.toJSON = function(rootObject, replacer, space) {     // replacer and space are optional
+        var plainJavaScriptObject = ko.toJS(rootObject);
+        return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space);
+    };
+
+    function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) {
+        visitedObjects = visitedObjects || new objectLookup();
+
+        rootObject = mapInputCallback(rootObject);
+        var canHaveProperties = (typeof rootObject == "object") && (rootObject !== null) && (rootObject !== undefined) && (!(rootObject instanceof Date)) && (!(rootObject instanceof String)) && (!(rootObject instanceof Number)) && (!(rootObject instanceof Boolean));
+        if (!canHaveProperties)
+            return rootObject;
+
+        var outputProperties = rootObject instanceof Array ? [] : {};
+        visitedObjects.save(rootObject, outputProperties);
+
+        visitPropertiesOrArrayEntries(rootObject, function(indexer) {
+            var propertyValue = mapInputCallback(rootObject[indexer]);
+
+            switch (typeof propertyValue) {
+                case "boolean":
+                case "number":
+                case "string":
+                case "function":
+                    outputProperties[indexer] = propertyValue;
+                    break;
+                case "object":
+                case "undefined":
+                    var previouslyMappedValue = visitedObjects.get(propertyValue);
+                    outputProperties[indexer] = (previouslyMappedValue !== undefined)
+                        ? previouslyMappedValue
+                        : mapJsObjectGraph(propertyValue, mapInputCallback, visitedObjects);
+                    break;
+            }
+        });
+
+        return outputProperties;
+    }
+
+    function visitPropertiesOrArrayEntries(rootObject, visitorCallback) {
+        if (rootObject instanceof Array) {
+            for (var i = 0; i < rootObject.length; i++)
+                visitorCallback(i);
+
+            // For arrays, also respect toJSON property for custom mappings (fixes #278)
+            if (typeof rootObject['toJSON'] == 'function')
+                visitorCallback('toJSON');
+        } else {
+            for (var propertyName in rootObject) {
+                visitorCallback(propertyName);
+            }
+        }
+    };
+
+    function objectLookup() {
+        this.keys = [];
+        this.values = [];
+    };
+
+    objectLookup.prototype = {
+        constructor: objectLookup,
+        save: function(key, value) {
+            var existingIndex = ko.utils.arrayIndexOf(this.keys, key);
+            if (existingIndex >= 0)
+                this.values[existingIndex] = value;
+            else {
+                this.keys.push(key);
+                this.values.push(value);
+            }
+        },
+        get: function(key) {
+            var existingIndex = ko.utils.arrayIndexOf(this.keys, key);
+            return (existingIndex >= 0) ? this.values[existingIndex] : undefined;
+        }
+    };
+})();
+
+ko.exportSymbol('toJS', ko.toJS);
+ko.exportSymbol('toJSON', ko.toJSON);
+(function () {
+    var hasDomDataExpandoProperty = '__ko__hasDomDataOptionValue__';
+
+    // Normally, SELECT elements and their OPTIONs can only take value of type 'string' (because the values
+    // are stored on DOM attributes). ko.selectExtensions provides a way for SELECTs/OPTIONs to have values
+    // that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns.
+    ko.selectExtensions = {
+        readValue : function(element) {
+            switch (ko.utils.tagNameLower(element)) {
+                case 'option':
+                    if (element[hasDomDataExpandoProperty] === true)
+                        return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey);
+                    return ko.utils.ieVersion <= 7
+                        ? (element.getAttributeNode('value') && element.getAttributeNode('value').specified ? element.value : element.text)
+                        : element.value;
+                case 'select':
+                    return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined;
+                default:
+                    return element.value;
+            }
+        },
+
+        writeValue: function(element, value, allowUnset) {
+            switch (ko.utils.tagNameLower(element)) {
+                case 'option':
+                    switch(typeof value) {
+                        case "string":
+                            ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined);
+                            if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node
+                                delete element[hasDomDataExpandoProperty];
+                            }
+                            element.value = value;
+                            break;
+                        default:
+                            // Store arbitrary object using DomData
+                            ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value);
+                            element[hasDomDataExpandoProperty] = true;
+
+                            // Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value.
+                            element.value = typeof value === "number" ? value : "";
+                            break;
+                    }
+                    break;
+                case 'select':
+                    if (value === "" || value === null)       // A blank string or null value will select the caption
+                        value = undefined;
+                    var selection = -1;
+                    for (var i = 0, n = element.options.length, optionValue; i < n; ++i) {
+                        optionValue = ko.selectExtensions.readValue(element.options[i]);
+                        // Include special check to handle selecting a caption with a blank string value
+                        if (optionValue == value || (optionValue == "" && value === undefined)) {
+                            selection = i;
+                            break;
+                        }
+                    }
+                    if (allowUnset || selection >= 0 || (value === undefined && element.size > 1)) {
+                        element.selectedIndex = selection;
+                    }
+                    break;
+                default:
+                    if ((value === null) || (value === undefined))
+                        value = "";
+                    element.value = value;
+                    break;
+            }
+        }
+    };
+})();
+
+ko.exportSymbol('selectExtensions', ko.selectExtensions);
+ko.exportSymbol('selectExtensions.readValue', ko.selectExtensions.readValue);
+ko.exportSymbol('selectExtensions.writeValue', ko.selectExtensions.writeValue);
+ko.expressionRewriting = (function () {
+    var javaScriptReservedWords = ["true", "false", "null", "undefined"];
+
+    // Matches something that can be assigned to--either an isolated identifier or something ending with a property accessor
+    // This is designed to be simple and avoid false negatives, but could produce false positives (e.g., a+b.c).
+    // This also will not properly handle nested brackets (e.g., obj1[obj2['prop']]; see #911).
+    var javaScriptAssignmentTarget = /^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i;
+
+    function getWriteableValue(expression) {
+        if (ko.utils.arrayIndexOf(javaScriptReservedWords, expression) >= 0)
+            return false;
+        var match = expression.match(javaScriptAssignmentTarget);
+        return match === null ? false : match[1] ? ('Object(' + match[1] + ')' + match[2]) : expression;
+    }
+
+    // The following regular expressions will be used to split an object-literal string into tokens
+
+        // These two match strings, either with double quotes or single quotes
+    var stringDouble = '"(?:[^"\\\\]|\\\\.)*"',
+        stringSingle = "'(?:[^'\\\\]|\\\\.)*'",
+        // Matches a regular expression (text enclosed by slashes), but will also match sets of divisions
+        // as a regular expression (this is handled by the parsing loop below).
+        stringRegexp = '/(?:[^/\\\\]|\\\\.)*/\w*',
+        // These characters have special meaning to the parser and must not appear in the middle of a
+        // token, except as part of a string.
+        specials = ',"\'{}()/:[\\]',
+        // Match text (at least two characters) that does not contain any of the above special characters,
+        // although some of the special characters are allowed to start it (all but the colon and comma).
+        // The text can contain spaces, but leading or trailing spaces are skipped.
+        everyThingElse = '[^\\s:,/][^' + specials + ']*[^\\s' + specials + ']',
+        // Match any non-space character not matched already. This will match colons and commas, since they're
+        // not matched by "everyThingElse", but will also match any other single character that wasn't already
+        // matched (for example: in "a: 1, b: 2", each of the non-space characters will be matched by oneNotSpace).
+        oneNotSpace = '[^\\s]',
+
+        // Create the actual regular expression by or-ing the above strings. The order is important.
+        bindingToken = RegExp(stringDouble + '|' + stringSingle + '|' + stringRegexp + '|' + everyThingElse + '|' + oneNotSpace, 'g'),
+
+        // Match end of previous token to determine whether a slash is a division or regex.
+        divisionLookBehind = /[\])"'A-Za-z0-9_$]+$/,
+        keywordRegexLookBehind = {'in':1,'return':1,'typeof':1};
+
+    function parseObjectLiteral(objectLiteralString) {
+        // Trim leading and trailing spaces from the string
+        var str = ko.utils.stringTrim(objectLiteralString);
+
+        // Trim braces '{' surrounding the whole object literal
+        if (str.charCodeAt(0) === 123) str = str.slice(1, -1);
+
+        // Split into tokens
+        var result = [], toks = str.match(bindingToken), key, values, depth = 0;
+
+        if (toks) {
+            // Append a comma so that we don't need a separate code block to deal with the last item
+            toks.push(',');
+
+            for (var i = 0, tok; tok = toks[i]; ++i) {
+                var c = tok.charCodeAt(0);
+                // A comma signals the end of a key/value pair if depth is zero
+                if (c === 44) { // ","
+                    if (depth <= 0) {
+                        if (key)
+                            result.push(values ? {key: key, value: values.join('')} : {'unknown': key});
+                        key = values = depth = 0;
+                        continue;
+                    }
+                // Simply skip the colon that separates the name and value
+                } else if (c === 58) { // ":"
+                    if (!values)
+                        continue;
+                // A set of slashes is initially matched as a regular expression, but could be division
+                } else if (c === 47 && i && tok.length > 1) {  // "/"
+                    // Look at the end of the previous token to determine if the slash is actually division
+                    var match = toks[i-1].match(divisionLookBehind);
+                    if (match && !keywordRegexLookBehind[match[0]]) {
+                        // The slash is actually a division punctuator; re-parse the remainder of the string (not including the slash)
+                        str = str.substr(str.indexOf(tok) + 1);
+                        toks = str.match(bindingToken);
+                        toks.push(',');
+                        i = -1;
+                        // Continue with just the slash
+                        tok = '/';
+                    }
+                // Increment depth for parentheses, braces, and brackets so that interior commas are ignored
+                } else if (c === 40 || c === 123 || c === 91) { // '(', '{', '['
+                    ++depth;
+                } else if (c === 41 || c === 125 || c === 93) { // ')', '}', ']'
+                    --depth;
+                // The key must be a single token; if it's a string, trim the quotes
+                } else if (!key && !values) {
+                    key = (c === 34 || c === 39) /* '"', "'" */ ? tok.slice(1, -1) : tok;
+                    continue;
+                }
+                if (values)
+                    values.push(tok);
+                else
+                    values = [tok];
+            }
+        }
+        return result;
+    }
+
+    // Two-way bindings include a write function that allow the handler to update the value even if it's not an observable.
+    var twoWayBindings = {};
+
+    function preProcessBindings(bindingsStringOrKeyValueArray, bindingOptions) {
+        bindingOptions = bindingOptions || {};
+
+        function processKeyValue(key, val) {
+            var writableVal;
+            function callPreprocessHook(obj) {
+                return (obj && obj['preprocess']) ? (val = obj['preprocess'](val, key, processKeyValue)) : true;
+            }
+            if (!bindingParams) {
+                if (!callPreprocessHook(ko['getBindingHandler'](key)))
+                    return;
+
+                if (twoWayBindings[key] && (writableVal = getWriteableValue(val))) {
+                    // For two-way bindings, provide a write method in case the value
+                    // isn't a writable observable.
+                    propertyAccessorResultStrings.push("'" + key + "':function(_z){" + writableVal + "=_z}");
+                }
+            }
+            // Values are wrapped in a function so that each value can be accessed independently
+            if (makeValueAccessors) {
+                val = 'function(){return ' + val + ' }';
+            }
+            resultStrings.push("'" + key + "':" + val);
+        }
+
+        var resultStrings = [],
+            propertyAccessorResultStrings = [],
+            makeValueAccessors = bindingOptions['valueAccessors'],
+            bindingParams = bindingOptions['bindingParams'],
+            keyValueArray = typeof bindingsStringOrKeyValueArray === "string" ?
+                parseObjectLiteral(bindingsStringOrKeyValueArray) : bindingsStringOrKeyValueArray;
+
+        ko.utils.arrayForEach(keyValueArray, function(keyValue) {
+            processKeyValue(keyValue.key || keyValue['unknown'], keyValue.value);
+        });
+
+        if (propertyAccessorResultStrings.length)
+            processKeyValue('_ko_property_writers', "{" + propertyAccessorResultStrings.join(",") + " }");
+
+        return resultStrings.join(",");
+    }
+
+    return {
+        bindingRewriteValidators: [],
+
+        twoWayBindings: twoWayBindings,
+
+        parseObjectLiteral: parseObjectLiteral,
+
+        preProcessBindings: preProcessBindings,
+
+        keyValueArrayContainsKey: function(keyValueArray, key) {
+            for (var i = 0; i < keyValueArray.length; i++)
+                if (keyValueArray[i]['key'] == key)
+                    return true;
+            return false;
+        },
+
+        // Internal, private KO utility for updating model properties from within bindings
+        // property:            If the property being updated is (or might be) an observable, pass it here
+        //                      If it turns out to be a writable observable, it will be written to directly
+        // allBindings:         An object with a get method to retrieve bindings in the current execution context.
+        //                      This will be searched for a '_ko_property_writers' property in case you're writing to a non-observable
+        // key:                 The key identifying the property to be written. Example: for { hasFocus: myValue }, write to 'myValue' by specifying the key 'hasFocus'
+        // value:               The value to be written
+        // checkIfDifferent:    If true, and if the property being written is a writable observable, the value will only be written if
+        //                      it is !== existing value on that writable observable
+        writeValueToProperty: function(property, allBindings, key, value, checkIfDifferent) {
+            if (!property || !ko.isObservable(property)) {
+                var propWriters = allBindings.get('_ko_property_writers');
+                if (propWriters && propWriters[key])
+                    propWriters[key](value);
+            } else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) {
+                property(value);
+            }
+        }
+    };
+})();
+
+ko.exportSymbol('expressionRewriting', ko.expressionRewriting);
+ko.exportSymbol('expressionRewriting.bindingRewriteValidators', ko.expressionRewriting.bindingRewriteValidators);
+ko.exportSymbol('expressionRewriting.parseObjectLiteral', ko.expressionRewriting.parseObjectLiteral);
+ko.exportSymbol('expressionRewriting.preProcessBindings', ko.expressionRewriting.preProcessBindings);
+
+// Making bindings explicitly declare themselves as "two way" isn't ideal in the long term (it would be better if
+// all bindings could use an official 'property writer' API without needing to declare that they might). However,
+// since this is not, and has never been, a public API (_ko_property_writers was never documented), it's acceptable
+// as an internal implementation detail in the short term.
+// For those developers who rely on _ko_property_writers in their custom bindings, we expose _twoWayBindings as an
+// undocumented feature that makes it relatively easy to upgrade to KO 3.0. However, this is still not an official
+// public API, and we reserve the right to remove it at any time if we create a real public property writers API.
+ko.exportSymbol('expressionRewriting._twoWayBindings', ko.expressionRewriting.twoWayBindings);
+
+// For backward compatibility, define the following aliases. (Previously, these function names were misleading because
+// they referred to JSON specifically, even though they actually work with arbitrary JavaScript object literal expressions.)
+ko.exportSymbol('jsonExpressionRewriting', ko.expressionRewriting);
+ko.exportSymbol('jsonExpressionRewriting.insertPropertyAccessorsIntoJson', ko.expressionRewriting.preProcessBindings);
+(function() {
+    // "Virtual elements" is an abstraction on top of the usual DOM API which understands the notion that comment nodes
+    // may be used to represent hierarchy (in addition to the DOM's natural hierarchy).
+    // If you call the DOM-manipulating functions on ko.virtualElements, you will be able to read and write the state
+    // of that virtual hierarchy
+    //
+    // The point of all this is to support containerless templates (e.g., <!-- ko foreach:someCollection -->blah<!-- /ko -->)
+    // without having to scatter special cases all over the binding and templating code.
+
+    // IE 9 cannot reliably read the "nodeValue" property of a comment node (see https://github.com/SteveSanderson/knockout/issues/186)
+    // but it does give them a nonstandard alternative property called "text" that it can read reliably. Other browsers don't have that property.
+    // So, use node.text where available, and node.nodeValue elsewhere
+    var commentNodesHaveTextProperty = document && document.createComment("test").text === "<!--test-->";
+
+    var startCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*ko(?:\s+([\s\S]+))?\s*-->$/ : /^\s*ko(?:\s+([\s\S]+))?\s*$/;
+    var endCommentRegex =   commentNodesHaveTextProperty ? /^<!--\s*\/ko\s*-->$/ : /^\s*\/ko\s*$/;
+    var htmlTagsWithOptionallyClosingChildren = { 'ul': true, 'ol': true };
+
+    function isStartComment(node) {
+        return (node.nodeType == 8) && startCommentRegex.test(commentNodesHaveTextProperty ? node.text : node.nodeValue);
+    }
+
+    function isEndComment(node) {
+        return (node.nodeType == 8) && endCommentRegex.test(commentNodesHaveTextProperty ? node.text : node.nodeValue);
+    }
+
+    function getVirtualChildren(startComment, allowUnbalanced) {
+        var currentNode = startComment;
+        var depth = 1;
+        var children = [];
+        while (currentNode = currentNode.nextSibling) {
+            if (isEndComment(currentNode)) {
+                depth--;
+                if (depth === 0)
+                    return children;
+            }
+
+            children.push(currentNode);
+
+            if (isStartComment(currentNode))
+                depth++;
+        }
+        if (!allowUnbalanced)
+            throw new Error("Cannot find closing comment tag to match: " + startComment.nodeValue);
+        return null;
+    }
+
+    function getMatchingEndComment(startComment, allowUnbalanced) {
+        var allVirtualChildren = getVirtualChildren(startComment, allowUnbalanced);
+        if (allVirtualChildren) {
+            if (allVirtualChildren.length > 0)
+                return allVirtualChildren[allVirtualChildren.length - 1].nextSibling;
+            return startComment.nextSibling;
+        } else
+            return null; // Must have no matching end comment, and allowUnbalanced is true
+    }
+
+    function getUnbalancedChildTags(node) {
+        // e.g., from <div>OK</div><!-- ko blah --><span>Another</span>, returns: <!-- ko blah --><span>Another</span>
+        //       from <div>OK</div><!-- /ko --><!-- /ko -->,             returns: <!-- /ko --><!-- /ko -->
+        var childNode = node.firstChild, captureRemaining = null;
+        if (childNode) {
+            do {
+                if (captureRemaining)                   // We already hit an unbalanced node and are now just scooping up all subsequent nodes
+                    captureRemaining.push(childNode);
+                else if (isStartComment(childNode)) {
+                    var matchingEndComment = getMatchingEndComment(childNode, /* allowUnbalanced: */ true);
+                    if (matchingEndComment)             // It's a balanced tag, so skip immediately to the end of this virtual set
+                        childNode = matchingEndComment;
+                    else
+                        captureRemaining = [childNode]; // It's unbalanced, so start capturing from this point
+                } else if (isEndComment(childNode)) {
+                    captureRemaining = [childNode];     // It's unbalanced (if it wasn't, we'd have skipped over it already), so start capturing
+                }
+            } while (childNode = childNode.nextSibling);
+        }
+        return captureRemaining;
+    }
+
+    ko.virtualElements = {
+        allowedBindings: {},
+
+        childNodes: function(node) {
+            return isStartComment(node) ? getVirtualChildren(node) : node.childNodes;
+        },
+
+        emptyNode: function(node) {
+            if (!isStartComment(node))
+                ko.utils.emptyDomNode(node);
+            else {
+                var virtualChildren = ko.virtualElements.childNodes(node);
+                for (var i = 0, j = virtualChildren.length; i < j; i++)
+                    ko.removeNode(virtualChildren[i]);
+            }
+        },
+
+        setDomNodeChildren: function(node, childNodes) {
+            if (!isStartComment(node))
+                ko.utils.setDomNodeChildren(node, childNodes);
+            else {
+                ko.virtualElements.emptyNode(node);
+                var endCommentNode = node.nextSibling; // Must be the next sibling, as we just emptied the children
+                for (var i = 0, j = childNodes.length; i < j; i++)
+                    endCommentNode.parentNode.insertBefore(childNodes[i], endCommentNode);
+            }
+        },
+
+        prepend: function(containerNode, nodeToPrepend) {
+            if (!isStartComment(containerNode)) {
+                if (containerNode.firstChild)
+                    containerNode.insertBefore(nodeToPrepend, containerNode.firstChild);
+                else
+                    containerNode.appendChild(nodeToPrepend);
+            } else {
+                // Start comments must always have a parent and at least one following sibling (the end comment)
+                containerNode.parentNode.insertBefore(nodeToPrepend, containerNode.nextSibling);
+            }
+        },
+
+        insertAfter: function(containerNode, nodeToInsert, insertAfterNode) {
+            if (!insertAfterNode) {
+                ko.virtualElements.prepend(containerNode, nodeToInsert);
+            } else if (!isStartComment(containerNode)) {
+                // Insert after insertion point
+                if (insertAfterNode.nextSibling)
+                    containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling);
+                else
+                    containerNode.appendChild(nodeToInsert);
+            } else {
+                // Children of start comments must always have a parent and at least one following sibling (the end comment)
+                containerNode.parentNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling);
+            }
+        },
+
+        firstChild: function(node) {
+            if (!isStartComment(node))
+                return node.firstChild;
+            if (!node.nextSibling || isEndComment(node.nextSibling))
+                return null;
+            return node.nextSibling;
+        },
+
+        nextSibling: function(node) {
+            if (isStartComment(node))
+                node = getMatchingEndComment(node);
+            if (node.nextSibling && isEndComment(node.nextSibling))
+                return null;
+            return node.nextSibling;
+        },
+
+        hasBindingValue: isStartComment,
+
+        virtualNodeBindingValue: function(node) {
+            var regexMatch = (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(startCommentRegex);
+            return regexMatch ? regexMatch[1] : null;
+        },
+
+        normaliseVirtualElementDomStructure: function(elementVerified) {
+            // Workaround for https://github.com/SteveSanderson/knockout/issues/155
+            // (IE <= 8 or IE 9 quirks mode parses your HTML weirdly, treating closing </li> tags as if they don't exist, thereby moving comment nodes
+            // that are direct descendants of <ul> into the preceding <li>)
+            if (!htmlTagsWithOptionallyClosingChildren[ko.utils.tagNameLower(elementVerified)])
+                return;
+
+            // Scan immediate children to see if they contain unbalanced comment tags. If they do, those comment tags
+            // must be intended to appear *after* that child, so move them there.
+            var childNode = elementVerified.firstChild;
+            if (childNode) {
+                do {
+                    if (childNode.nodeType === 1) {
+                        var unbalancedTags = getUnbalancedChildTags(childNode);
+                        if (unbalancedTags) {
+                            // Fix up the DOM by moving the unbalanced tags to where they most likely were intended to be placed - *after* the child
+                            var nodeToInsertBefore = childNode.nextSibling;
+                            for (var i = 0; i < unbalancedTags.length; i++) {
+                                if (nodeToInsertBefore)
+                                    elementVerified.insertBefore(unbalancedTags[i], nodeToInsertBefore);
+                                else
+                                    elementVerified.appendChild(unbalancedTags[i]);
+                            }
+                        }
+                    }
+                } while (childNode = childNode.nextSibling);
+            }
+        }
+    };
+})();
+ko.exportSymbol('virtualElements', ko.virtualElements);
+ko.exportSymbol('virtualElements.allowedBindings', ko.virtualElements.allowedBindings);
+ko.exportSymbol('virtualElements.emptyNode', ko.virtualElements.emptyNode);
+//ko.exportSymbol('virtualElements.firstChild', ko.virtualElements.firstChild);     // firstChild is not minified
+ko.exportSymbol('virtualElements.insertAfter', ko.virtualElements.insertAfter);
+//ko.exportSymbol('virtualElements.nextSibling', ko.virtualElements.nextSibling);   // nextSibling is not minified
+ko.exportSymbol('virtualElements.prepend', ko.virtualElements.prepend);
+ko.exportSymbol('virtualElements.setDomNodeChildren', ko.virtualElements.setDomNodeChildren);
+(function() {
+    var defaultBindingAttributeName = "data-bind";
+
+    ko.bindingProvider = function() {
+        this.bindingCache = {};
+    };
+
+    ko.utils.extend(ko.bindingProvider.prototype, {
+        'nodeHasBindings': function(node) {
+            switch (node.nodeType) {
+                case 1: // Element
+                    return node.getAttribute(defaultBindingAttributeName) != null
+                        || ko.components['getComponentNameForNode'](node);
+                case 8: // Comment node
+                    return ko.virtualElements.hasBindingValue(node);
+                default: return false;
+            }
+        },
+
+        'getBindings': function(node, bindingContext) {
+            var bindingsString = this['getBindingsString'](node, bindingContext),
+                parsedBindings = bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node) : null;
+            return ko.components.addBindingsForCustomElement(parsedBindings, node, bindingContext, /* valueAccessors */ false);
+        },
+
+        'getBindingAccessors': function(node, bindingContext) {
+            var bindingsString = this['getBindingsString'](node, bindingContext),
+                parsedBindings = bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node, { 'valueAccessors': true }) : null;
+            return ko.components.addBindingsForCustomElement(parsedBindings, node, bindingContext, /* valueAccessors */ true);
+        },
+
+        // The following function is only used internally by this default provider.
+        // It's not part of the interface definition for a general binding provider.
+        'getBindingsString': function(node, bindingContext) {
+            switch (node.nodeType) {
+                case 1: return node.getAttribute(defaultBindingAttributeName);   // Element
+                case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node
+                default: return null;
+            }
+        },
+
+        // The following function is only used internally by this default provider.
+        // It's not part of the interface definition for a general binding provider.
+        'parseBindingsString': function(bindingsString, bindingContext, node, options) {
+            try {
+                var bindingFunction = createBindingsStringEvaluatorViaCache(bindingsString, this.bindingCache, options);
+                return bindingFunction(bindingContext, node);
+            } catch (ex) {
+                ex.message = "Unable to parse bindings.\nBindings value: " + bindingsString + "\nMessage: " + ex.message;
+                throw ex;
+            }
+        }
+    });
+
+    ko.bindingProvider['instance'] = new ko.bindingProvider();
+
+    function createBindingsStringEvaluatorViaCache(bindingsString, cache, options) {
+        var cacheKey = bindingsString + (options && options['valueAccessors'] || '');
+        return cache[cacheKey]
+            || (cache[cacheKey] = createBindingsStringEvaluator(bindingsString, options));
+    }
+
+    function createBindingsStringEvaluator(bindingsString, options) {
+        // Build the source for a function that evaluates "expression"
+        // For each scope variable, add an extra level of "with" nesting
+        // Example result: with(sc1) { with(sc0) { return (expression) } }
+        var rewrittenBindings = ko.expressionRewriting.preProcessBindings(bindingsString, options),
+            functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}";
+        return new Function("$context", "$element", functionBody);
+    }
+})();
+
+ko.exportSymbol('bindingProvider', ko.bindingProvider);
+(function () {
+    ko.bindingHandlers = {};
+
+    // The following element types will not be recursed into during binding. In the future, we
+    // may consider adding <template> to this list, because such elements' contents are always
+    // intended to be bound in a different context from where they appear in the document.
+    var bindingDoesNotRecurseIntoElementTypes = {
+        // Don't want bindings that operate on text nodes to mutate <script> contents,
+        // because it's unexpected and a potential XSS issue
+        'script': true
+    };
+
+    // Use an overridable method for retrieving binding handlers so that a plugins may support dynamically created handlers
+    ko['getBindingHandler'] = function(bindingKey) {
+        return ko.bindingHandlers[bindingKey];
+    };
+
+    // The ko.bindingContext constructor is only called directly to create the root context. For child
+    // contexts, use bindingContext.createChildContext or bindingContext.extend.
+    ko.bindingContext = function(dataItemOrAccessor, parentContext, dataItemAlias, extendCallback) {
+
+        // The binding context object includes static properties for the current, parent, and root view models.
+        // If a view model is actually stored in an observable, the corresponding binding context object, and
+        // any child contexts, must be updated when the view model is changed.
+        function updateContext() {
+            // Most of the time, the context will directly get a view model object, but if a function is given,
+            // we call the function to retrieve the view model. If the function accesses any obsevables or returns
+            // an observable, the dependency is tracked, and those observables can later cause the binding
+            // context to be updated.
+            var dataItemOrObservable = isFunc ? dataItemOrAccessor() : dataItemOrAccessor,
+                dataItem = ko.utils.unwrapObservable(dataItemOrObservable);
+
+            if (parentContext) {
+                // When a "parent" context is given, register a dependency on the parent context. Thus whenever the
+                // parent context is updated, this context will also be updated.
+                if (parentContext._subscribable)
+                    parentContext._subscribable();
+
+                // Copy $root and any custom properties from the parent context
+                ko.utils.extend(self, parentContext);
+
+                // Because the above copy overwrites our own properties, we need to reset them.
+                // During the first execution, "subscribable" isn't set, so don't bother doing the update then.
+                if (subscribable) {
+                    self._subscribable = subscribable;
+                }
+            } else {
+                self['$parents'] = [];
+                self['$root'] = dataItem;
+
+                // Export 'ko' in the binding context so it will be available in bindings and templates
+                // even if 'ko' isn't exported as a global, such as when using an AMD loader.
+                // See https://github.com/SteveSanderson/knockout/issues/490
+                self['ko'] = ko;
+            }
+            self['$rawData'] = dataItemOrObservable;
+            self['$data'] = dataItem;
+            if (dataItemAlias)
+                self[dataItemAlias] = dataItem;
+
+            // The extendCallback function is provided when creating a child context or extending a context.
+            // It handles the specific actions needed to finish setting up the binding context. Actions in this
+            // function could also add dependencies to this binding context.
+            if (extendCallback)
+                extendCallback(self, parentContext, dataItem);
+
+            return self['$data'];
+        }
+        function disposeWhen() {
+            return nodes && !ko.utils.anyDomNodeIsAttachedToDocument(nodes);
+        }
+
+        var self = this,
+            isFunc = typeof(dataItemOrAccessor) == "function" && !ko.isObservable(dataItemOrAccessor),
+            nodes,
+            subscribable = ko.dependentObservable(updateContext, null, { disposeWhen: disposeWhen, disposeWhenNodeIsRemoved: true });
+
+        // At this point, the binding context has been initialized, and the "subscribable" computed observable is
+        // subscribed to any observables that were accessed in the process. If there is nothing to track, the
+        // computed will be inactive, and we can safely throw it away. If it's active, the computed is stored in
+        // the context object.
+        if (subscribable.isActive()) {
+            self._subscribable = subscribable;
+
+            // Always notify because even if the model ($data) hasn't changed, other context properties might have changed
+            subscribable['equalityComparer'] = null;
+
+            // We need to be able to dispose of this computed observable when it's no longer needed. This would be
+            // easy if we had a single node to watch, but binding contexts can be used by many different nodes, and
+            // we cannot assume that those nodes have any relation to each other. So instead we track any node that
+            // the context is attached to, and dispose the computed when all of those nodes have been cleaned.
+
+            // Add properties to *subscribable* instead of *self* because any properties added to *self* may be overwritten on updates
+            nodes = [];
+            subscribable._addNode = function(node) {
+                nodes.push(node);
+                ko.utils.domNodeDisposal.addDisposeCallback(node, function(node) {
+                    ko.utils.arrayRemoveItem(nodes, node);
+                    if (!nodes.length) {
+                        subscribable.dispose();
+                        self._subscribable = subscribable = undefined;
+                    }
+                });
+            };
+        }
+    }
+
+    // Extend the binding context hierarchy with a new view model object. If the parent context is watching
+    // any obsevables, the new child context will automatically get a dependency on the parent context.
+    // But this does not mean that the $data value of the child context will also get updated. If the child
+    // view model also depends on the parent view model, you must provide a function that returns the correct
+    // view model on each update.
+    ko.bindingContext.prototype['createChildContext'] = function (dataItemOrAccessor, dataItemAlias, extendCallback) {
+        return new ko.bindingContext(dataItemOrAccessor, this, dataItemAlias, function(self, parentContext) {
+            // Extend the context hierarchy by setting the appropriate pointers
+            self['$parentContext'] = parentContext;
+            self['$parent'] = parentContext['$data'];
+            self['$parents'] = (parentContext['$parents'] || []).slice(0);
+            self['$parents'].unshift(self['$parent']);
+            if (extendCallback)
+                extendCallback(self);
+        });
+    };
+
+    // Extend the binding context with new custom properties. This doesn't change the context hierarchy.
+    // Similarly to "child" contexts, provide a function here to make sure that the correct values are set
+    // when an observable view model is updated.
+    ko.bindingContext.prototype['extend'] = function(properties) {
+        // If the parent context references an observable view model, "_subscribable" will always be the
+        // latest view model object. If not, "_subscribable" isn't set, and we can use the static "$data" value.
+        return new ko.bindingContext(this._subscribable || this['$data'], this, null, function(self, parentContext) {
+            // This "child" context doesn't directly track a parent observable view model,
+            // so we need to manually set the $rawData value to match the parent.
+            self['$rawData'] = parentContext['$rawData'];
+            ko.utils.extend(self, typeof(properties) == "function" ? properties() : properties);
+        });
+    };
+
+    // Returns the valueAccesor function for a binding value
+    function makeValueAccessor(value) {
+        return function() {
+            return value;
+        };
+    }
+
+    // Returns the value of a valueAccessor function
+    function evaluateValueAccessor(valueAccessor) {
+        return valueAccessor();
+    }
+
+    // Given a function that returns bindings, create and return a new object that contains
+    // binding value-accessors functions. Each accessor function calls the original function
+    // so that it always gets the latest value and all dependencies are captured. This is used
+    // by ko.applyBindingsToNode and getBindingsAndMakeAccessors.
+    function makeAccessorsFromFunction(callback) {
+        return ko.utils.objectMap(ko.dependencyDetection.ignore(callback), function(value, key) {
+            return function() {
+                return callback()[key];
+            };
+        });
+    }
+
+    // Given a bindings function or object, create and return a new object that contains
+    // binding value-accessors functions. This is used by ko.applyBindingsToNode.
+    function makeBindingAccessors(bindings, context, node) {
+        if (typeof bindings === 'function') {
+            return makeAccessorsFromFunction(bindings.bind(null, context, node));
+        } else {
+            return ko.utils.objectMap(bindings, makeValueAccessor);
+        }
+    }
+
+    // This function is used if the binding provider doesn't include a getBindingAccessors function.
+    // It must be called with 'this' set to the provider instance.
+    function getBindingsAndMakeAccessors(node, context) {
+        return makeAccessorsFromFunction(this['getBindings'].bind(this, node, context));
+    }
+
+    function validateThatBindingIsAllowedForVirtualElements(bindingName) {
+        var validator = ko.virtualElements.allowedBindings[bindingName];
+        if (!validator)
+            throw new Error("The binding '" + bindingName + "' cannot be used with virtual elements")
+    }
+
+    function applyBindingsToDescendantsInternal (bindingContext, elementOrVirtualElement, bindingContextsMayDifferFromDomParentElement) {
+        var currentChild,
+            nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement),
+            provider = ko.bindingProvider['instance'],
+            preprocessNode = provider['preprocessNode'];
+
+        // Preprocessing allows a binding provider to mutate a node before bindings are applied to it. For example it's
+        // possible to insert new siblings after it, and/or replace the node with a different one. This can be used to
+        // implement custom binding syntaxes, such as {{ value }} for string interpolation, or custom element types that
+        // trigger insertion of <template> contents at that point in the document.
+        if (preprocessNode) {
+            while (currentChild = nextInQueue) {
+                nextInQueue = ko.virtualElements.nextSibling(currentChild);
+                preprocessNode.call(provider, currentChild);
+            }
+            // Reset nextInQueue for the next loop
+            nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement);
+        }
+
+        while (currentChild = nextInQueue) {
+            // Keep a record of the next child *before* applying bindings, in case the binding removes the current child from its position
+            nextInQueue = ko.virtualElements.nextSibling(currentChild);
+            applyBindingsToNodeAndDescendantsInternal(bindingContext, currentChild, bindingContextsMayDifferFromDomParentElement);
+        }
+    }
+
+    function applyBindingsToNodeAndDescendantsInternal (bindingContext, nodeVerified, bindingContextMayDifferFromDomParentElement) {
+        var shouldBindDescendants = true;
+
+        // Perf optimisation: Apply bindings only if...
+        // (1) We need to store the binding context on this node (because it may differ from the DOM parent node's binding context)
+        //     Note that we can't store binding contexts on non-elements (e.g., text nodes), as IE doesn't allow expando properties for those
+        // (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template)
+        var isElement = (nodeVerified.nodeType === 1);
+        if (isElement) // Workaround IE <= 8 HTML parsing weirdness
+            ko.virtualElements.normaliseVirtualElementDomStructure(nodeVerified);
+
+        var shouldApplyBindings = (isElement && bindingContextMayDifferFromDomParentElement)             // Case (1)
+                               || ko.bindingProvider['instance']['nodeHasBindings'](nodeVerified);       // Case (2)
+        if (shouldApplyBindings)
+            shouldBindDescendants = applyBindingsToNodeInternal(nodeVerified, null, bindingContext, bindingContextMayDifferFromDomParentElement)['shouldBindDescendants'];
+
+        if (shouldBindDescendants && !bindingDoesNotRecurseIntoElementTypes[ko.utils.tagNameLower(nodeVerified)]) {
+            // We're recursing automatically into (real or virtual) child nodes without changing binding contexts. So,
+            //  * For children of a *real* element, the binding context is certainly the same as on their DOM .parentNode,
+            //    hence bindingContextsMayDifferFromDomParentElement is false
+            //  * For children of a *virtual* element, we can't be sure. Evaluating .parentNode on those children may
+            //    skip over any number of intermediate virtual elements, any of which might define a custom binding context,
+            //    hence bindingContextsMayDifferFromDomParentElement is true
+            applyBindingsToDescendantsInternal(bindingContext, nodeVerified, /* bindingContextsMayDifferFromDomParentElement: */ !isElement);
+        }
+    }
+
+    var boundElementDomDataKey = ko.utils.domData.nextKey();
+
+
+    function topologicalSortBindings(bindings) {
+        // Depth-first sort
+        var result = [],                // The list of key/handler pairs that we will return
+            bindingsConsidered = {},    // A temporary record of which bindings are already in 'result'
+            cyclicDependencyStack = []; // Keeps track of a depth-search so that, if there's a cycle, we know which bindings caused it
+        ko.utils.objectForEach(bindings, function pushBinding(bindingKey) {
+            if (!bindingsConsidered[bindingKey]) {
+                var binding = ko['getBindingHandler'](bindingKey);
+                if (binding) {
+                    // First add dependencies (if any) of the current binding
+                    if (binding['after']) {
+                        cyclicDependencyStack.push(bindingKey);
+                        ko.utils.arrayForEach(binding['after'], function(bindingDependencyKey) {
+                            if (bindings[bindingDependencyKey]) {
+                                if (ko.utils.arrayIndexOf(cyclicDependencyStack, bindingDependencyKey) !== -1) {
+                                    throw Error("Cannot combine the following bindings, because they have a cyclic dependency: " + cyclicDependencyStack.join(", "));
+                                } else {
+                                    pushBinding(bindingDependencyKey);
+                                }
+                            }
+                        });
+                        cyclicDependencyStack.length--;
+                    }
+                    // Next add the current binding
+                    result.push({ key: bindingKey, handler: binding });
+                }
+                bindingsConsidered[bindingKey] = true;
+            }
+        });
+
+        return result;
+    }
+
+    function applyBindingsToNodeInternal(node, sourceBindings, bindingContext, bindingContextMayDifferFromDomParentElement) {
+        // Prevent multiple applyBindings calls for the same node, except when a binding value is specified
+        var alreadyBound = ko.utils.domData.get(node, boundElementDomDataKey);
+        if (!sourceBindings) {
+            if (alreadyBound) {
+                throw Error("You cannot apply bindings multiple times to the same element.");
+            }
+            ko.utils.domData.set(node, boundElementDomDataKey, true);
+        }
+
+        // Optimization: Don't store the binding context on this node if it's definitely the same as on node.parentNode, because
+        // we can easily recover it just by scanning up the node's ancestors in the DOM
+        // (note: here, parent node means "real DOM parent" not "virtual parent", as there's no O(1) way to find the virtual parent)
+        if (!alreadyBound && bindingContextMayDifferFromDomParentElement)
+            ko.storedBindingContextForNode(node, bindingContext);
+
+        // Use bindings if given, otherwise fall back on asking the bindings provider to give us some bindings
+        var bindings;
+        if (sourceBindings && typeof sourceBindings !== 'function') {
+            bindings = sourceBindings;
+        } else {
+            var provider = ko.bindingProvider['instance'],
+                getBindings = provider['getBindingAccessors'] || getBindingsAndMakeAccessors;
+
+            // Get the binding from the provider within a computed observable so that we can update the bindings whenever
+            // the binding context is updated or if the binding provider accesses observables.
+            var bindingsUpdater = ko.dependentObservable(
+                function() {
+                    bindings = sourceBindings ? sourceBindings(bindingContext, node) : getBindings.call(provider, node, bindingContext);
+                    // Register a dependency on the binding context to support obsevable view models.
+                    if (bindings && bindingContext._subscribable)
+                        bindingContext._subscribable();
+                    return bindings;
+                },
+                null, { disposeWhenNodeIsRemoved: node }
+            );
+
+            if (!bindings || !bindingsUpdater.isActive())
+                bindingsUpdater = null;
+        }
+
+        var bindingHandlerThatControlsDescendantBindings;
+        if (bindings) {
+            // Return the value accessor for a given binding. When bindings are static (won't be updated because of a binding
+            // context update), just return the value accessor from the binding. Otherwise, return a function that always gets
+            // the latest binding value and registers a dependency on the binding updater.
+            var getValueAccessor = bindingsUpdater
+                ? function(bindingKey) {
+                    return function() {
+                        return evaluateValueAccessor(bindingsUpdater()[bindingKey]);
+                    };
+                } : function(bindingKey) {
+                    return bindings[bindingKey];
+                };
+
+            // Use of allBindings as a function is maintained for backwards compatibility, but its use is deprecated
+            function allBindings() {
+                return ko.utils.objectMap(bindingsUpdater ? bindingsUpdater() : bindings, evaluateValueAccessor);
+            }
+            // The following is the 3.x allBindings API
+            allBindings['get'] = function(key) {
+                return bindings[key] && evaluateValueAccessor(getValueAccessor(key));
+            };
+            allBindings['has'] = function(key) {
+                return key in bindings;
+            };
+
+            // First put the bindings into the right order
+            var orderedBindings = topologicalSortBindings(bindings);
+
+            // Go through the sorted bindings, calling init and update for each
+            ko.utils.arrayForEach(orderedBindings, function(bindingKeyAndHandler) {
+                // Note that topologicalSortBindings has already filtered out any nonexistent binding handlers,
+                // so bindingKeyAndHandler.handler will always be nonnull.
+                var handlerInitFn = bindingKeyAndHandler.handler["init"],
+                    handlerUpdateFn = bindingKeyAndHandler.handler["update"],
+                    bindingKey = bindingKeyAndHandler.key;
+
+                if (node.nodeType === 8) {
+                    validateThatBindingIsAllowedForVirtualElements(bindingKey);
+                }
+
+                try {
+                    // Run init, ignoring any dependencies
+                    if (typeof handlerInitFn == "function") {
+                        ko.dependencyDetection.ignore(function() {
+                            var initResult = handlerInitFn(node, getValueAccessor(bindingKey), allBindings, bindingContext['$data'], bindingContext);
+
+                            // If this binding handler claims to control descendant bindings, make a note of this
+                            if (initResult && initResult['controlsDescendantBindings']) {
+                                if (bindingHandlerThatControlsDescendantBindings !== undefined)
+                                    throw new Error("Multiple bindings (" + bindingHandlerThatControlsDescendantBindings + " and " + bindingKey + ") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");
+                                bindingHandlerThatControlsDescendantBindings = bindingKey;
+                            }
+                        });
+                    }
+
+                    // Run update in its own computed wrapper
+                    if (typeof handlerUpdateFn == "function") {
+                        ko.dependentObservable(
+                            function() {
+                                handlerUpdateFn(node, getValueAccessor(bindingKey), allBindings, bindingContext['$data'], bindingContext);
+                            },
+                            null,
+                            { disposeWhenNodeIsRemoved: node }
+                        );
+                    }
+                } catch (ex) {
+                    ex.message = "Unable to process binding \"" + bindingKey + ": " + bindings[bindingKey] + "\"\nMessage: " + ex.message;
+                    throw ex;
+                }
+            });
+        }
+
+        return {
+            'shouldBindDescendants': bindingHandlerThatControlsDescendantBindings === undefined
+        };
+    };
+
+    var storedBindingContextDomDataKey = ko.utils.domData.nextKey();
+    ko.storedBindingContextForNode = function (node, bindingContext) {
+        if (arguments.length == 2) {
+            ko.utils.domData.set(node, storedBindingContextDomDataKey, bindingContext);
+            if (bindingContext._subscribable)
+                bindingContext._subscribable._addNode(node);
+        } else {
+            return ko.utils.domData.get(node, storedBindingContextDomDataKey);
+        }
+    }
+
+    function getBindingContext(viewModelOrBindingContext) {
+        return viewModelOrBindingContext && (viewModelOrBindingContext instanceof ko.bindingContext)
+            ? viewModelOrBindingContext
+            : new ko.bindingContext(viewModelOrBindingContext);
+    }
+
+    ko.applyBindingAccessorsToNode = function (node, bindings, viewModelOrBindingContext) {
+        if (node.nodeType === 1) // If it's an element, workaround IE <= 8 HTML parsing weirdness
+            ko.virtualElements.normaliseVirtualElementDomStructure(node);
+        return applyBindingsToNodeInternal(node, bindings, getBindingContext(viewModelOrBindingContext), true);
+    };
+
+    ko.applyBindingsToNode = function (node, bindings, viewModelOrBindingContext) {
+        var context = getBindingContext(viewModelOrBindingContext);
+        return ko.applyBindingAccessorsToNode(node, makeBindingAccessors(bindings, context, node), context);
+    };
+
+    ko.applyBindingsToDescendants = function(viewModelOrBindingContext, rootNode) {
+        if (rootNode.nodeType === 1 || rootNode.nodeType === 8)
+            applyBindingsToDescendantsInternal(getBindingContext(viewModelOrBindingContext), rootNode, true);
+    };
+
+    ko.applyBindings = function (viewModelOrBindingContext, rootNode) {
+        // If jQuery is loaded after Knockout, we won't initially have access to it. So save it here.
+        if (!jQueryInstance && window['jQuery']) {
+            jQueryInstance = window['jQuery'];
+        }
+
+        if (rootNode && (rootNode.nodeType !== 1) && (rootNode.nodeType !== 8))
+            throw new Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");
+        rootNode = rootNode || window.document.body; // Make "rootNode" parameter optional
+
+        applyBindingsToNodeAndDescendantsInternal(getBindingContext(viewModelOrBindingContext), rootNode, true);
+    };
+
+    // Retrieving binding context from arbitrary nodes
+    ko.contextFor = function(node) {
+        // We can only do something meaningful for elements and comment nodes (in particular, not text nodes, as IE can't store domdata for them)
+        switch (node.nodeType) {
+            case 1:
+            case 8:
+                var context = ko.storedBindingContextForNode(node);
+                if (context) return context;
+                if (node.parentNode) return ko.contextFor(node.parentNode);
+                break;
+        }
+        return undefined;
+    };
+    ko.dataFor = function(node) {
+        var context = ko.contextFor(node);
+        return context ? context['$data'] : undefined;
+    };
+
+    ko.exportSymbol('bindingHandlers', ko.bindingHandlers);
+    ko.exportSymbol('applyBindings', ko.applyBindings);
+    ko.exportSymbol('applyBindingsToDescendants', ko.applyBindingsToDescendants);
+    ko.exportSymbol('applyBindingAccessorsToNode', ko.applyBindingAccessorsToNode);
+    ko.exportSymbol('applyBindingsToNode', ko.applyBindingsToNode);
+    ko.exportSymbol('contextFor', ko.contextFor);
+    ko.exportSymbol('dataFor', ko.dataFor);
+})();
+(function(undefined) {
+    var loadingSubscribablesCache = {}, // Tracks component loads that are currently in flight
+        loadedDefinitionsCache = {};    // Tracks component loads that have already completed
+
+    ko.components = {
+        get: function(componentName, callback) {
+            var cachedDefinition = getObjectOwnProperty(loadedDefinitionsCache, componentName);
+            if (cachedDefinition) {
+                // It's already loaded and cached. Reuse the same definition object.
+                // Note that for API consistency, even cache hits complete asynchronously.
+                setTimeout(function() { callback(cachedDefinition) }, 0);
+            } else {
+                // Join the loading process that is already underway, or start a new one.
+                loadComponentAndNotify(componentName, callback);
+            }
+        },
+
+        clearCachedDefinition: function(componentName) {
+            delete loadedDefinitionsCache[componentName];
+        },
+
+        _getFirstResultFromLoaders: getFirstResultFromLoaders
+    };
+
+    function getObjectOwnProperty(obj, propName) {
+        return obj.hasOwnProperty(propName) ? obj[propName] : undefined;
+    }
+
+    function loadComponentAndNotify(componentName, callback) {
+        var subscribable = getObjectOwnProperty(loadingSubscribablesCache, componentName),
+            completedAsync;
+        if (!subscribable) {
+            // It's not started loading yet. Start loading, and when it's done, move it to loadedDefinitionsCache.
+            subscribable = loadingSubscribablesCache[componentName] = new ko.subscribable();
+            beginLoadingComponent(componentName, function(definition) {
+                loadedDefinitionsCache[componentName] = definition;
+                delete loadingSubscribablesCache[componentName];
+
+                // For API consistency, all loads complete asynchronously. However we want to avoid
+                // adding an extra setTimeout if it's unnecessary (i.e., the completion is already
+                // async) since setTimeout(..., 0) still takes about 16ms or more on most browsers.
+                if (completedAsync) {
+                    subscribable['notifySubscribers'](definition);
+                } else {
+                    setTimeout(function() {
+                        subscribable['notifySubscribers'](definition);
+                    }, 0);
+                }
+            });
+            completedAsync = true;
+        }
+        subscribable.subscribe(callback);
+    }
+
+    function beginLoadingComponent(componentName, callback) {
+        getFirstResultFromLoaders('getConfig', [componentName], function(config) {
+            if (config) {
+                // We have a config, so now load its definition
+                getFirstResultFromLoaders('loadComponent', [componentName, config], function(definition) {
+                    callback(definition);
+                });
+            } else {
+                // The component has no config - it's unknown to all the loaders.
+                // Note that this is not an error (e.g., a module loading error) - that would abort the
+                // process and this callback would not run. For this callback to run, all loaders must
+                // have confirmed they don't know about this component.
+                callback(null);
+            }
+        });
+    }
+
+    function getFirstResultFromLoaders(methodName, argsExceptCallback, callback, candidateLoaders) {
+        // On the first call in the stack, start with the full set of loaders
+        if (!candidateLoaders) {
+            candidateLoaders = ko.components['loaders'].slice(0); // Use a copy, because we'll be mutating this array
+        }
+
+        // Try the next candidate
+        var currentCandidateLoader = candidateLoaders.shift();
+        if (currentCandidateLoader) {
+            var methodInstance = currentCandidateLoader[methodName];
+            if (methodInstance) {
+                var wasAborted = false,
+                    synchronousReturnValue = methodInstance.apply(currentCandidateLoader, argsExceptCallback.concat(function(result) {
+                        if (wasAborted) {
+                            callback(null);
+                        } else if (result !== null) {
+                            // This candidate returned a value. Use it.
+                            callback(result);
+                        } else {
+                            // Try the next candidate
+                            getFirstResultFromLoaders(methodName, argsExceptCallback, callback, candidateLoaders);
+                        }
+                    }));
+
+                // Currently, loaders may not return anything synchronously. This leaves open the possibility
+                // that we'll extend the API to support synchronous return values in the future. It won't be
+                // a breaking change, because currently no loader is allowed to return anything except undefined.
+                if (synchronousReturnValue !== undefined) {
+                    wasAborted = true;
+
+                    // Method to suppress exceptions will remain undocumented. This is only to keep
+                    // KO's specs running tidily, since we can observe the loading got aborted without
+                    // having exceptions cluttering up the console too.
+                    if (!currentCandidateLoader['suppressLoaderExceptions']) {
+                        throw new Error('Component loaders must supply values by invoking the callback, not by returning values synchronously.');
+                    }
+                }
+            } else {
+                // This candidate doesn't have the relevant handler. Synchronously move on to the next one.
+                getFirstResultFromLoaders(methodName, argsExceptCallback, callback, candidateLoaders);
+            }
+        } else {
+            // No candidates returned a value
+            callback(null);
+        }
+    }
+
+    // Reference the loaders via string name so it's possible for developers
+    // to replace the whole array by assigning to ko.components.loaders
+    ko.components['loaders'] = [];
+
+    ko.exportSymbol('components', ko.components);
+    ko.exportSymbol('components.get', ko.components.get);
+    ko.exportSymbol('components.clearCachedDefinition', ko.components.clearCachedDefinition);
+})();
+(function(undefined) {
+
+    // The default loader is responsible for two things:
+    // 1. Maintaining the default in-memory registry of component configuration objects
+    //    (i.e., the thing you're writing to when you call ko.components.register(someName, ...))
+    // 2. Answering requests for components by fetching configuration objects
+    //    from that default in-memory registry and resolving them into standard
+    //    component definition objects (of the form { createViewModel: ..., template: ... })
+    // Custom loaders may override either of these facilities, i.e.,
+    // 1. To supply configuration objects from some other source (e.g., conventions)
+    // 2. Or, to resolve configuration objects by loading viewmodels/templates via arbitrary logic.
+
+    var defaultConfigRegistry = {};
+
+    ko.components.register = function(componentName, config) {
+        if (!config) {
+            throw new Error('Invalid configuration for ' + componentName);
+        }
+
+        if (ko.components.isRegistered(componentName)) {
+            throw new Error('Component ' + componentName + ' is already registered');
+        }
+
+        defaultConfigRegistry[componentName] = config;
+    }
+
+    ko.components.isRegistered = function(componentName) {
+        return componentName in defaultConfigRegistry;
+    }
+
+    ko.components.unregister = function(componentName) {
+        delete defaultConfigRegistry[componentName];
+        ko.components.clearCachedDefinition(componentName);
+    }
+
+    ko.components.defaultLoader = {
+        'getConfig': function(componentName, callback) {
+            var result = defaultConfigRegistry.hasOwnProperty(componentName)
+                ? defaultConfigRegistry[componentName]
+                : null;
+            callback(result);
+        },
+
+        'loadComponent': function(componentName, config, callback) {
+            var errorCallback = makeErrorCallback(componentName);
+            possiblyGetConfigFromAmd(errorCallback, config, function(loadedConfig) {
+                resolveConfig(componentName, errorCallback, loadedConfig, callback);
+            });
+        },
+
+        'loadTemplate': function(componentName, templateConfig, callback) {
+            resolveTemplate(makeErrorCallback(componentName), templateConfig, callback);
+        },
+
+        'loadViewModel': function(componentName, viewModelConfig, callback) {
+            resolveViewModel(makeErrorCallback(componentName), viewModelConfig, callback);
+        }
+    };
+
+    var createViewModelKey = 'createViewModel';
+
+    // Takes a config object of the form { template: ..., viewModel: ... }, and asynchronously convert it
+    // into the standard component definition format:
+    //    { template: <ArrayOfDomNodes>, createViewModel: function(params, componentInfo) { ... } }.
+    // Since both template and viewModel may need to be resolved asynchronously, both tasks are performed
+    // in parallel, and the results joined when both are ready. We don't depend on any promises infrastructure,
+    // so this is implemented manually below.
+    function resolveConfig(componentName, errorCallback, config, callback) {
+        var result = {},
+            makeCallBackWhenZero = 2,
+            tryIssueCallback = function() {
+                if (--makeCallBackWhenZero === 0) {
+                    callback(result);
+                }
+            },
+            templateConfig = config['template'],
+            viewModelConfig = config['viewModel'];
+
+        if (templateConfig) {
+            possiblyGetConfigFromAmd(errorCallback, templateConfig, function(loadedConfig) {
+                ko.components._getFirstResultFromLoaders('loadTemplate', [componentName, loadedConfig], function(resolvedTemplate) {
+                    result['template'] = resolvedTemplate;
+                    tryIssueCallback();
+                });
+            });
+        } else {
+            tryIssueCallback();
+        }
+
+        if (viewModelConfig) {
+            possiblyGetConfigFromAmd(errorCallback, viewModelConfig, function(loadedConfig) {
+                ko.components._getFirstResultFromLoaders('loadViewModel', [componentName, loadedConfig], function(resolvedViewModel) {
+                    result[createViewModelKey] = resolvedViewModel;
+                    tryIssueCallback();
+                });
+            });
+        } else {
+            tryIssueCallback();
+        }
+    }
+
+    function resolveTemplate(errorCallback, templateConfig, callback) {
+        if (typeof templateConfig === 'string') {
+            // Markup - parse it
+            callback(ko.utils.parseHtmlFragment(templateConfig));
+        } else if (templateConfig instanceof Array) {
+            // Assume already an array of DOM nodes - pass through unchanged
+            callback(templateConfig);
+        } else if (isDocumentFragment(templateConfig)) {
+            // Document fragment - use its child nodes
+            callback(ko.utils.makeArray(templateConfig.childNodes));
+        } else if (templateConfig['element']) {
+            var element = templateConfig['element'];
+            if (isDomElement(element)) {
+                // Element instance - copy its child nodes
+                callback(cloneNodesFromTemplateSourceElement(element));
+            } else if (typeof element === 'string') {
+                // Element ID - find it, then copy its child nodes
+                var elemInstance = document.getElementById(element);
+                if (elemInstance) {
+                    callback(cloneNodesFromTemplateSourceElement(elemInstance));
+                } else {
+                    errorCallback('Cannot find element with ID ' + element);
+                }
+            } else {
+                errorCallback('Unknown element type: ' + element);
+            }
+        } else {
+            errorCallback('Unknown template value: ' + templateConfig);
+        }
+    }
+
+    function resolveViewModel(errorCallback, viewModelConfig, callback) {
+        if (typeof viewModelConfig === 'function') {
+            // Constructor - convert to standard factory function format
+            // By design, this does *not* supply componentInfo to the constructor, as the intent is that
+            // componentInfo contains non-viewmodel data (e.g., the component's element) that should only
+            // be used in factory functions, not viewmodel constructors.
+            callback(function (params /*, componentInfo */) {
+                return new viewModelConfig(params);
+            });
+        } else if (typeof viewModelConfig[createViewModelKey] === 'function') {
+            // Already a factory function - use it as-is
+            callback(viewModelConfig[createViewModelKey]);
+        } else if ('instance' in viewModelConfig) {
+            // Fixed object instance - promote to createViewModel format for API consistency
+            var fixedInstance = viewModelConfig['instance'];
+            callback(function (params, componentInfo) {
+                return fixedInstance;
+            });
+        } else if ('viewModel' in viewModelConfig) {
+            // Resolved AMD module whose value is of the form { viewModel: ... }
+            resolveViewModel(errorCallback, viewModelConfig['viewModel'], callback);
+        } else {
+            errorCallback('Unknown viewModel value: ' + viewModelConfig);
+        }
+    }
+
+    function cloneNodesFromTemplateSourceElement(elemInstance) {
+        switch (ko.utils.tagNameLower(elemInstance)) {
+            case 'script':
+                return ko.utils.parseHtmlFragment(elemInstance.text);
+            case 'textarea':
+                return ko.utils.parseHtmlFragment(elemInstance.value);
+            case 'template':
+                // For browsers with proper <template> element support (i.e., where the .content property
+                // gives a document fragment), use that document fragment.
+                if (isDocumentFragment(elemInstance.content)) {
+                    return ko.utils.cloneNodes(elemInstance.content.childNodes);
+                }
+        }
+
+        // Regular elements such as <div>, and <template> elements on old browsers that don't really
+        // understand <template> and just treat it as a regular container
+        return ko.utils.cloneNodes(elemInstance.childNodes);
+    }
+
+    function isDomElement(obj) {
+        if (window['HTMLElement']) {
+            return obj instanceof HTMLElement;
+        } else {
+            return obj && obj.tagName && obj.nodeType === 1;
+        }
+    }
+
+    function isDocumentFragment(obj) {
+        if (window['DocumentFragment']) {
+            return obj instanceof DocumentFragment;
+        } else {
+            return obj && obj.nodeType === 11;
+        }
+    }
+
+    function possiblyGetConfigFromAmd(errorCallback, config, callback) {
+        if (typeof config['require'] === 'string') {
+            // The config is the value of an AMD module
+            if (require || window['require']) {
+                (require || window['require'])([config['require']], callback);
+            } else {
+                errorCallback('Uses require, but no AMD loader is present');
+            }
+        } else {
+            callback(config);
+        }
+    }
+
+    function makeErrorCallback(componentName) {
+        return function (message) {
+            throw new Error('Component \'' + componentName + '\': ' + message);
+        };
+    }
+
+    ko.exportSymbol('components.register', ko.components.register);
+    ko.exportSymbol('components.isRegistered', ko.components.isRegistered);
+    ko.exportSymbol('components.unregister', ko.components.unregister);
+
+    // Expose the default loader so that developers can directly ask it for configuration
+    // or to resolve configuration
+    ko.exportSymbol('components.defaultLoader', ko.components.defaultLoader);
+
+    // By default, the default loader is the only registered component loader
+    ko.components['loaders'].push(ko.components.defaultLoader);
+
+    // Privately expose the underlying config registry for use in old-IE shim
+    ko.components._allRegisteredComponents = defaultConfigRegistry;
+})();
+(function (undefined) {
+    // Overridable API for determining which component name applies to a given node. By overriding this,
+    // you can for example map specific tagNames to components that are not preregistered.
+    ko.components['getComponentNameForNode'] = function(node) {
+        var tagNameLower = ko.utils.tagNameLower(node);
+        return ko.components.isRegistered(tagNameLower) && tagNameLower;
+    };
+
+    ko.components.addBindingsForCustomElement = function(allBindings, node, bindingContext, valueAccessors) {
+        // Determine if it's really a custom element matching a component
+        if (node.nodeType === 1) {
+            var componentName = ko.components['getComponentNameForNode'](node);
+            if (componentName) {
+                // It does represent a component, so add a component binding for it
+                allBindings = allBindings || {};
+
+                if (allBindings['component']) {
+                    // Avoid silently overwriting some other 'component' binding that may already be on the element
+                    throw new Error('Cannot use the "component" binding on a custom element matching a component');
+                }
+
+                var componentBindingValue = { 'name': componentName, 'params': getComponentParamsFromCustomElement(node, bindingContext) };
+
+                allBindings['component'] = valueAccessors
+                    ? function() { return componentBindingValue; }
+                    : componentBindingValue;
+            }
+        }
+
+        return allBindings;
+    }
+
+    var nativeBindingProviderInstance = new ko.bindingProvider();
+
+    function getComponentParamsFromCustomElement(elem, bindingContext) {
+        var paramsAttribute = elem.getAttribute('params');
+
+        if (paramsAttribute) {
+            var params = nativeBindingProviderInstance['parseBindingsString'](paramsAttribute, bindingContext, elem, { 'valueAccessors': true, 'bindingParams': true }),
+                rawParamComputedValues = ko.utils.objectMap(params, function(paramValue, paramName) {
+                    return ko.computed(paramValue, null, { disposeWhenNodeIsRemoved: elem });
+                }),
+                result = ko.utils.objectMap(rawParamComputedValues, function(paramValueComputed, paramName) {
+                    // Does the evaluation of the parameter value unwrap any observables?
+                    if (!paramValueComputed.isActive()) {
+                        // No it doesn't, so there's no need for any computed wrapper. Just pass through the supplied value directly.
+                        // Example: "someVal: firstName, age: 123" (whether or not firstName is an observable/computed)
+                        return paramValueComputed.peek();
+                    } else {
+                        // Yes it does. Supply a computed property that unwraps both the outer (binding expression)
+                        // level of observability, and any inner (resulting model value) level of observability.
+                        // This means the component doesn't have to worry about multiple unwrapping.
+                        return ko.computed(function() {
+                            return ko.utils.unwrapObservable(paramValueComputed());
+                        }, null, { disposeWhenNodeIsRemoved: elem });
+                    }
+                });
+
+            // Give access to the raw computeds, as long as that wouldn't overwrite any custom param also called '$raw'
+            // This is in case the developer wants to react to outer (binding) observability separately from inner
+            // (model value) observability, or in case the model value observable has subobservables.
+            if (!result.hasOwnProperty('$raw')) {
+                result['$raw'] = rawParamComputedValues;
+            }
+
+            return result;
+        } else {
+            // For consistency, absence of a "params" attribute is treated the same as the presence of
+            // any empty one. Otherwise component viewmodels need special code to check whether or not
+            // 'params' or 'params.$raw' is null/undefined before reading subproperties, which is annoying.
+            return { '$raw': {} };
+        }
+    }
+
+    // --------------------------------------------------------------------------------
+    // Compatibility code for older (pre-HTML5) IE browsers
+
+    if (ko.utils.ieVersion < 9) {
+        // Whenever you preregister a component, enable it as a custom element in the current document
+        ko.components['register'] = (function(originalFunction) {
+            return function(componentName) {
+                document.createElement(componentName); // Allows IE<9 to parse markup containing the custom element
+                return originalFunction.apply(this, arguments);
+            }
+        })(ko.components['register']);
+
+        // Whenever you create a document fragment, enable all preregistered component names as custom elements
+        // This is needed to make innerShiv/jQuery HTML parsing correctly handle the custom elements
+        document.createDocumentFragment = (function(originalFunction) {
+            return function() {
+                var newDocFrag = originalFunction(),
+                    allComponents = ko.components._allRegisteredComponents;
+                for (var componentName in allComponents) {
+                    if (allComponents.hasOwnProperty(componentName)) {
+                        newDocFrag.createElement(componentName);
+                    }
+                }
+                return newDocFrag;
+            };
+        })(document.createDocumentFragment);
+    }
+})();(function(undefined) {
+
+    var componentLoadingOperationUniqueId = 0;
+
+    ko.bindingHandlers['component'] = {
+        'init': function(element, valueAccessor, ignored1, ignored2, bindingContext) {
+            var currentViewModel,
+                currentLoadingOperationId,
+                disposeAssociatedComponentViewModel = function () {
+                    var currentViewModelDispose = currentViewModel && currentViewModel['dispose'];
+                    if (typeof currentViewModelDispose === 'function') {
+                        currentViewModelDispose.call(currentViewModel);
+                    }
+
+                    // Any in-flight loading operation is no longer relevant, so make sure we ignore its completion
+                    currentLoadingOperationId = null;
+                };
+
+            ko.utils.domNodeDisposal.addDisposeCallback(element, disposeAssociatedComponentViewModel);
+
+            ko.computed(function () {
+                var value = ko.utils.unwrapObservable(valueAccessor()),
+                    componentName, componentParams;
+
+                if (typeof value === 'string') {
+                    componentName = value;
+                } else {
+                    componentName = ko.utils.unwrapObservable(value['name']);
+                    componentParams = ko.utils.unwrapObservable(value['params']);
+                }
+
+                if (!componentName) {
+                    throw new Error('No component name specified');
+                }
+
+                var loadingOperationId = currentLoadingOperationId = ++componentLoadingOperationUniqueId;
+                ko.components.get(componentName, function(componentDefinition) {
+                    // If this is not the current load operation for this element, ignore it.
+                    if (currentLoadingOperationId !== loadingOperationId) {
+                        return;
+                    }
+
+                    // Clean up previous state
+                    disposeAssociatedComponentViewModel();
+
+                    // Instantiate and bind new component. Implicitly this cleans any old DOM nodes.
+                    if (!componentDefinition) {
+                        throw new Error('Unknown component \'' + componentName + '\'');
+                    }
+                    cloneTemplateIntoElement(componentName, componentDefinition, element);
+                    var componentViewModel = createViewModel(componentDefinition, element, componentParams),
+                        childBindingContext = bindingContext['createChildContext'](componentViewModel);
+                    currentViewModel = componentViewModel;
+                    ko.applyBindingsToDescendants(childBindingContext, element);
+                });
+            }, null, { disposeWhenNodeIsRemoved: element });
+
+            return { 'controlsDescendantBindings': true };
+        }
+    };
+
+    ko.virtualElements.allowedBindings['component'] = true;
+
+    function cloneTemplateIntoElement(componentName, componentDefinition, element) {
+        var template = componentDefinition['template'];
+        if (!template) {
+            throw new Error('Component \'' + componentName + '\' has no template');
+        }
+
+        var clonedNodesArray = ko.utils.cloneNodes(template);
+        ko.virtualElements.setDomNodeChildren(element, clonedNodesArray);
+    }
+
+    function createViewModel(componentDefinition, element, componentParams) {
+        var componentViewModelFactory = componentDefinition['createViewModel'];
+        return componentViewModelFactory
+            ? componentViewModelFactory.call(componentDefinition, componentParams, { element: element })
+            : componentParams; // Template-only component
+    }
+
+})();
+var attrHtmlToJavascriptMap = { 'class': 'className', 'for': 'htmlFor' };
+ko.bindingHandlers['attr'] = {
+    'update': function(element, valueAccessor, allBindings) {
+        var value = ko.utils.unwrapObservable(valueAccessor()) || {};
+        ko.utils.objectForEach(value, function(attrName, attrValue) {
+            attrValue = ko.utils.unwrapObservable(attrValue);
+
+            // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely
+            // when someProp is a "no value"-like value (strictly null, false, or undefined)
+            // (because the absence of the "checked" attr is how to mark an element as not checked, etc.)
+            var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined);
+            if (toRemove)
+                element.removeAttribute(attrName);
+
+            // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the
+            // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior,
+            // but instead of figuring out the mode, we'll just set the attribute through the Javascript
+            // property for IE <= 8.
+            if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavascriptMap) {
+                attrName = attrHtmlToJavascriptMap[attrName];
+                if (toRemove)
+                    element.removeAttribute(attrName);
+                else
+                    element[attrName] = attrValue;
+            } else if (!toRemove) {
+                element.setAttribute(attrName, attrValue.toString());
+            }
+
+            // Treat "name" specially - although you can think of it as an attribute, it also needs
+            // special handling on older versions of IE (https://github.com/SteveSanderson/knockout/pull/333)
+            // Deliberately being case-sensitive here because XHTML would regard "Name" as a different thing
+            // entirely, and there's no strong reason to allow for such casing in HTML.
+            if (attrName === "name") {
+                ko.utils.setElementName(element, toRemove ? "" : attrValue.toString());
+            }
+        });
+    }
+};
+(function() {
+
+ko.bindingHandlers['checked'] = {
+    'after': ['value', 'attr'],
+    'init': function (element, valueAccessor, allBindings) {
+        var checkedValue = ko.pureComputed(function() {
+            // Treat "value" like "checkedValue" when it is included with "checked" binding
+            if (allBindings['has']('checkedValue')) {
+                return ko.utils.unwrapObservable(allBindings.get('checkedValue'));
+            } else if (allBindings['has']('value')) {
+                return ko.utils.unwrapObservable(allBindings.get('value'));
+            }
+
+            return element.value;
+        });
+
+        function updateModel() {
+            // This updates the model value from the view value.
+            // It runs in response to DOM events (click) and changes in checkedValue.
+            var isChecked = element.checked,
+                elemValue = useCheckedValue ? checkedValue() : isChecked;
+
+            // When we're first setting up this computed, don't change any model state.
+            if (ko.computedContext.isInitial()) {
+                return;
+            }
+
+            // We can ignore unchecked radio buttons, because some other radio
+            // button will be getting checked, and that one can take care of updating state.
+            if (isRadio && !isChecked) {
+                return;
+            }
+
+            var modelValue = ko.dependencyDetection.ignore(valueAccessor);
+            if (isValueArray) {
+                if (oldElemValue !== elemValue) {
+                    // When we're responding to the checkedValue changing, and the element is
+                    // currently checked, replace the old elem value with the new elem value
+                    // in the model array.
+                    if (isChecked) {
+                        ko.utils.addOrRemoveItem(modelValue, elemValue, true);
+                        ko.utils.addOrRemoveItem(modelValue, oldElemValue, false);
+                    }
+
+                    oldElemValue = elemValue;
+                } else {
+                    // When we're responding to the user having checked/unchecked a checkbox,
+                    // add/remove the element value to the model array.
+                    ko.utils.addOrRemoveItem(modelValue, elemValue, isChecked);
+                }
+            } else {
+                ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true);
+            }
+        };
+
+        function updateView() {
+            // This updates the view value from the model value.
+            // It runs in response to changes in the bound (checked) value.
+            var modelValue = ko.utils.unwrapObservable(valueAccessor());
+
+            if (isValueArray) {
+                // When a checkbox is bound to an array, being checked represents its value being present in that array
+                element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;
+            } else if (isCheckbox) {
+                // When a checkbox is bound to any other value (not an array), being checked represents the value being trueish
+                element.checked = modelValue;
+            } else {
+                // For radio buttons, being checked means that the radio button's value corresponds to the model value
+                element.checked = (checkedValue() === modelValue);
+            }
+        };
+
+        var isCheckbox = element.type == "checkbox",
+            isRadio = element.type == "radio";
+
+        // Only bind to check boxes and radio buttons
+        if (!isCheckbox && !isRadio) {
+            return;
+        }
+
+        var isValueArray = isCheckbox && (ko.utils.unwrapObservable(valueAccessor()) instanceof Array),
+            oldElemValue = isValueArray ? checkedValue() : undefined,
+            useCheckedValue = isRadio || isValueArray;
+
+        // IE 6 won't allow radio buttons to be selected unless they have a name
+        if (isRadio && !element.name)
+            ko.bindingHandlers['uniqueName']['init'](element, function() { return true });
+
+        // Set up two computeds to update the binding:
+
+        // The first responds to changes in the checkedValue value and to element clicks
+        ko.computed(updateModel, null, { disposeWhenNodeIsRemoved: element });
+        ko.utils.registerEventHandler(element, "click", updateModel);
+
+        // The second responds to changes in the model value (the one associated with the checked binding)
+        ko.computed(updateView, null, { disposeWhenNodeIsRemoved: element });
+    }
+};
+ko.expressionRewriting.twoWayBindings['checked'] = true;
+
+ko.bindingHandlers['checkedValue'] = {
+    'update': function (element, valueAccessor) {
+        element.value = ko.utils.unwrapObservable(valueAccessor());
+    }
+};
+
+})();var classesWrittenByBindingKey = '__ko__cssValue';
+ko.bindingHandlers['css'] = {
+    'update': function (element, valueAccessor) {
+        var value = ko.utils.unwrapObservable(valueAccessor());
+        if (typeof value == "object") {
+            ko.utils.objectForEach(value, function(className, shouldHaveClass) {
+                shouldHaveClass = ko.utils.unwrapObservable(shouldHaveClass);
+                ko.utils.toggleDomNodeCssClass(element, className, shouldHaveClass);
+            });
+        } else {
+            value = String(value || ''); // Make sure we don't try to store or set a non-string value
+            ko.utils.toggleDomNodeCssClass(element, element[classesWrittenByBindingKey], false);
+            element[classesWrittenByBindingKey] = value;
+            ko.utils.toggleDomNodeCssClass(element, value, true);
+        }
+    }
+};
+ko.bindingHandlers['enable'] = {
+    'update': function (element, valueAccessor) {
+        var value = ko.utils.unwrapObservable(valueAccessor());
+        if (value && element.disabled)
+            element.removeAttribute("disabled");
+        else if ((!value) && (!element.disabled))
+            element.disabled = true;
+    }
+};
+
+ko.bindingHandlers['disable'] = {
+    'update': function (element, valueAccessor) {
+        ko.bindingHandlers['enable']['update'](element, function() { return !ko.utils.unwrapObservable(valueAccessor()) });
+    }
+};
+// For certain common events (currently just 'click'), allow a simplified data-binding syntax
+// e.g. click:handler instead of the usual full-length event:{click:handler}
+function makeEventHandlerShortcut(eventName) {
+    ko.bindingHandlers[eventName] = {
+        'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+            var newValueAccessor = function () {
+                var result = {};
+                result[eventName] = valueAccessor();
+                return result;
+            };
+            return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindings, viewModel, bindingContext);
+        }
+    }
+}
+
+ko.bindingHandlers['event'] = {
+    'init' : function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+        var eventsToHandle = valueAccessor() || {};
+        ko.utils.objectForEach(eventsToHandle, function(eventName) {
+            if (typeof eventName == "string") {
+                ko.utils.registerEventHandler(element, eventName, function (event) {
+                    var handlerReturnValue;
+                    var handlerFunction = valueAccessor()[eventName];
+                    if (!handlerFunction)
+                        return;
+
+                    try {
+                        // Take all the event args, and prefix with the viewmodel
+                        var argsForHandler = ko.utils.makeArray(arguments);
+                        viewModel = bindingContext['$data'];
+                        argsForHandler.unshift(viewModel);
+                        handlerReturnValue = handlerFunction.apply(viewModel, argsForHandler);
+                    } finally {
+                        if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
+                            if (event.preventDefault)
+                                event.preventDefault();
+                            else
+                                event.returnValue = false;
+                        }
+                    }
+
+                    var bubble = allBindings.get(eventName + 'Bubble') !== false;
+                    if (!bubble) {
+                        event.cancelBubble = true;
+                        if (event.stopPropagation)
+                            event.stopPropagation();
+                    }
+                });
+            }
+        });
+    }
+};
+// "foreach: someExpression" is equivalent to "template: { foreach: someExpression }"
+// "foreach: { data: someExpression, afterAdd: myfn }" is equivalent to "template: { foreach: someExpression, afterAdd: myfn }"
+ko.bindingHandlers['foreach'] = {
+    makeTemplateValueAccessor: function(valueAccessor) {
+        return function() {
+            var modelValue = valueAccessor(),
+                unwrappedValue = ko.utils.peekObservable(modelValue);    // Unwrap without setting a dependency here
+
+            // If unwrappedValue is the array, pass in the wrapped value on its own
+            // The value will be unwrapped and tracked within the template binding
+            // (See https://github.com/SteveSanderson/knockout/issues/523)
+            if ((!unwrappedValue) || typeof unwrappedValue.length == "number")
+                return { 'foreach': modelValue, 'templateEngine': ko.nativeTemplateEngine.instance };
+
+            // If unwrappedValue.data is the array, preserve all relevant options and unwrap again value so we get updates
+            ko.utils.unwrapObservable(modelValue);
+            return {
+                'foreach': unwrappedValue['data'],
+                'as': unwrappedValue['as'],
+                'includeDestroyed': unwrappedValue['includeDestroyed'],
+                'afterAdd': unwrappedValue['afterAdd'],
+                'beforeRemove': unwrappedValue['beforeRemove'],
+                'afterRender': unwrappedValue['afterRender'],
+                'beforeMove': unwrappedValue['beforeMove'],
+                'afterMove': unwrappedValue['afterMove'],
+                'templateEngine': ko.nativeTemplateEngine.instance
+            };
+        };
+    },
+    'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+        return ko.bindingHandlers['template']['init'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor));
+    },
+    'update': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+        return ko.bindingHandlers['template']['update'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor), allBindings, viewModel, bindingContext);
+    }
+};
+ko.expressionRewriting.bindingRewriteValidators['foreach'] = false; // Can't rewrite control flow bindings
+ko.virtualElements.allowedBindings['foreach'] = true;
+var hasfocusUpdatingProperty = '__ko_hasfocusUpdating';
+var hasfocusLastValue = '__ko_hasfocusLastValue';
+ko.bindingHandlers['hasfocus'] = {
+    'init': function(element, valueAccessor, allBindings) {
+        var handleElementFocusChange = function(isFocused) {
+            // Where possible, ignore which event was raised and determine focus state using activeElement,
+            // as this avoids phantom focus/blur events raised when changing tabs in modern browsers.
+            // However, not all KO-targeted browsers (Firefox 2) support activeElement. For those browsers,
+            // prevent a loss of focus when changing tabs/windows by setting a flag that prevents hasfocus
+            // from calling 'blur()' on the element when it loses focus.
+            // Discussion at https://github.com/SteveSanderson/knockout/pull/352
+            element[hasfocusUpdatingProperty] = true;
+            var ownerDoc = element.ownerDocument;
+            if ("activeElement" in ownerDoc) {
+                var active;
+                try {
+                    active = ownerDoc.activeElement;
+                } catch(e) {
+                    // IE9 throws if you access activeElement during page load (see issue #703)
+                    active = ownerDoc.body;
+                }
+                isFocused = (active === element);
+            }
+            var modelValue = valueAccessor();
+            ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'hasfocus', isFocused, true);
+
+            //cache the latest value, so we can avoid unnecessarily calling focus/blur in the update function
+            element[hasfocusLastValue] = isFocused;
+            element[hasfocusUpdatingProperty] = false;
+        };
+        var handleElementFocusIn = handleElementFocusChange.bind(null, true);
+        var handleElementFocusOut = handleElementFocusChange.bind(null, false);
+
+        ko.utils.registerEventHandler(element, "focus", handleElementFocusIn);
+        ko.utils.registerEventHandler(element, "focusin", handleElementFocusIn); // For IE
+        ko.utils.registerEventHandler(element, "blur",  handleElementFocusOut);
+        ko.utils.registerEventHandler(element, "focusout",  handleElementFocusOut); // For IE
+    },
+    'update': function(element, valueAccessor) {
+        var value = !!ko.utils.unwrapObservable(valueAccessor()); //force boolean to compare with last value
+        if (!element[hasfocusUpdatingProperty] && element[hasfocusLastValue] !== value) {
+            value ? element.focus() : element.blur();
+            ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, value ? "focusin" : "focusout"]); // For IE, which doesn't reliably fire "focus" or "blur" events synchronously
+        }
+    }
+};
+ko.expressionRewriting.twoWayBindings['hasfocus'] = true;
+
+ko.bindingHandlers['hasFocus'] = ko.bindingHandlers['hasfocus']; // Make "hasFocus" an alias
+ko.expressionRewriting.twoWayBindings['hasFocus'] = true;
+ko.bindingHandlers['html'] = {
+    'init': function() {
+        // Prevent binding on the dynamically-injected HTML (as developers are unlikely to expect that, and it has security implications)
+        return { 'controlsDescendantBindings': true };
+    },
+    'update': function (element, valueAccessor) {
+        // setHtml will unwrap the value if needed
+        ko.utils.setHtml(element, valueAccessor());
+    }
+};
+// Makes a binding like with or if
+function makeWithIfBinding(bindingKey, isWith, isNot, makeContextCallback) {
+    ko.bindingHandlers[bindingKey] = {
+        'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+            var didDisplayOnLastUpdate,
+                savedNodes;
+            ko.computed(function() {
+                var dataValue = ko.utils.unwrapObservable(valueAccessor()),
+                    shouldDisplay = !isNot !== !dataValue, // equivalent to isNot ? !dataValue : !!dataValue
+                    isFirstRender = !savedNodes,
+                    needsRefresh = isFirstRender || isWith || (shouldDisplay !== didDisplayOnLastUpdate);
+
+                if (needsRefresh) {
+                    // Save a copy of the inner nodes on the initial update, but only if we have dependencies.
+                    if (isFirstRender && ko.computedContext.getDependenciesCount()) {
+                        savedNodes = ko.utils.cloneNodes(ko.virtualElements.childNodes(element), true /* shouldCleanNodes */);
+                    }
+
+                    if (shouldDisplay) {
+                        if (!isFirstRender) {
+                            ko.virtualElements.setDomNodeChildren(element, ko.utils.cloneNodes(savedNodes));
+                        }
+                        ko.applyBindingsToDescendants(makeContextCallback ? makeContextCallback(bindingContext, dataValue) : bindingContext, element);
+                    } else {
+                        ko.virtualElements.emptyNode(element);
+                    }
+
+                    didDisplayOnLastUpdate = shouldDisplay;
+                }
+            }, null, { disposeWhenNodeIsRemoved: element });
+            return { 'controlsDescendantBindings': true };
+        }
+    };
+    ko.expressionRewriting.bindingRewriteValidators[bindingKey] = false; // Can't rewrite control flow bindings
+    ko.virtualElements.allowedBindings[bindingKey] = true;
+}
+
+// Construct the actual binding handlers
+makeWithIfBinding('if');
+makeWithIfBinding('ifnot', false /* isWith */, true /* isNot */);
+makeWithIfBinding('with', true /* isWith */, false /* isNot */,
+    function(bindingContext, dataValue) {
+        return bindingContext['createChildContext'](dataValue);
+    }
+);
+var captionPlaceholder = {};
+ko.bindingHandlers['options'] = {
+    'init': function(element) {
+        if (ko.utils.tagNameLower(element) !== "select")
+            throw new Error("options binding applies only to SELECT elements");
+
+        // Remove all existing <option>s.
+        while (element.length > 0) {
+            element.remove(0);
+        }
+
+        // Ensures that the binding processor doesn't try to bind the options
+        return { 'controlsDescendantBindings': true };
+    },
+    'update': function (element, valueAccessor, allBindings) {
+        function selectedOptions() {
+            return ko.utils.arrayFilter(element.options, function (node) { return node.selected; });
+        }
+
+        var selectWasPreviouslyEmpty = element.length == 0;
+        var previousScrollTop = (!selectWasPreviouslyEmpty && element.multiple) ? element.scrollTop : null;
+        var unwrappedArray = ko.utils.unwrapObservable(valueAccessor());
+        var includeDestroyed = allBindings.get('optionsIncludeDestroyed');
+        var arrayToDomNodeChildrenOptions = {};
+        var captionValue;
+        var filteredArray;
+        var previousSelectedValues;
+
+        if (element.multiple) {
+            previousSelectedValues = ko.utils.arrayMap(selectedOptions(), ko.selectExtensions.readValue);
+        } else {
+            previousSelectedValues = element.selectedIndex >= 0 ? [ ko.selectExtensions.readValue(element.options[element.selectedIndex]) ] : [];
+        }
+
+        if (unwrappedArray) {
+            if (typeof unwrappedArray.length == "undefined") // Coerce single value into array
+                unwrappedArray = [unwrappedArray];
+
+            // Filter out any entries marked as destroyed
+            filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) {
+                return includeDestroyed || item === undefined || item === null || !ko.utils.unwrapObservable(item['_destroy']);
+            });
+
+            // If caption is included, add it to the array
+            if (allBindings['has']('optionsCaption')) {
+                captionValue = ko.utils.unwrapObservable(allBindings.get('optionsCaption'));
+                // If caption value is null or undefined, don't show a caption
+                if (captionValue !== null && captionValue !== undefined) {
+                    filteredArray.unshift(captionPlaceholder);
+                }
+            }
+        } else {
+            // If a falsy value is provided (e.g. null), we'll simply empty the select element
+        }
+
+        function applyToObject(object, predicate, defaultValue) {
+            var predicateType = typeof predicate;
+            if (predicateType == "function")    // Given a function; run it against the data value
+                return predicate(object);
+            else if (predicateType == "string") // Given a string; treat it as a property name on the data value
+                return object[predicate];
+            else                                // Given no optionsText arg; use the data value itself
+                return defaultValue;
+        }
+
+        // The following functions can run at two different times:
+        // The first is when the whole array is being updated directly from this binding handler.
+        // The second is when an observable value for a specific array entry is updated.
+        // oldOptions will be empty in the first case, but will be filled with the previously generated option in the second.
+        var itemUpdate = false;
+        function optionForArrayItem(arrayEntry, index, oldOptions) {
+            if (oldOptions.length) {
+                previousSelectedValues = oldOptions[0].selected ? [ ko.selectExtensions.readValue(oldOptions[0]) ] : [];
+                itemUpdate = true;
+            }
+            var option = element.ownerDocument.createElement("option");
+            if (arrayEntry === captionPlaceholder) {
+                ko.utils.setTextContent(option, allBindings.get('optionsCaption'));
+                ko.selectExtensions.writeValue(option, undefined);
+            } else {
+                // Apply a value to the option element
+                var optionValue = applyToObject(arrayEntry, allBindings.get('optionsValue'), arrayEntry);
+                ko.selectExtensions.writeValue(option, ko.utils.unwrapObservable(optionValue));
+
+                // Apply some text to the option element
+                var optionText = applyToObject(arrayEntry, allBindings.get('optionsText'), optionValue);
+                ko.utils.setTextContent(option, optionText);
+            }
+            return [option];
+        }
+
+        // By using a beforeRemove callback, we delay the removal until after new items are added. This fixes a selection
+        // problem in IE<=8 and Firefox. See https://github.com/knockout/knockout/issues/1208
+        arrayToDomNodeChildrenOptions['beforeRemove'] =
+            function (option) {
+                element.removeChild(option);
+            };
+
+        function setSelectionCallback(arrayEntry, newOptions) {
+            // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.
+            // That's why we first added them without selection. Now it's time to set the selection.
+            if (previousSelectedValues.length) {
+                var isSelected = ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[0])) >= 0;
+                ko.utils.setOptionNodeSelectionState(newOptions[0], isSelected);
+
+                // If this option was changed from being selected during a single-item update, notify the change
+                if (itemUpdate && !isSelected)
+                    ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, "change"]);
+            }
+        }
+
+        var callback = setSelectionCallback;
+        if (allBindings['has']('optionsAfterRender')) {
+            callback = function(arrayEntry, newOptions) {
+                setSelectionCallback(arrayEntry, newOptions);
+                ko.dependencyDetection.ignore(allBindings.get('optionsAfterRender'), null, [newOptions[0], arrayEntry !== captionPlaceholder ? arrayEntry : undefined]);
+            }
+        }
+
+        ko.utils.setDomNodeChildrenFromArrayMapping(element, filteredArray, optionForArrayItem, arrayToDomNodeChildrenOptions, callback);
+
+        ko.dependencyDetection.ignore(function () {
+            if (allBindings.get('valueAllowUnset') && allBindings['has']('value')) {
+                // The model value is authoritative, so make sure its value is the one selected
+                ko.selectExtensions.writeValue(element, ko.utils.unwrapObservable(allBindings.get('value')), true /* allowUnset */);
+            } else {
+                // Determine if the selection has changed as a result of updating the options list
+                var selectionChanged;
+                if (element.multiple) {
+                    // For a multiple-select box, compare the new selection count to the previous one
+                    // But if nothing was selected before, the selection can't have changed
+                    selectionChanged = previousSelectedValues.length && selectedOptions().length < previousSelectedValues.length;
+                } else {
+                    // For a single-select box, compare the current value to the previous value
+                    // But if nothing was selected before or nothing is selected now, just look for a change in selection
+                    selectionChanged = (previousSelectedValues.length && element.selectedIndex >= 0)
+                        ? (ko.selectExtensions.readValue(element.options[element.selectedIndex]) !== previousSelectedValues[0])
+                        : (previousSelectedValues.length || element.selectedIndex >= 0);
+                }
+
+                // Ensure consistency between model value and selected option.
+                // If the dropdown was changed so that selection is no longer the same,
+                // notify the value or selectedOptions binding.
+                if (selectionChanged) {
+                    ko.utils.triggerEvent(element, "change");
+                }
+            }
+        });
+
+        // Workaround for IE bug
+        ko.utils.ensureSelectElementIsRenderedCorrectly(element);
+
+        if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20)
+            element.scrollTop = previousScrollTop;
+    }
+};
+ko.bindingHandlers['options'].optionValueDomDataKey = ko.utils.domData.nextKey();
+ko.bindingHandlers['selectedOptions'] = {
+    'after': ['options', 'foreach'],
+    'init': function (element, valueAccessor, allBindings) {
+        ko.utils.registerEventHandler(element, "change", function () {
+            var value = valueAccessor(), valueToWrite = [];
+            ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) {
+                if (node.selected)
+                    valueToWrite.push(ko.selectExtensions.readValue(node));
+            });
+            ko.expressionRewriting.writeValueToProperty(value, allBindings, 'selectedOptions', valueToWrite);
+        });
+    },
+    'update': function (element, valueAccessor) {
+        if (ko.utils.tagNameLower(element) != "select")
+            throw new Error("values binding applies only to SELECT elements");
+
+        var newValue = ko.utils.unwrapObservable(valueAccessor());
+        if (newValue && typeof newValue.length == "number") {
+            ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) {
+                var isSelected = ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0;
+                ko.utils.setOptionNodeSelectionState(node, isSelected);
+            });
+        }
+    }
+};
+ko.expressionRewriting.twoWayBindings['selectedOptions'] = true;
+ko.bindingHandlers['style'] = {
+    'update': function (element, valueAccessor) {
+        var value = ko.utils.unwrapObservable(valueAccessor() || {});
+        ko.utils.objectForEach(value, function(styleName, styleValue) {
+            styleValue = ko.utils.unwrapObservable(styleValue);
+
+            if (styleValue === null || styleValue === undefined || styleValue === false) {
+                // Empty string removes the value, whereas null/undefined have no effect
+                styleValue = "";
+            }
+
+            element.style[styleName] = styleValue;
+        });
+    }
+};
+ko.bindingHandlers['submit'] = {
+    'init': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+        if (typeof valueAccessor() != "function")
+            throw new Error("The value for a submit binding must be a function");
+        ko.utils.registerEventHandler(element, "submit", function (event) {
+            var handlerReturnValue;
+            var value = valueAccessor();
+            try { handlerReturnValue = value.call(bindingContext['$data'], element); }
+            finally {
+                if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
+                    if (event.preventDefault)
+                        event.preventDefault();
+                    else
+                        event.returnValue = false;
+                }
+            }
+        });
+    }
+};
+ko.bindingHandlers['text'] = {
+    'init': function() {
+        // Prevent binding on the dynamically-injected text node (as developers are unlikely to expect that, and it has security implications).
+        // It should also make things faster, as we no longer have to consider whether the text node might be bindable.
+        return { 'controlsDescendantBindings': true };
+    },
+    'update': function (element, valueAccessor) {
+        ko.utils.setTextContent(element, valueAccessor());
+    }
+};
+ko.virtualElements.allowedBindings['text'] = true;
+(function () {
+
+if (window && window.navigator) {
+    var parseVersion = function (matches) {
+        if (matches) {
+            return parseFloat(matches[1]);
+        }
+    };
+
+    // Detect various browser versions because some old versions don't fully support the 'input' event
+    var operaVersion = window.opera && window.opera.version && parseInt(window.opera.version()),
+        userAgent = window.navigator.userAgent,
+        safariVersion = parseVersion(userAgent.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),
+        firefoxVersion = parseVersion(userAgent.match(/Firefox\/([^ ]*)/));
+}
+
+// IE 8 and 9 have bugs that prevent the normal events from firing when the value changes.
+// But it does fire the 'selectionchange' event on many of those, presumably because the
+// cursor is moving and that counts as the selection changing. The 'selectionchange' event is
+// fired at the document level only and doesn't directly indicate which element changed. We
+// set up just one event handler for the document and use 'activeElement' to determine which
+// element was changed.
+if (ko.utils.ieVersion < 10) {
+    var selectionChangeRegisteredName = ko.utils.domData.nextKey(),
+        selectionChangeHandlerName = ko.utils.domData.nextKey();
+    var selectionChangeHandler = function(event) {
+        var target = this.activeElement,
+            handler = target && ko.utils.domData.get(target, selectionChangeHandlerName);
+        if (handler) {
+            handler(event);
+        }
+    };
+    var registerForSelectionChangeEvent = function (element, handler) {
+        var ownerDoc = element.ownerDocument;
+        if (!ko.utils.domData.get(ownerDoc, selectionChangeRegisteredName)) {
+            ko.utils.domData.set(ownerDoc, selectionChangeRegisteredName, true);
+            ko.utils.registerEventHandler(ownerDoc, 'selectionchange', selectionChangeHandler);
+        }
+        ko.utils.domData.set(element, selectionChangeHandlerName, handler);
+    };
+}
+
+ko.bindingHandlers['textInput'] = {
+    'init': function (element, valueAccessor, allBindings) {
+
+        var previousElementValue = element.value,
+            timeoutHandle,
+            elementValueBeforeEvent;
+
+        var updateModel = function (event) {
+            clearTimeout(timeoutHandle);
+            elementValueBeforeEvent = timeoutHandle = undefined;
+
+            var elementValue = element.value;
+            if (previousElementValue !== elementValue) {
+                // Provide a way for tests to know exactly which event was processed
+                if (DEBUG && event) element['_ko_textInputProcessedEvent'] = event.type;
+                previousElementValue = elementValue;
+                ko.expressionRewriting.writeValueToProperty(valueAccessor(), allBindings, 'textInput', elementValue);
+            }
+        };
+
+        var deferUpdateModel = function (event) {
+            if (!timeoutHandle) {
+                // The elementValueBeforeEvent variable is set *only* during the brief gap between an
+                // event firing and the updateModel function running. This allows us to ignore model
+                // updates that are from the previous state of the element, usually due to techniques
+                // such as rateLimit. Such updates, if not ignored, can cause keystrokes to be lost.
+                elementValueBeforeEvent = element.value;
+                var handler = DEBUG ? updateModel.bind(element, {type: event.type}) : updateModel;
+                timeoutHandle = setTimeout(handler, 4);
+            }
+        };
+
+        var updateView = function () {
+            var modelValue = ko.utils.unwrapObservable(valueAccessor());
+
+            if (modelValue === null || modelValue === undefined) {
+                modelValue = '';
+            }
+
+            if (elementValueBeforeEvent !== undefined && modelValue === elementValueBeforeEvent) {
+                setTimeout(updateView, 4);
+                return;
+            }
+
+            // Update the element only if the element and model are different. On some browsers, updating the value
+            // will move the cursor to the end of the input, which would be bad while the user is typing.
+            if (element.value !== modelValue) {
+                previousElementValue = modelValue;  // Make sure we ignore events (propertychange) that result from updating the value
+                element.value = modelValue;
+            }
+        };
+
+        var onEvent = function (event, handler) {
+            ko.utils.registerEventHandler(element, event, handler);
+        };
+
+        if (DEBUG && ko.bindingHandlers['textInput']['_forceUpdateOn']) {
+            // Provide a way for tests to specify exactly which events are bound
+            ko.utils.arrayForEach(ko.bindingHandlers['textInput']['_forceUpdateOn'], function(eventName) {
+                if (eventName.slice(0,5) == 'after') {
+                    onEvent(eventName.slice(5), deferUpdateModel);
+                } else {
+                    onEvent(eventName, updateModel);
+                }
+            });
+        } else {
+            if (ko.utils.ieVersion < 10) {
+                // Internet Explorer <= 8 doesn't support the 'input' event, but does include 'propertychange' that fires whenever
+                // any property of an element changes. Unlike 'input', it also fires if a property is changed from JavaScript code,
+                // but that's an acceptable compromise for this binding. IE 9 does support 'input', but since it doesn't fire it
+                // when using autocomplete, we'll use 'propertychange' for it also.
+                onEvent('propertychange', function(event) {
+                    if (event.propertyName === 'value') {
+                        updateModel(event);
+                    }
+                });
+
+                if (ko.utils.ieVersion == 8) {
+                    // IE 8 has a bug where it fails to fire 'propertychange' on the first update following a value change from
+                    // JavaScript code. It also doesn't fire if you clear the entire value. To fix this, we bind to the following
+                    // events too.
+                    onEvent('keyup', updateModel);      // A single keystoke
+                    onEvent('keydown', updateModel);    // The first character when a key is held down
+                }
+                if (ko.utils.ieVersion >= 8) {
+                    // Internet Explorer 9 doesn't fire the 'input' event when deleting text, including using
+                    // the backspace, delete, or ctrl-x keys, clicking the 'x' to clear the input, dragging text
+                    // out of the field, and cutting or deleting text using the context menu. 'selectionchange'
+                    // can detect all of those except dragging text out of the field, for which we use 'dragend'.
+                    // These are also needed in IE8 because of the bug described above.
+                    registerForSelectionChangeEvent(element, updateModel);  // 'selectionchange' covers cut, paste, drop, delete, etc.
+                    onEvent('dragend', deferUpdateModel);
+                }
+            } else {
+                // All other supported browsers support the 'input' event, which fires whenever the content of the element is changed
+                // through the user interface.
+                onEvent('input', updateModel);
+
+                if (safariVersion < 5 && ko.utils.tagNameLower(element) === "textarea") {
+                    // Safari <5 doesn't fire the 'input' event for <textarea> elements (it does fire 'textInput'
+                    // but only when typing). So we'll just catch as much as we can with keydown, cut, and paste.
+                    onEvent('keydown', deferUpdateModel);
+                    onEvent('paste', deferUpdateModel);
+                    onEvent('cut', deferUpdateModel);
+                } else if (operaVersion < 11) {
+                    // Opera 10 doesn't always fire the 'input' event for cut, paste, undo & drop operations.
+                    // We can try to catch some of those using 'keydown'.
+                    onEvent('keydown', deferUpdateModel);
+                } else if (firefoxVersion < 4.0) {
+                    // Firefox <= 3.6 doesn't fire the 'input' event when text is filled in through autocomplete
+                    onEvent('DOMAutoComplete', updateModel);
+
+                    // Firefox <=3.5 doesn't fire the 'input' event when text is dropped into the input.
+                    onEvent('dragdrop', updateModel);       // <3.5
+                    onEvent('drop', updateModel);           // 3.5
+                }
+            }
+        }
+
+        // Bind to the change event so that we can catch programmatic updates of the value that fire this event.
+        onEvent('change', updateModel);
+
+        ko.computed(updateView, null, { disposeWhenNodeIsRemoved: element });
+    }
+};
+ko.expressionRewriting.twoWayBindings['textInput'] = true;
+
+// textinput is an alias for textInput
+ko.bindingHandlers['textinput'] = {
+    // preprocess is the only way to set up a full alias
+    'preprocess': function (value, name, addBinding) {
+        addBinding('textInput', value);
+    }
+};
+
+})();ko.bindingHandlers['uniqueName'] = {
+    'init': function (element, valueAccessor) {
+        if (valueAccessor()) {
+            var name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex);
+            ko.utils.setElementName(element, name);
+        }
+    }
+};
+ko.bindingHandlers['uniqueName'].currentIndex = 0;
+ko.bindingHandlers['value'] = {
+    'after': ['options', 'foreach'],
+    'init': function (element, valueAccessor, allBindings) {
+        // If the value binding is placed on a radio/checkbox, then just pass through to checkedValue and quit
+        if (element.tagName.toLowerCase() == "input" && (element.type == "checkbox" || element.type == "radio")) {
+            ko.applyBindingAccessorsToNode(element, { 'checkedValue': valueAccessor });
+            return;
+        }
+
+        // Always catch "change" event; possibly other events too if asked
+        var eventsToCatch = ["change"];
+        var requestedEventsToCatch = allBindings.get("valueUpdate");
+        var propertyChangedFired = false;
+        var elementValueBeforeEvent = null;
+
+        if (requestedEventsToCatch) {
+            if (typeof requestedEventsToCatch == "string") // Allow both individual event names, and arrays of event names
+                requestedEventsToCatch = [requestedEventsToCatch];
+            ko.utils.arrayPushAll(eventsToCatch, requestedEventsToCatch);
+            eventsToCatch = ko.utils.arrayGetDistinctValues(eventsToCatch);
+        }
+
+        var valueUpdateHandler = function() {
+            elementValueBeforeEvent = null;
+            propertyChangedFired = false;
+            var modelValue = valueAccessor();
+            var elementValue = ko.selectExtensions.readValue(element);
+            ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'value', elementValue);
+        }
+
+        // Workaround for https://github.com/SteveSanderson/knockout/issues/122
+        // IE doesn't fire "change" events on textboxes if the user selects a value from its autocomplete list
+        var ieAutoCompleteHackNeeded = ko.utils.ieVersion && element.tagName.toLowerCase() == "input" && element.type == "text"
+                                       && element.autocomplete != "off" && (!element.form || element.form.autocomplete != "off");
+        if (ieAutoCompleteHackNeeded && ko.utils.arrayIndexOf(eventsToCatch, "propertychange") == -1) {
+            ko.utils.registerEventHandler(element, "propertychange", function () { propertyChangedFired = true });
+            ko.utils.registerEventHandler(element, "focus", function () { propertyChangedFired = false });
+            ko.utils.registerEventHandler(element, "blur", function() {
+                if (propertyChangedFired) {
+                    valueUpdateHandler();
+                }
+            });
+        }
+
+        ko.utils.arrayForEach(eventsToCatch, function(eventName) {
+            // The syntax "after<eventname>" means "run the handler asynchronously after the event"
+            // This is useful, for example, to catch "keydown" events after the browser has updated the control
+            // (otherwise, ko.selectExtensions.readValue(this) will receive the control's value *before* the key event)
+            var handler = valueUpdateHandler;
+            if (ko.utils.stringStartsWith(eventName, "after")) {
+                handler = function() {
+                    // The elementValueBeforeEvent variable is non-null *only* during the brief gap between
+                    // a keyX event firing and the valueUpdateHandler running, which is scheduled to happen
+                    // at the earliest asynchronous opportunity. We store this temporary information so that
+                    // if, between keyX and valueUpdateHandler, the underlying model value changes separately,
+                    // we can overwrite that model value change with the value the user just typed. Otherwise,
+                    // techniques like rateLimit can trigger model changes at critical moments that will
+                    // override the user's inputs, causing keystrokes to be lost.
+                    elementValueBeforeEvent = ko.selectExtensions.readValue(element);
+                    setTimeout(valueUpdateHandler, 0);
+                };
+                eventName = eventName.substring("after".length);
+            }
+            ko.utils.registerEventHandler(element, eventName, handler);
+        });
+
+        var updateFromModel = function () {
+            var newValue = ko.utils.unwrapObservable(valueAccessor());
+            var elementValue = ko.selectExtensions.readValue(element);
+
+            if (elementValueBeforeEvent !== null && newValue === elementValueBeforeEvent) {
+                setTimeout(updateFromModel, 0);
+                return;
+            }
+
+            var valueHasChanged = (newValue !== elementValue);
+
+            if (valueHasChanged) {
+                if (ko.utils.tagNameLower(element) === "select") {
+                    var allowUnset = allBindings.get('valueAllowUnset');
+                    var applyValueAction = function () {
+                        ko.selectExtensions.writeValue(element, newValue, allowUnset);
+                    };
+                    applyValueAction();
+
+                    if (!allowUnset && newValue !== ko.selectExtensions.readValue(element)) {
+                        // If you try to set a model value that can't be represented in an already-populated dropdown, reject that change,
+                        // because you're not allowed to have a model value that disagrees with a visible UI selection.
+                        ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, "change"]);
+                    } else {
+                        // Workaround for IE6 bug: It won't reliably apply values to SELECT nodes during the same execution thread
+                        // right after you've changed the set of OPTION nodes on it. So for that node type, we'll schedule a second thread
+                        // to apply the value as well.
+                        setTimeout(applyValueAction, 0);
+                    }
+                } else {
+                    ko.selectExtensions.writeValue(element, newValue);
+                }
+            }
+        };
+
+        ko.computed(updateFromModel, null, { disposeWhenNodeIsRemoved: element });
+    },
+    'update': function() {} // Keep for backwards compatibility with code that may have wrapped value binding
+};
+ko.expressionRewriting.twoWayBindings['value'] = true;
+ko.bindingHandlers['visible'] = {
+    'update': function (element, valueAccessor) {
+        var value = ko.utils.unwrapObservable(valueAccessor());
+        var isCurrentlyVisible = !(element.style.display == "none");
+        if (value && !isCurrentlyVisible)
+            element.style.display = "";
+        else if ((!value) && isCurrentlyVisible)
+            element.style.display = "none";
+    }
+};
+// 'click' is just a shorthand for the usual full-length event:{click:handler}
+makeEventHandlerShortcut('click');
+// If you want to make a custom template engine,
+//
+// [1] Inherit from this class (like ko.nativeTemplateEngine does)
+// [2] Override 'renderTemplateSource', supplying a function with this signature:
+//
+//        function (templateSource, bindingContext, options) {
+//            // - templateSource.text() is the text of the template you should render
+//            // - bindingContext.$data is the data you should pass into the template
+//            //   - you might also want to make bindingContext.$parent, bindingContext.$parents,
+//            //     and bindingContext.$root available in the template too
+//            // - options gives you access to any other properties set on "data-bind: { template: options }"
+//            //
+//            // Return value: an array of DOM nodes
+//        }
+//
+// [3] Override 'createJavaScriptEvaluatorBlock', supplying a function with this signature:
+//
+//        function (script) {
+//            // Return value: Whatever syntax means "Evaluate the JavaScript statement 'script' and output the result"
+//            //               For example, the jquery.tmpl template engine converts 'someScript' to '${ someScript }'
+//        }
+//
+//     This is only necessary if you want to allow data-bind attributes to reference arbitrary template variables.
+//     If you don't want to allow that, you can set the property 'allowTemplateRewriting' to false (like ko.nativeTemplateEngine does)
+//     and then you don't need to override 'createJavaScriptEvaluatorBlock'.
+
+ko.templateEngine = function () { };
+
+ko.templateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) {
+    throw new Error("Override renderTemplateSource");
+};
+
+ko.templateEngine.prototype['createJavaScriptEvaluatorBlock'] = function (script) {
+    throw new Error("Override createJavaScriptEvaluatorBlock");
+};
+
+ko.templateEngine.prototype['makeTemplateSource'] = function(template, templateDocument) {
+    // Named template
+    if (typeof template == "string") {
+        templateDocument = templateDocument || document;
+        var elem = templateDocument.getElementById(template);
+        if (!elem)
+            throw new Error("Cannot find template with ID " + template);
+        return new ko.templateSources.domElement(elem);
+    } else if ((template.nodeType == 1) || (template.nodeType == 8)) {
+        // Anonymous template
+        return new ko.templateSources.anonymousTemplate(template);
+    } else
+        throw new Error("Unknown template type: " + template);
+};
+
+ko.templateEngine.prototype['renderTemplate'] = function (template, bindingContext, options, templateDocument) {
+    var templateSource = this['makeTemplateSource'](template, templateDocument);
+    return this['renderTemplateSource'](templateSource, bindingContext, options);
+};
+
+ko.templateEngine.prototype['isTemplateRewritten'] = function (template, templateDocument) {
+    // Skip rewriting if requested
+    if (this['allowTemplateRewriting'] === false)
+        return true;
+    return this['makeTemplateSource'](template, templateDocument)['data']("isRewritten");
+};
+
+ko.templateEngine.prototype['rewriteTemplate'] = function (template, rewriterCallback, templateDocument) {
+    var templateSource = this['makeTemplateSource'](template, templateDocument);
+    var rewritten = rewriterCallback(templateSource['text']());
+    templateSource['text'](rewritten);
+    templateSource['data']("isRewritten", true);
+};
+
+ko.exportSymbol('templateEngine', ko.templateEngine);
+
+ko.templateRewriting = (function () {
+    var memoizeDataBindingAttributeSyntaxRegex = /(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi;
+    var memoizeVirtualContainerBindingSyntaxRegex = /<!--\s*ko\b\s*([\s\S]*?)\s*-->/g;
+
+    function validateDataBindValuesForRewriting(keyValueArray) {
+        var allValidators = ko.expressionRewriting.bindingRewriteValidators;
+        for (var i = 0; i < keyValueArray.length; i++) {
+            var key = keyValueArray[i]['key'];
+            if (allValidators.hasOwnProperty(key)) {
+                var validator = allValidators[key];
+
+                if (typeof validator === "function") {
+                    var possibleErrorMessage = validator(keyValueArray[i]['value']);
+                    if (possibleErrorMessage)
+                        throw new Error(possibleErrorMessage);
+                } else if (!validator) {
+                    throw new Error("This template engine does not support the '" + key + "' binding within its templates");
+                }
+            }
+        }
+    }
+
+    function constructMemoizedTagReplacement(dataBindAttributeValue, tagToRetain, nodeName, templateEngine) {
+        var dataBindKeyValueArray = ko.expressionRewriting.parseObjectLiteral(dataBindAttributeValue);
+        validateDataBindValuesForRewriting(dataBindKeyValueArray);
+        var rewrittenDataBindAttributeValue = ko.expressionRewriting.preProcessBindings(dataBindKeyValueArray, {'valueAccessors':true});
+
+        // For no obvious reason, Opera fails to evaluate rewrittenDataBindAttributeValue unless it's wrapped in an additional
+        // anonymous function, even though Opera's built-in debugger can evaluate it anyway. No other browser requires this
+        // extra indirection.
+        var applyBindingsToNextSiblingScript =
+            "ko.__tr_ambtns(function($context,$element){return(function(){return{ " + rewrittenDataBindAttributeValue + " } })()},'" + nodeName.toLowerCase() + "')";
+        return templateEngine['createJavaScriptEvaluatorBlock'](applyBindingsToNextSiblingScript) + tagToRetain;
+    }
+
+    return {
+        ensureTemplateIsRewritten: function (template, templateEngine, templateDocument) {
+            if (!templateEngine['isTemplateRewritten'](template, templateDocument))
+                templateEngine['rewriteTemplate'](template, function (htmlString) {
+                    return ko.templateRewriting.memoizeBindingAttributeSyntax(htmlString, templateEngine);
+                }, templateDocument);
+        },
+
+        memoizeBindingAttributeSyntax: function (htmlString, templateEngine) {
+            return htmlString.replace(memoizeDataBindingAttributeSyntaxRegex, function () {
+                return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[4], /* tagToRetain: */ arguments[1], /* nodeName: */ arguments[2], templateEngine);
+            }).replace(memoizeVirtualContainerBindingSyntaxRegex, function() {
+                return constructMemoizedTagReplacement(/* dataBindAttributeValue: */ arguments[1], /* tagToRetain: */ "<!-- ko -->", /* nodeName: */ "#comment", templateEngine);
+            });
+        },
+
+        applyMemoizedBindingsToNextSibling: function (bindings, nodeName) {
+            return ko.memoization.memoize(function (domNode, bindingContext) {
+                var nodeToBind = domNode.nextSibling;
+                if (nodeToBind && nodeToBind.nodeName.toLowerCase() === nodeName) {
+                    ko.applyBindingAccessorsToNode(nodeToBind, bindings, bindingContext);
+                }
+            });
+        }
+    }
+})();
+
+
+// Exported only because it has to be referenced by string lookup from within rewritten template
+ko.exportSymbol('__tr_ambtns', ko.templateRewriting.applyMemoizedBindingsToNextSibling);
+(function() {
+    // A template source represents a read/write way of accessing a template. This is to eliminate the need for template loading/saving
+    // logic to be duplicated in every template engine (and means they can all work with anonymous templates, etc.)
+    //
+    // Two are provided by default:
+    //  1. ko.templateSources.domElement       - reads/writes the text content of an arbitrary DOM element
+    //  2. ko.templateSources.anonymousElement - uses ko.utils.domData to read/write text *associated* with the DOM element, but
+    //                                           without reading/writing the actual element text content, since it will be overwritten
+    //                                           with the rendered template output.
+    // You can implement your own template source if you want to fetch/store templates somewhere other than in DOM elements.
+    // Template sources need to have the following functions:
+    //   text()             - returns the template text from your storage location
+    //   text(value)        - writes the supplied template text to your storage location
+    //   data(key)          - reads values stored using data(key, value) - see below
+    //   data(key, value)   - associates "value" with this template and the key "key". Is used to store information like "isRewritten".
+    //
+    // Optionally, template sources can also have the following functions:
+    //   nodes()            - returns a DOM element containing the nodes of this template, where available
+    //   nodes(value)       - writes the given DOM element to your storage location
+    // If a DOM element is available for a given template source, template engines are encouraged to use it in preference over text()
+    // for improved speed. However, all templateSources must supply text() even if they don't supply nodes().
+    //
+    // Once you've implemented a templateSource, make your template engine use it by subclassing whatever template engine you were
+    // using and overriding "makeTemplateSource" to return an instance of your custom template source.
+
+    ko.templateSources = {};
+
+    // ---- ko.templateSources.domElement -----
+
+    ko.templateSources.domElement = function(element) {
+        this.domElement = element;
+    }
+
+    ko.templateSources.domElement.prototype['text'] = function(/* valueToWrite */) {
+        var tagNameLower = ko.utils.tagNameLower(this.domElement),
+            elemContentsProperty = tagNameLower === "script" ? "text"
+                                 : tagNameLower === "textarea" ? "value"
+                                 : "innerHTML";
+
+        if (arguments.length == 0) {
+            return this.domElement[elemContentsProperty];
+        } else {
+            var valueToWrite = arguments[0];
+            if (elemContentsProperty === "innerHTML")
+                ko.utils.setHtml(this.domElement, valueToWrite);
+            else
+                this.domElement[elemContentsProperty] = valueToWrite;
+        }
+    };
+
+    var dataDomDataPrefix = ko.utils.domData.nextKey() + "_";
+    ko.templateSources.domElement.prototype['data'] = function(key /*, valueToWrite */) {
+        if (arguments.length === 1) {
+            return ko.utils.domData.get(this.domElement, dataDomDataPrefix + key);
+        } else {
+            ko.utils.domData.set(this.domElement, dataDomDataPrefix + key, arguments[1]);
+        }
+    };
+
+    // ---- ko.templateSources.anonymousTemplate -----
+    // Anonymous templates are normally saved/retrieved as DOM nodes through "nodes".
+    // For compatibility, you can also read "text"; it will be serialized from the nodes on demand.
+    // Writing to "text" is still supported, but then the template data will not be available as DOM nodes.
+
+    var anonymousTemplatesDomDataKey = ko.utils.domData.nextKey();
+    ko.templateSources.anonymousTemplate = function(element) {
+        this.domElement = element;
+    }
+    ko.templateSources.anonymousTemplate.prototype = new ko.templateSources.domElement();
+    ko.templateSources.anonymousTemplate.prototype.constructor = ko.templateSources.anonymousTemplate;
+    ko.templateSources.anonymousTemplate.prototype['text'] = function(/* valueToWrite */) {
+        if (arguments.length == 0) {
+            var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {};
+            if (templateData.textData === undefined && templateData.containerData)
+                templateData.textData = templateData.containerData.innerHTML;
+            return templateData.textData;
+        } else {
+            var valueToWrite = arguments[0];
+            ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {textData: valueToWrite});
+        }
+    };
+    ko.templateSources.domElement.prototype['nodes'] = function(/* valueToWrite */) {
+        if (arguments.length == 0) {
+            var templateData = ko.utils.domData.get(this.domElement, anonymousTemplatesDomDataKey) || {};
+            return templateData.containerData;
+        } else {
+            var valueToWrite = arguments[0];
+            ko.utils.domData.set(this.domElement, anonymousTemplatesDomDataKey, {containerData: valueToWrite});
+        }
+    };
+
+    ko.exportSymbol('templateSources', ko.templateSources);
+    ko.exportSymbol('templateSources.domElement', ko.templateSources.domElement);
+    ko.exportSymbol('templateSources.anonymousTemplate', ko.templateSources.anonymousTemplate);
+})();
+(function () {
+    var _templateEngine;
+    ko.setTemplateEngine = function (templateEngine) {
+        if ((templateEngine != undefined) && !(templateEngine instanceof ko.templateEngine))
+            throw new Error("templateEngine must inherit from ko.templateEngine");
+        _templateEngine = templateEngine;
+    }
+
+    function invokeForEachNodeInContinuousRange(firstNode, lastNode, action) {
+        var node, nextInQueue = firstNode, firstOutOfRangeNode = ko.virtualElements.nextSibling(lastNode);
+        while (nextInQueue && ((node = nextInQueue) !== firstOutOfRangeNode)) {
+            nextInQueue = ko.virtualElements.nextSibling(node);
+            action(node, nextInQueue);
+        }
+    }
+
+    function activateBindingsOnContinuousNodeArray(continuousNodeArray, bindingContext) {
+        // To be used on any nodes that have been rendered by a template and have been inserted into some parent element
+        // Walks through continuousNodeArray (which *must* be continuous, i.e., an uninterrupted sequence of sibling nodes, because
+        // the algorithm for walking them relies on this), and for each top-level item in the virtual-element sense,
+        // (1) Does a regular "applyBindings" to associate bindingContext with this node and to activate any non-memoized bindings
+        // (2) Unmemoizes any memos in the DOM subtree (e.g., to activate bindings that had been memoized during template rewriting)
+
+        if (continuousNodeArray.length) {
+            var firstNode = continuousNodeArray[0],
+                lastNode = continuousNodeArray[continuousNodeArray.length - 1],
+                parentNode = firstNode.parentNode,
+                provider = ko.bindingProvider['instance'],
+                preprocessNode = provider['preprocessNode'];
+
+            if (preprocessNode) {
+                invokeForEachNodeInContinuousRange(firstNode, lastNode, function(node, nextNodeInRange) {
+                    var nodePreviousSibling = node.previousSibling;
+                    var newNodes = preprocessNode.call(provider, node);
+                    if (newNodes) {
+                        if (node === firstNode)
+                            firstNode = newNodes[0] || nextNodeInRange;
+                        if (node === lastNode)
+                            lastNode = newNodes[newNodes.length - 1] || nodePreviousSibling;
+                    }
+                });
+
+                // Because preprocessNode can change the nodes, including the first and last nodes, update continuousNodeArray to match.
+                // We need the full set, including inner nodes, because the unmemoize step might remove the first node (and so the real
+                // first node needs to be in the array).
+                continuousNodeArray.length = 0;
+                if (!firstNode) { // preprocessNode might have removed all the nodes, in which case there's nothing left to do
+                    return;
+                }
+                if (firstNode === lastNode) {
+                    continuousNodeArray.push(firstNode);
+                } else {
+                    continuousNodeArray.push(firstNode, lastNode);
+                    ko.utils.fixUpContinuousNodeArray(continuousNodeArray, parentNode);
+                }
+            }
+
+            // Need to applyBindings *before* unmemoziation, because unmemoization might introduce extra nodes (that we don't want to re-bind)
+            // whereas a regular applyBindings won't introduce new memoized nodes
+            invokeForEachNodeInContinuousRange(firstNode, lastNode, function(node) {
+                if (node.nodeType === 1 || node.nodeType === 8)
+                    ko.applyBindings(bindingContext, node);
+            });
+            invokeForEachNodeInContinuousRange(firstNode, lastNode, function(node) {
+                if (node.nodeType === 1 || node.nodeType === 8)
+                    ko.memoization.unmemoizeDomNodeAndDescendants(node, [bindingContext]);
+            });
+
+            // Make sure any changes done by applyBindings or unmemoize are reflected in the array
+            ko.utils.fixUpContinuousNodeArray(continuousNodeArray, parentNode);
+        }
+    }
+
+    function getFirstNodeFromPossibleArray(nodeOrNodeArray) {
+        return nodeOrNodeArray.nodeType ? nodeOrNodeArray
+                                        : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0]
+                                        : null;
+    }
+
+    function executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options) {
+        options = options || {};
+        var firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
+        var templateDocument = firstTargetNode && firstTargetNode.ownerDocument;
+        var templateEngineToUse = (options['templateEngine'] || _templateEngine);
+        ko.templateRewriting.ensureTemplateIsRewritten(template, templateEngineToUse, templateDocument);
+        var renderedNodesArray = templateEngineToUse['renderTemplate'](template, bindingContext, options, templateDocument);
+
+        // Loosely check result is an array of DOM nodes
+        if ((typeof renderedNodesArray.length != "number") || (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType != "number"))
+            throw new Error("Template engine must return an array of DOM nodes");
+
+        var haveAddedNodesToParent = false;
+        switch (renderMode) {
+            case "replaceChildren":
+                ko.virtualElements.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray);
+                haveAddedNodesToParent = true;
+                break;
+            case "replaceNode":
+                ko.utils.replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray);
+                haveAddedNodesToParent = true;
+                break;
+            case "ignoreTargetNode": break;
+            default:
+                throw new Error("Unknown renderMode: " + renderMode);
+        }
+
+        if (haveAddedNodesToParent) {
+            activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext);
+            if (options['afterRender'])
+                ko.dependencyDetection.ignore(options['afterRender'], null, [renderedNodesArray, bindingContext['$data']]);
+        }
+
+        return renderedNodesArray;
+    }
+
+    function resolveTemplateName(template, data, context) {
+        // The template can be specified as:
+        if (ko.isObservable(template)) {
+            // 1. An observable, with string value
+            return template();
+        } else if (typeof template === 'function') {
+            // 2. A function of (data, context) returning a string
+            return template(data, context);
+        } else {
+            // 3. A string
+            return template;
+        }
+    }
+
+    ko.renderTemplate = function (template, dataOrBindingContext, options, targetNodeOrNodeArray, renderMode) {
+        options = options || {};
+        if ((options['templateEngine'] || _templateEngine) == undefined)
+            throw new Error("Set a template engine before calling renderTemplate");
+        renderMode = renderMode || "replaceChildren";
+
+        if (targetNodeOrNodeArray) {
+            var firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
+
+            var whenToDispose = function () { return (!firstTargetNode) || !ko.utils.domNodeIsAttachedToDocument(firstTargetNode); }; // Passive disposal (on next evaluation)
+            var activelyDisposeWhenNodeIsRemoved = (firstTargetNode && renderMode == "replaceNode") ? firstTargetNode.parentNode : firstTargetNode;
+
+            return ko.dependentObservable( // So the DOM is automatically updated when any dependency changes
+                function () {
+                    // Ensure we've got a proper binding context to work with
+                    var bindingContext = (dataOrBindingContext && (dataOrBindingContext instanceof ko.bindingContext))
+                        ? dataOrBindingContext
+                        : new ko.bindingContext(ko.utils.unwrapObservable(dataOrBindingContext));
+
+                    var templateName = resolveTemplateName(template, bindingContext['$data'], bindingContext),
+                        renderedNodesArray = executeTemplate(targetNodeOrNodeArray, renderMode, templateName, bindingContext, options);
+
+                    if (renderMode == "replaceNode") {
+                        targetNodeOrNodeArray = renderedNodesArray;
+                        firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray);
+                    }
+                },
+                null,
+                { disposeWhen: whenToDispose, disposeWhenNodeIsRemoved: activelyDisposeWhenNodeIsRemoved }
+            );
+        } else {
+            // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node
+            return ko.memoization.memoize(function (domNode) {
+                ko.renderTemplate(template, dataOrBindingContext, options, domNode, "replaceNode");
+            });
+        }
+    };
+
+    ko.renderTemplateForEach = function (template, arrayOrObservableArray, options, targetNode, parentBindingContext) {
+        // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then
+        // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter.
+        var arrayItemContext;
+
+        // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode
+        var executeTemplateForArrayItem = function (arrayValue, index) {
+            // Support selecting template as a function of the data being rendered
+            arrayItemContext = parentBindingContext['createChildContext'](arrayValue, options['as'], function(context) {
+                context['$index'] = index;
+            });
+
+            var templateName = resolveTemplateName(template, arrayValue, arrayItemContext);
+            return executeTemplate(null, "ignoreTargetNode", templateName, arrayItemContext, options);
+        }
+
+        // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode
+        var activateBindingsCallback = function(arrayValue, addedNodesArray, index) {
+            activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext);
+            if (options['afterRender'])
+                options['afterRender'](addedNodesArray, arrayValue);
+        };
+
+        return ko.dependentObservable(function () {
+            var unwrappedArray = ko.utils.unwrapObservable(arrayOrObservableArray) || [];
+            if (typeof unwrappedArray.length == "undefined") // Coerce single value into array
+                unwrappedArray = [unwrappedArray];
+
+            // Filter out any entries marked as destroyed
+            var filteredArray = ko.utils.arrayFilter(unwrappedArray, function(item) {
+                return options['includeDestroyed'] || item === undefined || item === null || !ko.utils.unwrapObservable(item['_destroy']);
+            });
+
+            // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function).
+            // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping.
+            ko.dependencyDetection.ignore(ko.utils.setDomNodeChildrenFromArrayMapping, null, [targetNode, filteredArray, executeTemplateForArrayItem, options, activateBindingsCallback]);
+
+        }, null, { disposeWhenNodeIsRemoved: targetNode });
+    };
+
+    var templateComputedDomDataKey = ko.utils.domData.nextKey();
+    function disposeOldComputedAndStoreNewOne(element, newComputed) {
+        var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey);
+        if (oldComputed && (typeof(oldComputed.dispose) == 'function'))
+            oldComputed.dispose();
+        ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && newComputed.isActive()) ? newComputed : undefined);
+    }
+
+    ko.bindingHandlers['template'] = {
+        'init': function(element, valueAccessor) {
+            // Support anonymous templates
+            var bindingValue = ko.utils.unwrapObservable(valueAccessor());
+            if (typeof bindingValue == "string" || bindingValue['name']) {
+                // It's a named template - clear the element
+                ko.virtualElements.emptyNode(element);
+            } else {
+                // It's an anonymous template - store the element contents, then clear the element
+                var templateNodes = ko.virtualElements.childNodes(element),
+                    container = ko.utils.moveCleanedNodesToContainerElement(templateNodes); // This also removes the nodes from their current parent
+                new ko.templateSources.anonymousTemplate(element)['nodes'](container);
+            }
+            return { 'controlsDescendantBindings': true };
+        },
+        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
+            var value = valueAccessor(),
+                dataValue,
+                options = ko.utils.unwrapObservable(value),
+                shouldDisplay = true,
+                templateComputed = null,
+                templateName;
+
+            if (typeof options == "string") {
+                templateName = value;
+                options = {};
+            } else {
+                templateName = options['name'];
+
+                // Support "if"/"ifnot" conditions
+                if ('if' in options)
+                    shouldDisplay = ko.utils.unwrapObservable(options['if']);
+                if (shouldDisplay && 'ifnot' in options)
+                    shouldDisplay = !ko.utils.unwrapObservable(options['ifnot']);
+
+                dataValue = ko.utils.unwrapObservable(options['data']);
+            }
+
+            if ('foreach' in options) {
+                // Render once for each data point (treating data set as empty if shouldDisplay==false)
+                var dataArray = (shouldDisplay && options['foreach']) || [];
+                templateComputed = ko.renderTemplateForEach(templateName || element, dataArray, options, element, bindingContext);
+            } else if (!shouldDisplay) {
+                ko.virtualElements.emptyNode(element);
+            } else {
+                // Render once for this single data point (or use the viewModel if no data was provided)
+                var innerBindingContext = ('data' in options) ?
+                    bindingContext['createChildContext'](dataValue, options['as']) :  // Given an explitit 'data' value, we create a child binding context for it
+                    bindingContext;                                                        // Given no explicit 'data' value, we retain the same binding context
+                templateComputed = ko.renderTemplate(templateName || element, innerBindingContext, options, element);
+            }
+
+            // It only makes sense to have a single template computed per element (otherwise which one should have its output displayed?)
+            disposeOldComputedAndStoreNewOne(element, templateComputed);
+        }
+    };
+
+    // Anonymous templates can't be rewritten. Give a nice error message if you try to do it.
+    ko.expressionRewriting.bindingRewriteValidators['template'] = function(bindingValue) {
+        var parsedBindingValue = ko.expressionRewriting.parseObjectLiteral(bindingValue);
+
+        if ((parsedBindingValue.length == 1) && parsedBindingValue[0]['unknown'])
+            return null; // It looks like a string literal, not an object literal, so treat it as a named template (which is allowed for rewriting)
+
+        if (ko.expressionRewriting.keyValueArrayContainsKey(parsedBindingValue, "name"))
+            return null; // Named templates can be rewritten, so return "no error"
+        return "This template engine does not support anonymous templates nested within its templates";
+    };
+
+    ko.virtualElements.allowedBindings['template'] = true;
+})();
+
+ko.exportSymbol('setTemplateEngine', ko.setTemplateEngine);
+ko.exportSymbol('renderTemplate', ko.renderTemplate);
+// Go through the items that have been added and deleted and try to find matches between them.
+ko.utils.findMovesInArrayComparison = function (left, right, limitFailedCompares) {
+    if (left.length && right.length) {
+        var failedCompares, l, r, leftItem, rightItem;
+        for (failedCompares = l = 0; (!limitFailedCompares || failedCompares < limitFailedCompares) && (leftItem = left[l]); ++l) {
+            for (r = 0; rightItem = right[r]; ++r) {
+                if (leftItem['value'] === rightItem['value']) {
+                    leftItem['moved'] = rightItem['index'];
+                    rightItem['moved'] = leftItem['index'];
+                    right.splice(r, 1);         // This item is marked as moved; so remove it from right list
+                    failedCompares = r = 0;     // Reset failed compares count because we're checking for consecutive failures
+                    break;
+                }
+            }
+            failedCompares += r;
+        }
+    }
+};
+
+ko.utils.compareArrays = (function () {
+    var statusNotInOld = 'added', statusNotInNew = 'deleted';
+
+    // Simple calculation based on Levenshtein distance.
+    function compareArrays(oldArray, newArray, options) {
+        // For backward compatibility, if the third arg is actually a bool, interpret
+        // it as the old parameter 'dontLimitMoves'. Newer code should use { dontLimitMoves: true }.
+        options = (typeof options === 'boolean') ? { 'dontLimitMoves': options } : (options || {});
+        oldArray = oldArray || [];
+        newArray = newArray || [];
+
+        if (oldArray.length <= newArray.length)
+            return compareSmallArrayToBigArray(oldArray, newArray, statusNotInOld, statusNotInNew, options);
+        else
+            return compareSmallArrayToBigArray(newArray, oldArray, statusNotInNew, statusNotInOld, options);
+    }
+
+    function compareSmallArrayToBigArray(smlArray, bigArray, statusNotInSml, statusNotInBig, options) {
+        var myMin = Math.min,
+            myMax = Math.max,
+            editDistanceMatrix = [],
+            smlIndex, smlIndexMax = smlArray.length,
+            bigIndex, bigIndexMax = bigArray.length,
+            compareRange = (bigIndexMax - smlIndexMax) || 1,
+            maxDistance = smlIndexMax + bigIndexMax + 1,
+            thisRow, lastRow,
+            bigIndexMaxForRow, bigIndexMinForRow;
+
+        for (smlIndex = 0; smlIndex <= smlIndexMax; smlIndex++) {
+            lastRow = thisRow;
+            editDistanceMatrix.push(thisRow = []);
+            bigIndexMaxForRow = myMin(bigIndexMax, smlIndex + compareRange);
+            bigIndexMinForRow = myMax(0, smlIndex - 1);
+            for (bigIndex = bigIndexMinForRow; bigIndex <= bigIndexMaxForRow; bigIndex++) {
+                if (!bigIndex)
+                    thisRow[bigIndex] = smlIndex + 1;
+                else if (!smlIndex)  // Top row - transform empty array into new array via additions
+                    thisRow[bigIndex] = bigIndex + 1;
+                else if (smlArray[smlIndex - 1] === bigArray[bigIndex - 1])
+                    thisRow[bigIndex] = lastRow[bigIndex - 1];                  // copy value (no edit)
+                else {
+                    var northDistance = lastRow[bigIndex] || maxDistance;       // not in big (deletion)
+                    var westDistance = thisRow[bigIndex - 1] || maxDistance;    // not in small (addition)
+                    thisRow[bigIndex] = myMin(northDistance, westDistance) + 1;
+                }
+            }
+        }
+
+        var editScript = [], meMinusOne, notInSml = [], notInBig = [];
+        for (smlIndex = smlIndexMax, bigIndex = bigIndexMax; smlIndex || bigIndex;) {
+            meMinusOne = editDistanceMatrix[smlIndex][bigIndex] - 1;
+            if (bigIndex && meMinusOne === editDistanceMatrix[smlIndex][bigIndex-1]) {
+                notInSml.push(editScript[editScript.length] = {     // added
+                    'status': statusNotInSml,
+                    'value': bigArray[--bigIndex],
+                    'index': bigIndex });
+            } else if (smlIndex && meMinusOne === editDistanceMatrix[smlIndex - 1][bigIndex]) {
+                notInBig.push(editScript[editScript.length] = {     // deleted
+                    'status': statusNotInBig,
+                    'value': smlArray[--smlIndex],
+                    'index': smlIndex });
+            } else {
+                --bigIndex;
+                --smlIndex;
+                if (!options['sparse']) {
+                    editScript.push({
+                        'status': "retained",
+                        'value': bigArray[bigIndex] });
+                }
+            }
+        }
+
+        // Set a limit on the number of consecutive non-matching comparisons; having it a multiple of
+        // smlIndexMax keeps the time complexity of this algorithm linear.
+        ko.utils.findMovesInArrayComparison(notInSml, notInBig, smlIndexMax * 10);
+
+        return editScript.reverse();
+    }
+
+    return compareArrays;
+})();
+
+ko.exportSymbol('utils.compareArrays', ko.utils.compareArrays);
+(function () {
+    // Objective:
+    // * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes,
+    //   map the array elements to arrays of DOM nodes, concatenate together all these arrays, and use them to populate the container DOM node
+    // * Next time we're given the same combination of things (with the array possibly having mutated), update the container DOM node
+    //   so that its children is again the concatenation of the mappings of the array elements, but don't re-map any array elements that we
+    //   previously mapped - retain those nodes, and just insert/delete other ones
+
+    // "callbackAfterAddingNodes" will be invoked after any "mapping"-generated nodes are inserted into the container node
+    // You can use this, for example, to activate bindings on those nodes.
+
+    function mapNodeAndRefreshWhenChanged(containerNode, mapping, valueToMap, callbackAfterAddingNodes, index) {
+        // Map this array value inside a dependentObservable so we re-map when any dependency changes
+        var mappedNodes = [];
+        var dependentObservable = ko.dependentObservable(function() {
+            var newMappedNodes = mapping(valueToMap, index, ko.utils.fixUpContinuousNodeArray(mappedNodes, containerNode)) || [];
+
+            // On subsequent evaluations, just replace the previously-inserted DOM nodes
+            if (mappedNodes.length > 0) {
+                ko.utils.replaceDomNodes(mappedNodes, newMappedNodes);
+                if (callbackAfterAddingNodes)
+                    ko.dependencyDetection.ignore(callbackAfterAddingNodes, null, [valueToMap, newMappedNodes, index]);
+            }
+
+            // Replace the contents of the mappedNodes array, thereby updating the record
+            // of which nodes would be deleted if valueToMap was itself later removed
+            mappedNodes.length = 0;
+            ko.utils.arrayPushAll(mappedNodes, newMappedNodes);
+        }, null, { disposeWhenNodeIsRemoved: containerNode, disposeWhen: function() { return !ko.utils.anyDomNodeIsAttachedToDocument(mappedNodes); } });
+        return { mappedNodes : mappedNodes, dependentObservable : (dependentObservable.isActive() ? dependentObservable : undefined) };
+    }
+
+    var lastMappingResultDomDataKey = ko.utils.domData.nextKey();
+
+    ko.utils.setDomNodeChildrenFromArrayMapping = function (domNode, array, mapping, options, callbackAfterAddingNodes) {
+        // Compare the provided array against the previous one
+        array = array || [];
+        options = options || {};
+        var isFirstExecution = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) === undefined;
+        var lastMappingResult = ko.utils.domData.get(domNode, lastMappingResultDomDataKey) || [];
+        var lastArray = ko.utils.arrayMap(lastMappingResult, function (x) { return x.arrayEntry; });
+        var editScript = ko.utils.compareArrays(lastArray, array, options['dontLimitMoves']);
+
+        // Build the new mapping result
+        var newMappingResult = [];
+        var lastMappingResultIndex = 0;
+        var newMappingResultIndex = 0;
+
+        var nodesToDelete = [];
+        var itemsToProcess = [];
+        var itemsForBeforeRemoveCallbacks = [];
+        var itemsForMoveCallbacks = [];
+        var itemsForAfterAddCallbacks = [];
+        var mapData;
+
+        function itemMovedOrRetained(editScriptIndex, oldPosition) {
+            mapData = lastMappingResult[oldPosition];
+            if (newMappingResultIndex !== oldPosition)
+                itemsForMoveCallbacks[editScriptIndex] = mapData;
+            // Since updating the index might change the nodes, do so before calling fixUpContinuousNodeArray
+            mapData.indexObservable(newMappingResultIndex++);
+            ko.utils.fixUpContinuousNodeArray(mapData.mappedNodes, domNode);
+            newMappingResult.push(mapData);
+            itemsToProcess.push(mapData);
+        }
+
+        function callCallback(callback, items) {
+            if (callback) {
+                for (var i = 0, n = items.length; i < n; i++) {
+                    if (items[i]) {
+                        ko.utils.arrayForEach(items[i].mappedNodes, function(node) {
+                            callback(node, i, items[i].arrayEntry);
+                        });
+                    }
+                }
+            }
+        }
+
+        for (var i = 0, editScriptItem, movedIndex; editScriptItem = editScript[i]; i++) {
+            movedIndex = editScriptItem['moved'];
+            switch (editScriptItem['status']) {
+                case "deleted":
+                    if (movedIndex === undefined) {
+                        mapData = lastMappingResult[lastMappingResultIndex];
+
+                        // Stop tracking changes to the mapping for these nodes
+                        if (mapData.dependentObservable)
+                            mapData.dependentObservable.dispose();
+
+                        // Queue these nodes for later removal
+                        nodesToDelete.push.apply(nodesToDelete, ko.utils.fixUpContinuousNodeArray(mapData.mappedNodes, domNode));
+                        if (options['beforeRemove']) {
+                            itemsForBeforeRemoveCallbacks[i] = mapData;
+                            itemsToProcess.push(mapData);
+                        }
+                    }
+                    lastMappingResultIndex++;
+                    break;
+
+                case "retained":
+                    itemMovedOrRetained(i, lastMappingResultIndex++);
+                    break;
+
+                case "added":
+                    if (movedIndex !== undefined) {
+                        itemMovedOrRetained(i, movedIndex);
+                    } else {
+                        mapData = { arrayEntry: editScriptItem['value'], indexObservable: ko.observable(newMappingResultIndex++) };
+                        newMappingResult.push(mapData);
+                        itemsToProcess.push(mapData);
+                        if (!isFirstExecution)
+                            itemsForAfterAddCallbacks[i] = mapData;
+                    }
+                    break;
+            }
+        }
+
+        // Call beforeMove first before any changes have been made to the DOM
+        callCallback(options['beforeMove'], itemsForMoveCallbacks);
+
+        // Next remove nodes for deleted items (or just clean if there's a beforeRemove callback)
+        ko.utils.arrayForEach(nodesToDelete, options['beforeRemove'] ? ko.cleanNode : ko.removeNode);
+
+        // Next add/reorder the remaining items (will include deleted items if there's a beforeRemove callback)
+        for (var i = 0, nextNode = ko.virtualElements.firstChild(domNode), lastNode, node; mapData = itemsToProcess[i]; i++) {
+            // Get nodes for newly added items
+            if (!mapData.mappedNodes)
+                ko.utils.extend(mapData, mapNodeAndRefreshWhenChanged(domNode, mapping, mapData.arrayEntry, callbackAfterAddingNodes, mapData.indexObservable));
+
+            // Put nodes in the right place if they aren't there already
+            for (var j = 0; node = mapData.mappedNodes[j]; nextNode = node.nextSibling, lastNode = node, j++) {
+                if (node !== nextNode)
+                    ko.virtualElements.insertAfter(domNode, node, lastNode);
+            }
+
+            // Run the callbacks for newly added nodes (for example, to apply bindings, etc.)
+            if (!mapData.initialized && callbackAfterAddingNodes) {
+                callbackAfterAddingNodes(mapData.arrayEntry, mapData.mappedNodes, mapData.indexObservable);
+                mapData.initialized = true;
+            }
+        }
+
+        // If there's a beforeRemove callback, call it after reordering.
+        // Note that we assume that the beforeRemove callback will usually be used to remove the nodes using
+        // some sort of animation, which is why we first reorder the nodes that will be removed. If the
+        // callback instead removes the nodes right away, it would be more efficient to skip reordering them.
+        // Perhaps we'll make that change in the future if this scenario becomes more common.
+        callCallback(options['beforeRemove'], itemsForBeforeRemoveCallbacks);
+
+        // Finally call afterMove and afterAdd callbacks
+        callCallback(options['afterMove'], itemsForMoveCallbacks);
+        callCallback(options['afterAdd'], itemsForAfterAddCallbacks);
+
+        // Store a copy of the array items we just considered so we can difference it next time
+        ko.utils.domData.set(domNode, lastMappingResultDomDataKey, newMappingResult);
+    }
+})();
+
+ko.exportSymbol('utils.setDomNodeChildrenFromArrayMapping', ko.utils.setDomNodeChildrenFromArrayMapping);
+ko.nativeTemplateEngine = function () {
+    this['allowTemplateRewriting'] = false;
+}
+
+ko.nativeTemplateEngine.prototype = new ko.templateEngine();
+ko.nativeTemplateEngine.prototype.constructor = ko.nativeTemplateEngine;
+ko.nativeTemplateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options) {
+    var useNodesIfAvailable = !(ko.utils.ieVersion < 9), // IE<9 cloneNode doesn't work properly
+        templateNodesFunc = useNodesIfAvailable ? templateSource['nodes'] : null,
+        templateNodes = templateNodesFunc ? templateSource['nodes']() : null;
+
+    if (templateNodes) {
+        return ko.utils.makeArray(templateNodes.cloneNode(true).childNodes);
+    } else {
+        var templateText = templateSource['text']();
+        return ko.utils.parseHtmlFragment(templateText);
+    }
+};
+
+ko.nativeTemplateEngine.instance = new ko.nativeTemplateEngine();
+ko.setTemplateEngine(ko.nativeTemplateEngine.instance);
+
+ko.exportSymbol('nativeTemplateEngine', ko.nativeTemplateEngine);
+(function() {
+    ko.jqueryTmplTemplateEngine = function () {
+        // Detect which version of jquery-tmpl you're using. Unfortunately jquery-tmpl
+        // doesn't expose a version number, so we have to infer it.
+        // Note that as of Knockout 1.3, we only support jQuery.tmpl 1.0.0pre and later,
+        // which KO internally refers to as version "2", so older versions are no longer detected.
+        var jQueryTmplVersion = this.jQueryTmplVersion = (function() {
+            if (!jQueryInstance || !(jQueryInstance['tmpl']))
+                return 0;
+            // Since it exposes no official version number, we use our own numbering system. To be updated as jquery-tmpl evolves.
+            try {
+                if (jQueryInstance['tmpl']['tag']['tmpl']['open'].toString().indexOf('__') >= 0) {
+                    // Since 1.0.0pre, custom tags should append markup to an array called "__"
+                    return 2; // Final version of jquery.tmpl
+                }
+            } catch(ex) { /* Apparently not the version we were looking for */ }
+
+            return 1; // Any older version that we don't support
+        })();
+
+        function ensureHasReferencedJQueryTemplates() {
+            if (jQueryTmplVersion < 2)
+                throw new Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");
+        }
+
+        function executeTemplate(compiledTemplate, data, jQueryTemplateOptions) {
+            return jQueryInstance['tmpl'](compiledTemplate, data, jQueryTemplateOptions);
+        }
+
+        this['renderTemplateSource'] = function(templateSource, bindingContext, options) {
+            options = options || {};
+            ensureHasReferencedJQueryTemplates();
+
+            // Ensure we have stored a precompiled version of this template (don't want to reparse on every render)
+            var precompiled = templateSource['data']('precompiled');
+            if (!precompiled) {
+                var templateText = templateSource['text']() || "";
+                // Wrap in "with($whatever.koBindingContext) { ... }"
+                templateText = "{{ko_with $item.koBindingContext}}" + templateText + "{{/ko_with}}";
+
+                precompiled = jQueryInstance['template'](null, templateText);
+                templateSource['data']('precompiled', precompiled);
+            }
+
+            var data = [bindingContext['$data']]; // Prewrap the data in an array to stop jquery.tmpl from trying to unwrap any arrays
+            var jQueryTemplateOptions = jQueryInstance['extend']({ 'koBindingContext': bindingContext }, options['templateOptions']);
+
+            var resultNodes = executeTemplate(precompiled, data, jQueryTemplateOptions);
+            resultNodes['appendTo'](document.createElement("div")); // Using "appendTo" forces jQuery/jQuery.tmpl to perform necessary cleanup work
+
+            jQueryInstance['fragments'] = {}; // Clear jQuery's fragment cache to avoid a memory leak after a large number of template renders
+            return resultNodes;
+        };
+
+        this['createJavaScriptEvaluatorBlock'] = function(script) {
+            return "{{ko_code ((function() { return " + script + " })()) }}";
+        };
+
+        this['addTemplate'] = function(templateName, templateMarkup) {
+            document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
+        };
+
+        if (jQueryTmplVersion > 0) {
+            jQueryInstance['tmpl']['tag']['ko_code'] = {
+                open: "__.push($1 || '');"
+            };
+            jQueryInstance['tmpl']['tag']['ko_with'] = {
+                open: "with($1) {",
+                close: "} "
+            };
+        }
+    };
+
+    ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine();
+    ko.jqueryTmplTemplateEngine.prototype.constructor = ko.jqueryTmplTemplateEngine;
+
+    // Use this one by default *only if jquery.tmpl is referenced*
+    var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine();
+    if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0)
+        ko.setTemplateEngine(jqueryTmplTemplateEngineInstance);
+
+    ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine);
+})();
+}));
+}());
+})();
\ No newline at end of file
diff --git a/lib/web/mage/apply/main.js b/lib/web/mage/apply/main.js
new file mode 100644
index 00000000000..42c7ce8493f
--- /dev/null
+++ b/lib/web/mage/apply/main.js
@@ -0,0 +1,133 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([
+    './registry',
+    'underscore',
+    'require'
+], function(registry, _, require) {
+    'use strict';
+
+    /**
+     * Initializes components assigned to a specied element via data-* attribute.
+     * @param {HTMLElement} el - Element to initialize components with.
+     * @private
+     */
+    function initElement(el) {
+        var data;
+
+        data = el.getAttribute('data-mage-apply');
+        data = JSON.parse(data);
+
+        _.each(data, function(config, component){
+            
+            if (registry.has(el, component)) {
+                return;
+            }
+
+            config = getConfig(el, component, config);
+
+            require([component], function(callback) {
+                registry.add(el, component);
+
+                callback(el, config);
+            });
+        });
+    }
+
+
+    /**
+     * Searches for a configurational object assigned to an element.
+     * @param {HTMLElement} el - Element that will be used as a parentNode for a configurational element.
+     * @param {String} component - Components name.
+     * @param {String|Object} config - Configurational object or its' selector.
+     * @returns {Object} Components' configuration.
+     * @private
+     */
+    function getConfig(el, component, config) {
+        var configNode,
+            nodeData;
+
+        configNode  = getConfigNode(config, component, el);
+        nodeData    = configNode ? JSON.parse(configNode.firstChild.nodeValue) : {};
+
+        return typeof config === 'object' ?
+            _.extend(config, nodeData) :
+            nodeData;
+    }
+
+
+    /**
+     * Searches for a components' configurational node.
+     * @param {string} selector - Configurational node selector.
+     * @param {String} component - Components name.
+     * @param {HTMLElement} parent - Element that will used as a parentNode for a configurational
+            element in case if its' selector is not specified.
+     * @returns {HTMLElement} Configurational node.
+     * @private
+     */
+    function getConfigNode(selector, component, parent) {
+        var node;
+
+        if (parent.tagName === 'SCRIPT') {
+            node = parent;
+        }
+        else{
+            node = selector && typeof selector === 'string' ?
+                document.querySelector(selector) :
+                parent.querySelector('script[type="mage/config"]');
+
+            if (!selector && (!node || node.parentNode !== parent)) {
+                node = false;
+            }
+        }
+
+        return node;
+    }
+
+    return {
+        /**
+         * Initializes components assigned to HTML elements via [data-mage-apply].
+         */
+        apply: function() {
+            var elements;
+
+            elements = document.querySelectorAll('[data-mage-apply]');
+
+            elements = Array.prototype.slice.call(elements);
+
+            elements.forEach(initElement);
+        },
+
+        /**
+         * Creates a wrapper function on a jQuerys' component constructor.
+         * @param {jQuery} $ - jQuery object.
+         * @param {String} constr - Constructors' name.
+         * returns {Function}
+         */
+        jqWrapper: function($, constr) {
+            return function(el, data) {
+                return $.fn[constr].call($(el), data);
+            };
+        }
+    };
+});
\ No newline at end of file
diff --git a/lib/web/mage/apply/registry.js b/lib/web/mage/apply/registry.js
new file mode 100644
index 00000000000..00e264ec934
--- /dev/null
+++ b/lib/web/mage/apply/registry.js
@@ -0,0 +1,99 @@
+/**
+ * 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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+define([], function(){
+    'use strict';
+
+    var initialized = {};
+
+    /**
+     * Generates a unique identifier.
+     * @returns {String}
+     * @private
+     */
+    function uniqueid() {
+        var idstr = String.fromCharCode((Math.random() * 25 + 65) | 0),
+            ascicode;
+
+        while (idstr.length < 5) {
+            ascicode = Math.floor((Math.random() * 42) + 48);
+
+            if (ascicode < 58 || ascicode > 64) {
+                idstr += String.fromCharCode(ascicode);
+            }
+        }
+
+        return idstr;
+    }
+
+    return {
+        /**
+         * Adds component to the initialized components list for the specified element.
+         * @param {HTMLElement} el - Element whose component should be added.
+         * @param {String} component - Components' name.
+         */
+        add: function(el, component) {
+            var uid = el.uid,
+                components;
+
+            if (!uid) {
+                el.uid = uid = uniqueid();
+                initialized[uid] = [];
+            }
+
+            components = initialized[uid];
+
+            if (!~components.indexOf(component)) {
+                components.push(component);
+            }
+        },
+
+
+        /**
+         * Removes component from the elements' list.
+         * @param {HTMLElement} el - Element whose component should be removed.
+         * @param {String} component - Components' name.
+         */
+        remove: function(el, component) {
+            var components;
+
+            if (this.has(el, component)) {
+                components = initialized[el.uid];
+
+                components.splice(components.indexOf(component), 1);
+            }
+        },
+
+
+        /**
+         * Checks whether the specfied element has a component in its' list.
+         * @param {HTMLElement} el - Element to check.
+         * @param {String} component - Components' name.
+         * @returns {Boolean}
+         */
+        has: function(el, component) {
+            var components = initialized[el.uid];
+
+            return components && ~components.indexOf(component);
+        }
+    };
+});
\ No newline at end of file
diff --git a/lib/web/mage/backend/bootstrap.js b/lib/web/mage/backend/bootstrap.js
index 06b119bcf05..ffc9ec3ba45 100644
--- a/lib/web/mage/backend/bootstrap.js
+++ b/lib/web/mage/backend/bootstrap.js
@@ -24,8 +24,9 @@
 /*global FORM_KEY:true*/
 define([
     "jquery",
+    "mage/apply/main",
     "mage/mage"
-], function($){
+], function($, Mage){
     'use strict';
 
     $.ajaxSetup({
@@ -85,6 +86,8 @@ define([
          */
         $.mage.init();
 
+        Mage.apply();
+
         /*
          * Initialization of notification widget
          */
diff --git a/lib/web/mage/bootstrap.js b/lib/web/mage/bootstrap.js
index c6cbc1f4602..f68c5e64e71 100644
--- a/lib/web/mage/bootstrap.js
+++ b/lib/web/mage/bootstrap.js
@@ -23,8 +23,9 @@
 /*jshint jquery:true browser:true */
 define([
     "jquery",
+    "mage/apply/main",
     "mage/mage"
-], function($){
+], function($, Mage){
     'use strict';
     
     $.ajaxSetup({
@@ -37,6 +38,8 @@ define([
          * and subscribe init action to contentUpdated event
          */
         $.mage.init();
+
+        Mage.apply();
     };
 
     $(bootstrap);
diff --git a/lib/web/mage/components.js b/lib/web/mage/components.js
index cbd757e331f..83ba3566d72 100644
--- a/lib/web/mage/components.js
+++ b/lib/web/mage/components.js
@@ -54,7 +54,7 @@ define([], function() {
         address: 'Magento_Customer/address',
         priceOption: 'Magento_Catalog/js/price-option',
         requireCookie: 'Magento_Core/js/require-cookie',
-        addToCart: 'Magento_Catalog/js/msrp',
+        addToCart: 'Magento_Msrp/js/msrp',
         tierPrice: 'Magento_Catalog/js/tier-price',
         dateOption: 'Magento_Catalog/js/date-option',
         zoom: 'mage/zoom',
diff --git a/lib/web/mage/dropdown.js b/lib/web/mage/dropdown.js
index 6e07d8aaa45..7a19c99f8da 100644
--- a/lib/web/mage/dropdown.js
+++ b/lib/web/mage/dropdown.js
@@ -202,5 +202,4 @@ define([
             }
         }
     });
-
 });
diff --git a/lib/web/moment.js b/lib/web/moment.js
new file mode 100644
index 00000000000..c30bbff233b
--- /dev/null
+++ b/lib/web/moment.js
@@ -0,0 +1,6 @@
+//! moment.js
+//! version : 2.8.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function d(a){rb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}function e(a,b){var c=!0;return l(function(){return c&&(d(a),c=!1),b.apply(this,arguments)},b)}function f(a,b){nc[a]||(d(b),nc[a]=!0)}function g(a,b){return function(c){return o(a.call(this,c),b)}}function h(a,b){return function(c){return this.localeData().ordinal(a.call(this,c),b)}}function i(){}function j(a,b){b!==!1&&E(a),m(this,a),this._d=new Date(+a._d)}function k(a){var b=x(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=rb.localeData(),this._bubble()}function l(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function m(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=b._pf),"undefined"!=typeof b._locale&&(a._locale=b._locale),Fb.length>0)for(c in Fb)d=Fb[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function n(a){return 0>a?Math.ceil(a):Math.floor(a)}function o(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.length<b;)d="0"+d;return(e?c?"+":"":"-")+d}function p(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function q(a,b){var c;return b=J(b,a),a.isBefore(b)?c=p(a,b):(c=p(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c}function r(a,b){return function(c,d){var e,g;return null===d||isNaN(+d)||(f(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),g=c,c=d,d=g),c="string"==typeof c?+c:c,e=rb.duration(c,d),s(this,e,a),this}}function s(a,b,c,d){var e=b._milliseconds,f=b._days,g=b._months;d=null==d?!0:d,e&&a._d.setTime(+a._d+e*c),f&&lb(a,"Date",kb(a,"Date")+f*c),g&&jb(a,kb(a,"Month")+g*c),d&&rb.updateOffset(a,f||g)}function t(a){return"[object Array]"===Object.prototype.toString.call(a)}function u(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function v(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&z(a[d])!==z(b[d]))&&g++;return g+f}function w(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=gc[a]||hc[b]||b}return a}function x(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=w(c),b&&(d[b]=a[c]));return d}function y(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}rb[b]=function(e,f){var g,h,i=rb._locale[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=rb().utc().set(d,a);return i.call(rb._locale,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function z(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function A(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function B(a,b,c){return fb(rb([a,11,31+b-c]),b,c).week}function C(a){return D(a)?366:365}function D(a){return a%4===0&&a%100!==0||a%400===0}function E(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[yb]<0||a._a[yb]>11?yb:a._a[zb]<1||a._a[zb]>A(a._a[xb],a._a[yb])?zb:a._a[Ab]<0||a._a[Ab]>23?Ab:a._a[Bb]<0||a._a[Bb]>59?Bb:a._a[Cb]<0||a._a[Cb]>59?Cb:a._a[Db]<0||a._a[Db]>999?Db:-1,a._pf._overflowDayOfYear&&(xb>b||b>zb)&&(b=zb),a._pf.overflow=b)}function F(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function G(a){return a?a.toLowerCase().replace("_","-"):a}function H(a){for(var b,c,d,e,f=0;f<a.length;){for(e=G(a[f]).split("-"),b=e.length,c=G(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=I(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&v(e,c,!0)>=b-1)break;b--}f++}return null}function I(a){var b=null;if(!Eb[a]&&Gb)try{b=rb.locale(),require("./locale/"+a),rb.locale(b)}catch(c){}return Eb[a]}function J(a,b){return b._isUTC?rb(a).zone(b._offset||0):rb(a).local()}function K(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function L(a){var b,c,d=a.match(Kb);for(b=0,c=d.length;c>b;b++)d[b]=mc[d[b]]?mc[d[b]]:K(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function M(a,b){return a.isValid()?(b=N(b,a.localeData()),ic[b]||(ic[b]=L(b)),ic[b](a)):a.localeData().invalidDate()}function N(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Lb.lastIndex=0;d>=0&&Lb.test(a);)a=a.replace(Lb,c),Lb.lastIndex=0,d-=1;return a}function O(a,b){var c,d=b._strict;switch(a){case"Q":return Wb;case"DDDD":return Yb;case"YYYY":case"GGGG":case"gggg":return d?Zb:Ob;case"Y":case"G":case"g":return _b;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?$b:Pb;case"S":if(d)return Wb;case"SS":if(d)return Xb;case"SSS":if(d)return Yb;case"DDD":return Nb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Rb;case"a":case"A":return b._locale._meridiemParse;case"X":return Ub;case"Z":case"ZZ":return Sb;case"T":return Tb;case"SSSS":return Qb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?Xb:Mb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Mb;case"Do":return Vb;default:return c=new RegExp(X(W(a.replace("\\","")),"i"))}}function P(a){a=a||"";var b=a.match(Sb)||[],c=b[b.length-1]||[],d=(c+"").match(ec)||["-",0,0],e=+(60*d[1])+z(d[2]);return"+"===d[0]?-e:e}function Q(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[yb]=3*(z(b)-1));break;case"M":case"MM":null!=b&&(e[yb]=z(b)-1);break;case"MMM":case"MMMM":d=c._locale.monthsParse(b),null!=d?e[yb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[zb]=z(b));break;case"Do":null!=b&&(e[zb]=z(parseInt(b,10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=z(b));break;case"YY":e[xb]=rb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[xb]=z(b);break;case"a":case"A":c._isPm=c._locale.isPM(b);break;case"H":case"HH":case"h":case"hh":e[Ab]=z(b);break;case"m":case"mm":e[Bb]=z(b);break;case"s":case"ss":e[Cb]=z(b);break;case"S":case"SS":case"SSS":case"SSSS":e[Db]=z(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=P(b);break;case"dd":case"ddd":case"dddd":d=c._locale.weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=z(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=rb.parseTwoDigitYear(b)}}function R(a){var c,d,e,f,g,h,i;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[xb],fb(rb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(g=a._locale._week.dow,h=a._locale._week.doy,d=b(c.gg,a._a[xb],fb(rb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=gb(d,e,f,h,g),a._a[xb]=i.year,a._dayOfYear=i.dayOfYear}function S(a){var c,d,e,f,g=[];if(!a._d){for(e=U(a),a._w&&null==a._a[zb]&&null==a._a[yb]&&R(a),a._dayOfYear&&(f=b(a._a[xb],e[xb]),a._dayOfYear>C(f)&&(a._pf._overflowDayOfYear=!0),d=bb(f,0,a._dayOfYear),a._a[yb]=d.getUTCMonth(),a._a[zb]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];a._d=(a._useUTC?bb:ab).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()+a._tzm)}}function T(a){var b;a._d||(b=x(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],S(a))}function U(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function V(a){if(a._f===rb.ISO_8601)return void Z(a);a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=""+a._i,h=g.length,i=0;for(d=N(a._f,a._locale).match(Kb)||[],b=0;b<d.length;b++)e=d[b],c=(g.match(O(e,a))||[])[0],c&&(f=g.substr(0,g.indexOf(c)),f.length>0&&a._pf.unusedInput.push(f),g=g.slice(g.indexOf(c)+c.length),i+=c.length),mc[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),Q(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=h-i,g.length>0&&a._pf.unusedInput.push(g),a._isPm&&a._a[Ab]<12&&(a._a[Ab]+=12),a._isPm===!1&&12===a._a[Ab]&&(a._a[Ab]=0),S(a),E(a)}function W(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function X(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function Y(a){var b,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;f<a._f.length;f++)g=0,b=m({},a),b._pf=c(),b._f=a._f[f],V(b),F(b)&&(g+=b._pf.charsLeftOver,g+=10*b._pf.unusedTokens.length,b._pf.score=g,(null==e||e>g)&&(e=g,d=b));l(a,d||b)}function Z(a){var b,c,d=a._i,e=ac.exec(d);if(e){for(a._pf.iso=!0,b=0,c=cc.length;c>b;b++)if(cc[b][1].exec(d)){a._f=cc[b][0]+(e[6]||" ");break}for(b=0,c=dc.length;c>b;b++)if(dc[b][1].exec(d)){a._f+=dc[b][0];break}d.match(Sb)&&(a._f+="Z"),V(a)}else a._isValid=!1}function $(a){Z(a),a._isValid===!1&&(delete a._isValid,rb.createFromInputFallback(a))}function _(b){var c,d=b._i;d===a?b._d=new Date:u(d)?b._d=new Date(+d):null!==(c=Hb.exec(d))?b._d=new Date(+c[1]):"string"==typeof d?$(b):t(d)?(b._a=d.slice(0),S(b)):"object"==typeof d?T(b):"number"==typeof d?b._d=new Date(d):rb.createFromInputFallback(b)}function ab(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function bb(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function cb(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function db(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function eb(a,b,c){var d=rb.duration(a).abs(),e=wb(d.as("s")),f=wb(d.as("m")),g=wb(d.as("h")),h=wb(d.as("d")),i=wb(d.as("M")),j=wb(d.as("y")),k=e<jc.s&&["s",e]||1===f&&["m"]||f<jc.m&&["mm",f]||1===g&&["h"]||g<jc.h&&["hh",g]||1===h&&["d"]||h<jc.d&&["dd",h]||1===i&&["M"]||i<jc.M&&["MM",i]||1===j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,db.apply({},k)}function fb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=rb(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function gb(a,b,c,d,e){var f,g,h=bb(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:C(a-1)+g}}function hb(b){var c=b._i,d=b._f;return b._locale=b._locale||rb.localeData(b._l),null===c||d===a&&""===c?rb.invalid({nullInput:!0}):("string"==typeof c&&(b._i=c=b._locale.preparse(c)),rb.isMoment(c)?new j(c,!0):(d?t(d)?Y(b):V(b):_(b),new j(b)))}function ib(a,b){var c,d;if(1===b.length&&t(b[0])&&(b=b[0]),!b.length)return rb();for(c=b[0],d=1;d<b.length;++d)b[d][a](c)&&(c=b[d]);return c}function jb(a,b){var c;return"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),A(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function kb(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function lb(a,b,c){return"Month"===b?jb(a,c):a._d["set"+(a._isUTC?"UTC":"")+b](c)}function mb(a,b){return function(c){return null!=c?(lb(this,a,c),rb.updateOffset(this,b),this):kb(this,a)}}function nb(a){return 400*a/146097}function ob(a){return 146097*a/400}function pb(a){rb.duration.fn[a]=function(){return this._data[a]}}function qb(a){"undefined"==typeof ender&&(sb=vb.moment,vb.moment=a?e("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.",rb):rb)}for(var rb,sb,tb,ub="2.8.1",vb="undefined"!=typeof global?global:this,wb=Math.round,xb=0,yb=1,zb=2,Ab=3,Bb=4,Cb=5,Db=6,Eb={},Fb=[],Gb="undefined"!=typeof module&&module.exports,Hb=/^\/?Date\((\-?\d+)/i,Ib=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Jb=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Kb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,Lb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,Mb=/\d\d?/,Nb=/\d{1,3}/,Ob=/\d{1,4}/,Pb=/[+\-]?\d{1,6}/,Qb=/\d+/,Rb=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Sb=/Z|[\+\-]\d\d:?\d\d/gi,Tb=/T/i,Ub=/[\+\-]?\d+(\.\d{1,3})?/,Vb=/\d{1,2}/,Wb=/\d/,Xb=/\d\d/,Yb=/\d{3}/,Zb=/\d{4}/,$b=/[+-]?\d{6}/,_b=/[+-]?\d+/,ac=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,bc="YYYY-MM-DDTHH:mm:ssZ",cc=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],dc=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],ec=/([\+\-]|\d\d)/gi,fc=("Date|Hours|Minutes|Seconds|Milliseconds".split("|"),{Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6}),gc={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",Q:"quarter",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},hc={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},ic={},jc={s:45,m:45,h:22,d:26,M:11},kc="DDD w W M D d".split(" "),lc="M D H h m s w W".split(" "),mc={M:function(){return this.month()+1},MMM:function(a){return this.localeData().monthsShort(this,a)},MMMM:function(a){return this.localeData().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.localeData().weekdaysMin(this,a)},ddd:function(a){return this.localeData().weekdaysShort(this,a)},dddd:function(a){return this.localeData().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return o(this.year()%100,2)},YYYY:function(){return o(this.year(),4)},YYYYY:function(){return o(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+o(Math.abs(a),6)},gg:function(){return o(this.weekYear()%100,2)},gggg:function(){return o(this.weekYear(),4)},ggggg:function(){return o(this.weekYear(),5)},GG:function(){return o(this.isoWeekYear()%100,2)},GGGG:function(){return o(this.isoWeekYear(),4)},GGGGG:function(){return o(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return z(this.milliseconds()/100)},SS:function(){return o(z(this.milliseconds()/10),2)},SSS:function(){return o(this.milliseconds(),3)},SSSS:function(){return o(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+o(z(a/60),2)+":"+o(z(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+o(z(a/60),2)+o(z(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},nc={},oc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];kc.length;)tb=kc.pop(),mc[tb+"o"]=h(mc[tb],tb);for(;lc.length;)tb=lc.pop(),mc[tb+tb]=g(mc[tb],2);mc.DDDD=g(mc.DDD,3),l(i.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=rb.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=rb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return fb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),rb=function(b,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=d,g._l=e,g._strict=f,g._isUTC=!1,g._pf=c(),hb(g)},rb.suppressDeprecationWarnings=!1,rb.createFromInputFallback=e("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i)}),rb.min=function(){var a=[].slice.call(arguments,0);return ib("isBefore",a)},rb.max=function(){var a=[].slice.call(arguments,0);return ib("isAfter",a)},rb.utc=function(b,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=d,g._strict=f,g._pf=c(),hb(g).utc()},rb.unix=function(a){return rb(1e3*a)},rb.duration=function(a,b){var c,d,e,f,g=a,h=null;return rb.isDuration(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=Ib.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:z(h[zb])*c,h:z(h[Ab])*c,m:z(h[Bb])*c,s:z(h[Cb])*c,ms:z(h[Db])*c}):(h=Jb.exec(a))?(c="-"===h[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},g={y:e(h[2]),M:e(h[3]),d:e(h[4]),h:e(h[5]),m:e(h[6]),s:e(h[7]),w:e(h[8])}):"object"==typeof g&&("from"in g||"to"in g)&&(f=q(rb(g.from),rb(g.to)),g={},g.ms=f.milliseconds,g.M=f.months),d=new k(g),rb.isDuration(a)&&a.hasOwnProperty("_locale")&&(d._locale=a._locale),d},rb.version=ub,rb.defaultFormat=bc,rb.ISO_8601=function(){},rb.momentProperties=Fb,rb.updateOffset=function(){},rb.relativeTimeThreshold=function(b,c){return jc[b]===a?!1:c===a?jc[b]:(jc[b]=c,!0)},rb.lang=e("moment.lang is deprecated. Use moment.locale instead.",function(a,b){return rb.locale(a,b)}),rb.locale=function(a,b){var c;return a&&(c="undefined"!=typeof b?rb.defineLocale(a,b):rb.localeData(a),c&&(rb.duration._locale=rb._locale=c)),rb._locale._abbr},rb.defineLocale=function(a,b){return null!==b?(b.abbr=a,Eb[a]||(Eb[a]=new i),Eb[a].set(b),rb.locale(a),Eb[a]):(delete Eb[a],null)},rb.langData=e("moment.langData is deprecated. Use moment.localeData instead.",function(a){return rb.localeData(a)}),rb.localeData=function(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return rb._locale;if(!t(a)){if(b=I(a))return b;a=[a]}return H(a)},rb.isMoment=function(a){return a instanceof j||null!=a&&a.hasOwnProperty("_isAMomentObject")},rb.isDuration=function(a){return a instanceof k};for(tb=oc.length-1;tb>=0;--tb)y(oc[tb]);rb.normalizeUnits=function(a){return w(a)},rb.invalid=function(a){var b=rb.utc(0/0);return null!=a?l(b._pf,a):b._pf.userInvalidated=!0,b},rb.parseZone=function(){return rb.apply(null,arguments).parseZone()},rb.parseTwoDigitYear=function(a){return z(a)+(z(a)>68?1900:2e3)},l(rb.fn=j.prototype,{clone:function(){return rb(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=rb(this).utc();return 0<a.year()&&a.year()<=9999?M(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):M(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return F(this)},isDSTShifted:function(){return this._a?this.isValid()&&v(this._a,(this._isUTC?rb.utc(this._a):rb(this._a)).toArray())>0:!1},parsingFlags:function(){return l({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(a){return this.zone(0,a)},local:function(a){return this._isUTC&&(this.zone(0,a),this._isUTC=!1,a&&this.add(this._d.getTimezoneOffset(),"m")),this},format:function(a){var b=M(this,a||rb.defaultFormat);return this.localeData().postformat(b)},add:r(1,"add"),subtract:r(-1,"subtract"),diff:function(a,b,c){var d,e,f=J(a,this),g=6e4*(this.zone()-f.zone());return b=w(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-rb(this).startOf("month")-(f-rb(f).startOf("month")))/d,e-=6e4*(this.zone()-rb(this).startOf("month").zone()-(f.zone()-rb(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:n(e)},from:function(a,b){return rb.duration({to:this,from:a}).locale(this.locale()).humanize(!b)},fromNow:function(a){return this.from(rb(),a)},calendar:function(a){var b=a||rb(),c=J(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this))},isLeapYear:function(){return D(this.year())},isDST:function(){return this.zone()<this.clone().month(0).zone()||this.zone()<this.clone().month(5).zone()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=cb(a,this.localeData()),this.add(a-b,"d")):b},month:mb("Month",!0),startOf:function(a){switch(a=w(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(a){return a=w(a),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms")},isAfter:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)>+rb(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+rb(a).startOf(b)},isSame:function(a,b){return b=b||"ms",+this.clone().startOf(b)===+J(a,this).startOf(b)},min:e("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(a){return a=rb.apply(null,arguments),this>a?this:a}),max:e("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=rb.apply(null,arguments),a>this?this:a}),zone:function(a,b){var c,d=this._offset||0;return null==a?this._isUTC?d:this._d.getTimezoneOffset():("string"==typeof a&&(a=P(a)),Math.abs(a)<16&&(a=60*a),!this._isUTC&&b&&(c=this._d.getTimezoneOffset()),this._offset=a,this._isUTC=!0,null!=c&&this.subtract(c,"m"),d!==a&&(!b||this._changeInProgress?s(this,rb.duration(d-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,rb.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?rb(a).zone():0,(this.zone()-a)%60===0},daysInMonth:function(){return A(this.year(),this.month())},dayOfYear:function(a){var b=wb((rb(this).startOf("day")-rb(this).startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=fb(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")},isoWeekYear:function(a){var b=fb(this,1,4).year;return null==a?b:this.add(a-b,"y")},week:function(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")},isoWeek:function(a){var b=fb(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")},weekday:function(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return B(this.year(),1,4)},weeksInYear:function(){var a=this.localeData()._week;return B(this.year(),a.dow,a.doy)},get:function(a){return a=w(a),this[a]()},set:function(a,b){return a=w(a),"function"==typeof this[a]&&this[a](b),this},locale:function(b){return b===a?this._locale._abbr:(this._locale=rb.localeData(b),this)},lang:e("moment().lang() is deprecated. Use moment().localeData() instead.",function(b){return b===a?this.localeData():(this._locale=rb.localeData(b),this)}),localeData:function(){return this._locale}}),rb.fn.millisecond=rb.fn.milliseconds=mb("Milliseconds",!1),rb.fn.second=rb.fn.seconds=mb("Seconds",!1),rb.fn.minute=rb.fn.minutes=mb("Minutes",!1),rb.fn.hour=rb.fn.hours=mb("Hours",!0),rb.fn.date=mb("Date",!0),rb.fn.dates=e("dates accessor is deprecated. Use date instead.",mb("Date",!0)),rb.fn.year=mb("FullYear",!0),rb.fn.years=e("years accessor is deprecated. Use year instead.",mb("FullYear",!0)),rb.fn.days=rb.fn.day,rb.fn.months=rb.fn.month,rb.fn.weeks=rb.fn.week,rb.fn.isoWeeks=rb.fn.isoWeek,rb.fn.quarters=rb.fn.quarter,rb.fn.toJSON=rb.fn.toISOString,l(rb.duration.fn=k.prototype,{_bubble:function(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;g.milliseconds=d%1e3,a=n(d/1e3),g.seconds=a%60,b=n(a/60),g.minutes=b%60,c=n(b/60),g.hours=c%24,e+=n(c/24),h=n(nb(e)),e-=n(ob(h)),f+=n(e/30),e%=30,h+=n(f/12),f%=12,g.days=e,g.months=f,g.years=h},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return n(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*z(this._months/12)},humanize:function(a){var b=eb(this,!a,this.localeData());return a&&(b=this.localeData().pastFuture(+this,b)),this.localeData().postformat(b)},add:function(a,b){var c=rb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=rb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=w(a),this[a.toLowerCase()+"s"]()},as:function(a){var b,c;if(a=w(a),b=this._days+this._milliseconds/864e5,"month"===a||"year"===a)return c=this._months+12*nb(b),"month"===a?c:c/12;switch(b+=ob(this._months/12),a){case"week":return b/7;case"day":return b;case"hour":return 24*b;case"minute":return 24*b*60;case"second":return 24*b*60*60;case"millisecond":return 24*b*60*60*1e3;default:throw new Error("Unknown unit "+a)}},lang:rb.fn.lang,locale:rb.fn.locale,toIsoString:e("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"},localeData:function(){return this._locale}});for(tb in fc)fc.hasOwnProperty(tb)&&pb(tb.toLowerCase());rb.duration.fn.asMilliseconds=function(){return this.as("ms")},rb.duration.fn.asSeconds=function(){return this.as("s")},rb.duration.fn.asMinutes=function(){return this.as("m")},rb.duration.fn.asHours=function(){return this.as("h")},rb.duration.fn.asDays=function(){return this.as("d")},rb.duration.fn.asWeeks=function(){return this.as("weeks")},rb.duration.fn.asMonths=function(){return this.as("M")},rb.duration.fn.asYears=function(){return this.as("y")},rb.locale("en",{ordinal:function(a){var b=a%10,c=1===z(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),Gb?module.exports=rb:"function"==typeof define&&define.amd?(define("moment",function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(vb.moment=sb),rb}),qb(!0)):qb()}).call(this);
\ No newline at end of file
diff --git a/lib/web/requirejs/text.js b/lib/web/requirejs/text.js
new file mode 100644
index 00000000000..9b8dddd7d9d
--- /dev/null
+++ b/lib/web/requirejs/text.js
@@ -0,0 +1,390 @@
+/**
+ * @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/requirejs/text for details
+ */
+/*jslint regexp: true */
+/*global require, XMLHttpRequest, ActiveXObject,
+  define, window, process, Packages,
+  java, location, Components, FileUtils */
+
+define(['module'], function (module) {
+    'use strict';
+
+    var text, fs, Cc, Ci, xpcIsWindows,
+        progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
+        xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
+        bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
+        hasLocation = typeof location !== 'undefined' && location.href,
+        defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
+        defaultHostName = hasLocation && location.hostname,
+        defaultPort = hasLocation && (location.port || undefined),
+        buildMap = {},
+        masterConfig = (module.config && module.config()) || {};
+
+    text = {
+        version: '2.0.12',
+
+        strip: function (content) {
+            //Strips <?xml ...?> declarations so that external SVG and XML
+            //documents can be added to a document without worry. Also, if the string
+            //is an HTML document, only the part inside the body tag is returned.
+            if (content) {
+                content = content.replace(xmlRegExp, "");
+                var matches = content.match(bodyRegExp);
+                if (matches) {
+                    content = matches[1];
+                }
+            } else {
+                content = "";
+            }
+            return content;
+        },
+
+        jsEscape: function (content) {
+            return content.replace(/(['\\])/g, '\\$1')
+                .replace(/[\f]/g, "\\f")
+                .replace(/[\b]/g, "\\b")
+                .replace(/[\n]/g, "\\n")
+                .replace(/[\t]/g, "\\t")
+                .replace(/[\r]/g, "\\r")
+                .replace(/[\u2028]/g, "\\u2028")
+                .replace(/[\u2029]/g, "\\u2029");
+        },
+
+        createXhr: masterConfig.createXhr || function () {
+            //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
+            var xhr, i, progId;
+            if (typeof XMLHttpRequest !== "undefined") {
+                return new XMLHttpRequest();
+            } else if (typeof ActiveXObject !== "undefined") {
+                for (i = 0; i < 3; i += 1) {
+                    progId = progIds[i];
+                    try {
+                        xhr = new ActiveXObject(progId);
+                    } catch (e) {}
+
+                    if (xhr) {
+                        progIds = [progId];  // so faster next time
+                        break;
+                    }
+                }
+            }
+
+            return xhr;
+        },
+
+        /**
+         * Parses a resource name into its component parts. Resource names
+         * look like: module/name.ext!strip, where the !strip part is
+         * optional.
+         * @param {String} name the resource name
+         * @returns {Object} with properties "moduleName", "ext" and "strip"
+         * where strip is a boolean.
+         */
+        parseName: function (name) {
+            var modName, ext, temp,
+                strip = false,
+                index = name.indexOf("."),
+                isRelative = name.indexOf('./') === 0 ||
+                             name.indexOf('../') === 0;
+
+            if (index !== -1 && (!isRelative || index > 1)) {
+                modName = name.substring(0, index);
+                ext = name.substring(index + 1, name.length);
+            } else {
+                modName = name;
+            }
+
+            temp = ext || modName;
+            index = temp.indexOf("!");
+            if (index !== -1) {
+                //Pull off the strip arg.
+                strip = temp.substring(index + 1) === "strip";
+                temp = temp.substring(0, index);
+                if (ext) {
+                    ext = temp;
+                } else {
+                    modName = temp;
+                }
+            }
+
+            return {
+                moduleName: modName,
+                ext: ext,
+                strip: strip
+            };
+        },
+
+        xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
+
+        /**
+         * Is an URL on another domain. Only works for browser use, returns
+         * false in non-browser environments. Only used to know if an
+         * optimized .js version of a text resource should be loaded
+         * instead.
+         * @param {String} url
+         * @returns Boolean
+         */
+        useXhr: function (url, protocol, hostname, port) {
+            var uProtocol, uHostName, uPort,
+                match = text.xdRegExp.exec(url);
+            if (!match) {
+                return true;
+            }
+            uProtocol = match[2];
+            uHostName = match[3];
+
+            uHostName = uHostName.split(':');
+            uPort = uHostName[1];
+            uHostName = uHostName[0];
+
+            return (!uProtocol || uProtocol === protocol) &&
+                   (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
+                   ((!uPort && !uHostName) || uPort === port);
+        },
+
+        finishLoad: function (name, strip, content, onLoad) {
+            content = strip ? text.strip(content) : content;
+            if (masterConfig.isBuild) {
+                buildMap[name] = content;
+            }
+            onLoad(content);
+        },
+
+        load: function (name, req, onLoad, config) {
+            //Name has format: some.module.filext!strip
+            //The strip part is optional.
+            //if strip is present, then that means only get the string contents
+            //inside a body tag in an HTML string. For XML/SVG content it means
+            //removing the <?xml ...?> declarations so the content can be inserted
+            //into the current doc without problems.
+
+            // Do not bother with the work if a build and text will
+            // not be inlined.
+            if (config && config.isBuild && !config.inlineText) {
+                onLoad();
+                return;
+            }
+
+            masterConfig.isBuild = config && config.isBuild;
+
+            var parsed = text.parseName(name),
+                nonStripName = parsed.moduleName +
+                    (parsed.ext ? '.' + parsed.ext : ''),
+                url = req.toUrl(nonStripName),
+                useXhr = (masterConfig.useXhr) ||
+                         text.useXhr;
+
+            // Do not load if it is an empty: url
+            if (url.indexOf('empty:') === 0) {
+                onLoad();
+                return;
+            }
+
+            //Load the text. Use XHR if possible and in a browser.
+            if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
+                text.get(url, function (content) {
+                    text.finishLoad(name, parsed.strip, content, onLoad);
+                }, function (err) {
+                    if (onLoad.error) {
+                        onLoad.error(err);
+                    }
+                });
+            } else {
+                //Need to fetch the resource across domains. Assume
+                //the resource has been optimized into a JS module. Fetch
+                //by the module name + extension, but do not include the
+                //!strip part to avoid file system issues.
+                req([nonStripName], function (content) {
+                    text.finishLoad(parsed.moduleName + '.' + parsed.ext,
+                                    parsed.strip, content, onLoad);
+                });
+            }
+        },
+
+        write: function (pluginName, moduleName, write, config) {
+            if (buildMap.hasOwnProperty(moduleName)) {
+                var content = text.jsEscape(buildMap[moduleName]);
+                write.asModule(pluginName + "!" + moduleName,
+                               "define(function () { return '" +
+                                   content +
+                               "';});\n");
+            }
+        },
+
+        writeFile: function (pluginName, moduleName, req, write, config) {
+            var parsed = text.parseName(moduleName),
+                extPart = parsed.ext ? '.' + parsed.ext : '',
+                nonStripName = parsed.moduleName + extPart,
+                //Use a '.js' file name so that it indicates it is a
+                //script that can be loaded across domains.
+                fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
+
+            //Leverage own load() method to load plugin value, but only
+            //write out values that do not have the strip argument,
+            //to avoid any potential issues with ! in file names.
+            text.load(nonStripName, req, function (value) {
+                //Use own write() method to construct full module value.
+                //But need to create shell that translates writeFile's
+                //write() to the right interface.
+                var textWrite = function (contents) {
+                    return write(fileName, contents);
+                };
+                textWrite.asModule = function (moduleName, contents) {
+                    return write.asModule(moduleName, fileName, contents);
+                };
+
+                text.write(pluginName, nonStripName, textWrite, config);
+            }, config);
+        }
+    };
+
+    if (masterConfig.env === 'node' || (!masterConfig.env &&
+            typeof process !== "undefined" &&
+            process.versions &&
+            !!process.versions.node &&
+            !process.versions['node-webkit'])) {
+        //Using special require.nodeRequire, something added by r.js.
+        fs = require.nodeRequire('fs');
+
+        text.get = function (url, callback, errback) {
+            try {
+                var file = fs.readFileSync(url, 'utf8');
+                //Remove BOM (Byte Mark Order) from utf8 files if it is there.
+                if (file.indexOf('\uFEFF') === 0) {
+                    file = file.substring(1);
+                }
+                callback(file);
+            } catch (e) {
+                if (errback) {
+                    errback(e);
+                }
+            }
+        };
+    } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
+            text.createXhr())) {
+        text.get = function (url, callback, errback, headers) {
+            var xhr = text.createXhr(), header;
+            xhr.open('GET', url, true);
+
+            //Allow plugins direct access to xhr headers
+            if (headers) {
+                for (header in headers) {
+                    if (headers.hasOwnProperty(header)) {
+                        xhr.setRequestHeader(header.toLowerCase(), headers[header]);
+                    }
+                }
+            }
+
+            //Allow overrides specified in config
+            if (masterConfig.onXhr) {
+                masterConfig.onXhr(xhr, url);
+            }
+
+            xhr.onreadystatechange = function (evt) {
+                var status, err;
+                //Do not explicitly handle errors, those should be
+                //visible via console output in the browser.
+                if (xhr.readyState === 4) {
+                    status = xhr.status || 0;
+                    if (status > 399 && status < 600) {
+                        //An http 4xx or 5xx error. Signal an error.
+                        err = new Error(url + ' HTTP status: ' + status);
+                        err.xhr = xhr;
+                        if (errback) {
+                            errback(err);
+                        }
+                    } else {
+                        callback(xhr.responseText);
+                    }
+
+                    if (masterConfig.onXhrComplete) {
+                        masterConfig.onXhrComplete(xhr, url);
+                    }
+                }
+            };
+            xhr.send(null);
+        };
+    } else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
+            typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
+        //Why Java, why is this so awkward?
+        text.get = function (url, callback) {
+            var stringBuffer, line,
+                encoding = "utf-8",
+                file = new java.io.File(url),
+                lineSeparator = java.lang.System.getProperty("line.separator"),
+                input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
+                content = '';
+            try {
+                stringBuffer = new java.lang.StringBuffer();
+                line = input.readLine();
+
+                // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
+                // http://www.unicode.org/faq/utf_bom.html
+
+                // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
+                // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
+                if (line && line.length() && line.charAt(0) === 0xfeff) {
+                    // Eat the BOM, since we've already found the encoding on this file,
+                    // and we plan to concatenating this buffer with others; the BOM should
+                    // only appear at the top of a file.
+                    line = line.substring(1);
+                }
+
+                if (line !== null) {
+                    stringBuffer.append(line);
+                }
+
+                while ((line = input.readLine()) !== null) {
+                    stringBuffer.append(lineSeparator);
+                    stringBuffer.append(line);
+                }
+                //Make sure we return a JavaScript string and not a Java string.
+                content = String(stringBuffer.toString()); //String
+            } finally {
+                input.close();
+            }
+            callback(content);
+        };
+    } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
+            typeof Components !== 'undefined' && Components.classes &&
+            Components.interfaces)) {
+        //Avert your gaze!
+        Cc = Components.classes;
+        Ci = Components.interfaces;
+        Components.utils['import']('resource://gre/modules/FileUtils.jsm');
+        xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
+
+        text.get = function (url, callback) {
+            var inStream, convertStream, fileObj,
+                readData = {};
+
+            if (xpcIsWindows) {
+                url = url.replace(/\//g, '\\');
+            }
+
+            fileObj = new FileUtils.File(url);
+
+            //XPCOM, you so crazy
+            try {
+                inStream = Cc['@mozilla.org/network/file-input-stream;1']
+                           .createInstance(Ci.nsIFileInputStream);
+                inStream.init(fileObj, 1, 0, false);
+
+                convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
+                                .createInstance(Ci.nsIConverterInputStream);
+                convertStream.init(inStream, "utf-8", inStream.available(),
+                Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+                convertStream.readString(inStream.available(), readData);
+                convertStream.close();
+                inStream.close();
+                callback(readData.value);
+            } catch (e) {
+                throw new Error((fileObj && fileObj.path || '') + ': ' + e);
+            }
+        };
+    }
+    return text;
+});
\ No newline at end of file
diff --git a/lib/web/underscore.js b/lib/web/underscore.js
index a12f0d96cfb..d5b3375f28d 100644
--- a/lib/web/underscore.js
+++ b/lib/web/underscore.js
@@ -1,6 +1,6 @@
-//     Underscore.js 1.4.4
+//     Underscore.js 1.7.0
 //     http://underscorejs.org
-//     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
+//     (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 //     Underscore may be freely distributed under the MIT license.
 
 (function() {
@@ -8,37 +8,26 @@
   // Baseline setup
   // --------------
 
-  // Establish the root object, `window` in the browser, or `global` on the server.
+  // Establish the root object, `window` in the browser, or `exports` on the server.
   var root = this;
 
   // Save the previous value of the `_` variable.
   var previousUnderscore = root._;
 
-  // Establish the object that gets returned to break out of a loop iteration.
-  var breaker = {};
-
   // Save bytes in the minified (but not gzipped) version:
   var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
 
   // Create quick reference variables for speed access to core prototypes.
-  var push             = ArrayProto.push,
-      slice            = ArrayProto.slice,
-      concat           = ArrayProto.concat,
-      toString         = ObjProto.toString,
-      hasOwnProperty   = ObjProto.hasOwnProperty;
+  var
+    push             = ArrayProto.push,
+    slice            = ArrayProto.slice,
+    concat           = ArrayProto.concat,
+    toString         = ObjProto.toString,
+    hasOwnProperty   = ObjProto.hasOwnProperty;
 
   // All **ECMAScript 5** native function implementations that we hope to use
   // are declared here.
   var
-    nativeForEach      = ArrayProto.forEach,
-    nativeMap          = ArrayProto.map,
-    nativeReduce       = ArrayProto.reduce,
-    nativeReduceRight  = ArrayProto.reduceRight,
-    nativeFilter       = ArrayProto.filter,
-    nativeEvery        = ArrayProto.every,
-    nativeSome         = ArrayProto.some,
-    nativeIndexOf      = ArrayProto.indexOf,
-    nativeLastIndexOf  = ArrayProto.lastIndexOf,
     nativeIsArray      = Array.isArray,
     nativeKeys         = Object.keys,
     nativeBind         = FuncProto.bind;
@@ -52,8 +41,7 @@
 
   // Export the Underscore object for **Node.js**, with
   // backwards-compatibility for the old `require()` API. If we're in
-  // the browser, add `_` as a global object via a string identifier,
-  // for Closure Compiler "advanced" mode.
+  // the browser, add `_` as a global object.
   if (typeof exports !== 'undefined') {
     if (typeof module !== 'undefined' && module.exports) {
       exports = module.exports = _;
@@ -64,98 +52,125 @@
   }
 
   // Current version.
-  _.VERSION = '1.4.4';
+  _.VERSION = '1.7.0';
+
+  // Internal function that returns an efficient (for current engines) version
+  // of the passed-in callback, to be repeatedly applied in other Underscore
+  // functions.
+  var createCallback = function(func, context, argCount) {
+    if (context === void 0) return func;
+    switch (argCount == null ? 3 : argCount) {
+      case 1: return function(value) {
+        return func.call(context, value);
+      };
+      case 2: return function(value, other) {
+        return func.call(context, value, other);
+      };
+      case 3: return function(value, index, collection) {
+        return func.call(context, value, index, collection);
+      };
+      case 4: return function(accumulator, value, index, collection) {
+        return func.call(context, accumulator, value, index, collection);
+      };
+    }
+    return function() {
+      return func.apply(context, arguments);
+    };
+  };
+
+  // A mostly-internal function to generate callbacks that can be applied
+  // to each element in a collection, returning the desired result — either
+  // identity, an arbitrary callback, a property matcher, or a property accessor.
+  _.iteratee = function(value, context, argCount) {
+    if (value == null) return _.identity;
+    if (_.isFunction(value)) return createCallback(value, context, argCount);
+    if (_.isObject(value)) return _.matches(value);
+    return _.property(value);
+  };
 
   // Collection Functions
   // --------------------
 
   // The cornerstone, an `each` implementation, aka `forEach`.
-  // Handles objects with the built-in `forEach`, arrays, and raw objects.
-  // Delegates to **ECMAScript 5**'s native `forEach` if available.
-  var each = _.each = _.forEach = function(obj, iterator, context) {
-    if (obj == null) return;
-    if (nativeForEach && obj.forEach === nativeForEach) {
-      obj.forEach(iterator, context);
-    } else if (obj.length === +obj.length) {
-      for (var i = 0, l = obj.length; i < l; i++) {
-        if (iterator.call(context, obj[i], i, obj) === breaker) return;
+  // Handles raw objects in addition to array-likes. Treats all
+  // sparse array-likes as if they were dense.
+  _.each = _.forEach = function(obj, iteratee, context) {
+    if (obj == null) return obj;
+    iteratee = createCallback(iteratee, context);
+    var i, length = obj.length;
+    if (length === +length) {
+      for (i = 0; i < length; i++) {
+        iteratee(obj[i], i, obj);
       }
     } else {
-      for (var key in obj) {
-        if (_.has(obj, key)) {
-          if (iterator.call(context, obj[key], key, obj) === breaker) return;
-        }
+      var keys = _.keys(obj);
+      for (i = 0, length = keys.length; i < length; i++) {
+        iteratee(obj[keys[i]], keys[i], obj);
       }
     }
+    return obj;
   };
 
-  // Return the results of applying the iterator to each element.
-  // Delegates to **ECMAScript 5**'s native `map` if available.
-  _.map = _.collect = function(obj, iterator, context) {
-    var results = [];
-    if (obj == null) return results;
-    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
-    each(obj, function(value, index, list) {
-      results[results.length] = iterator.call(context, value, index, list);
-    });
+  // Return the results of applying the iteratee to each element.
+  _.map = _.collect = function(obj, iteratee, context) {
+    if (obj == null) return [];
+    iteratee = _.iteratee(iteratee, context);
+    var keys = obj.length !== +obj.length && _.keys(obj),
+        length = (keys || obj).length,
+        results = Array(length),
+        currentKey;
+    for (var index = 0; index < length; index++) {
+      currentKey = keys ? keys[index] : index;
+      results[index] = iteratee(obj[currentKey], currentKey, obj);
+    }
     return results;
   };
 
   var reduceError = 'Reduce of empty array with no initial value';
 
   // **Reduce** builds up a single result from a list of values, aka `inject`,
-  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
-  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
-    var initial = arguments.length > 2;
+  // or `foldl`.
+  _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
     if (obj == null) obj = [];
-    if (nativeReduce && obj.reduce === nativeReduce) {
-      if (context) iterator = _.bind(iterator, context);
-      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+    iteratee = createCallback(iteratee, context, 4);
+    var keys = obj.length !== +obj.length && _.keys(obj),
+        length = (keys || obj).length,
+        index = 0, currentKey;
+    if (arguments.length < 3) {
+      if (!length) throw new TypeError(reduceError);
+      memo = obj[keys ? keys[index++] : index++];
+    }
+    for (; index < length; index++) {
+      currentKey = keys ? keys[index] : index;
+      memo = iteratee(memo, obj[currentKey], currentKey, obj);
     }
-    each(obj, function(value, index, list) {
-      if (!initial) {
-        memo = value;
-        initial = true;
-      } else {
-        memo = iterator.call(context, memo, value, index, list);
-      }
-    });
-    if (!initial) throw new TypeError(reduceError);
     return memo;
   };
 
   // The right-associative version of reduce, also known as `foldr`.
-  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
-  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
-    var initial = arguments.length > 2;
+  _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
     if (obj == null) obj = [];
-    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
-      if (context) iterator = _.bind(iterator, context);
-      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+    iteratee = createCallback(iteratee, context, 4);
+    var keys = obj.length !== + obj.length && _.keys(obj),
+        index = (keys || obj).length,
+        currentKey;
+    if (arguments.length < 3) {
+      if (!index) throw new TypeError(reduceError);
+      memo = obj[keys ? keys[--index] : --index];
     }
-    var length = obj.length;
-    if (length !== +length) {
-      var keys = _.keys(obj);
-      length = keys.length;
+    while (index--) {
+      currentKey = keys ? keys[index] : index;
+      memo = iteratee(memo, obj[currentKey], currentKey, obj);
     }
-    each(obj, function(value, index, list) {
-      index = keys ? keys[--length] : --length;
-      if (!initial) {
-        memo = obj[index];
-        initial = true;
-      } else {
-        memo = iterator.call(context, memo, obj[index], index, list);
-      }
-    });
-    if (!initial) throw new TypeError(reduceError);
     return memo;
   };
 
   // Return the first value which passes a truth test. Aliased as `detect`.
-  _.find = _.detect = function(obj, iterator, context) {
+  _.find = _.detect = function(obj, predicate, context) {
     var result;
-    any(obj, function(value, index, list) {
-      if (iterator.call(context, value, index, list)) {
+    predicate = _.iteratee(predicate, context);
+    _.some(obj, function(value, index, list) {
+      if (predicate(value, index, list)) {
         result = value;
         return true;
       }
@@ -164,61 +179,58 @@
   };
 
   // Return all the elements that pass a truth test.
-  // Delegates to **ECMAScript 5**'s native `filter` if available.
   // Aliased as `select`.
-  _.filter = _.select = function(obj, iterator, context) {
+  _.filter = _.select = function(obj, predicate, context) {
     var results = [];
     if (obj == null) return results;
-    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
-    each(obj, function(value, index, list) {
-      if (iterator.call(context, value, index, list)) results[results.length] = value;
+    predicate = _.iteratee(predicate, context);
+    _.each(obj, function(value, index, list) {
+      if (predicate(value, index, list)) results.push(value);
     });
     return results;
   };
 
   // Return all the elements for which a truth test fails.
-  _.reject = function(obj, iterator, context) {
-    return _.filter(obj, function(value, index, list) {
-      return !iterator.call(context, value, index, list);
-    }, context);
+  _.reject = function(obj, predicate, context) {
+    return _.filter(obj, _.negate(_.iteratee(predicate)), context);
   };
 
   // Determine whether all of the elements match a truth test.
-  // Delegates to **ECMAScript 5**'s native `every` if available.
   // Aliased as `all`.
-  _.every = _.all = function(obj, iterator, context) {
-    iterator || (iterator = _.identity);
-    var result = true;
-    if (obj == null) return result;
-    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
-    each(obj, function(value, index, list) {
-      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
-    });
-    return !!result;
+  _.every = _.all = function(obj, predicate, context) {
+    if (obj == null) return true;
+    predicate = _.iteratee(predicate, context);
+    var keys = obj.length !== +obj.length && _.keys(obj),
+        length = (keys || obj).length,
+        index, currentKey;
+    for (index = 0; index < length; index++) {
+      currentKey = keys ? keys[index] : index;
+      if (!predicate(obj[currentKey], currentKey, obj)) return false;
+    }
+    return true;
   };
 
   // Determine if at least one element in the object matches a truth test.
-  // Delegates to **ECMAScript 5**'s native `some` if available.
   // Aliased as `any`.
-  var any = _.some = _.any = function(obj, iterator, context) {
-    iterator || (iterator = _.identity);
-    var result = false;
-    if (obj == null) return result;
-    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
-    each(obj, function(value, index, list) {
-      if (result || (result = iterator.call(context, value, index, list))) return breaker;
-    });
-    return !!result;
+  _.some = _.any = function(obj, predicate, context) {
+    if (obj == null) return false;
+    predicate = _.iteratee(predicate, context);
+    var keys = obj.length !== +obj.length && _.keys(obj),
+        length = (keys || obj).length,
+        index, currentKey;
+    for (index = 0; index < length; index++) {
+      currentKey = keys ? keys[index] : index;
+      if (predicate(obj[currentKey], currentKey, obj)) return true;
+    }
+    return false;
   };
 
   // Determine if the array or object contains a given value (using `===`).
   // Aliased as `include`.
   _.contains = _.include = function(obj, target) {
     if (obj == null) return false;
-    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
-    return any(obj, function(value) {
-      return value === target;
-    });
+    if (obj.length !== +obj.length) obj = _.values(obj);
+    return _.indexOf(obj, target) >= 0;
   };
 
   // Invoke a method (with arguments) on every item in a collection.
@@ -232,83 +244,104 @@
 
   // Convenience version of a common use case of `map`: fetching a property.
   _.pluck = function(obj, key) {
-    return _.map(obj, function(value){ return value[key]; });
+    return _.map(obj, _.property(key));
   };
 
   // Convenience version of a common use case of `filter`: selecting only objects
   // containing specific `key:value` pairs.
-  _.where = function(obj, attrs, first) {
-    if (_.isEmpty(attrs)) return first ? null : [];
-    return _[first ? 'find' : 'filter'](obj, function(value) {
-      for (var key in attrs) {
-        if (attrs[key] !== value[key]) return false;
-      }
-      return true;
-    });
+  _.where = function(obj, attrs) {
+    return _.filter(obj, _.matches(attrs));
   };
 
   // Convenience version of a common use case of `find`: getting the first object
   // containing specific `key:value` pairs.
   _.findWhere = function(obj, attrs) {
-    return _.where(obj, attrs, true);
-  };
-
-  // Return the maximum element or (element-based computation).
-  // Can't optimize arrays of integers longer than 65,535 elements.
-  // See: https://bugs.webkit.org/show_bug.cgi?id=80797
-  _.max = function(obj, iterator, context) {
-    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
-      return Math.max.apply(Math, obj);
+    return _.find(obj, _.matches(attrs));
+  };
+
+  // Return the maximum element (or element-based computation).
+  _.max = function(obj, iteratee, context) {
+    var result = -Infinity, lastComputed = -Infinity,
+        value, computed;
+    if (iteratee == null && obj != null) {
+      obj = obj.length === +obj.length ? obj : _.values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value > result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = _.iteratee(iteratee, context);
+      _.each(obj, function(value, index, list) {
+        computed = iteratee(value, index, list);
+        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+          result = value;
+          lastComputed = computed;
+        }
+      });
     }
-    if (!iterator && _.isEmpty(obj)) return -Infinity;
-    var result = {computed : -Infinity, value: -Infinity};
-    each(obj, function(value, index, list) {
-      var computed = iterator ? iterator.call(context, value, index, list) : value;
-      computed >= result.computed && (result = {value : value, computed : computed});
-    });
-    return result.value;
+    return result;
   };
 
   // Return the minimum element (or element-based computation).
-  _.min = function(obj, iterator, context) {
-    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
-      return Math.min.apply(Math, obj);
+  _.min = function(obj, iteratee, context) {
+    var result = Infinity, lastComputed = Infinity,
+        value, computed;
+    if (iteratee == null && obj != null) {
+      obj = obj.length === +obj.length ? obj : _.values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value < result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = _.iteratee(iteratee, context);
+      _.each(obj, function(value, index, list) {
+        computed = iteratee(value, index, list);
+        if (computed < lastComputed || computed === Infinity && result === Infinity) {
+          result = value;
+          lastComputed = computed;
+        }
+      });
     }
-    if (!iterator && _.isEmpty(obj)) return Infinity;
-    var result = {computed : Infinity, value: Infinity};
-    each(obj, function(value, index, list) {
-      var computed = iterator ? iterator.call(context, value, index, list) : value;
-      computed < result.computed && (result = {value : value, computed : computed});
-    });
-    return result.value;
+    return result;
   };
 
-  // Shuffle an array.
+  // Shuffle a collection, using the modern version of the
+  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
   _.shuffle = function(obj) {
-    var rand;
-    var index = 0;
-    var shuffled = [];
-    each(obj, function(value) {
-      rand = _.random(index++);
-      shuffled[index - 1] = shuffled[rand];
-      shuffled[rand] = value;
-    });
+    var set = obj && obj.length === +obj.length ? obj : _.values(obj);
+    var length = set.length;
+    var shuffled = Array(length);
+    for (var index = 0, rand; index < length; index++) {
+      rand = _.random(0, index);
+      if (rand !== index) shuffled[index] = shuffled[rand];
+      shuffled[rand] = set[index];
+    }
     return shuffled;
   };
 
-  // An internal function to generate lookup iterators.
-  var lookupIterator = function(value) {
-    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
+  // Sample **n** random values from a collection.
+  // If **n** is not specified, returns a single random element.
+  // The internal `guard` argument allows it to work with `map`.
+  _.sample = function(obj, n, guard) {
+    if (n == null || guard) {
+      if (obj.length !== +obj.length) obj = _.values(obj);
+      return obj[_.random(obj.length - 1)];
+    }
+    return _.shuffle(obj).slice(0, Math.max(0, n));
   };
 
-  // Sort the object's values by a criterion produced by an iterator.
-  _.sortBy = function(obj, value, context) {
-    var iterator = lookupIterator(value);
+  // Sort the object's values by a criterion produced by an iteratee.
+  _.sortBy = function(obj, iteratee, context) {
+    iteratee = _.iteratee(iteratee, context);
     return _.pluck(_.map(obj, function(value, index, list) {
       return {
-        value : value,
-        index : index,
-        criteria : iterator.call(context, value, index, list)
+        value: value,
+        index: index,
+        criteria: iteratee(value, index, list)
       };
     }).sort(function(left, right) {
       var a = left.criteria;
@@ -317,53 +350,56 @@
         if (a > b || a === void 0) return 1;
         if (a < b || b === void 0) return -1;
       }
-      return left.index < right.index ? -1 : 1;
+      return left.index - right.index;
     }), 'value');
   };
 
   // An internal function used for aggregate "group by" operations.
-  var group = function(obj, value, context, behavior) {
-    var result = {};
-    var iterator = lookupIterator(value || _.identity);
-    each(obj, function(value, index) {
-      var key = iterator.call(context, value, index, obj);
-      behavior(result, key, value);
-    });
-    return result;
+  var group = function(behavior) {
+    return function(obj, iteratee, context) {
+      var result = {};
+      iteratee = _.iteratee(iteratee, context);
+      _.each(obj, function(value, index) {
+        var key = iteratee(value, index, obj);
+        behavior(result, value, key);
+      });
+      return result;
+    };
   };
 
   // Groups the object's values by a criterion. Pass either a string attribute
   // to group by, or a function that returns the criterion.
-  _.groupBy = function(obj, value, context) {
-    return group(obj, value, context, function(result, key, value) {
-      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
-    });
-  };
+  _.groupBy = group(function(result, value, key) {
+    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
+  });
+
+  // Indexes the object's values by a criterion, similar to `groupBy`, but for
+  // when you know that your index values will be unique.
+  _.indexBy = group(function(result, value, key) {
+    result[key] = value;
+  });
 
   // Counts instances of an object that group by a certain criterion. Pass
   // either a string attribute to count by, or a function that returns the
   // criterion.
-  _.countBy = function(obj, value, context) {
-    return group(obj, value, context, function(result, key) {
-      if (!_.has(result, key)) result[key] = 0;
-      result[key]++;
-    });
-  };
+  _.countBy = group(function(result, value, key) {
+    if (_.has(result, key)) result[key]++; else result[key] = 1;
+  });
 
   // Use a comparator function to figure out the smallest index at which
   // an object should be inserted so as to maintain order. Uses binary search.
-  _.sortedIndex = function(array, obj, iterator, context) {
-    iterator = iterator == null ? _.identity : lookupIterator(iterator);
-    var value = iterator.call(context, obj);
+  _.sortedIndex = function(array, obj, iteratee, context) {
+    iteratee = _.iteratee(iteratee, context, 1);
+    var value = iteratee(obj);
     var low = 0, high = array.length;
     while (low < high) {
-      var mid = (low + high) >>> 1;
-      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
+      var mid = low + high >>> 1;
+      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
     }
     return low;
   };
 
-  // Safely convert anything iterable into a real, live array.
+  // Safely create a real, live array from anything iterable.
   _.toArray = function(obj) {
     if (!obj) return [];
     if (_.isArray(obj)) return slice.call(obj);
@@ -374,7 +410,18 @@
   // Return the number of elements in an object.
   _.size = function(obj) {
     if (obj == null) return 0;
-    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
+    return obj.length === +obj.length ? obj.length : _.keys(obj).length;
+  };
+
+  // Split a collection into two arrays: one whose elements all satisfy the given
+  // predicate, and one whose elements all do not satisfy the predicate.
+  _.partition = function(obj, predicate, context) {
+    predicate = _.iteratee(predicate, context);
+    var pass = [], fail = [];
+    _.each(obj, function(value, key, obj) {
+      (predicate(value, key, obj) ? pass : fail).push(value);
+    });
+    return [pass, fail];
   };
 
   // Array Functions
@@ -385,7 +432,9 @@
   // allows it to work with `_.map`.
   _.first = _.head = _.take = function(array, n, guard) {
     if (array == null) return void 0;
-    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+    if (n == null || guard) return array[0];
+    if (n < 0) return [];
+    return slice.call(array, 0, n);
   };
 
   // Returns everything but the last entry of the array. Especially useful on
@@ -393,18 +442,15 @@
   // the array, excluding the last N. The **guard** check allows it to work with
   // `_.map`.
   _.initial = function(array, n, guard) {
-    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
   };
 
   // Get the last element of an array. Passing **n** will return the last N
   // values in the array. The **guard** check allows it to work with `_.map`.
   _.last = function(array, n, guard) {
     if (array == null) return void 0;
-    if ((n != null) && !guard) {
-      return slice.call(array, Math.max(array.length - n, 0));
-    } else {
-      return array[array.length - 1];
-    }
+    if (n == null || guard) return array[array.length - 1];
+    return slice.call(array, Math.max(array.length - n, 0));
   };
 
   // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
@@ -412,7 +458,7 @@
   // the rest N values in the array. The **guard**
   // check allows it to work with `_.map`.
   _.rest = _.tail = _.drop = function(array, n, guard) {
-    return slice.call(array, (n == null) || guard ? 1 : n);
+    return slice.call(array, n == null || guard ? 1 : n);
   };
 
   // Trim out all falsy values from an array.
@@ -421,20 +467,26 @@
   };
 
   // Internal implementation of a recursive `flatten` function.
-  var flatten = function(input, shallow, output) {
-    each(input, function(value) {
-      if (_.isArray(value)) {
-        shallow ? push.apply(output, value) : flatten(value, shallow, output);
+  var flatten = function(input, shallow, strict, output) {
+    if (shallow && _.every(input, _.isArray)) {
+      return concat.apply(output, input);
+    }
+    for (var i = 0, length = input.length; i < length; i++) {
+      var value = input[i];
+      if (!_.isArray(value) && !_.isArguments(value)) {
+        if (!strict) output.push(value);
+      } else if (shallow) {
+        push.apply(output, value);
       } else {
-        output.push(value);
+        flatten(value, shallow, strict, output);
       }
-    });
+    }
     return output;
   };
 
-  // Return a completely flattened version of an array.
+  // Flatten out an array, either recursively (by default), or just one level.
   _.flatten = function(array, shallow) {
-    return flatten(array, shallow, []);
+    return flatten(array, shallow, false, []);
   };
 
   // Return a version of the array that does not contain the specified value(s).
@@ -445,56 +497,74 @@
   // Produce a duplicate-free version of the array. If the array has already
   // been sorted, you have the option of using a faster algorithm.
   // Aliased as `unique`.
-  _.uniq = _.unique = function(array, isSorted, iterator, context) {
-    if (_.isFunction(isSorted)) {
-      context = iterator;
-      iterator = isSorted;
+  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+    if (array == null) return [];
+    if (!_.isBoolean(isSorted)) {
+      context = iteratee;
+      iteratee = isSorted;
       isSorted = false;
     }
-    var initial = iterator ? _.map(array, iterator, context) : array;
-    var results = [];
+    if (iteratee != null) iteratee = _.iteratee(iteratee, context);
+    var result = [];
     var seen = [];
-    each(initial, function(value, index) {
-      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
-        seen.push(value);
-        results.push(array[index]);
+    for (var i = 0, length = array.length; i < length; i++) {
+      var value = array[i];
+      if (isSorted) {
+        if (!i || seen !== value) result.push(value);
+        seen = value;
+      } else if (iteratee) {
+        var computed = iteratee(value, i, array);
+        if (_.indexOf(seen, computed) < 0) {
+          seen.push(computed);
+          result.push(value);
+        }
+      } else if (_.indexOf(result, value) < 0) {
+        result.push(value);
       }
-    });
-    return results;
+    }
+    return result;
   };
 
   // Produce an array that contains the union: each distinct element from all of
   // the passed-in arrays.
   _.union = function() {
-    return _.uniq(concat.apply(ArrayProto, arguments));
+    return _.uniq(flatten(arguments, true, true, []));
   };
 
   // Produce an array that contains every item shared between all the
   // passed-in arrays.
   _.intersection = function(array) {
-    var rest = slice.call(arguments, 1);
-    return _.filter(_.uniq(array), function(item) {
-      return _.every(rest, function(other) {
-        return _.indexOf(other, item) >= 0;
-      });
-    });
+    if (array == null) return [];
+    var result = [];
+    var argsLength = arguments.length;
+    for (var i = 0, length = array.length; i < length; i++) {
+      var item = array[i];
+      if (_.contains(result, item)) continue;
+      for (var j = 1; j < argsLength; j++) {
+        if (!_.contains(arguments[j], item)) break;
+      }
+      if (j === argsLength) result.push(item);
+    }
+    return result;
   };
 
   // Take the difference between one array and a number of other arrays.
   // Only the elements present in just the first array will remain.
   _.difference = function(array) {
-    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
-    return _.filter(array, function(value){ return !_.contains(rest, value); });
+    var rest = flatten(slice.call(arguments, 1), true, true, []);
+    return _.filter(array, function(value){
+      return !_.contains(rest, value);
+    });
   };
 
   // Zip together multiple lists into a single array -- elements that share
   // an index go together.
-  _.zip = function() {
-    var args = slice.call(arguments);
-    var length = _.max(_.pluck(args, 'length'));
-    var results = new Array(length);
+  _.zip = function(array) {
+    if (array == null) return [];
+    var length = _.max(arguments, 'length').length;
+    var results = Array(length);
     for (var i = 0; i < length; i++) {
-      results[i] = _.pluck(args, "" + i);
+      results[i] = _.pluck(arguments, i);
     }
     return results;
   };
@@ -505,7 +575,7 @@
   _.object = function(list, values) {
     if (list == null) return {};
     var result = {};
-    for (var i = 0, l = list.length; i < l; i++) {
+    for (var i = 0, length = list.length; i < length; i++) {
       if (values) {
         result[list[i]] = values[i];
       } else {
@@ -515,37 +585,32 @@
     return result;
   };
 
-  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
-  // we need this function. Return the position of the first occurrence of an
-  // item in an array, or -1 if the item is not included in the array.
-  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+  // Return the position of the first occurrence of an item in an array,
+  // or -1 if the item is not included in the array.
   // If the array is large and already in sort order, pass `true`
   // for **isSorted** to use binary search.
   _.indexOf = function(array, item, isSorted) {
     if (array == null) return -1;
-    var i = 0, l = array.length;
+    var i = 0, length = array.length;
     if (isSorted) {
       if (typeof isSorted == 'number') {
-        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+        i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
       } else {
         i = _.sortedIndex(array, item);
         return array[i] === item ? i : -1;
       }
     }
-    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
-    for (; i < l; i++) if (array[i] === item) return i;
+    for (; i < length; i++) if (array[i] === item) return i;
     return -1;
   };
 
-  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
   _.lastIndexOf = function(array, item, from) {
     if (array == null) return -1;
-    var hasIndex = from != null;
-    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
-      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
+    var idx = array.length;
+    if (typeof from == 'number') {
+      idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
     }
-    var i = (hasIndex ? from : array.length);
-    while (i--) if (array[i] === item) return i;
+    while (--idx >= 0) if (array[idx] === item) return idx;
     return -1;
   };
 
@@ -557,15 +622,13 @@
       stop = start || 0;
       start = 0;
     }
-    step = arguments[2] || 1;
+    step = step || 1;
 
-    var len = Math.max(Math.ceil((stop - start) / step), 0);
-    var idx = 0;
-    var range = new Array(len);
+    var length = Math.max(Math.ceil((stop - start) / step), 0);
+    var range = Array(length);
 
-    while(idx < len) {
-      range[idx++] = start;
-      start += step;
+    for (var idx = 0; idx < length; idx++, start += step) {
+      range[idx] = start;
     }
 
     return range;
@@ -574,50 +637,77 @@
   // Function (ahem) Functions
   // ------------------
 
+  // Reusable constructor function for prototype setting.
+  var Ctor = function(){};
+
   // Create a function bound to a given object (assigning `this`, and arguments,
   // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
   // available.
   _.bind = function(func, context) {
-    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
-    var args = slice.call(arguments, 2);
-    return function() {
-      return func.apply(context, args.concat(slice.call(arguments)));
+    var args, bound;
+    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+    args = slice.call(arguments, 2);
+    bound = function() {
+      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+      Ctor.prototype = func.prototype;
+      var self = new Ctor;
+      Ctor.prototype = null;
+      var result = func.apply(self, args.concat(slice.call(arguments)));
+      if (_.isObject(result)) return result;
+      return self;
     };
+    return bound;
   };
 
   // Partially apply a function by creating a version that has had some of its
-  // arguments pre-filled, without changing its dynamic `this` context.
+  // arguments pre-filled, without changing its dynamic `this` context. _ acts
+  // as a placeholder, allowing any combination of arguments to be pre-filled.
   _.partial = function(func) {
-    var args = slice.call(arguments, 1);
+    var boundArgs = slice.call(arguments, 1);
     return function() {
-      return func.apply(this, args.concat(slice.call(arguments)));
+      var position = 0;
+      var args = boundArgs.slice();
+      for (var i = 0, length = args.length; i < length; i++) {
+        if (args[i] === _) args[i] = arguments[position++];
+      }
+      while (position < arguments.length) args.push(arguments[position++]);
+      return func.apply(this, args);
     };
   };
 
-  // Bind all of an object's methods to that object. Useful for ensuring that
-  // all callbacks defined on an object belong to it.
+  // Bind a number of an object's methods to that object. Remaining arguments
+  // are the method names to be bound. Useful for ensuring that all callbacks
+  // defined on an object belong to it.
   _.bindAll = function(obj) {
-    var funcs = slice.call(arguments, 1);
-    if (funcs.length === 0) funcs = _.functions(obj);
-    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+    var i, length = arguments.length, key;
+    if (length <= 1) throw new Error('bindAll must be passed function names');
+    for (i = 1; i < length; i++) {
+      key = arguments[i];
+      obj[key] = _.bind(obj[key], obj);
+    }
     return obj;
   };
 
   // Memoize an expensive function by storing its results.
   _.memoize = function(func, hasher) {
-    var memo = {};
-    hasher || (hasher = _.identity);
-    return function() {
-      var key = hasher.apply(this, arguments);
-      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+    var memoize = function(key) {
+      var cache = memoize.cache;
+      var address = hasher ? hasher.apply(this, arguments) : key;
+      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+      return cache[address];
     };
+    memoize.cache = {};
+    return memoize;
   };
 
   // Delays a function for the given number of milliseconds, and then calls
   // it with the arguments supplied.
   _.delay = function(func, wait) {
     var args = slice.call(arguments, 2);
-    return setTimeout(function(){ return func.apply(null, args); }, wait);
+    return setTimeout(function(){
+      return func.apply(null, args);
+    }, wait);
   };
 
   // Defers a function, scheduling it to run after the current call stack has
@@ -627,26 +717,34 @@
   };
 
   // Returns a function, that, when invoked, will only be triggered at most once
-  // during a given window of time.
-  _.throttle = function(func, wait) {
-    var context, args, timeout, result;
+  // during a given window of time. Normally, the throttled function will run
+  // as much as it can, without ever going more than once per `wait` duration;
+  // but if you'd like to disable the execution on the leading edge, pass
+  // `{leading: false}`. To disable execution on the trailing edge, ditto.
+  _.throttle = function(func, wait, options) {
+    var context, args, result;
+    var timeout = null;
     var previous = 0;
+    if (!options) options = {};
     var later = function() {
-      previous = new Date;
+      previous = options.leading === false ? 0 : _.now();
       timeout = null;
       result = func.apply(context, args);
+      if (!timeout) context = args = null;
     };
     return function() {
-      var now = new Date;
+      var now = _.now();
+      if (!previous && options.leading === false) previous = now;
       var remaining = wait - (now - previous);
       context = this;
       args = arguments;
-      if (remaining <= 0) {
+      if (remaining <= 0 || remaining > wait) {
         clearTimeout(timeout);
         timeout = null;
         previous = now;
         result = func.apply(context, args);
-      } else if (!timeout) {
+        if (!timeout) context = args = null;
+      } else if (!timeout && options.trailing !== false) {
         timeout = setTimeout(later, remaining);
       }
       return result;
@@ -658,31 +756,34 @@
   // N milliseconds. If `immediate` is passed, trigger the function on the
   // leading edge, instead of the trailing.
   _.debounce = function(func, wait, immediate) {
-    var timeout, result;
-    return function() {
-      var context = this, args = arguments;
-      var later = function() {
+    var timeout, args, context, timestamp, result;
+
+    var later = function() {
+      var last = _.now() - timestamp;
+
+      if (last < wait && last > 0) {
+        timeout = setTimeout(later, wait - last);
+      } else {
         timeout = null;
-        if (!immediate) result = func.apply(context, args);
-      };
-      var callNow = immediate && !timeout;
-      clearTimeout(timeout);
-      timeout = setTimeout(later, wait);
-      if (callNow) result = func.apply(context, args);
-      return result;
+        if (!immediate) {
+          result = func.apply(context, args);
+          if (!timeout) context = args = null;
+        }
+      }
     };
-  };
 
-  // Returns a function that will be executed at most one time, no matter how
-  // often you call it. Useful for lazy initialization.
-  _.once = function(func) {
-    var ran = false, memo;
     return function() {
-      if (ran) return memo;
-      ran = true;
-      memo = func.apply(this, arguments);
-      func = null;
-      return memo;
+      context = this;
+      args = arguments;
+      timestamp = _.now();
+      var callNow = immediate && !timeout;
+      if (!timeout) timeout = setTimeout(later, wait);
+      if (callNow) {
+        result = func.apply(context, args);
+        context = args = null;
+      }
+
+      return result;
     };
   };
 
@@ -690,29 +791,31 @@
   // allowing you to adjust arguments, run code before and after, and
   // conditionally execute the original function.
   _.wrap = function(func, wrapper) {
+    return _.partial(wrapper, func);
+  };
+
+  // Returns a negated version of the passed-in predicate.
+  _.negate = function(predicate) {
     return function() {
-      var args = [func];
-      push.apply(args, arguments);
-      return wrapper.apply(this, args);
+      return !predicate.apply(this, arguments);
     };
   };
 
   // Returns a function that is the composition of a list of functions, each
   // consuming the return value of the function that follows.
   _.compose = function() {
-    var funcs = arguments;
+    var args = arguments;
+    var start = args.length - 1;
     return function() {
-      var args = arguments;
-      for (var i = funcs.length - 1; i >= 0; i--) {
-        args = [funcs[i].apply(this, args)];
-      }
-      return args[0];
+      var i = start;
+      var result = args[start].apply(this, arguments);
+      while (i--) result = args[i].call(this, result);
+      return result;
     };
   };
 
   // Returns a function that will only be executed after being called N times.
   _.after = function(times, func) {
-    if (times <= 0) return func();
     return function() {
       if (--times < 1) {
         return func.apply(this, arguments);
@@ -720,36 +823,65 @@
     };
   };
 
+  // Returns a function that will only be executed before being called N times.
+  _.before = function(times, func) {
+    var memo;
+    return function() {
+      if (--times > 0) {
+        memo = func.apply(this, arguments);
+      } else {
+        func = null;
+      }
+      return memo;
+    };
+  };
+
+  // Returns a function that will be executed at most one time, no matter how
+  // often you call it. Useful for lazy initialization.
+  _.once = _.partial(_.before, 2);
+
   // Object Functions
   // ----------------
 
   // Retrieve the names of an object's properties.
   // Delegates to **ECMAScript 5**'s native `Object.keys`
-  _.keys = nativeKeys || function(obj) {
-    if (obj !== Object(obj)) throw new TypeError('Invalid object');
+  _.keys = function(obj) {
+    if (!_.isObject(obj)) return [];
+    if (nativeKeys) return nativeKeys(obj);
     var keys = [];
-    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+    for (var key in obj) if (_.has(obj, key)) keys.push(key);
     return keys;
   };
 
   // Retrieve the values of an object's properties.
   _.values = function(obj) {
-    var values = [];
-    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+    var keys = _.keys(obj);
+    var length = keys.length;
+    var values = Array(length);
+    for (var i = 0; i < length; i++) {
+      values[i] = obj[keys[i]];
+    }
     return values;
   };
 
   // Convert an object into a list of `[key, value]` pairs.
   _.pairs = function(obj) {
-    var pairs = [];
-    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+    var keys = _.keys(obj);
+    var length = keys.length;
+    var pairs = Array(length);
+    for (var i = 0; i < length; i++) {
+      pairs[i] = [keys[i], obj[keys[i]]];
+    }
     return pairs;
   };
 
   // Invert the keys and values of an object. The values must be serializable.
   _.invert = function(obj) {
     var result = {};
-    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+    var keys = _.keys(obj);
+    for (var i = 0, length = keys.length; i < length; i++) {
+      result[obj[keys[i]]] = keys[i];
+    }
     return result;
   };
 
@@ -765,45 +897,62 @@
 
   // Extend a given object with all the properties in passed-in object(s).
   _.extend = function(obj) {
-    each(slice.call(arguments, 1), function(source) {
-      if (source) {
-        for (var prop in source) {
-          obj[prop] = source[prop];
+    if (!_.isObject(obj)) return obj;
+    var source, prop;
+    for (var i = 1, length = arguments.length; i < length; i++) {
+      source = arguments[i];
+      for (prop in source) {
+        if (hasOwnProperty.call(source, prop)) {
+            obj[prop] = source[prop];
         }
       }
-    });
+    }
     return obj;
   };
 
   // Return a copy of the object only containing the whitelisted properties.
-  _.pick = function(obj) {
-    var copy = {};
-    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
-    each(keys, function(key) {
-      if (key in obj) copy[key] = obj[key];
-    });
-    return copy;
+  _.pick = function(obj, iteratee, context) {
+    var result = {}, key;
+    if (obj == null) return result;
+    if (_.isFunction(iteratee)) {
+      iteratee = createCallback(iteratee, context);
+      for (key in obj) {
+        var value = obj[key];
+        if (iteratee(value, key, obj)) result[key] = value;
+      }
+    } else {
+      var keys = concat.apply([], slice.call(arguments, 1));
+      obj = new Object(obj);
+      for (var i = 0, length = keys.length; i < length; i++) {
+        key = keys[i];
+        if (key in obj) result[key] = obj[key];
+      }
+    }
+    return result;
   };
 
    // Return a copy of the object without the blacklisted properties.
-  _.omit = function(obj) {
-    var copy = {};
-    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
-    for (var key in obj) {
-      if (!_.contains(keys, key)) copy[key] = obj[key];
+  _.omit = function(obj, iteratee, context) {
+    if (_.isFunction(iteratee)) {
+      iteratee = _.negate(iteratee);
+    } else {
+      var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
+      iteratee = function(value, key) {
+        return !_.contains(keys, key);
+      };
     }
-    return copy;
+    return _.pick(obj, iteratee, context);
   };
 
   // Fill in a given object with default properties.
   _.defaults = function(obj) {
-    each(slice.call(arguments, 1), function(source) {
-      if (source) {
-        for (var prop in source) {
-          if (obj[prop] == null) obj[prop] = source[prop];
-        }
+    if (!_.isObject(obj)) return obj;
+    for (var i = 1, length = arguments.length; i < length; i++) {
+      var source = arguments[i];
+      for (var prop in source) {
+        if (obj[prop] === void 0) obj[prop] = source[prop];
       }
-    });
+    }
     return obj;
   };
 
@@ -824,8 +973,8 @@
   // Internal recursive comparison function for `isEqual`.
   var eq = function(a, b, aStack, bStack) {
     // Identical objects are equal. `0 === -0`, but they aren't identical.
-    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
-    if (a === b) return a !== 0 || 1 / a == 1 / b;
+    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+    if (a === b) return a !== 0 || 1 / a === 1 / b;
     // A strict comparison is necessary because `null == undefined`.
     if (a == null || b == null) return a === b;
     // Unwrap any wrapped objects.
@@ -833,29 +982,27 @@
     if (b instanceof _) b = b._wrapped;
     // Compare `[[Class]]` names.
     var className = toString.call(a);
-    if (className != toString.call(b)) return false;
+    if (className !== toString.call(b)) return false;
     switch (className) {
-      // Strings, numbers, dates, and booleans are compared by value.
+      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+      case '[object RegExp]':
+      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
       case '[object String]':
         // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
         // equivalent to `new String("5")`.
-        return a == String(b);
+        return '' + a === '' + b;
       case '[object Number]':
-        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
-        // other numeric values.
-        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+        // `NaN`s are equivalent, but non-reflexive.
+        // Object(NaN) is equivalent to NaN
+        if (+a !== +a) return +b !== +b;
+        // An `egal` comparison is performed for other numeric values.
+        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
       case '[object Date]':
       case '[object Boolean]':
         // Coerce dates and booleans to numeric primitive values. Dates are compared by their
         // millisecond representations. Note that invalid dates with millisecond representations
         // of `NaN` are not equivalent.
-        return +a == +b;
-      // RegExps are compared by their source patterns and flags.
-      case '[object RegExp]':
-        return a.source == b.source &&
-               a.global == b.global &&
-               a.multiline == b.multiline &&
-               a.ignoreCase == b.ignoreCase;
+        return +a === +b;
     }
     if (typeof a != 'object' || typeof b != 'object') return false;
     // Assume equality for cyclic structures. The algorithm for detecting cyclic
@@ -864,17 +1011,29 @@
     while (length--) {
       // Linear search. Performance is inversely proportional to the number of
       // unique nested structures.
-      if (aStack[length] == a) return bStack[length] == b;
+      if (aStack[length] === a) return bStack[length] === b;
+    }
+    // Objects with different constructors are not equivalent, but `Object`s
+    // from different frames are.
+    var aCtor = a.constructor, bCtor = b.constructor;
+    if (
+      aCtor !== bCtor &&
+      // Handle Object.create(x) cases
+      'constructor' in a && 'constructor' in b &&
+      !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+        _.isFunction(bCtor) && bCtor instanceof bCtor)
+    ) {
+      return false;
     }
     // Add the first object to the stack of traversed objects.
     aStack.push(a);
     bStack.push(b);
-    var size = 0, result = true;
+    var size, result;
     // Recursively compare objects and arrays.
-    if (className == '[object Array]') {
+    if (className === '[object Array]') {
       // Compare array lengths to determine if a deep comparison is necessary.
       size = a.length;
-      result = size == b.length;
+      result = size === b.length;
       if (result) {
         // Deep compare the contents, ignoring non-numeric properties.
         while (size--) {
@@ -882,28 +1041,17 @@
         }
       }
     } else {
-      // Objects with different constructors are not equivalent, but `Object`s
-      // from different frames are.
-      var aCtor = a.constructor, bCtor = b.constructor;
-      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
-                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
-        return false;
-      }
       // Deep compare objects.
-      for (var key in a) {
-        if (_.has(a, key)) {
-          // Count the expected number of properties.
-          size++;
-          // Deep compare each member.
-          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
-        }
-      }
-      // Ensure that both objects contain the same number of properties.
+      var keys = _.keys(a), key;
+      size = keys.length;
+      // Ensure that both objects contain the same number of properties before comparing deep equality.
+      result = _.keys(b).length === size;
       if (result) {
-        for (key in b) {
-          if (_.has(b, key) && !(size--)) break;
+        while (size--) {
+          // Deep compare each member
+          key = keys[size];
+          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
         }
-        result = !size;
       }
     }
     // Remove the first object from the stack of traversed objects.
@@ -921,7 +1069,7 @@
   // An "empty" object has no enumerable own-properties.
   _.isEmpty = function(obj) {
     if (obj == null) return true;
-    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+    if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
     for (var key in obj) if (_.has(obj, key)) return false;
     return true;
   };
@@ -934,18 +1082,19 @@
   // Is a given value an array?
   // Delegates to ECMA5's native Array.isArray
   _.isArray = nativeIsArray || function(obj) {
-    return toString.call(obj) == '[object Array]';
+    return toString.call(obj) === '[object Array]';
   };
 
   // Is a given variable an object?
   _.isObject = function(obj) {
-    return obj === Object(obj);
+    var type = typeof obj;
+    return type === 'function' || type === 'object' && !!obj;
   };
 
   // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
-  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
     _['is' + name] = function(obj) {
-      return toString.call(obj) == '[object ' + name + ']';
+      return toString.call(obj) === '[object ' + name + ']';
     };
   });
 
@@ -953,14 +1102,14 @@
   // there isn't any inspectable "Arguments" type.
   if (!_.isArguments(arguments)) {
     _.isArguments = function(obj) {
-      return !!(obj && _.has(obj, 'callee'));
+      return _.has(obj, 'callee');
     };
   }
 
-  // Optimize `isFunction` if appropriate.
-  if (typeof (/./) !== 'function') {
+  // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
+  if (typeof /./ !== 'function') {
     _.isFunction = function(obj) {
-      return typeof obj === 'function';
+      return typeof obj == 'function' || false;
     };
   }
 
@@ -971,12 +1120,12 @@
 
   // Is the given value `NaN`? (NaN is the only number which does not equal itself).
   _.isNaN = function(obj) {
-    return _.isNumber(obj) && obj != +obj;
+    return _.isNumber(obj) && obj !== +obj;
   };
 
   // Is a given value a boolean?
   _.isBoolean = function(obj) {
-    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
   };
 
   // Is a given value equal to null?
@@ -992,7 +1141,7 @@
   // Shortcut function for checking if an object has a given property directly
   // on itself (in other words, not on a prototype).
   _.has = function(obj, key) {
-    return hasOwnProperty.call(obj, key);
+    return obj != null && hasOwnProperty.call(obj, key);
   };
 
   // Utility Functions
@@ -1005,15 +1154,45 @@
     return this;
   };
 
-  // Keep the identity function around for default iterators.
+  // Keep the identity function around for default iteratees.
   _.identity = function(value) {
     return value;
   };
 
+  // Predicate-generating functions. Often useful outside of Underscore.
+  _.constant = function(value) {
+    return function() {
+      return value;
+    };
+  };
+
+  _.noop = function(){};
+
+  _.property = function(key) {
+    return function(obj) {
+      return obj[key];
+    };
+  };
+
+  // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+  _.matches = function(attrs) {
+    var pairs = _.pairs(attrs), length = pairs.length;
+    return function(obj) {
+      if (obj == null) return !length;
+      obj = new Object(obj);
+      for (var i = 0; i < length; i++) {
+        var pair = pairs[i], key = pair[0];
+        if (pair[1] !== obj[key] || !(key in obj)) return false;
+      }
+      return true;
+    };
+  };
+
   // Run a function **n** times.
-  _.times = function(n, iterator, context) {
-    var accum = Array(n);
-    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
+  _.times = function(n, iteratee, context) {
+    var accum = Array(Math.max(0, n));
+    iteratee = createCallback(iteratee, context, 1);
+    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
     return accum;
   };
 
@@ -1026,53 +1205,45 @@
     return min + Math.floor(Math.random() * (max - min + 1));
   };
 
-  // List of HTML entities for escaping.
-  var entityMap = {
-    escape: {
-      '&': '&amp;',
-      '<': '&lt;',
-      '>': '&gt;',
-      '"': '&quot;',
-      "'": '&#x27;',
-      '/': '&#x2F;'
-    }
+  // A (possibly faster) way to get the current timestamp as an integer.
+  _.now = Date.now || function() {
+    return new Date().getTime();
   };
-  entityMap.unescape = _.invert(entityMap.escape);
 
-  // Regexes containing the keys and values listed immediately above.
-  var entityRegexes = {
-    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
-    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
+   // List of HTML entities for escaping.
+  var escapeMap = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#x27;',
+    '`': '&#x60;'
   };
+  var unescapeMap = _.invert(escapeMap);
 
   // Functions for escaping and unescaping strings to/from HTML interpolation.
-  _.each(['escape', 'unescape'], function(method) {
-    _[method] = function(string) {
-      if (string == null) return '';
-      return ('' + string).replace(entityRegexes[method], function(match) {
-        return entityMap[method][match];
-      });
+  var createEscaper = function(map) {
+    var escaper = function(match) {
+      return map[match];
     };
-  });
+    // Regexes for identifying a key that needs to be escaped
+    var source = '(?:' + _.keys(map).join('|') + ')';
+    var testRegexp = RegExp(source);
+    var replaceRegexp = RegExp(source, 'g');
+    return function(string) {
+      string = string == null ? '' : '' + string;
+      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+    };
+  };
+  _.escape = createEscaper(escapeMap);
+  _.unescape = createEscaper(unescapeMap);
 
-  // If the value of the named property is a function then invoke it;
-  // otherwise, return it.
+  // If the value of the named `property` is a function then invoke it with the
+  // `object` as context; otherwise, return it.
   _.result = function(object, property) {
-    if (object == null) return null;
+    if (object == null) return void 0;
     var value = object[property];
-    return _.isFunction(value) ? value.call(object) : value;
-  };
-
-  // Add your own custom functions to the Underscore object.
-  _.mixin = function(obj) {
-    each(_.functions(obj), function(name){
-      var func = _[name] = obj[name];
-      _.prototype[name] = function() {
-        var args = [this._wrapped];
-        push.apply(args, arguments);
-        return result.call(this, func.apply(_, args));
-      };
-    });
+    return _.isFunction(value) ? object[property]() : value;
   };
 
   // Generate a unique integer id (unique within the entire client session).
@@ -1103,22 +1274,26 @@
     '\\':     '\\',
     '\r':     'r',
     '\n':     'n',
-    '\t':     't',
     '\u2028': 'u2028',
     '\u2029': 'u2029'
   };
 
-  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
+
+  var escapeChar = function(match) {
+    return '\\' + escapes[match];
+  };
 
   // JavaScript micro-templating, similar to John Resig's implementation.
   // Underscore templating handles arbitrary delimiters, preserves whitespace,
   // and correctly escapes quotes within interpolated code.
-  _.template = function(text, data, settings) {
-    var render;
+  // NB: `oldSettings` only exists for backwards compatibility.
+  _.template = function(text, settings, oldSettings) {
+    if (!settings && oldSettings) settings = oldSettings;
     settings = _.defaults({}, settings, _.templateSettings);
 
     // Combine delimiters into one regular expression via alternation.
-    var matcher = new RegExp([
+    var matcher = RegExp([
       (settings.escape || noMatch).source,
       (settings.interpolate || noMatch).source,
       (settings.evaluate || noMatch).source
@@ -1128,19 +1303,18 @@
     var index = 0;
     var source = "__p+='";
     text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-      source += text.slice(index, offset)
-        .replace(escaper, function(match) { return '\\' + escapes[match]; });
+      source += text.slice(index, offset).replace(escaper, escapeChar);
+      index = offset + match.length;
 
       if (escape) {
         source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-      }
-      if (interpolate) {
+      } else if (interpolate) {
         source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-      }
-      if (evaluate) {
+      } else if (evaluate) {
         source += "';\n" + evaluate + "\n__p+='";
       }
-      index = offset + match.length;
+
+      // Adobe VMs need the match returned to produce the correct offest.
       return match;
     });
     source += "';\n";
@@ -1150,29 +1324,31 @@
 
     source = "var __t,__p='',__j=Array.prototype.join," +
       "print=function(){__p+=__j.call(arguments,'');};\n" +
-      source + "return __p;\n";
+      source + 'return __p;\n';
 
     try {
-      render = new Function(settings.variable || 'obj', '_', source);
+      var render = new Function(settings.variable || 'obj', '_', source);
     } catch (e) {
       e.source = source;
       throw e;
     }
 
-    if (data) return render(data, _);
     var template = function(data) {
       return render.call(this, data, _);
     };
 
-    // Provide the compiled function source as a convenience for precompilation.
-    template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
+    // Provide the compiled source as a convenience for precompilation.
+    var argument = settings.variable || 'obj';
+    template.source = 'function(' + argument + '){\n' + source + '}';
 
     return template;
   };
 
-  // Add a "chain" function, which will delegate to the wrapper.
+  // Add a "chain" function. Start chaining a wrapped Underscore object.
   _.chain = function(obj) {
-    return _(obj).chain();
+    var instance = _(obj);
+    instance._chain = true;
+    return instance;
   };
 
   // OOP
@@ -1186,41 +1362,55 @@
     return this._chain ? _(obj).chain() : obj;
   };
 
+  // Add your own custom functions to the Underscore object.
+  _.mixin = function(obj) {
+    _.each(_.functions(obj), function(name) {
+      var func = _[name] = obj[name];
+      _.prototype[name] = function() {
+        var args = [this._wrapped];
+        push.apply(args, arguments);
+        return result.call(this, func.apply(_, args));
+      };
+    });
+  };
+
   // Add all of the Underscore functions to the wrapper object.
   _.mixin(_);
 
   // Add all mutator Array functions to the wrapper.
-  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
     var method = ArrayProto[name];
     _.prototype[name] = function() {
       var obj = this._wrapped;
       method.apply(obj, arguments);
-      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
+      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
       return result.call(this, obj);
     };
   });
 
   // Add all accessor Array functions to the wrapper.
-  each(['concat', 'join', 'slice'], function(name) {
+  _.each(['concat', 'join', 'slice'], function(name) {
     var method = ArrayProto[name];
     _.prototype[name] = function() {
       return result.call(this, method.apply(this._wrapped, arguments));
     };
   });
 
-  _.extend(_.prototype, {
-
-    // Start chaining a wrapped Underscore object.
-    chain: function() {
-      this._chain = true;
-      return this;
-    },
-
-    // Extracts the result from a wrapped and chained object.
-    value: function() {
-      return this._wrapped;
-    }
-
-  });
-
-}).call(this);
+  // Extracts the result from a wrapped and chained object.
+  _.prototype.value = function() {
+    return this._wrapped;
+  };
+
+  // AMD registration happens at the end for compatibility with AMD loaders
+  // that may not enforce next-turn semantics on modules. Even though general
+  // practice for AMD registration is to be anonymous, underscore registers
+  // as a named module because, like jQuery, it is a base library that is
+  // popular enough to be bundled in a third party lib, but not be part of
+  // an AMD load request. Those cases could generate an error when an
+  // anonymous define() is called outside of a loader request.
+  if (typeof define === 'function' && define.amd) {
+    define('underscore', [], function() {
+      return _;
+    });
+  }
+}.call(this));
\ No newline at end of file
diff --git a/setup/composer.json b/setup/composer.json
index 639c6f37b1b..0de23fc2c2f 100644
--- a/setup/composer.json
+++ b/setup/composer.json
@@ -11,17 +11,22 @@
         "phpmd/phpmd" : "1.4.*"
     },
     "autoload": {
+        "psr-0":{
+            "Zend_": "../lib/internal/"
+        },
         "psr-4": {
+            "Magento\\Composer\\": "module/Magento/Composer/src/",
+            "Magento\\Filesystem\\": "module/Magento/Filesystem/src/",
+            "Magento\\Locale\\": "module/Magento/Locale/src/",
             "Magento\\Setup\\": "module/Magento/Setup/src/",
             "Magento\\Config\\": "module/Magento/Config/src/",
-            "Magento\\Install\\": "module/Magento/Install/src/"
+            "Magento\\": ["../app/code/Magento/", "../lib/internal/Magento/"]
         }
     },
     "autoload-dev": {
         "psr-4": {
             "Magento\\Setup\\Tests\\": "module/Magento/Setup/tests/",
-            "Magento\\Config\\Tests\\": "module/Magento/Config/tests/",
-            "Magento\\Install\\Tests\\": "module/Magento/Install/tests/"
+            "Magento\\Config\\Tests\\": "module/Magento/Config/tests/"
         }
     }
 }
diff --git a/setup/config/application.config.php b/setup/config/application.config.php
index 2e0cf621a35..46e588b0b70 100644
--- a/setup/config/application.config.php
+++ b/setup/config/application.config.php
@@ -24,21 +24,17 @@
 
 return [
     'modules' => [
-        'Magento\Composer',
         'Magento\Config',
         'Magento\Filesystem',
-        'Magento\Locale',
-        'Magento\Module',
         'Magento\Setup',
-        'Magento\Framework',
     ],
     'module_listener_options' => [
         'module_paths' => [
-            './module',
-            './vendor',
+            __DIR__ . '/../module',
+            __DIR__ . '/../vendor',
         ],
         'config_glob_paths' => array(
-            'config/autoload/{,*.}{global,local}.php',
+            __DIR__ . '/autoload/{,*.}{global,local}.php',
         ),
     ],
 ];
diff --git a/setup/module/Magento/Config/Module.php b/setup/module/Magento/Config/Module.php
index 6a3dc37ca48..e5a51ba1084 100644
--- a/setup/module/Magento/Config/Module.php
+++ b/setup/module/Magento/Config/Module.php
@@ -24,9 +24,9 @@
 
 namespace Magento\Config;
 
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
+use Zend\ModuleManager\Feature\ConfigProviderInterface;
 
-class Module implements AutoloaderProviderInterface
+class Module implements ConfigProviderInterface
 {
     /**
      * @return array
@@ -36,17 +36,4 @@ class Module implements AutoloaderProviderInterface
         return include __DIR__ . '/config/module.config.php';
     }
 
-    /**
-     * @return array
-     */
-    public function getAutoloaderConfig()
-    {
-        return array(
-            'Zend\Loader\StandardAutoloader' => array(
-                'namespaces' => array(
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ),
-            ),
-        );
-    }
 }
diff --git a/setup/module/Magento/Config/phpunit.xml.dist b/setup/module/Magento/Config/phpunit.xml.dist
index 179827cce7e..fde4d6362f7 100644
--- a/setup/module/Magento/Config/phpunit.xml.dist
+++ b/setup/module/Magento/Config/phpunit.xml.dist
@@ -23,17 +23,19 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit backupGlobals="false"
-         backupStaticAttributes="false"
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
          colors="true"
+         bootstrap="../../../vendor/autoload.php"
+         backupGlobals="false"
+         backupStaticAttributes="false"
          convertErrorsToExceptions="true"
          convertNoticesToExceptions="true"
          convertWarningsToExceptions="true"
          processIsolation="false"
          stopOnFailure="false"
          syntaxCheck="false"
-         bootstrap="../../../vendor/autoload.php"
-        >
+>
     <testsuites>
         <testsuite name="Magento Config Module Test Suite">
             <directory>./tests/</directory>
diff --git a/setup/module/Magento/Config/src/Config.php b/setup/module/Magento/Config/src/Config.php
index f99c6239ed8..4ff55abc4af 100644
--- a/setup/module/Magento/Config/src/Config.php
+++ b/setup/module/Magento/Config/src/Config.php
@@ -50,7 +50,6 @@ class Config extends ZendConfig
             } else {
                 $this->data[$key] = $value;
             }
-
             $this->count++;
         }
     }
diff --git a/setup/module/Magento/Config/src/Dom.php b/setup/module/Magento/Config/src/Dom.php
deleted file mode 100644
index 8166e63e420..00000000000
--- a/setup/module/Magento/Config/src/Dom.php
+++ /dev/null
@@ -1,386 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Magento configuration XML DOM utility
- */
-namespace Magento\Config;
-
-class Dom
-{
-    /**
-     * Prefix which will be used for root namespace
-     */
-    const ROOT_NAMESPACE_PREFIX = 'x';
-
-    /**
-     * Format of items in errors array to be used by default. Available placeholders - fields of \LibXMLError.
-     */
-    const ERROR_FORMAT_DEFAULT = "%message%\nLine: %line%\n";
-
-    /**
-     * Dom document
-     *
-     * @var \DOMDocument
-     */
-    protected $_dom;
-
-    /**
-     * @var Dom\NodeMergingConfig
-     */
-    protected $_nodeMergingConfig;
-
-    /**
-     * Name of attribute that specifies type of argument node
-     *
-     * @var string|null
-     */
-    protected $_typeAttributeName;
-
-    /**
-     * Schema validation file
-     *
-     * @var string
-     */
-    protected $_schemaFile;
-
-    /**
-     * Format of error messages
-     *
-     * @var string
-     */
-    protected $_errorFormat;
-
-    /**
-     * Default namespace for xml elements
-     *
-     * @var string
-     */
-    protected $_rootNamespace;
-
-    /**
-     * Build DOM with initial XML contents and specifying identifier attributes for merging
-     *
-     * Format of $idAttributes: array('/xpath/to/some/node' => 'id_attribute_name')
-     * The path to ID attribute name should not include any attribute notations or modifiers -- only node names
-     *
-     * @param string $xml
-     * @param array $idAttributes
-     * @param string $typeAttributeName
-     * @param string $schemaFile
-     * @param string $errorFormat
-     */
-    public function __construct(
-        $xml,
-        array $idAttributes = array(),
-        $typeAttributeName = null,
-        $schemaFile = null,
-        $errorFormat = self::ERROR_FORMAT_DEFAULT
-    ) {
-        $this->_schemaFile = $schemaFile;
-        $this->_nodeMergingConfig = new Dom\NodeMergingConfig(new Dom\NodePathMatcher(), $idAttributes);
-        $this->_typeAttributeName = $typeAttributeName;
-        $this->_errorFormat = $errorFormat;
-        $this->_dom = $this->_initDom($xml);
-        $this->_rootNamespace = $this->_dom->lookupNamespaceUri($this->_dom->namespaceURI);
-    }
-
-    /**
-     * Merge $xml into DOM document
-     *
-     * @param string $xml
-     * @return void
-     */
-    public function merge($xml)
-    {
-        $dom = $this->_initDom($xml);
-        $this->_mergeNode($dom->documentElement, '');
-    }
-
-    /**
-     * Recursive merging of the \DOMElement into the original document
-     *
-     * Algorithm:
-     * 1. Find the same node in original document
-     * 2. Extend and override original document node attributes and scalar value if found
-     * 3. Append new node if original document doesn't have the same node
-     *
-     * @param \DOMElement $node
-     * @param string $parentPath path to parent node
-     * @return void
-     */
-    protected function _mergeNode(\DOMElement $node, $parentPath)
-    {
-        $path = $this->_getNodePathByParent($node, $parentPath);
-
-        $matchedNode = $this->_getMatchedNode($path);
-
-        /* Update matched node attributes and value */
-        if ($matchedNode) {
-
-            //different node type
-            if ($this->_typeAttributeName && $node->hasAttribute(
-                $this->_typeAttributeName
-            ) && $matchedNode->hasAttribute(
-                $this->_typeAttributeName
-            ) && $node->getAttribute(
-                $this->_typeAttributeName
-            ) !== $matchedNode->getAttribute(
-                $this->_typeAttributeName
-            )
-            ) {
-                $parentMatchedNode = $this->_getMatchedNode($parentPath);
-                $newNode = $this->_dom->importNode($node, true);
-                $parentMatchedNode->replaceChild($newNode, $matchedNode);
-                return;
-            }
-
-            $this->_mergeAttributes($matchedNode, $node);
-            if (!$node->hasChildNodes()) {
-                return;
-            }
-            /* override node value */
-            if ($this->_isTextNode($node)) {
-                /* skip the case when the matched node has children, otherwise they get overridden */
-                if (!$matchedNode->hasChildNodes() || $this->_isTextNode($matchedNode)) {
-                    $matchedNode->nodeValue = $node->childNodes->item(0)->nodeValue;
-                }
-            } else {
-                /* recursive merge for all child nodes */
-                foreach ($node->childNodes as $childNode) {
-                    if ($childNode instanceof \DOMElement) {
-                        $this->_mergeNode($childNode, $path);
-                    }
-                }
-            }
-        } else {
-            /* Add node as is to the document under the same parent element */
-            $parentMatchedNode = $this->_getMatchedNode($parentPath);
-            $newNode = $this->_dom->importNode($node, true);
-            $parentMatchedNode->appendChild($newNode);
-        }
-    }
-
-    /**
-     * Check if the node content is text
-     *
-     * @param \DOMElement $node
-     * @return bool
-     */
-    protected function _isTextNode($node)
-    {
-        return $node->childNodes->length == 1 && $node->childNodes->item(0) instanceof \DOMText;
-    }
-
-    /**
-     * Merges attributes of the merge node to the base node
-     *
-     * @param \DOMElement $baseNode
-     * @param \DOMNode $mergeNode
-     * @return void
-     */
-    protected function _mergeAttributes($baseNode, $mergeNode)
-    {
-        foreach ($mergeNode->attributes as $attribute) {
-            $baseNode->setAttribute($this->_getAttributeName($attribute), $attribute->value);
-        }
-    }
-
-    /**
-     * Identify node path based on parent path and node attributes
-     *
-     * @param \DOMElement $node
-     * @param string $parentPath
-     * @return string
-     */
-    protected function _getNodePathByParent(\DOMElement $node, $parentPath)
-    {
-        $prefix = is_null($this->_rootNamespace) ? '' : self::ROOT_NAMESPACE_PREFIX . ':';
-        $path = $parentPath . '/' . $prefix . $node->tagName;
-        $idAttribute = $this->_nodeMergingConfig->getIdAttribute($path);
-        if (is_array($idAttribute)) {
-            $constraints = [];
-            foreach ($idAttribute as $attribute) {
-                $value = $node->getAttribute($attribute);
-                $constraints[] = "@{$attribute}='{$value}'";
-            }
-            $path .= '[' . join(' and ', $constraints) . ']';
-        } elseif ($idAttribute && ($value = $node->getAttribute($idAttribute))) {
-            $path .= "[@{$idAttribute}='{$value}']";
-        }
-        return $path;
-    }
-
-    /**
-     * Getter for node by path
-     *
-     * @param string $nodePath
-     * @throws \Exception An exception is possible if original document contains multiple nodes for identifier
-     * @return \DOMElement|null
-     */
-    protected function _getMatchedNode($nodePath)
-    {
-        $xPath = new \DOMXPath($this->_dom);
-        if ($this->_rootNamespace) {
-            $xPath->registerNamespace(self::ROOT_NAMESPACE_PREFIX, $this->_rootNamespace);
-        }
-        $matchedNodes = $xPath->query($nodePath);
-        $node = null;
-        if ($matchedNodes->length > 1) {
-            throw new \Exception("More than one node matching the query: {$nodePath}");
-        } elseif ($matchedNodes->length == 1) {
-            $node = $matchedNodes->item(0);
-        }
-        return $node;
-    }
-
-    /**
-     * Validate dom document
-     *
-     * @param \DOMDocument $dom
-     * @param string $schemaFileName
-     * @param string $errorFormat
-     * @return array of errors
-     * @throws \Exception
-     */
-    public static function validateDomDocument(
-        \DOMDocument $dom,
-        $schemaFileName,
-        $errorFormat = self::ERROR_FORMAT_DEFAULT
-    ) {
-        libxml_use_internal_errors(true);
-        try {
-            $result = $dom->schemaValidate($schemaFileName);
-            $errors = array();
-            if (!$result) {
-                $validationErrors = libxml_get_errors();
-                if (count($validationErrors)) {
-                    foreach ($validationErrors as $error) {
-                        $errors[] = self::_renderErrorMessage($error, $errorFormat);
-                    }
-                } else {
-                    $errors[] = 'Unknown validation error';
-                }
-            }
-        } catch (\Exception $exception) {
-            libxml_use_internal_errors(false);
-            throw $exception;
-        }
-        libxml_use_internal_errors(false);
-        return $errors;
-    }
-
-    /**
-     * Render error message string by replacing placeholders '%field%' with properties of \LibXMLError
-     *
-     * @param \LibXMLError $errorInfo
-     * @param string $format
-     * @return string
-     * @throws \InvalidArgumentException
-     */
-    private static function _renderErrorMessage(\LibXMLError $errorInfo, $format)
-    {
-        $result = $format;
-        foreach ($errorInfo as $field => $value) {
-            $placeholder = '%' . $field . '%';
-            $value = trim((string)$value);
-            $result = str_replace($placeholder, $value, $result);
-        }
-        if (strpos($result, '%') !== false) {
-            throw new \InvalidArgumentException("Error format '{$format}' contains unsupported placeholders.");
-        }
-        return $result;
-    }
-
-    /**
-     * DOM document getter
-     *
-     * @return \DOMDocument
-     */
-    public function getDom()
-    {
-        return $this->_dom;
-    }
-
-    /**
-     * Create DOM document based on $xml parameter
-     *
-     * @param string $xml
-     * @return \DOMDocument
-     * @throws Dom\ValidationException
-     */
-    protected function _initDom($xml)
-    {
-        $dom = new \DOMDocument();
-        $dom->loadXML($xml);
-        if ($this->_schemaFile) {
-            $errors = self::validateDomDocument($dom, $this->_schemaFile, $this->_errorFormat);
-            if (count($errors)) {
-                throw new Dom\ValidationException(implode("\n", $errors));
-            }
-        }
-        return $dom;
-    }
-
-    /**
-     * Validate self contents towards to specified schema
-     *
-     * @param string $schemaFileName absolute path to schema file
-     * @param array &$errors
-     * @return bool
-     */
-    public function validate($schemaFileName, &$errors = array())
-    {
-        $errors = self::validateDomDocument($this->_dom, $schemaFileName, $this->_errorFormat);
-        return !count($errors);
-    }
-
-    /**
-     * Set schema file
-     *
-     * @param string $schemaFile
-     * @return $this
-     */
-    public function setSchemaFile($schemaFile)
-    {
-        $this->_schemaFile = $schemaFile;
-        return $this;
-    }
-
-    /**
-     * Returns the attribute name with prefix, if there is one
-     *
-     * @param \DOMAttr $attribute
-     * @return string
-     */
-    private function _getAttributeName($attribute)
-    {
-        if (!is_null($attribute->prefix) && !empty($attribute->prefix)) {
-            $attributeName = $attribute->prefix . ':' . $attribute->name;
-        } else {
-            $attributeName = $attribute->name;
-        }
-        return $attributeName;
-    }
-}
diff --git a/setup/module/Magento/Config/src/Dom/NodePathMatcher.php b/setup/module/Magento/Config/src/Dom/NodePathMatcher.php
deleted file mode 100644
index 071163db28c..00000000000
--- a/setup/module/Magento/Config/src/Dom/NodePathMatcher.php
+++ /dev/null
@@ -1,58 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Config\Dom;
-
-/**
- * Matching of XPath expressions to path patterns
- */
-class NodePathMatcher
-{
-    /**
-     * Whether a subject XPath matches to a given path pattern
-     *
-     * @param string $pathPattern Example: '/some/static/path' or '/some/regexp/path(/item)+'
-     * @param string $xpathSubject Example: '/some[@attr="value"]/static/ns:path'
-     * @return bool
-     */
-    public function match($pathPattern, $xpathSubject)
-    {
-        $pathSubject = $this->simplifyXpath($xpathSubject);
-        $pathPattern = '#^' . $pathPattern . '$#';
-        return (bool)preg_match($pathPattern, $pathSubject);
-    }
-
-    /**
-     * Strip off predicates and namespaces from the XPath
-     *
-     * @param string $xpath
-     * @return string
-     */
-    protected function simplifyXpath($xpath)
-    {
-        $result = $xpath;
-        $result = preg_replace('/\[@[^\]]+?\]/', '', $result);
-        $result = preg_replace('/\/[^:]+?\:/', '/', $result);
-        return $result;
-    }
-}
diff --git a/setup/module/Magento/Config/src/Reader/Filesystem.php b/setup/module/Magento/Config/src/Reader/Filesystem.php
index e6f094a8f2b..415e474a3bd 100644
--- a/setup/module/Magento/Config/src/Reader/Filesystem.php
+++ b/setup/module/Magento/Config/src/Reader/Filesystem.php
@@ -88,7 +88,7 @@ class Filesystem implements ReaderInterface
         ConverterInterface $converter,
         SchemaLocatorInterface $schemaLocator,
         $fileName,
-        $domDocumentClass = 'Magento\Config\Dom',
+        $domDocumentClass = '\Magento\Framework\Config\Dom',
         $idAttributes = array()
     ) {
         $this->fileResolver = $fileResolver;
@@ -122,7 +122,7 @@ class Filesystem implements ReaderInterface
      */
     protected function readFiles($fileList)
     {
-        /** @var \Magento\Config\Dom $configMerger */
+        /** @var \Magento\Framework\Config\Dom $configMerger */
         $configMerger = null;
         foreach ($fileList as $key => $content) {
             try {
@@ -131,7 +131,7 @@ class Filesystem implements ReaderInterface
                 } else {
                     $configMerger->merge($content);
                 }
-            } catch (\Magento\Config\Dom\ValidationException $e) {
+            } catch (\Magento\Framework\Config\Dom\ValidationException $e) {
                 throw new \Exception("Invalid XML in file " . $key . ":\n" . $e->getMessage());
             }
         }
@@ -154,13 +154,13 @@ class Filesystem implements ReaderInterface
      *
      * @param string $mergerClass
      * @param string $initialContents
-     * @return \Magento\Config\Dom
+     * @return \Magento\Framework\Config\Dom
      * @throws \UnexpectedValueException
      */
     protected function createConfigMerger($mergerClass, $initialContents)
     {
         $result = new $mergerClass($initialContents, $this->idAttributes, null, $this->schemaFile);
-        if (!$result instanceof \Magento\Config\Dom) {
+        if (!$result instanceof \Magento\Framework\Config\Dom) {
             throw new \UnexpectedValueException(
                 "Instance of the DOM config merger is expected, got {$mergerClass} instead."
             );
diff --git a/setup/module/Magento/Filesystem/Module.php b/setup/module/Magento/Filesystem/Module.php
index 73ca3871e47..fa65d5da760 100644
--- a/setup/module/Magento/Filesystem/Module.php
+++ b/setup/module/Magento/Filesystem/Module.php
@@ -25,11 +25,8 @@
 namespace Magento\Filesystem;
 
 use Zend\ModuleManager\Feature\ConfigProviderInterface;
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
 
-class Module implements
-    ConfigProviderInterface,
-    AutoloaderProviderInterface
+class Module implements ConfigProviderInterface
 {
     /**
      * @return array|mixed|\Traversable
@@ -40,18 +37,4 @@ class Module implements
             include __DIR__ . '/config/di.config.php'
         );
     }
-
-    /**
-     * @return array
-     */
-    public function getAutoloaderConfig()
-    {
-        return [
-            'Zend\Loader\StandardAutoloader' => [
-                'namespaces' => [
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ],
-            ],
-        ];
-    }
 }
diff --git a/setup/module/Magento/Framework/Module.php b/setup/module/Magento/Framework/Module.php
deleted file mode 100644
index 02f1a9d76d9..00000000000
--- a/setup/module/Magento/Framework/Module.php
+++ /dev/null
@@ -1,44 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Framework;
-
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
-
-class Module implements AutoloaderProviderInterface
-{
-    /**
-     * @return array
-     */
-    public function getAutoloaderConfig()
-    {
-        return [
-            'Zend\Loader\StandardAutoloader' => [
-                'namespaces' => [
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ],
-            ],
-        ];
-    }
-}
diff --git a/setup/module/Magento/Framework/src/DB/ExpressionConverter.php b/setup/module/Magento/Framework/src/DB/ExpressionConverter.php
deleted file mode 100644
index b0dffbb5cf0..00000000000
--- a/setup/module/Magento/Framework/src/DB/ExpressionConverter.php
+++ /dev/null
@@ -1,102 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Framework\DB;
-
-class ExpressionConverter
-{
-    /**
-     * Dictionary for generate short name
-     *
-     * @var array
-     */
-    protected static $_translateMap = array(
-        'address'       => 'addr',
-        'admin'         => 'adm',
-        'attribute'     => 'attr',
-        'enterprise'    => 'ent',
-        'catalog'       => 'cat',
-        'category'      => 'ctgr',
-        'customer'      => 'cstr',
-        'notification'  => 'ntfc',
-        'product'       => 'prd',
-        'session'       => 'sess',
-        'user'          => 'usr',
-        'entity'        => 'entt',
-        'datetime'      => 'dtime',
-        'decimal'       => 'dec',
-        'varchar'       => 'vchr',
-        'index'         => 'idx',
-        'compare'       => 'cmp',
-        'bundle'        => 'bndl',
-        'option'        => 'opt',
-        'gallery'       => 'glr',
-        'media'         => 'mda',
-        'value'         => 'val',
-        'link'          => 'lnk',
-        'title'         => 'ttl',
-        'super'         => 'spr',
-        'label'         => 'lbl',
-        'website'       => 'ws',
-        'aggregat'      => 'aggr',
-        'minimal'       => 'min',
-        'inventory'     => 'inv',
-        'status'        => 'sts',
-        'agreement'     => 'agrt',
-        'layout'        => 'lyt',
-        'resource'      => 'res',
-        'directory'     => 'dir',
-        'downloadable'  => 'dl',
-        'element'       => 'elm',
-        'fieldset'      => 'fset',
-        'checkout'      => 'chkt',
-        'newsletter'    => 'nlttr',
-        'shipping'      => 'shpp',
-        'calculation'   => 'calc',
-        'search'        => 'srch',
-        'query'         => 'qr'
-    );
-
-    /**
-     * Convert name using dictionary
-     *
-     * @param string $name
-     * @return string
-     */
-    public static function shortName($name)
-    {
-        return strtr($name, self::$_translateMap);
-    }
-
-    /**
-     * Add or replace translate to dictionary
-     *
-     * @param string $from
-     * @param string $to
-     * @return void
-     */
-    public static function addTranslate($from, $to)
-    {
-        self::$_translateMap[$from] = $to;
-    }
-}
diff --git a/setup/module/Magento/Framework/src/Math/Random.php b/setup/module/Magento/Framework/src/Math/Random.php
deleted file mode 100644
index ff025bee9d7..00000000000
--- a/setup/module/Magento/Framework/src/Math/Random.php
+++ /dev/null
@@ -1,84 +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.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Framework\Math;
-
-/**
- * Random data generator
- */
-class Random
-{
-    /**#@+
-     * Frequently used character classes
-     */
-    const CHARS_LOWERS = 'abcdefghijklmnopqrstuvwxyz';
-
-    const CHARS_UPPERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-    const CHARS_DIGITS = '0123456789';
-
-    /**#@-*/
-
-    /**
-     * Get random string
-     *
-     * @param int         $length
-     * @param null|string $chars
-     * @return string
-     */
-    public function getRandomString($length, $chars = null)
-    {
-        $str = '';
-        if (null === $chars) {
-            $chars = self::CHARS_LOWERS . self::CHARS_UPPERS . self::CHARS_DIGITS;
-        }
-
-        if (function_exists('openssl_random_pseudo_bytes')) {
-            // use openssl lib if it is installed
-            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
-                $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE);
-                $hex = bin2hex($bytes); // hex() doubles the length of the string
-                $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc
-                $str .= $chars[$rand]; // random character in $chars
-            }
-        } elseif ($fp = @fopen('/dev/urandom', 'rb')) {
-            // attempt to use /dev/urandom if it exists but openssl isn't available
-            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
-                $bytes = @fread($fp, PHP_INT_SIZE);
-                $hex = bin2hex($bytes); // hex() doubles the length of the string
-                $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc
-                $str .= $chars[$rand]; // random character in $chars
-            }
-            fclose($fp);
-        } else {
-            // fallback to mt_rand() if all else fails
-            mt_srand(10000000 * (double)microtime());
-            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
-                $rand = mt_rand(0, $lc); // random integer from 0 to $lc
-                $str .= $chars[$rand]; // random character in $chars
-            }
-        }
-
-        return $str;
-    }
-}
diff --git a/setup/module/Magento/Locale/Module.php b/setup/module/Magento/Locale/Module.php
deleted file mode 100644
index d7a8c7b9430..00000000000
--- a/setup/module/Magento/Locale/Module.php
+++ /dev/null
@@ -1,44 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Locale;
-
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
-
-class Module implements AutoloaderProviderInterface
-{
-    /**
-     * @return array
-     */
-    public function getAutoloaderConfig()
-    {
-        return [
-            'Zend\Loader\StandardAutoloader' => [
-                'namespaces' => [
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ],
-            ],
-        ];
-    }
-}
diff --git a/setup/module/Magento/Module/Module.php b/setup/module/Magento/Module/Module.php
deleted file mode 100644
index 9cfec3e3b78..00000000000
--- a/setup/module/Magento/Module/Module.php
+++ /dev/null
@@ -1,58 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Module;
-
-use Zend\ModuleManager\Feature\ConfigProviderInterface;
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
-
-class Module implements
-    ConfigProviderInterface,
-    AutoloaderProviderInterface
-{
-    /**
-     * @return array|mixed|\Traversable
-     */
-    public function getConfig()
-    {
-        return array_merge(
-            include __DIR__ . '/config/module.config.php',
-            include __DIR__ . '/config/di.config.php'
-        );
-    }
-
-    /**
-     * @return array
-     */
-    public function getAutoloaderConfig()
-    {
-        return [
-            'Zend\Loader\StandardAutoloader' => [
-                'namespaces' => [
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ],
-            ],
-        ];
-    }
-}
diff --git a/setup/module/Magento/Module/config/di.config.php b/setup/module/Magento/Module/config/di.config.php
deleted file mode 100644
index 980766c79cf..00000000000
--- a/setup/module/Magento/Module/config/di.config.php
+++ /dev/null
@@ -1,36 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-return [
-    'di' => [
-        'instance' => [
-            'preference' => [
-                'Magento\Module\Dependency\ManagerInterface' => 'Magento\Module\Dependency\Manager',
-                'Magento\Module\Setup\Connection\AdapterInterface' => 'Magento\Module\Setup\Connection\Adapter',
-                'Magento\Module\Resource\ResourceInterface' => 'Magento\Module\Resource\Resource',
-                'Magento\Module\ModuleListInterface' => 'Magento\Module\ModuleList'
-            ]
-        ],
-    ],
-];
diff --git a/setup/module/Magento/Module/config/module.config.php b/setup/module/Magento/Module/config/module.config.php
deleted file mode 100644
index d5ba5073e80..00000000000
--- a/setup/module/Magento/Module/config/module.config.php
+++ /dev/null
@@ -1,25 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-return [];
diff --git a/setup/module/Magento/Module/src/Setup/Config.php b/setup/module/Magento/Module/src/Setup/Config.php
deleted file mode 100644
index 05f83b79739..00000000000
--- a/setup/module/Magento/Module/src/Setup/Config.php
+++ /dev/null
@@ -1,192 +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.
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Module\Setup;
-
-use Magento\Filesystem\Directory\Write;
-use Magento\Filesystem\Filesystem;
-
-/**
- * Config installer
- */
-class Config
-{
-    const TMP_INSTALL_DATE_VALUE = 'd-d-d-d-d';
-
-    const TMP_ENCRYPT_KEY_VALUE = 'k-k-k-k-k';
-
-    /**
-     * Path to local configuration file
-     *
-     * @var string
-     */
-    protected $localConfigFile = 'local.xml';
-
-    /**
-     * @var array
-     */
-    protected $configData = array();
-
-    /**
-     * @var Filesystem
-     */
-    protected $filesystem;
-
-    /**
-     * @var Write
-     */
-    protected $configDirectory;
-
-    /**
-     * @param Filesystem $filesystem
-     */
-    public function __construct(
-        Filesystem $filesystem
-    ) {
-        $this->filesystem = $filesystem;
-        $this->configDirectory = $filesystem->getDirectoryWrite('etc');
-    }
-
-    /**
-     * @param array $data
-     * @return $this
-     */
-    public function setConfigData($data)
-    {
-        if (is_array($data)) {
-            $this->configData = $this->convert($data);
-        }
-        return $this;
-    }
-
-
-    /**
-     * Retrieve config data
-     *
-     * @return array
-     */
-    public function getConfigData()
-    {
-        return $this->configData;
-    }
-
-    /**
-     * Generate installation data and record them into local.xml using local.xml.template
-     *
-     * @return void
-     */
-    public function install()
-    {
-        $this->configData['date'] = self::TMP_INSTALL_DATE_VALUE;
-        $this->configData['key'] = self::TMP_ENCRYPT_KEY_VALUE;
-
-        $this->checkData();
-
-        $contents = $this->configDirectory->readFile('local.xml.template');
-        foreach ($this->configData as $index => $value) {
-            $contents = str_replace('{{' . $index . '}}', '<![CDATA[' . $value . ']]>', $contents);
-        }
-
-        $this->configDirectory->writeFile($this->localConfigFile, $contents, LOCK_EX);
-        $this->configDirectory->changePermissions($this->localConfigFile, 0777);
-    }
-
-    /**
-     * @param string $date
-     * @return $this
-     */
-    public function replaceTmpInstallDate($date = 'now')
-    {
-        $stamp = strtotime((string)$date);
-        $localXml = $this->configDirectory->readFile($this->localConfigFile);
-        $localXml = str_replace(self::TMP_INSTALL_DATE_VALUE, date('r', $stamp), $localXml);
-        $this->configDirectory->writeFile($this->localConfigFile, $localXml, LOCK_EX);
-
-        return $this;
-    }
-
-    /**
-     * @param string $key
-     * @return $this
-     */
-    public function replaceTmpEncryptKey($key)
-    {
-        $localXml = $this->configDirectory->readFile($this->localConfigFile);
-        $localXml = str_replace(self::TMP_ENCRYPT_KEY_VALUE, $key, $localXml);
-        $this->configDirectory->writeFile($this->localConfigFile, $localXml, LOCK_EX);
-
-        return $this;
-    }
-
-    /**
-     * Convert config
-     * @param array $source
-     * @return array
-     */
-    protected function convert(array $source = array())
-    {
-        $result = array();
-        $result['db_host'] = isset($source['db']['host']) ? $source['db']['host'] : '';
-        $result['db_name'] = isset($source['db']['name']) ? $source['db']['name'] : '';
-        $result['db_user'] = isset($source['db']['user']) ? $source['db']['user'] :'';
-        $result['db_pass'] = isset($source['db']['password']) ? $source['db']['password'] : '';
-        $result['db_prefix'] = isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : '';
-        $result['session_save'] = 'files';
-        $result['backend_frontname'] = isset($source['config']['address']['admin'])
-            ? $source['config']['address']['admin']
-            : '';
-        $result['db_model'] = '';
-        $result['db_init_statements'] = '';
-
-        $result['admin_username'] = isset($source['admin']['username']) ? $source['admin']['username'] : '';
-        $result['admin_password'] = isset($source['admin']['password']) ? $source['admin']['password'] : '';
-        $result['admin_email'] = isset($source['admin']['email']) ? $source['admin']['email'] : '';
-
-        return $result;
-    }
-
-    /**
-     * Check database connection data
-     *
-     * @throws \Exception
-     */
-    protected function checkData()
-    {
-        if (!isset($this->configData['db_name']) || empty($this->configData['db_name'])) {
-            throw new \Exception('The Database Name field cannot be empty.');
-        }
-        //make all table prefix to lower letter
-        if ($this->configData['db_prefix'] != '') {
-            $this->configData['db_prefix'] = strtolower($this->configData['db_prefix']);
-        }
-        //check table prefix
-        if ($this->configData['db_prefix'] != '') {
-            if (!preg_match('/^[a-z]+[a-z0-9_]*$/', $this->configData['db_prefix'])) {
-                throw new \Exception(
-                    'The table prefix should contain only letters (a-z), numbers (0-9) or underscores (_); the first character should be a letter.'
-                );
-            }
-        }
-    }
-}
diff --git a/setup/module/Magento/Setup/Module.php b/setup/module/Magento/Setup/Module.php
index 98a9ae065b1..c5c08cc8a13 100644
--- a/setup/module/Magento/Setup/Module.php
+++ b/setup/module/Magento/Setup/Module.php
@@ -24,22 +24,25 @@
 
 namespace Magento\Setup;
 
+use Zend\Console\Adapter\AdapterInterface;
 use Zend\ModuleManager\Feature\BootstrapListenerInterface;
 use Zend\ModuleManager\Feature\ConfigProviderInterface;
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
+use Zend\ModuleManager\Feature\ConsoleBannerProviderInterface;
+use Zend\ModuleManager\Feature\ConsoleUsageProviderInterface;
 use Zend\Mvc\ModuleRouteListener;
 use Zend\Mvc\MvcEvent;
 use Zend\EventManager\EventInterface;
 use Magento\Setup\Mvc\View\Http\InjectTemplateListener;
+use Magento\Setup\Controller\ConsoleController;
 
 class Module implements
     BootstrapListenerInterface,
     ConfigProviderInterface,
-    AutoloaderProviderInterface
+    ConsoleBannerProviderInterface,
+    ConsoleUsageProviderInterface
 {
     /**
-     * @param EventInterface $e
-     * @return void
+     * {@inheritdoc}
      */
     public function onBootstrap(EventInterface $e)
     {
@@ -77,7 +80,7 @@ class Module implements
     }
 
     /**
-     * @return array|mixed|\Traversable
+     * {@inheritdoc}
      */
     public function getConfig()
     {
@@ -91,16 +94,20 @@ class Module implements
     }
 
     /**
-     * @return array
+     * {@inheritdoc}
      */
-    public function getAutoloaderConfig()
+    public function getConsoleBanner(AdapterInterface $console)
     {
-        return array(
-            'Zend\Loader\StandardAutoloader' => array(
-                'namespaces' => array(
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ),
-            ),
-        );
+        return "==-------------------==\n"
+            . "   Magento Setup CLI   \n"
+            . "==-------------------==\n";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConsoleUsage(AdapterInterface $console)
+    {
+        return ConsoleController::getConsoleUsage();
     }
 }
diff --git a/setup/module/Magento/Setup/config/di.config.php b/setup/module/Magento/Setup/config/di.config.php
index d79148db72d..d0db93929f4 100644
--- a/setup/module/Magento/Setup/config/di.config.php
+++ b/setup/module/Magento/Setup/config/di.config.php
@@ -35,11 +35,13 @@ return [
             'Magento\Setup\Controller\Success\EncryptionController',
             'Magento\Setup\Controller\InstallController',
             'Magento\Setup\Controller\Install\ProgressController',
+            'Magento\Setup\Controller\Install\ClearProgressController',
             'Magento\Setup\Controller\Install\StartController',
             'Magento\Setup\Controller\IndexController',
             'Magento\Setup\Controller\LandingController',
             'Magento\Setup\Controller\EnvironmentController',
             'Magento\Setup\Controller\UserController',
+            'Magento\Setup\Controller\ConsoleController',
 
             'Magento\Setup\Controller\Controls\HeaderController',
             'Magento\Setup\Controller\Controls\MenuController',
@@ -56,6 +58,11 @@ return [
             'preference' => [
                 'Zend\EventManager\EventManagerInterface' => 'EventManager',
                 'Zend\ServiceManager\ServiceLocatorInterface' => 'ServiceManager',
+                'Magento\Setup\Module\Dependency\ManagerInterface' => 'Magento\Setup\Module\Dependency\Manager',
+                'Magento\Setup\Module\Setup\Connection\AdapterInterface' =>
+                    'Magento\Setup\Module\Setup\Connection\Adapter',
+                'Magento\Setup\Module\Resource\ResourceInterface' => 'Magento\Setup\Module\Resource\Resource',
+                'Magento\Setup\Module\ModuleListInterface' => 'Magento\Setup\Module\ModuleList',
             ]
         ],
     ],
diff --git a/setup/module/Magento/Setup/config/router.config.php b/setup/module/Magento/Setup/config/router.config.php
index ad704f2193f..f4df0510301 100644
--- a/setup/module/Magento/Setup/config/router.config.php
+++ b/setup/module/Magento/Setup/config/router.config.php
@@ -22,6 +22,8 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+use Magento\Setup\Controller\ConsoleController;
+
 return [
     'route_manager' => [
         'invokables' => [
@@ -56,4 +58,5 @@ return [
             ],
         ],
     ],
-];
\ No newline at end of file
+    'console' => ['router' => ['routes' => ConsoleController::getRouterConfig()]],
+];
diff --git a/setup/module/Magento/Setup/phpunit.xml.dist b/setup/module/Magento/Setup/phpunit.xml.dist
index 8a009cfd998..af44aab2867 100644
--- a/setup/module/Magento/Setup/phpunit.xml.dist
+++ b/setup/module/Magento/Setup/phpunit.xml.dist
@@ -23,16 +23,18 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<phpunit backupGlobals="false"
-         backupStaticAttributes="false"
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
          colors="true"
+         bootstrap="../../../vendor/autoload.php"
+         backupGlobals="false"
+         backupStaticAttributes="false"
          convertErrorsToExceptions="true"
          convertNoticesToExceptions="true"
          convertWarningsToExceptions="true"
          processIsolation="false"
          stopOnFailure="false"
          syntaxCheck="false"
-         bootstrap="../../../vendor/autoload.php"
 >
     <testsuites>
         <testsuite name="Magento Setup Module Test Suite">
diff --git a/setup/module/Magento/Setup/src/Controller/ConsoleController.php b/setup/module/Magento/Setup/src/Controller/ConsoleController.php
new file mode 100644
index 00000000000..6156a74e862
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Controller/ConsoleController.php
@@ -0,0 +1,406 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Controller;
+
+use Magento\Locale\Lists;
+use Magento\Setup\Module\Setup\Config;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\Installer;
+use Magento\Setup\Model\ConsoleLogger;
+use Magento\Webapi\Exception;
+use Zend\Console\Request as ConsoleRequest;
+use Zend\EventManager\EventManagerInterface;
+use Zend\Stdlib\RequestInterface as Request;
+use Zend\Mvc\Controller\AbstractActionController;
+use \Magento\Setup\Model\UserConfigurationData as UserConfig;
+use Magento\Setup\Model\AdminAccount;
+
+/**
+ * Controller that handles all setup commands via command line interface.
+ *
+ * @package Magento\Setup\Controller
+ */
+class ConsoleController extends AbstractActionController
+{
+    /**#@+
+     * Supported command types
+     */
+    const CMD_HELP = 'help';
+    const CMD_INSTALL = 'install';
+    const CMD_INSTALL_CONFIG = 'install-configuration';
+    const CMD_INSTALL_SCHEMA = 'install-schema';
+    const CMD_INSTALL_DATA = 'install-data';
+    const CMD_INSTALL_USER_CONFIG = 'install-user-configuration';
+    const CMD_INSTALL_ADMIN_USER = 'install-admin-user';
+    const CMD_UPDATE = 'update';
+    /**#@- */
+
+    /**#@+
+     * Additional keys for "info" command
+     */
+    const INFO_LOCALES = 'languages';
+    const INFO_CURRENCIES = 'currencies';
+    const INFO_TIMEZONES = 'timezones';
+    /**#@- */
+
+    /**
+     * Map of controller actions exposed in CLI
+     *
+     * @var string[]
+     */
+    private static $actions = [
+        self::CMD_HELP => 'help',
+        self::CMD_INSTALL => 'install',
+        self::CMD_INSTALL_CONFIG => 'installDeploymentConfig',
+        self::CMD_INSTALL_SCHEMA => 'installSchema',
+        self::CMD_INSTALL_DATA => 'installData',
+        self::CMD_INSTALL_USER_CONFIG => 'installUserConfig',
+        self::CMD_INSTALL_ADMIN_USER => 'installAdminUser',
+        self::CMD_UPDATE => 'updateAction',
+    ];
+
+    /**
+     * Options for "help" command
+     *
+     * @var string[]
+     */
+    private static $helpOptions = [
+        self::CMD_INSTALL,
+        self::CMD_INSTALL_CONFIG,
+        self::CMD_INSTALL_SCHEMA,
+        self::CMD_INSTALL_DATA,
+        self::CMD_INSTALL_USER_CONFIG,
+        self::CMD_INSTALL_ADMIN_USER,
+        self::CMD_UPDATE,
+        self::INFO_LOCALES,
+        self::INFO_CURRENCIES,
+        self::INFO_TIMEZONES,
+    ];
+
+    /**
+     * Logger
+     *
+     * @var ConsoleLogger
+     */
+    private $log;
+
+    /**
+     * Options Lists
+     *
+     * @var Lists
+     */
+    private $options;
+
+    /**
+     * Installer service
+     *
+     * @var Installer
+     */
+    private $installer;
+
+    /**
+     * Gets router configuration to be used in module definition
+     *
+     * @return array
+     */
+    public static function getRouterConfig()
+    {
+        $result = [];
+        $config = self::getCliConfig();
+        foreach (self::$actions as $type => $action) {
+            $result[$type] = ['options' => [
+                'route' => $config[$type]['route'],
+                'defaults' => ['controller' => __CLASS__, 'action' => $action],
+            ]];
+        }
+        return $result;
+    }
+
+    /**
+     * Gets console usage to be used in module definition
+     *
+     * @return array
+     */
+    public static function getConsoleUsage()
+    {
+        $result = ["Usage:\n"];
+        foreach (self::getCliConfig() as $cmd) {
+            $result[$cmd['usage_short']] = $cmd['usage_desc'];
+        }
+        foreach (self::$helpOptions as $type) {
+            $result[] = '    ' . ConsoleController::CMD_HELP . ' ' . $type;
+        }
+        return $result;
+    }
+
+    /**
+     * The CLI that this controller implements
+     *
+     * @return array
+     */
+    private static function getCliConfig()
+    {
+        $deployConfig = '--' . Config::KEY_DB_HOST . '='
+            . ' --' . Config::KEY_DB_NAME . '='
+            . ' --' . Config::KEY_DB_USER . '='
+            . ' --' . Config::KEY_BACKEND_FRONTNAME . '='
+            . ' [--' . Config::KEY_DB_PASS . '=]'
+            . ' [--' . Config::KEY_DB_PREFIX . '=]'
+            . ' [--' . Config::KEY_DB_MODEL . '=]'
+            . ' [--' . Config::KEY_DB_INIT_STATEMENTS . '=]'
+            . ' [--' . Config::KEY_SESSION_SAVE . '=]'
+            . ' [--' . Config::KEY_ENCRYPTION_KEY . '=]';
+        $userConfig = '--' . UserConfig::KEY_BASE_URL . '='
+            . ' --' . UserConfig::KEY_LANGUAGE . '='
+            . ' --' . UserConfig::KEY_TIMEZONE . '='
+            . ' --' . UserConfig::KEY_CURRENCY . '='
+            . ' [--' . UserConfig::KEY_USE_SEF_URL . '=]'
+            . ' [--' . UserConfig::KEY_IS_SECURE . '=]'
+            . ' [--' . UserConfig::KEY_BASE_URL_SECURE . '=]'
+            . ' [--' . UserConfig::KEY_IS_SECURE_ADMIN . '=]';
+        $adminUser = '--' . AdminAccount::KEY_USERNAME . '='
+            . ' --' . AdminAccount::KEY_PASSWORD . '='
+            . ' --' . AdminAccount::KEY_EMAIL . '='
+            . ' --' . AdminAccount::KEY_FIRST_NAME . '='
+            . ' --' . AdminAccount::KEY_LAST_NAME . '=';
+        return [
+            self::CMD_INSTALL => [
+                'route' => self::CMD_INSTALL . ' ' . $deployConfig . ' ' . $userConfig
+                    . ' ' . $adminUser,
+                'usage' => $deployConfig . "\n"
+                    . $userConfig . "\n"
+                    . $adminUser,
+                'usage_short' => self::CMD_INSTALL . ' <options>',
+                'usage_desc' => 'Install Magento application',
+            ],
+            self::CMD_UPDATE => [
+                'route' => self::CMD_UPDATE,
+                'usage' => '',
+                'usage_short' => self::CMD_UPDATE,
+                'usage_desc' => 'Update database schema and data',
+            ],
+            self::CMD_INSTALL_CONFIG => [
+                'route' => self::CMD_INSTALL_CONFIG . ' ' . $deployConfig,
+                'usage' => $deployConfig,
+                'usage_short' => self::CMD_INSTALL_CONFIG . ' <options>',
+                'usage_desc' => 'Install deployment configuration',
+            ],
+            self::CMD_INSTALL_SCHEMA => [
+                'route' => self::CMD_INSTALL_SCHEMA,
+                'usage' => '',
+                'usage_short' => self::CMD_INSTALL_SCHEMA,
+                'usage_desc' => 'Install DB schema',
+            ],
+            self::CMD_INSTALL_DATA => [
+                'route' => self::CMD_INSTALL_DATA,
+                'usage' => '',
+                'usage_short' => self::CMD_INSTALL_DATA,
+                'usage_desc' => 'Install data fixtures',
+            ],
+            self::CMD_INSTALL_USER_CONFIG => [
+                'route' => self::CMD_INSTALL_USER_CONFIG . ' ' . $userConfig,
+                'usage' => $userConfig,
+                'usage_short' => self::CMD_INSTALL_USER_CONFIG . ' <options>',
+                'usage_desc' => 'Install user configuration',
+            ],
+            self::CMD_INSTALL_ADMIN_USER => [
+                'route' => self::CMD_INSTALL_ADMIN_USER . ' ' . $adminUser,
+                'usage' => $adminUser,
+                'usage_short' => self::CMD_INSTALL_ADMIN_USER . ' <options>',
+                'usage_desc' => 'Install admin user account',
+            ],
+            self::CMD_HELP => [
+                'route' => self::CMD_HELP . ' (' . implode('|', self::$helpOptions) . '):type',
+                'usage' => '<' . implode('|', self::$helpOptions) . '>',
+                'usage_short' => self::CMD_HELP . ' <topic>',
+                'usage_desc' => 'Help about particular command or topic:',
+            ],
+        ];
+    }
+
+    /**
+     * Constructor
+     *
+     * @param ConsoleLogger $consoleLogger
+     * @param Lists $options
+     * @param InstallerFactory $installerFactory
+     */
+    public function __construct(
+        ConsoleLogger $consoleLogger,
+        Lists $options,
+        InstallerFactory $installerFactory
+    ) {
+        $this->log = $consoleLogger;
+        $this->options = $options;
+        $this->installer = $installerFactory->create($consoleLogger);
+    }
+
+    /**
+     * Adding Check for Allowing only console application to come through
+     *
+     * {@inheritdoc}
+     */
+    public function setEventManager(EventManagerInterface $events)
+    {
+        parent::setEventManager($events);
+        $controller = $this;
+        $events->attach('dispatch', function ($action) use ($controller) {
+            /** @var $action \Zend\Mvc\Controller\AbstractActionController */
+            // Make sure that we are running in a console and the user has not tricked our
+            // application into running this action from a public web server.
+            if (!$action->getRequest() instanceof ConsoleRequest) {
+                throw new \RuntimeException('You can only use this action from a console!');
+            }
+        }, 100); // execute before executing action logic
+        return $this;
+    }
+
+    /**
+     * Controller for Install Command
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function installAction()
+    {
+        try {
+            /** @var \Zend\Console\Request $request */
+            $request = $this->getRequest();
+            $this->installer->install($request->getParams());
+        } catch (Exception $e) {
+            $this->log->logError($e);
+        }
+    }
+
+    /**
+     * Creates the local.xml file
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function installDeploymentConfigAction()
+    {
+        /** @var \Zend\Console\Request $request */
+        $request = $this->getRequest();
+        $this->installer->installDeploymentConfig($request->getParams());
+    }
+
+    /**
+     * Installs and updates database schema
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function installSchemaAction()
+    {
+        $this->installer->installSchema();
+    }
+
+    /**
+     * Installs and updates data fixtures
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function installDataAction()
+    {
+        $this->installer->installDataFixtures();
+    }
+
+    /**
+     * Updates database schema and data
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function updateAction()
+    {
+        $this->installer->installSchema();
+        $this->installer->installDataFixtures();
+    }
+
+    /**
+     * Installs user configuration
+     */
+    public function installUserConfigAction()
+    {
+        /** @var \Zend\Console\Request $request */
+        $request = $this->getRequest();
+        $this->installer->installUserConfig($request->getParams());
+    }
+
+    /**
+     * Installs admin user
+     */
+    public function installAdminUserAction()
+    {
+        /** @var \Zend\Console\Request $request */
+        $request = $this->getRequest();
+        $this->installer->installAdminUser($request->getParams());
+    }
+
+    /**
+     * Shows necessary information for installing Magento
+     *
+     * @return string
+     * @throws \Exception
+     */
+    public function helpAction()
+    {
+        $type = $this->getRequest()->getParam('type');
+        $details = self::getCliConfig();
+        switch($type) {
+            case self::INFO_LOCALES:
+                return $this->arrayToString($this->options->getLocaleList());
+            case self::INFO_CURRENCIES:
+                return $this->arrayToString($this->options->getCurrencyList());
+            case self::INFO_TIMEZONES:
+                return $this->arrayToString($this->options->getTimezoneList());
+            default:
+                if (isset($details[$type])) {
+                    if ($details[$type]['usage']) {
+                        return "\nAvailable parameters:\n{$details[$type]['usage']}\n";
+                    }
+                    return "\nThis command has no parameters.\n";
+                }
+                throw new \InvalidArgumentException("Unknown type: {$type}");
+        }
+    }
+
+    /**
+     * Convert an array to string
+     *
+     * @param array $input
+     * @return string
+     */
+    private function arrayToString($input)
+    {
+        $result = '';
+        foreach ($input as $key => $value) {
+            $result .= "$key => $value\n";
+        }
+        return $result;
+    }
+}
diff --git a/setup/module/Magento/Setup/src/Controller/Data/DatabaseController.php b/setup/module/Magento/Setup/src/Controller/Data/DatabaseController.php
index ec9c4421dc8..fb1420583a7 100644
--- a/setup/module/Magento/Setup/src/Controller/Data/DatabaseController.php
+++ b/setup/module/Magento/Setup/src/Controller/Data/DatabaseController.php
@@ -17,16 +17,16 @@
  * 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.
- *   
+ *
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 namespace Magento\Setup\Controller\Data;
 
+use Magento\Setup\Model\Installer;
 use Zend\Mvc\Controller\AbstractActionController;
 use Zend\View\Model\JsonModel;
 use Zend\Json\Json;
-use Magento\Setup\Model\DatabaseCheck;
 
 class DatabaseController extends AbstractActionController
 {
@@ -51,23 +51,11 @@ class DatabaseController extends AbstractActionController
     {
         $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
         try {
-            $db = new DatabaseCheck($this->prepareDbConfig($params));
-            return $this->jsonModel->setVariables(['success' => $db->checkConnection()]);
+            Installer::checkDatabaseConnection($params['name'], $params['host'], $params['user'], $params['password']);
+            return $this->jsonModel->setVariables(['success' => true]);
         } catch (\Exception $e) {
             return $this->jsonModel->setVariables(['success' => false]);
         }
     }
 
-    protected function prepareDbConfig(array $data = array())
-    {
-        return array(
-            'driver'         => "Pdo",
-            'dsn'            => "mysql:dbname=" . $data['name']. ";host=" .$data['host'],
-            'username'       => $data['user'],
-            'password'       => isset($data['password']) ? $data['password'] : null,
-            'driver_options' => array(
-                \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
-            ),
-        );
-    }
 }
diff --git a/setup/module/Magento/Setup/src/Controller/Data/FilePermissionsController.php b/setup/module/Magento/Setup/src/Controller/Data/FilePermissionsController.php
index 01544eb5360..6135ab9765c 100644
--- a/setup/module/Magento/Setup/src/Controller/Data/FilePermissionsController.php
+++ b/setup/module/Magento/Setup/src/Controller/Data/FilePermissionsController.php
@@ -17,7 +17,7 @@
  * 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.
- *   
+ *
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
@@ -56,22 +56,19 @@ class FilePermissionsController extends AbstractActionController
      */
     public function indexAction()
     {
-        $required = $this->permissions->getRequired();
-        $current = $this->permissions->getCurrent();
-
         $responseType = ResponseTypeInterface::RESPONSE_TYPE_SUCCESS;
-        if (array_diff($required, $current)) {
+        if ($this->permissions->checkPermission()) {
             $responseType = ResponseTypeInterface::RESPONSE_TYPE_ERROR;
         }
 
         $data = [
             'responseType' => $responseType,
             'data' => [
-                'required' => $required,
-                'current' => $current,
+                'required' => $this->permissions->getRequired(),
+                'current' => $this->permissions->getCurrent(),
             ],
         ];
 
         return $this->jsonModel->setVariables($data);
     }
-}
+}
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/UrlTest.php b/setup/module/Magento/Setup/src/Controller/Install/ClearProgressController.php
similarity index 60%
rename from dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/UrlTest.php
rename to setup/module/Magento/Setup/src/Controller/Install/ClearProgressController.php
index 1a9404621c8..351483669c1 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/UrlTest.php
+++ b/setup/module/Magento/Setup/src/Controller/Install/ClearProgressController.php
@@ -21,27 +21,35 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Model\Resource;
+namespace Magento\Setup\Controller\Install;
 
-class UrlTest extends \PHPUnit_Framework_TestCase
+use Magento\Setup\Model\WebLogger;
+use Zend\Mvc\Controller\AbstractActionController;
+use Zend\View\Model\JsonModel;
+
+class ClearProgressController extends AbstractActionController
 {
     /**
-     * @var \Magento\Catalog\Model\Resource\Url
+     * @param JsonModel $view
+     * @param WebLogger $logger
      */
-    protected $_model;
-
-    protected function setUp()
-    {
-        $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Resource\Url'
-        );
+    public function __construct(
+        JsonModel $view,
+        WebLogger $logger
+    ) {
+        $this->json = $view;
+        $this->logger = $logger;
     }
 
     /**
-     * @magentoDataFixture Magento/Catalog/Model/Resource/_files/url_rewrites.php
+     * Clears installation log
+     *
+     * @return JsonModel
      */
-    public function testGetLastUsedRewriteRequestIncrement()
+    public function indexAction()
     {
-        $this->assertEquals(1000, $this->_model->getLastUsedRewriteRequestIncrement('url-key-', '.html', 1));
+        $this->logger->clear();
+        $this->json->setVariable('success', true);
+        return $this->json;
     }
 }
diff --git a/setup/module/Magento/Setup/src/Controller/Install/ProgressController.php b/setup/module/Magento/Setup/src/Controller/Install/ProgressController.php
index 60ac35dfd42..622e82ff192 100644
--- a/setup/module/Magento/Setup/src/Controller/Install/ProgressController.php
+++ b/setup/module/Magento/Setup/src/Controller/Install/ProgressController.php
@@ -23,20 +23,30 @@
  */
 namespace Magento\Setup\Controller\Install;
 
-use Magento\Module\ModuleListInterface;
-use Magento\Setup\Model\Logger;
+use Magento\Setup\Module\ModuleListInterface;
+use Magento\Setup\Model\WebLogger;
 use Zend\Mvc\Controller\AbstractActionController;
 use Zend\View\Model\JsonModel;
 
 class ProgressController extends AbstractActionController
 {
+    /**
+     * How many times installer will loop through the list of modules
+     */
+    const MODULE_LOOPS_COUNT = 2;
+
+    /**
+     * The number of additional log messages in the code
+     */
+    const ADDITIONAL_LOG_MESSAGE_COUNT = 15;
+
     /**
      * @var \Zend\View\Model\JsonModel
      */
     protected $json;
 
     /**
-     * @var Logger
+     * @var WebLogger
      */
     protected $logger;
 
@@ -45,12 +55,12 @@ class ProgressController extends AbstractActionController
     /**
      * @param JsonModel $view
      * @param ModuleListInterface $moduleList
-     * @param Logger $logger
+     * @param WebLogger $logger
      */
     public function __construct(
         JsonModel $view,
         ModuleListInterface $moduleList,
-        Logger $logger
+        WebLogger $logger
     ) {
         $this->moduleList = $moduleList;
         $this->logger = $logger;
@@ -62,14 +72,14 @@ class ProgressController extends AbstractActionController
      */
     public function indexAction()
     {
-        //@todo I fix it
         $moduleCount = count($this->moduleList->getModules());
         $log = $this->logger->get();
         $progress = 0;
         if (!empty($log)) {
-            $progress = round(count($log)/$moduleCount*90);
+            $progress = round(
+                (count($log) * 100)/($moduleCount * self::MODULE_LOOPS_COUNT + self::ADDITIONAL_LOG_MESSAGE_COUNT)
+            );
         }
-        $progress += 5;
 
         return $this->json->setVariables(
             array(
diff --git a/setup/module/Magento/Setup/src/Controller/Install/StartController.php b/setup/module/Magento/Setup/src/Controller/Install/StartController.php
index 1a5ce07b640..17a1ca3e05b 100644
--- a/setup/module/Magento/Setup/src/Controller/Install/StartController.php
+++ b/setup/module/Magento/Setup/src/Controller/Install/StartController.php
@@ -21,213 +21,150 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Setup\Controller\Install;
 
-use Magento\Framework\Math\Random;
-use Magento\Module\ModuleListInterface;
-use Magento\Module\Setup\Config;
-use Magento\Module\SetupFactory;
-use Magento\Setup\Model\AdminAccountFactory;
-use Magento\Setup\Model\Logger;
-use Magento\Config\ConfigFactory;
-use Zend\Json\Json;
+use Magento\Setup\Module\Setup\Config;
 use Zend\Mvc\Controller\AbstractActionController;
+use Magento\Setup\Model\WebLogger;
+use Zend\Json\Json;
 use Zend\View\Model\JsonModel;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\Installer;
+use Zend\Stdlib\Parameters;
+use Magento\Setup\Model\UserConfigurationData as UserConfig;
+use Magento\Setup\Model\AdminAccount;
 
+/**
+ * UI Controller that handles installation
+ *
+ * @package Magento\Setup\Controller\Install
+ */
 class StartController extends AbstractActionController
 {
     /**
+     * JSON Model Object
+     *
      * @var JsonModel
      */
-    protected $json;
-
-    /**
-     * @var []
-     */
-    protected $moduleList;
-
-    /**
-     * @var Logger
-     */
-    protected $logger;
+    private $json;
 
     /**
-     * @var Config
+     * @var WebLogger
      */
-    protected $config;
+    private $log;
 
     /**
-     * @var ConfigFactory
+     * @var Installer
      */
-    protected $systemConfig;
-
-    /**
-     * @var AdminAccountFactory
-     */
-    protected $adminAccountFactory;
-
-    /**
-     * @var Random
-     */
-    protected $random;
+    private $installer;
 
     /**
+     * Default Constructor
+     *
      * @param JsonModel $view
-     * @param ModuleListInterface $moduleList
-     * @param SetupFactory $setupFactory
-     * @param AdminAccountFactory $adminAccountFactory
-     * @param Logger $logger
-     * @param Random $random
-     * @param Config $config
+     * @param WebLogger $logger
+     * @param InstallerFactory $installerFactory
      */
     public function __construct(
         JsonModel $view,
-        ModuleListInterface $moduleList,
-        SetupFactory $setupFactory,
-        AdminAccountFactory $adminAccountFactory,
-        Logger $logger,
-        Random $random,
-        Config $config,
-        ConfigFactory $systemConfig
+        WebLogger $logger,
+        InstallerFactory $installerFactory
     ) {
-        $this->logger = $logger;
         $this->json = $view;
-        $this->moduleList = $moduleList->getModules();
-        $this->setupFactory = $setupFactory;
-        $this->config = $config;
-        $this->systemConfig = $systemConfig;
-        $this->adminAccountFactory = $adminAccountFactory;
-        $this->random = $random;
+        $this->log = $logger;
+        $this->installer = $installerFactory->create($logger);
     }
 
     /**
+     * Index Action
+     *
      * @return JsonModel
      */
     public function indexAction()
     {
-        $this->logger->clear();
-
-        $data = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
-
-        $this->config->setConfigData($data);
-        $this->config->install();
-
-        $this->setupFactory->setConfig($this->config->getConfigData());
-
-        $moduleNames = array_keys($this->moduleList);
-        foreach ($moduleNames as $moduleName) {
-            $setup = $this->setupFactory->create($moduleName);
-            $setup->applyUpdates();
-            $this->logger->logSuccess($moduleName);
-        }
-        $this->logger->logSuccess('Artifact');
-
-        // Set data to config
-        $setup->addConfigData(
-            'web/seo/use_rewrites',
-            isset($data['config']['rewrites']['allowed']) ? $data['config']['rewrites']['allowed'] : 0
-        );
-
-        $setup->addConfigData(
-            'web/unsecure/base_url',
-            isset($data['config']['address']['web']) ? $data['config']['address']['web'] : '{{unsecure_base_url}}'
-        );
-        $setup->addConfigData(
-            'web/secure/use_in_frontend',
-            isset($data['config']['https']['front']) ? $data['config']['https']['front'] : 0
-        );
-        $setup->addConfigData(
-            'web/secure/base_url',
-            isset($data['config']['address']['web']) ? $data['config']['address']['web'] : '{{secure_base_url}}'
-        );
-        $setup->addConfigData(
-            'web/secure/use_in_adminhtml',
-            isset($data['config']['https']['admin']) ? $data['config']['https']['admin'] : 0
-        );
-        $setup->addConfigData(
-            'general/locale/code',
-            isset($data['store']['language']) ? $data['store']['language'] : 'en_US'
-        );
-        $setup->addConfigData(
-            'general/locale/timezone',
-            isset($data['store']['timezone']) ? $data['store']['timezone'] : 'America/Los_Angeles'
-        );
-
-        $currencyCode = isset($data['store']['currency']) ? $data['store']['currency'] : 'USD';
-
-        $setup->addConfigData('currency/options/base', $currencyCode);
-        $setup->addConfigData('currency/options/default', $currencyCode);
-        $setup->addConfigData('currency/options/allow', $currencyCode);
-
-        // Create administrator account
-        $this->adminAccountFactory->setConfig($this->config->getConfigData());
-        $adminAccount = $this->adminAccountFactory->create($setup);
-        $adminAccount->save();
-
-        $this->logger->logSuccess('Admin User');
-
-        if ($data['config']['encrypt']['type'] == 'magento') {
-            $key = md5($this->random->getRandomString(10));
-        } else {
-            $key = $data['config']['encrypt']['key'];
-        }
-
-        $this->config->replaceTmpEncryptKey($key);
-        $this->config->replaceTmpInstallDate(date('r'));
-
-        $phpPath = $this->phpExecutablePath();
-        exec(
-            $phpPath .
-            'php -f ' . escapeshellarg($this->systemConfig->create()->getMagentoBasePath() .
-                '/dev/shell/run_data_fixtures.php'),
-            $output,
-            $exitCode
-        );
-        if ($exitCode !== 0) {
-            $outputMsg = implode(PHP_EOL, $output);
-            $this->logger->logError(
-                new \Exception('Data Update Failed with Exit Code: ' . $exitCode . PHP_EOL . $outputMsg)
+        $this->log->clear();
+        try {
+            $data = array_merge(
+                $this->importDeploymentConfigForm(),
+                $this->importUserConfigForm(),
+                $this->importAdminUserForm()
             );
-            $this->json->setVariable('success', false);
-        } else {
-            $this->logger->logSuccess('Data Updates');
+            $config = $this->installer->install($data);
+            $this->json->setVariable('key', $config->get(Config::KEY_ENCRYPTION_KEY));
             $this->json->setVariable('success', true);
+        } catch(\Exception $e) {
+            $this->log->logError($e);
+            $this->json->setVariable('success', false);
         }
-
-        $this->json->setVariable('key', $key);
         return $this->json;
     }
 
     /**
-     * @return string
-     * @throws \Exception
+     * Maps data from request to format of deployment config model
+     *
+     * @return array
      */
-    private function phpExecutablePath()
+    private function importDeploymentConfigForm()
     {
-        try {
-            $phpPath = '';
-            $iniFile = fopen(php_ini_loaded_file(), 'r');
-            while ($line = fgets($iniFile)) {
-                if ((strpos($line, 'extension_dir') !== false) && (strrpos($line, ";") !==0)) {
-                    $extPath = explode("=", $line);
-                    $pathFull = explode("\"", $extPath[1]);
-                    $pathParts[1] = str_replace('\\', '/', $pathFull[1]);
-                    foreach (explode('/', $pathParts[1]) as $piece) {
-                        $phpPath .= $piece . '/';
-                        if (strpos($piece, phpversion()) !== false) {
-                            if (file_exists($phpPath.'bin')) {
-                                $phpPath .= 'bin' . '/';
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
-            fclose($iniFile);
-        } catch(\Exception $e){
-            throw $e;
-        }
+        $source = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
+        $result = [];
+        $result[Config::KEY_DB_HOST] = isset($source['db']['host']) ? $source['db']['host'] : '';
+        $result[Config::KEY_DB_NAME] = isset($source['db']['name']) ? $source['db']['name'] : '';
+        $result[Config::KEY_DB_USER] = isset($source['db']['user']) ? $source['db']['user'] :'';
+        $result[Config::KEY_DB_PASS] = isset($source['db']['password']) ? $source['db']['password'] : '';
+        $result[Config::KEY_DB_PREFIX] = isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : '';
+        $result[Config::KEY_BACKEND_FRONTNAME] = isset($source['config']['address']['admin'])
+            ? $source['config']['address']['admin']
+            : '';
+        $result[Config::KEY_ENCRYPTION_KEY] = isset($source['config']['encrypt']['key'])
+            ? $source['config']['encrypt']['key']
+            : '';
+        return $result;
+    }
+
+    /**
+     * Maps data from request to format of user config model
+     *
+     * @return array
+     */
+    private function importUserConfigForm()
+    {
+        $source = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
+        $result = [];
+        $result[UserConfig::KEY_USE_SEF_URL] = isset($source['config']['rewrites']['allowed'])
+            ? $source['config']['rewrites']['allowed'] : '';
+        $result[UserConfig::KEY_BASE_URL] = isset($source['config']['address']['web'])
+            ? $source['config']['address']['web'] : '';
+        $result[UserConfig::KEY_IS_SECURE] = isset($source['config']['https']['front'])
+            ? $source['config']['https']['front'] : '';
+        $result[UserConfig::KEY_BASE_URL_SECURE] = isset($source['config']['address']['web'])
+            ? $source['config']['address']['web'] : '';
+        $result[UserConfig::KEY_IS_SECURE_ADMIN] = isset($source['config']['https']['admin'])
+            ? $source['config']['https']['admin'] : '';
+        $result[UserConfig::KEY_LANGUAGE] = isset($source['store']['language'])
+            ? $source['store']['language'] : '';
+        $result[UserConfig::KEY_TIMEZONE] = isset($source['store']['timezone'])
+            ? $source['store']['timezone'] : '';
+        $result[UserConfig::KEY_CURRENCY] = isset($source['store']['currency'])
+            ? $source['store']['currency'] : '';
+        return $result;
+    }
 
-        return $phpPath;
+    /**
+     * Maps data from request to format of admin account model
+     *
+     * @return array
+     */
+    private function importAdminUserForm()
+    {
+        $source = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
+        $result = [];
+        $result[AdminAccount::KEY_USERNAME] = isset($source['admin']['username']) ? $source['admin']['username'] : '';
+        $result[AdminAccount::KEY_PASSWORD] = isset($source['admin']['password']) ? $source['admin']['password'] : '';
+        $result[AdminAccount::KEY_EMAIL] = isset($source['admin']['email']) ? $source['admin']['email'] : '';
+        $result[AdminAccount::KEY_FIRST_NAME] = $result[AdminAccount::KEY_USERNAME];
+        $result[AdminAccount::KEY_LAST_NAME] = $result[AdminAccount::KEY_USERNAME];
+        return $result;
     }
 }
diff --git a/setup/module/Magento/Framework/src/DB/Adapter/AdapterInterface.php b/setup/module/Magento/Setup/src/Framework/DB/Adapter/AdapterInterface.php
similarity index 94%
rename from setup/module/Magento/Framework/src/DB/Adapter/AdapterInterface.php
rename to setup/module/Magento/Setup/src/Framework/DB/Adapter/AdapterInterface.php
index 79c39edf140..a5ca82e852a 100644
--- a/setup/module/Magento/Framework/src/DB/Adapter/AdapterInterface.php
+++ b/setup/module/Magento/Setup/src/Framework/DB/Adapter/AdapterInterface.php
@@ -21,9 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Framework\DB\Adapter;
+namespace Magento\Setup\Framework\DB\Adapter;
 
-use Magento\Framework\DB\Ddl\Table;
+use Magento\Setup\Framework\DB\Ddl\Table;
 
 /**
  * Magento Database Adapter Interface
@@ -93,21 +93,21 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
     /**
      * Begin new DB transaction for connection
      *
-     * @return \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @return \Magento\Setup\Framework\DB\Adapter\Pdo\Mysql
      */
     public function beginTransaction();
 
     /**
      * Commit DB transaction
      *
-     * @return \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @return \Magento\Setup\Framework\DB\Adapter\Pdo\Mysql
      */
     public function commit();
 
     /**
      * Roll-back DB transaction
      *
-     * @return \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @return \Magento\Setup\Framework\DB\Adapter\Pdo\Mysql
      */
     public function rollBack();
 
@@ -153,7 +153,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      *
      * @param string $tableName
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function truncateTable($tableName, $schemaName = null);
 
@@ -206,7 +206,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
     public function describeTable($tableName, $schemaName = null);
 
     /**
-     * Create \Magento\Framework\DB\Ddl\Table object by data from describe table
+     * Create \Magento\Setup\Framework\DB\Ddl\Table object by data from describe table
      *
      * @param string $tableName
      * @param string $newTableName
@@ -222,7 +222,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param array|string $definition
      * @param boolean $flushData
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\Pdo\Mysql
+     * @return \Magento\Setup\Framework\DB\Adapter\Pdo\Mysql
      */
     public function modifyColumnByDdl($tableName, $columnName, $definition, $flushData = false, $schemaName = null);
 
@@ -246,7 +246,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param string $columnName
      * @param array|string $definition  string specific or universal array DB Server definition
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function addColumn($tableName, $columnName, $definition, $schemaName = null);
 
@@ -261,7 +261,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param array|string $definition
      * @param boolean $flushData        flush table statistic
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function changeColumn(
         $tableName,
@@ -280,7 +280,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param array|string $definition
      * @param boolean $flushData
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function modifyColumn($tableName, $columnName, $definition, $flushData = false, $schemaName = null);
 
@@ -364,7 +364,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param boolean $purge trying remove invalid data
      * @param string $schemaName
      * @param string $refSchemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -387,7 +387,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
      * @param string $tableName
      * @param string $fkName
      * @param string $schemaName
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function dropForeignKey($tableName, $fkName, $schemaName = null);
 
@@ -417,7 +417,7 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
     public function getForeignKeys($tableName, $schemaName = null);
 
     /**
-     * Creates and returns a new \Magento\Framework\DB\Select object for this adapter.
+     * Creates and returns a new \Magento\Setup\Framework\DB\Select object for this adapter.
      *
      * @return \Zend\Db\Sql\Select
      */
@@ -530,14 +530,14 @@ interface AdapterInterface extends \Zend\Db\Adapter\AdapterInterface
     /**
      * Run additional environment before setup
      *
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function startSetup();
 
     /**
      * Run additional environment after setup
      *
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function endSetup();
 
diff --git a/setup/module/Magento/Framework/src/DB/Adapter/Pdo/Mysql.php b/setup/module/Magento/Setup/src/Framework/DB/Adapter/Pdo/Mysql.php
similarity index 98%
rename from setup/module/Magento/Framework/src/DB/Adapter/Pdo/Mysql.php
rename to setup/module/Magento/Setup/src/Framework/DB/Adapter/Pdo/Mysql.php
index e03f7a0a651..75d6f635fed 100644
--- a/setup/module/Magento/Framework/src/DB/Adapter/Pdo/Mysql.php
+++ b/setup/module/Magento/Setup/src/Framework/DB/Adapter/Pdo/Mysql.php
@@ -21,12 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Framework\DB\Adapter\Pdo;
+namespace Magento\Setup\Framework\DB\Adapter\Pdo;
 
 use Magento\Filesystem\Filesystem;
-use Magento\Framework\DB\Adapter\AdapterInterface;
-use Magento\Framework\DB\Ddl\Table;
-use Magento\Framework\DB\ExpressionConverter;
+use Magento\Setup\Framework\DB\Adapter\AdapterInterface;
+use Magento\Setup\Framework\DB\Ddl\Table;
+use \Magento\Framework\DB\ExpressionConverter;
 use Zend\Db\Adapter\Adapter;
 use Zend\Db\Adapter\Driver\StatementInterface;
 use Zend\Db\Adapter\Driver;
@@ -66,7 +66,7 @@ class Mysql extends Adapter implements AdapterInterface
      *
      * @var int
      */
-    protected $_transactionLevel    = 0;
+    protected $_transactionLevel = 0;
 
     /**
      * Whether transaction was rolled back or not
@@ -89,49 +89,49 @@ class Mysql extends Adapter implements AdapterInterface
      *
      * @var array
      */
-    protected $_bindParams          = array();
+    protected $_bindParams = [];
 
     /**
      * Autoincrement for bind value. Used by regexp callback.
      *
      * @var int
      */
-    protected $_bindIncrement       = 0;
+    protected $_bindIncrement = 0;
 
     /**
      * Write SQL debug data to file
      *
      * @var bool
      */
-    protected $_debug               = false;
+    protected $_debug = false;
 
     /**
      * Minimum query duration time to be logged
      *
      * @var float
      */
-    protected $_logQueryTime        = 0.05;
+    protected $_logQueryTime = 0.05;
 
     /**
      * Log all queries (ignored minimum query duration time)
      *
      * @var bool
      */
-    protected $_logAllQueries       = false;
+    protected $_logAllQueries = false;
 
     /**
      * Add to log call stack data (backtrace)
      *
      * @var bool
      */
-    protected $_logCallStack        = false;
+    protected $_logCallStack = false;
 
     /**
      * Path to SQL debug data log
      *
      * @var string
      */
-    protected $_debugFile           = '/debug/pdo_mysql.log';
+    protected $_debugFile = '/debug/pdo_mysql.log';
 
     /**
      * Filesystem class
@@ -145,7 +145,7 @@ class Mysql extends Adapter implements AdapterInterface
      *
      * @var float
      */
-    protected $_debugTimer          = 0;
+    protected $_debugTimer = 0;
 
     /**
      * MySQL column - Table DDL type pairs
@@ -177,10 +177,14 @@ class Mysql extends Adapter implements AdapterInterface
     protected $_ddlRoutines = array('alt', 'cre', 'ren', 'dro', 'tru');
 
     /**
-     * @var String
+     * Contructor to create
+     *
+     * @param array|Driver\DriverInterface $driver
+     * @param Platform\PlatformInterface $platform
+     * @param ResultSet\ResultSetInterface $queryResultPrototype
+     * @param Profiler\ProfilerInterface $profiler
+     * @param Filesystem $filesystem
      */
-    protected $string;
-
     public function __construct(
         $driver,
         Platform\PlatformInterface $platform = null,
@@ -305,6 +309,14 @@ class Mysql extends Adapter implements AdapterInterface
         return $result;
     }
 
+    /**
+     * Fetch all queries
+     *
+     * @param \Zend\Db\Sql\Select $sql
+     * @param array $bind
+     * @param null $fetchMode
+     * @return StatementInterface|ResultSet\ResultSetInterface
+     */
     public function fetchAll($sql, $bind = array(), $fetchMode = null)
     {
         if ($sql instanceof \Zend\Db\Sql\Select) {
@@ -358,13 +370,7 @@ class Mysql extends Adapter implements AdapterInterface
     }
 
     /**
-     * query() is a convenience function
-     *
-     * @param string $sql
-     * @param string|array|ParameterContainer $parametersOrQueryMode
-     * @param ResultSet\ResultSetInterface $resultPrototype
-     * @throws InvalidArgumentException
-     * @return StatementInterface|ResultSet\ResultSetInterface
+     * {@inheritdoc}
      */
     public function query(
         $sql,
@@ -1211,7 +1217,7 @@ class Mysql extends Adapter implements AdapterInterface
     }
 
     /**
-     * Create \Magento\Framework\DB\Ddl\Table object by data from describe table
+     * Create \Magento\Setup\Framework\DB\Ddl\Table object by data from describe table
      *
      * @param string $tableName
      * @param string $newTableName
@@ -2255,12 +2261,12 @@ class Mysql extends Adapter implements AdapterInterface
     /**
      * Add time values (intervals) to a date value
      *
-     * @see INTERVAL_* constants for $unit
-     *
-     * @param \Zend_Db_Expr|string $date   quoted field name or SQL statement
+     * @param \Zend_Db_Expr|string $date quoted field name or SQL statement
      * @param int $interval
      * @param string $unit
      * @return \Zend_Db_Expr
+     *
+     * @see INTERVAL_* constants for $unit
      */
     public function getDateAddSql($date, $interval, $unit)
     {
@@ -2271,12 +2277,11 @@ class Mysql extends Adapter implements AdapterInterface
     /**
      * Subtract time values (intervals) to a date value
      *
-     * @see INTERVAL_* constants for $expr
-     *
-     * @param \Zend_Db_Expr|string $date   quoted field name or SQL statement
+     * @param \Zend_Db_Expr|string $date quoted field name or SQL statement
      * @param int|string $interval
      * @param string $unit
      * @return \Zend_Db_Expr
+     * @see INTERVAL_* constants for $expr
      */
     public function getDateSubSql($date, $interval, $unit)
     {
@@ -2483,7 +2488,7 @@ class Mysql extends Adapter implements AdapterInterface
      * Prepare insert data
      *
      * @param mixed $row
-     * @param array $bind
+     * @param array &$bind
      * @return string
      */
     protected function _prepareInsertData($row, &$bind)
@@ -2629,11 +2634,11 @@ class Mysql extends Adapter implements AdapterInterface
     /**
      * Create trigger
      *
-     * @param \Magento\Framework\DB\Ddl\Trigger $trigger
+     * @param \Magento\Setup\Framework\DB\Ddl\Trigger $trigger
      * @throws ErrorException
      * @return StatementInterface
      */
-    public function createTrigger(\Magento\Framework\DB\Ddl\Trigger $trigger)
+    public function createTrigger(\Magento\Setup\Framework\DB\Ddl\Trigger $trigger)
     {
         if (!$trigger->getStatements()) {
             throw new ErrorException(sprintf(__('Trigger %s has not statements available'), $trigger->getName()));
@@ -2690,6 +2695,9 @@ class Mysql extends Adapter implements AdapterInterface
     /**
      * Quotes an identifier.
      *
+     * @param array|string|\Zend_Db_Expr $ident
+     * @param bool $auto
+     * @return string
      */
     public function quoteIdentifier($ident, $auto = false)
     {
diff --git a/setup/module/Magento/Framework/src/DB/Ddl/Table.php b/setup/module/Magento/Setup/src/Framework/DB/Ddl/Table.php
similarity index 99%
rename from setup/module/Magento/Framework/src/DB/Ddl/Table.php
rename to setup/module/Magento/Setup/src/Framework/DB/Ddl/Table.php
index f45c9b09e8a..983f0b413b7 100644
--- a/setup/module/Magento/Framework/src/DB/Ddl/Table.php
+++ b/setup/module/Magento/Setup/src/Framework/DB/Ddl/Table.php
@@ -28,9 +28,9 @@
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Framework\DB\Ddl;
+namespace Magento\Setup\Framework\DB\Ddl;
 
-use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Setup\Framework\DB\Adapter\AdapterInterface;
 use Zend\Db\Exception\ErrorException;
 
 class Table
diff --git a/setup/module/Magento/Framework/src/DB/Ddl/Trigger.php b/setup/module/Magento/Setup/src/Framework/DB/Ddl/Trigger.php
similarity index 99%
rename from setup/module/Magento/Framework/src/DB/Ddl/Trigger.php
rename to setup/module/Magento/Setup/src/Framework/DB/Ddl/Trigger.php
index 828345793e3..3efc769d553 100644
--- a/setup/module/Magento/Framework/src/DB/Ddl/Trigger.php
+++ b/setup/module/Magento/Setup/src/Framework/DB/Ddl/Trigger.php
@@ -21,7 +21,7 @@
  * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Framework\DB\Ddl;
+namespace Magento\Setup\Framework\DB\Ddl;
 
 use Zend\Db\Exception\ErrorException;
 
diff --git a/setup/module/Magento/Setup/src/Model/AdminAccount.php b/setup/module/Magento/Setup/src/Model/AdminAccount.php
index 6d3b1f60c63..d67c3b38138 100644
--- a/setup/module/Magento/Setup/src/Model/AdminAccount.php
+++ b/setup/module/Magento/Setup/src/Model/AdminAccount.php
@@ -25,38 +25,53 @@
 namespace Magento\Setup\Model;
 
 use Magento\Framework\Math\Random;
-use Magento\Module\Setup;
+use Magento\Setup\Module\Setup;
 
 class AdminAccount
 {
+    /**#@+
+     * Data keys
+     */
+    const KEY_USERNAME = 'admin_username';
+    const KEY_PASSWORD = 'admin_password';
+    const KEY_EMAIL = 'admin_email';
+    const KEY_FIRST_NAME = 'admin_firstname';
+    const KEY_LAST_NAME = 'admin_lastname';
+    /**#@- */
+
     /**
-     * @var Seyup
+     * Setup
+     *
+     * @var Setup
      */
-    protected $setup;
+    private $setup;
 
     /**
+     * Configurations
+     *
      * @var []
      */
-    protected $config;
+    private $data;
 
     /**
+     * Random Generator
+     *
      * @var \Magento\Framework\Math\Random
      */
-    protected $random;
+    private $random;
 
     /**
+     * Default Constructor
+     *
      * @param Setup $setup
      * @param Random $random
-     * @param array $config
+     * @param array $data
      */
-    public function __construct(
-        Setup $setup,
-        Random $random,
-        array $config = array()
-    ) {
+    public function __construct(Setup $setup, Random $random, array $data)
+    {
         $this->setup  = $setup;
-        $this->config = $config;
         $this->random = $random;
+        $this->data = $data;
     }
 
     /**
@@ -67,7 +82,7 @@ class AdminAccount
     protected function generatePassword()
     {
         $salt = $this->random->getRandomString(32);
-        return md5($salt . $this->config['admin_password']) . ':' . $salt;
+        return md5($salt . $this->data[self::KEY_PASSWORD]) . ':' . $salt;
     }
 
     /**
@@ -78,11 +93,11 @@ class AdminAccount
     public function save()
     {
         $adminData = [
-            'firstname' => $this->config['admin_username'],
-            'lastname' => $this->config['admin_username'],
-            'username' => $this->config['admin_username'],
+            'firstname' => $this->data[self::KEY_FIRST_NAME],
+            'lastname' => $this->data[self::KEY_LAST_NAME],
+            'username' => $this->data[self::KEY_USERNAME],
             'password' => $this->generatePassword(),
-            'email' => $this->config['admin_email'],
+            'email' => $this->data[self::KEY_EMAIL],
             'created' => date('Y-m-d H:i:s'),
             'modified' => date('Y-m-d H:i:s'),
             'extra' => serialize(null),
@@ -112,12 +127,12 @@ class AdminAccount
                 'role_type' => 'U',
                 'user_id' => $adminId,
                 'user_type' => 2,
-                'role_name' => $this->config['admin_username'],
+                'role_name' => $this->data[self::KEY_USERNAME],
             ]
         ];
 
         foreach ($roles as $role) {
-            $this->setup->getConnection()->insert($this->setup->getTable('admin_role'), $role, true);
+            $this->setup->getConnection()->insert($this->setup->getTable('authorization_role'), $role, true);
         }
     }
 }
diff --git a/setup/module/Magento/Setup/src/Model/AdminAccountFactory.php b/setup/module/Magento/Setup/src/Model/AdminAccountFactory.php
index 48b6103c43e..7f3d10fa8e9 100644
--- a/setup/module/Magento/Setup/src/Model/AdminAccountFactory.php
+++ b/setup/module/Magento/Setup/src/Model/AdminAccountFactory.php
@@ -24,54 +24,35 @@
 
 namespace Magento\Setup\Model;
 
-use Magento\Framework\Math\Random;
-use Magento\Module\Setup\Connection\AdapterInterface;
-use Magento\Module\Setup;
+use Zend\ServiceManager\ServiceLocatorInterface;
+use Magento\Setup\Module\Setup;
 
 class AdminAccountFactory
 {
     /**
-     * @var AdapterInterface
+     * @var ServiceLocatorInterface
      */
-    protected $adapter;
+    protected $serviceLocator;
 
     /**
-     * @var array
+     * @param ServiceLocatorInterface $serviceLocator
      */
-    protected $configuration = [];
-
-    /**
-     * @var Random
-     */
-    protected $random;
-
-    /**
-     * @param Random $random
-     */
-    public function __construct(
-        Random $random
-    ) {
-        $this->random = $random;
-    }
-
-    /**
-     * @param array $config
-     */
-    public function setConfig(array $config)
+    public function __construct(ServiceLocatorInterface $serviceLocator)
     {
-        $this->configuration = $config;
+        $this->serviceLocator = $serviceLocator;
     }
 
     /**
      * @param Setup $setup
+     * @param array $data
      * @return AdminAccount
      */
-    public function create(Setup $setup)
+    public function create(Setup $setup, $data)
     {
         return new AdminAccount(
             $setup,
-            $this->random,
-            $this->configuration
+            $this->serviceLocator->get('Magento\Framework\Math\Random'),
+            $data
         );
     }
 }
diff --git a/setup/module/Magento/Setup/src/Model/ConsoleLogger.php b/setup/module/Magento/Setup/src/Model/ConsoleLogger.php
new file mode 100644
index 00000000000..9d034a559ff
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Model/ConsoleLogger.php
@@ -0,0 +1,83 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Model;
+
+use Zend\Console\Console;
+/**
+ * Console Logger
+ *
+ * @package Magento\Setup\Model
+ */
+class ConsoleLogger implements LoggerInterface
+{
+
+    /**
+     * Console
+     *
+     * @var \Zend\Console\Adapter\AdapterInterface
+     */
+    protected $console;
+
+    /**
+     * Default Constructor
+     */
+    public function __construct()
+    {
+        $this->console = Console::getInstance();
+    }
+
+    /**
+     * Logs success message
+     *
+     * @param string $message
+     * @return void
+     */
+    public function logSuccess($message)
+    {
+        $this->console->writeLine("[SUCCESS]" . ($message ? ": $message" : ''), 11);
+    }
+
+    /**
+     * Logs error message
+     *
+     * @param \Exception $e
+     * @return void
+     */
+    public function logError(\Exception $e)
+    {
+        $this->console->writeLine("[ERROR]: " . $e, 10);
+    }
+
+    /**
+     * Logs message to log writer
+     *
+     * @param string $message
+     * @return void
+     */
+    public function log($message)
+    {
+        $this->console->writeLine($message, 13);
+    }
+}
diff --git a/setup/module/Magento/Setup/src/Model/DatabaseCheck.php b/setup/module/Magento/Setup/src/Model/DatabaseCheck.php
index 3a55c233c37..f3b7b8fe618 100644
--- a/setup/module/Magento/Setup/src/Model/DatabaseCheck.php
+++ b/setup/module/Magento/Setup/src/Model/DatabaseCheck.php
@@ -24,7 +24,7 @@
 
 namespace Magento\Setup\Model;
 
-use Magento\Framework\DB\Adapter\Pdo\Mysql;
+use Magento\Setup\Framework\DB\Adapter\Pdo\Mysql;
 
 class DatabaseCheck
 {
diff --git a/setup/module/Magento/Setup/src/Model/FilePermissions.php b/setup/module/Magento/Setup/src/Model/FilePermissions.php
index c0b95d3c9ff..ed28f139ba2 100644
--- a/setup/module/Magento/Setup/src/Model/FilePermissions.php
+++ b/setup/module/Magento/Setup/src/Model/FilePermissions.php
@@ -131,4 +131,16 @@ class FilePermissions
         }
         return true;
     }
+
+    /**
+     * Checks if has file permission or not
+     *
+     * @return array
+     */
+    public function checkPermission()
+    {
+        $required = $this->getRequired();
+        $current = $this->getCurrent();
+        return array_diff($required, $current);
+    }
 }
diff --git a/setup/module/Magento/Setup/src/Model/Installer.php b/setup/module/Magento/Setup/src/Model/Installer.php
new file mode 100644
index 00000000000..a6521aac6df
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Model/Installer.php
@@ -0,0 +1,321 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Model;
+
+use Zend\Stdlib\Parameters;
+use Magento\Setup\Module\Setup\ConfigFactory as DeploymentConfigFactory;
+use Magento\Config\ConfigFactory as SystemConfigFactory;
+use Magento\Setup\Module\Setup\Config;
+use Magento\Setup\Module\SetupFactory;
+use Magento\Setup\Module\ModuleListInterface;
+use Magento\Framework\Math\Random;
+
+class Installer
+{
+    /**
+     * File permissions checker
+     *
+     * @var FilePermissions
+     */
+    private $filePermissions;
+
+    /**
+     * Deployment configuration factory
+     *
+     * @var DeploymentConfigFactory
+     */
+    private $deploymentConfigFactory;
+
+    /**
+     * Resource setup factory
+     *
+     * @var SetupFactory;
+     */
+    private $setupFactory;
+
+    /**
+     * Module Lists
+     *
+     * @var ModuleListInterface
+     */
+    private $moduleList;
+
+    /**
+     * System configuration factory
+     *
+     * @var SystemConfigFactory
+     */
+    private $systemConfigFactory;
+
+    /**
+     * Admin account factory
+     *
+     * @var AdminAccountFactory
+     */
+    private $adminAccountFactory;
+
+    /**
+     * Logger
+     *
+     * @var LoggerInterface
+     */
+    private $log;
+
+    /**
+     * Random Generator
+     *
+     * @var Random
+     */
+    protected $random;
+
+    /**
+     * @param FilePermissions $filePermissions
+     * @param DeploymentConfigFactory $deploymentConfigFactory
+     * @param SetupFactory $setupFactory
+     * @param ModuleListInterface $moduleList
+     * @param SystemConfigFactory $systemConfigFactory
+     * @param AdminAccountFactory $adminAccountFactory
+     * @param LoggerInterface $log
+     * @param Random $random
+     */
+    public function __construct(
+        FilePermissions $filePermissions,
+        DeploymentConfigFactory $deploymentConfigFactory,
+        SetupFactory $setupFactory,
+        ModuleListInterface $moduleList,
+        SystemConfigFactory $systemConfigFactory,
+        AdminAccountFactory $adminAccountFactory,
+        LoggerInterface $log,
+        Random $random
+    ) {
+        $this->filePermissions = $filePermissions;
+        $this->deploymentConfigFactory = $deploymentConfigFactory;
+        $this->setupFactory = $setupFactory;
+        $this->moduleList = $moduleList;
+        $this->systemConfigFactory = $systemConfigFactory;
+        $this->adminAccountFactory = $adminAccountFactory;
+        $this->log = $log;
+        $this->random = $random;
+    }
+
+    /**
+     * Install Magento application
+     *
+     * @param \ArrayObject|array $request
+     * @return Config
+     */
+    public function install($request)
+    {
+        $this->log->log('Starting Magento installation:');
+
+        $this->log->log('File permissions check...');
+        $this->checkFilePermissions();
+
+        $this->log->log('Installing deployment configuration...');
+        $deploymentConfig = $this->installDeploymentConfig($request);
+
+        $this->log->log('Installing database schema:');
+        $this->installSchema();
+
+        $this->log->log('Installing user configuration...');
+        $this->installUserConfig($request);
+
+        $this->log->log('Installing data fixtures:');
+        $this->installDataFixtures();
+
+        $this->log->log('Installing admin user...');
+        $this->installAdminUser($request);
+
+        $this->log->logSuccess('Magento installation complete.');
+
+        return $deploymentConfig;
+    }
+
+    /**
+     * Check permissions of directories that are expected to be writable
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function checkFilePermissions()
+    {
+        $results = $this->filePermissions->checkPermission();
+        if ($results) {
+            $errorMsg = 'Missing writing permissions to the following directories: ';
+            foreach ($results as $result) {
+                $errorMsg .= '\'' . $result . '\' ';
+            }
+            throw new \Exception($errorMsg);
+        }
+    }
+
+    /**
+     * Installs deployment configuration
+     *
+     * @param \ArrayObject|array $data
+     * @return Config
+     */
+    public function installDeploymentConfig($data)
+    {
+        $data[Config::KEY_DATE] = date('r');
+        if (empty($data[config::KEY_ENCRYPTION_KEY])) {
+            $data[config::KEY_ENCRYPTION_KEY] = md5($this->random->getRandomString(10));
+        }
+        $config = $this->deploymentConfigFactory->create((array)$data);
+        $config->saveToFile();
+        return $config;
+    }
+
+    /**
+     * Installs DB schema
+     *
+     * @return void
+     */
+    public function installSchema()
+    {
+        $moduleNames = array_keys($this->moduleList->getModules());
+
+        $this->log->log('Schema creation/updates:');
+        foreach ($moduleNames as $moduleName) {
+            $this->log->log("Module '{$moduleName}':");
+            $setup = $this->setupFactory->createSetupModule($this->log, $moduleName);
+            $setup->applyUpdates();
+        }
+
+        $this->log->log('Schema post-updates:');
+        foreach ($moduleNames as $moduleName) {
+            $this->log->log("Module '{$moduleName}':");
+            $setup = $this->setupFactory->createSetupModule($this->log, $moduleName);
+            $setup->applyRecurringUpdates();
+        }
+    }
+
+    /**
+     * Installs data fixtures
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function installDataFixtures()
+    {
+        $systemConfig = $this->systemConfigFactory->create();
+        $phpPath = self::getPhpExecutablePath();
+        $command = $phpPath . 'php -f ' . $systemConfig->getMagentoBasePath() . '/dev/shell/run_data_fixtures.php 2>&1';
+        $this->log->log($command);
+        exec($command, $output, $exitCode);
+        if ($exitCode !== 0) {
+            $outputMsg = implode(PHP_EOL, $output);
+            throw new \Exception('exec() returned error [' . $exitCode . ']' . PHP_EOL . $outputMsg);
+        }
+    }
+
+    /**
+     * Finds the executable path for PHP
+     *
+     * @return string
+     * @throws \Exception
+     */
+    private static function getPhpExecutablePath()
+    {
+        $result = '';
+        $iniFile = fopen(php_ini_loaded_file(), 'r');
+        while ($line = fgets($iniFile)) {
+            if ((strpos($line, 'extension_dir') !== false) && (strrpos($line, ";") !==0)) {
+                $extPath = explode("=", $line);
+                $pathFull = explode("\"", $extPath[1]);
+                $pathParts = str_replace('\\', '/', $pathFull[1]);
+                foreach (explode('/', $pathParts) as $piece) {
+                    if ((file_exists($result . 'php') && !is_dir($result . 'php'))
+                        || (file_exists($result . 'php.exe') && !is_dir($result . 'php.exe'))) {
+                        break;
+                    } else if ((file_exists($result . 'bin/php') && !is_dir($result . 'bin/php'))
+                        || (file_exists($result . 'bin/php.exe') && !is_dir($result . 'bin/php.exe'))) {
+                        $result .= 'bin' . '/';
+                        break;
+                    } else {
+                        $result .= $piece . '/';
+                    }
+                }
+                break;
+            }
+        }
+        fclose($iniFile);
+        return $result;
+    }
+
+    /**
+     * Installs user configuration
+     *
+     * @param \ArrayObject|array $data
+     * @return void
+     */
+    public function installUserConfig($data)
+    {
+        $setup = $this->setupFactory->createSetup($this->log);
+        $userConfig = new UserConfigurationData($setup);
+        $userConfig->install($data);
+    }
+
+    /**
+     * Creates admin account
+     *
+     * @param \ArrayObject|array $data
+     * @return void
+     */
+    public function installAdminUser($data)
+    {
+        $setup = $this->setupFactory->createSetup($this->log);
+        $adminAccount = $this->adminAccountFactory->create($setup, (array)$data);
+        $adminAccount->save();
+    }
+
+    /**
+     * Checks Database Connection
+     *
+     * @param string $dbName
+     * @param string $dbHost
+     * @param string $dbUser
+     * @param string $dbPass
+     * @return boolean
+     * @throws \Exception
+     */
+    public static function checkDatabaseConnection($dbName, $dbHost, $dbUser, $dbPass = '')
+    {
+        $dbConnectionInfo = array(
+            'driver' => "Pdo",
+            'dsn' => "mysql:dbname=" . $dbName . ";host=" . $dbHost,
+            'username' => $dbUser,
+            'password' => $dbPass,
+            'driver_options' => array(
+                \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
+            ),
+        );
+        $checkDB = new DatabaseCheck($dbConnectionInfo);
+        if (!$checkDB->checkConnection()) {
+            throw new \Exception('Database connection failure.');
+        }
+        return true;
+    }
+}
diff --git a/setup/module/Magento/Setup/src/Model/InstallerFactory.php b/setup/module/Magento/Setup/src/Model/InstallerFactory.php
new file mode 100644
index 00000000000..a92bdef4d24
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Model/InstallerFactory.php
@@ -0,0 +1,61 @@
+<?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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Model;
+
+use Zend\ServiceManager\ServiceLocatorInterface;
+
+class InstallerFactory
+{
+    /**
+     * @var ServiceLocatorInterface
+     */
+    protected $serviceLocator;
+
+    /**
+     * @param ServiceLocatorInterface $serviceLocator
+     */
+    public function __construct(ServiceLocatorInterface $serviceLocator)
+    {
+        $this->serviceLocator = $serviceLocator;
+    }
+
+    /**
+     * @param LoggerInterface $log
+     * @return Installer
+     */
+    public function create(LoggerInterface $log)
+    {
+        return new Installer(
+            $this->serviceLocator->get('Magento\Setup\Model\FilePermissions'),
+            $this->serviceLocator->get('Magento\Setup\Module\Setup\ConfigFactory'),
+            $this->serviceLocator->get('Magento\Setup\Module\SetupFactory'),
+            $this->serviceLocator->get('Magento\Setup\Module\ModuleList'),
+            $this->serviceLocator->get('Magento\Config\ConfigFactory'),
+            $this->serviceLocator->get('Magento\Setup\Model\AdminAccountFactory'),
+            $log,
+            $this->serviceLocator->get('Magento\Framework\Math\Random')
+        );
+    }
+}
diff --git a/setup/module/Magento/Composer/Module.php b/setup/module/Magento/Setup/src/Model/LoggerInterface.php
similarity index 62%
rename from setup/module/Magento/Composer/Module.php
rename to setup/module/Magento/Setup/src/Model/LoggerInterface.php
index de34446a33a..656d96d2c29 100644
--- a/setup/module/Magento/Composer/Module.php
+++ b/setup/module/Magento/Setup/src/Model/LoggerInterface.php
@@ -22,23 +22,37 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Composer;
+namespace Magento\Setup\Model;
 
-use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
-
-class Module implements AutoloaderProviderInterface
+/**
+ * Interface to Log Message in Setup
+ *
+ * @package Magento\Setup\Model
+ */
+interface LoggerInterface
 {
     /**
-     * @return array
+     * Logs success message
+     *
+     * @param string $message
+     * @return void
+     */
+    public function logSuccess($message);
+
+    /**
+     * Logs error message
+     *
+     * @param \Exception $e
+     * @return void
+     */
+    public function logError(\Exception $e);
+
+
+    /**
+     * Logs message to log writer
+     *
+     * @param string $message
+     * @return void
      */
-    public function getAutoloaderConfig()
-    {
-        return [
-            'Zend\Loader\StandardAutoloader' => [
-                'namespaces' => [
-                    __NAMESPACE__ => __DIR__ . '/src/',
-                ],
-            ],
-        ];
-    }
+    public function log($message);
 }
diff --git a/setup/module/Magento/Setup/src/Model/UserConfigurationData.php b/setup/module/Magento/Setup/src/Model/UserConfigurationData.php
new file mode 100644
index 00000000000..1a34b54c4f7
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Model/UserConfigurationData.php
@@ -0,0 +1,133 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Model;
+
+use Magento\Setup\Module\Setup;
+use Magento\Store\Model\Store;
+use Magento\Core\Helper\Data;
+use Magento\Directory\Model\Currency;
+
+/**
+ * Model Class to Install User Configuration Data
+ *
+ * @package Magento\Setup\Model
+ */
+class UserConfigurationData
+{
+    /**#@+
+     * Model data keys
+     */
+    const KEY_USE_SEF_URL = 'use_rewrites';
+    const KEY_BASE_URL = 'base_url';
+    const KEY_BASE_URL_SECURE = 'base_url_secure';
+    const KEY_IS_SECURE = 'use_secure';
+    const KEY_IS_SECURE_ADMIN = 'use_secure_admin';
+    const KEY_LANGUAGE = 'language';
+    const KEY_TIMEZONE = 'timezone';
+    const KEY_CURRENCY = 'currency';
+    /**#@- */
+
+    /**
+     * Map of configuration paths to data keys
+     *
+     * @var array
+     */
+    private static $pathDataMap = [
+        Store::XML_PATH_USE_REWRITES => self::KEY_USE_SEF_URL,
+        Store::XML_PATH_UNSECURE_BASE_URL => self::KEY_BASE_URL,
+        Store::XML_PATH_SECURE_IN_FRONTEND => self::KEY_IS_SECURE,
+        Store::XML_PATH_SECURE_BASE_URL => self::KEY_BASE_URL_SECURE,
+        Store::XML_PATH_SECURE_IN_ADMINHTML => self::KEY_IS_SECURE_ADMIN,
+        Data::XML_PATH_DEFAULT_LOCALE => self::KEY_LANGUAGE,
+        Data::XML_PATH_DEFAULT_TIMEZONE => self::KEY_TIMEZONE,
+        Currency::XML_PATH_CURRENCY_BASE => self::KEY_CURRENCY,
+        Currency::XML_PATH_CURRENCY_DEFAULT => self::KEY_CURRENCY,
+        Currency::XML_PATH_CURRENCY_ALLOW => self::KEY_CURRENCY,
+    ];
+
+    /**
+     * Default data values
+     *
+     * @var array
+     */
+    private static $defaults = [
+        self::KEY_USE_SEF_URL => 0,
+        self::KEY_BASE_URL => '{{unsecure_base_url}}',
+        self::KEY_IS_SECURE => 0,
+        self::KEY_BASE_URL_SECURE => '{{unsecure_base_url}}',
+        self::KEY_IS_SECURE_ADMIN => 0,
+        self::KEY_LANGUAGE => 'en_US',
+        self::KEY_TIMEZONE => 'America/Los_Angeles',
+        self::KEY_CURRENCY => 'USD',
+    ];
+
+    /**
+     * Setup Instance
+     *
+     * @var Setup $setup
+     */
+    protected $setup;
+
+    /**
+     * Default Constructor
+     *
+     * @param Setup $setup
+     */
+    public function __construct(Setup $setup)
+    {
+        $this->setup = $setup;
+    }
+
+    /**
+     * Installs All Configuration Data
+     *
+     * @param array $data
+     * @return void
+     */
+    public function install($data)
+    {
+        foreach (self::$defaults as $key => $value) {
+            if (isset($data[$key])) {
+                $value = $data[$key];
+            }
+            foreach (array_keys(self::$pathDataMap, $key) as $path) {
+                $this->installData($path, $value);
+            }
+        }
+    }
+
+    /**
+     * Installs Configuration Data
+     *
+     * @param string $key
+     * @param mixed $value
+     * @return void
+     * @throws \Exception
+     */
+    public function installData($key, $value)
+    {
+        $this->setup->addConfigData($key, $value);
+    }
+}
diff --git a/setup/module/Magento/Setup/src/Model/Logger.php b/setup/module/Magento/Setup/src/Model/WebLogger.php
similarity index 59%
rename from setup/module/Magento/Setup/src/Model/Logger.php
rename to setup/module/Magento/Setup/src/Model/WebLogger.php
index e47954fba31..20559c5c756 100644
--- a/setup/module/Magento/Setup/src/Model/Logger.php
+++ b/setup/module/Magento/Setup/src/Model/WebLogger.php
@@ -24,19 +24,30 @@
 
 namespace Magento\Setup\Model;
 
-class Logger
+/**
+ * Web UI Logger
+ *
+ * @package Magento\Setup\Model
+ */
+class WebLogger implements LoggerInterface
 {
     /**
+     * Log File
+     *
      * @var string
      */
     protected $logFile = 'install.log';
 
     /**
+     * Currently open file resource
+     *
      * @var resource
      */
     protected $resource;
 
     /**
+     * Whether the log contains an error message
+     *
      * @var bool
      */
     protected $hasError = false;
@@ -46,37 +57,67 @@ class Logger
         $this->logFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $this->logFile;
     }
 
-    public function open()
+    /**
+     * Opens log file in the specified mode
+     *
+     * @param string $mode
+     * @return void
+     */
+    private function open($mode)
     {
-        $this->resource = @fopen($this->logFile, 'a+');
+        $this->resource = @fopen($this->logFile, $mode);
     }
 
-    public function close()
+    /**
+     * Closes the log file
+     *
+     * @return void
+     */
+    private function close()
     {
         fclose($this->resource);
     }
 
     /**
-     * @param string $moduleName
+     * {@inheritdoc}
      */
-    public function logSuccess($moduleName)
+    public function logSuccess($message)
     {
-        $this->open();
-        fwrite($this->resource, '<span class="text-success">[SUCCESS] ' . $moduleName . ' ... installed</span>' . PHP_EOL);
-        $this->close();
+        $this->writeToFile('<span class="text-success">[SUCCESS] ' . $message . '</span>');
     }
 
     /**
-     * @param \Exception $e
+     * {@inheritdoc}
      */
     public function logError(\Exception $e)
     {
-        $this->open();
-        fwrite($this->resource, '<span class="text-danger">[ERROR] ' . $e . '<span>' . PHP_EOL);
+        $this->writeToFile('<span class="text-danger">[ERROR] ' . $e . '<span>');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function log($message)
+    {
+        $this->writeToFile('<span class="text-info">' . $message . '</span>');
+    }
+
+    /**
+     * Write the message to file
+     *
+     * @param string $message
+     * @return void
+     */
+    private function writeToFile($message)
+    {
+        $this->open('a+');
+        fwrite($this->resource, $message . PHP_EOL);
         $this->close();
     }
 
     /**
+     * Whether there is an error in the log
+     *
      * @return bool
      */
     public function hasError()
@@ -85,11 +126,13 @@ class Logger
     }
 
     /**
+     * Gets contents of the log
+     *
      * @return array
      */
     public function get()
     {
-        $this->open();
+        $this->open('r+');
         fseek($this->resource, 0);
         $messages = [];
         while (($string = fgets($this->resource)) !== false) {
@@ -102,9 +145,13 @@ class Logger
         return $messages;
     }
 
+    /**
+     * Clears contents of the log
+     *
+     * @return void
+     */
     public function clear()
     {
         @unlink($this->logFile);
     }
 }
- 
\ No newline at end of file
diff --git a/setup/module/Magento/Module/src/Converter/Dom.php b/setup/module/Magento/Setup/src/Module/Converter/Dom.php
similarity index 99%
rename from setup/module/Magento/Module/src/Converter/Dom.php
rename to setup/module/Magento/Setup/src/Module/Converter/Dom.php
index 4a05701bb47..5be38db2b09 100644
--- a/setup/module/Magento/Module/src/Converter/Dom.php
+++ b/setup/module/Magento/Setup/src/Module/Converter/Dom.php
@@ -24,7 +24,7 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module\Converter;
+namespace Magento\Setup\Module\Converter;
 
 use Magento\Config\Converter\ConverterInterface;
 
diff --git a/setup/module/Magento/Module/src/Dependency/Manager.php b/setup/module/Magento/Setup/src/Module/Dependency/Manager.php
similarity index 99%
rename from setup/module/Magento/Module/src/Dependency/Manager.php
rename to setup/module/Magento/Setup/src/Module/Dependency/Manager.php
index 16c836a56d5..c4bc9b28d6f 100644
--- a/setup/module/Magento/Module/src/Dependency/Manager.php
+++ b/setup/module/Magento/Setup/src/Module/Dependency/Manager.php
@@ -24,7 +24,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module\Dependency;
+namespace Magento\Setup\Module\Dependency;
 
 class Manager implements ManagerInterface
 {
diff --git a/setup/module/Magento/Module/src/Dependency/ManagerInterface.php b/setup/module/Magento/Setup/src/Module/Dependency/ManagerInterface.php
similarity index 97%
rename from setup/module/Magento/Module/src/Dependency/ManagerInterface.php
rename to setup/module/Magento/Setup/src/Module/Dependency/ManagerInterface.php
index 393b1062388..eb68c0723ff 100644
--- a/setup/module/Magento/Module/src/Dependency/ManagerInterface.php
+++ b/setup/module/Magento/Setup/src/Module/Dependency/ManagerInterface.php
@@ -24,7 +24,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module\Dependency;
+namespace Magento\Setup\Module\Dependency;
 
 interface ManagerInterface
 {
diff --git a/setup/module/Magento/Module/src/Dir.php b/setup/module/Magento/Setup/src/Module/Dir.php
similarity index 96%
rename from setup/module/Magento/Module/src/Dir.php
rename to setup/module/Magento/Setup/src/Module/Dir.php
index e310ad25e9f..2857ca73435 100644
--- a/setup/module/Magento/Module/src/Dir.php
+++ b/setup/module/Magento/Setup/src/Module/Dir.php
@@ -23,15 +23,13 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
 use Magento\Filesystem\Directory\ReadInterface;
 use Magento\Filesystem\Filesystem;
 
 class Dir
 {
-    const MODULES_DIR = 'code';
-
     /**
      * Modules root directory
      *
@@ -44,7 +42,7 @@ class Dir
      */
     public function __construct(Filesystem $filesystem)
     {
-        $this->_modulesDirectory = $filesystem->getDirectoryRead(self::MODULES_DIR);
+        $this->_modulesDirectory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MODULES_DIR);
     }
 
     /**
diff --git a/setup/module/Magento/Module/src/FileResolver.php b/setup/module/Magento/Setup/src/Module/FileResolver.php
similarity index 99%
rename from setup/module/Magento/Module/src/FileResolver.php
rename to setup/module/Magento/Setup/src/Module/FileResolver.php
index 3ac2052067b..585682fbe22 100644
--- a/setup/module/Magento/Module/src/FileResolver.php
+++ b/setup/module/Magento/Setup/src/Module/FileResolver.php
@@ -22,7 +22,7 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
 use Magento\Config\Config;
 use Zend\Stdlib\Glob;
diff --git a/setup/module/Magento/Module/src/ModuleList.php b/setup/module/Magento/Setup/src/Module/ModuleList.php
similarity index 95%
rename from setup/module/Magento/Module/src/ModuleList.php
rename to setup/module/Magento/Setup/src/Module/ModuleList.php
index e436707fe0a..6e174b47127 100644
--- a/setup/module/Magento/Module/src/ModuleList.php
+++ b/setup/module/Magento/Setup/src/Module/ModuleList.php
@@ -22,9 +22,9 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
-use Magento\Module\Reader\Filesystem;
+use Magento\Setup\Module\Reader\Filesystem;
 
 class ModuleList implements ModuleListInterface
 {
diff --git a/setup/module/Magento/Module/src/ModuleListInterface.php b/setup/module/Magento/Setup/src/Module/ModuleListInterface.php
similarity index 97%
rename from setup/module/Magento/Module/src/ModuleListInterface.php
rename to setup/module/Magento/Setup/src/Module/ModuleListInterface.php
index eb15a1ad646..e660996ca43 100644
--- a/setup/module/Magento/Module/src/ModuleListInterface.php
+++ b/setup/module/Magento/Setup/src/Module/ModuleListInterface.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
 interface ModuleListInterface
 {
diff --git a/setup/module/Magento/Module/src/Reader/Filesystem.php b/setup/module/Magento/Setup/src/Module/Reader/Filesystem.php
similarity index 93%
rename from setup/module/Magento/Module/src/Reader/Filesystem.php
rename to setup/module/Magento/Setup/src/Module/Reader/Filesystem.php
index 8cf18d1e709..5814b77ea1a 100644
--- a/setup/module/Magento/Module/src/Reader/Filesystem.php
+++ b/setup/module/Magento/Setup/src/Module/Reader/Filesystem.php
@@ -24,18 +24,18 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module\Reader;
+namespace Magento\Setup\Module\Reader;
 
 use Magento\Config\Reader\Filesystem as ConfigFilesystem;
-use Magento\Module\FileResolver;
-use Magento\Module\Converter\Dom;
-use Magento\Module\SchemaLocator;
-use Magento\Module\Dependency\ManagerInterface;
+use Magento\Setup\Module\FileResolver;
+use Magento\Setup\Module\Converter\Dom;
+use Magento\Setup\Module\SchemaLocator;
+use Magento\Setup\Module\Dependency\ManagerInterface;
 
 class Filesystem extends ConfigFilesystem
 {
     /**
-     * @var \Magento\Module\Dependency\ManagerInterface
+     * @var \Magento\Setup\Module\Dependency\ManagerInterface
      */
     protected $dependencyManager;
 
@@ -64,7 +64,7 @@ class Filesystem extends ConfigFilesystem
         SchemaLocator $schemaLocator,
         ManagerInterface $dependencyManager,
         $fileName = 'module.xml',
-        $domDocumentClass = 'Magento\Config\Dom',
+        $domDocumentClass = 'Magento\Framework\Config\Dom',
         $idAttributes = array()
     ) {
         parent::__construct(
diff --git a/setup/module/Magento/Module/src/Resource/Resource.php b/setup/module/Magento/Setup/src/Module/Resource/Resource.php
similarity index 91%
rename from setup/module/Magento/Module/src/Resource/Resource.php
rename to setup/module/Magento/Setup/src/Module/Resource/Resource.php
index 83f7ca1dd44..46167fb297f 100644
--- a/setup/module/Magento/Module/src/Resource/Resource.php
+++ b/setup/module/Magento/Setup/src/Module/Resource/Resource.php
@@ -21,12 +21,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module\Resource;
+namespace Magento\Setup\Module\Resource;
 
 use Zend\Db\Sql\Sql;
 use Zend\Db\ResultSet;
-use Magento\Framework\DB\Adapter\AdapterInterface;
-use Magento\Module\ResourceInterface;
+use Magento\Setup\Framework\DB\Adapter\AdapterInterface;
+use Magento\Setup\Module\ResourceInterface;
 
 /**
  * Resource Resource Model
@@ -67,6 +67,11 @@ class Resource implements ResourceInterface
         $this->tablePrefix = $tablePrefix;
     }
 
+    /**
+     * Load schema/db version
+     *
+     * @return $this
+     */
     protected function loadVersionDb()
     {
         self::$versions = array();
@@ -119,6 +124,11 @@ class Resource implements ResourceInterface
         }
     }
 
+    /**
+     * Get name of the resources table.
+     *
+     * @return string
+     */
     protected function getMainTable()
     {
         return $this->adapter->getTableName($this->tablePrefix . self::MAIN_TABLE);
diff --git a/setup/module/Magento/Module/src/ResourceInterface.php b/setup/module/Magento/Setup/src/Module/ResourceInterface.php
similarity index 97%
rename from setup/module/Magento/Module/src/ResourceInterface.php
rename to setup/module/Magento/Setup/src/Module/ResourceInterface.php
index 78dfdbb9d36..89e1839b8d7 100644
--- a/setup/module/Magento/Module/src/ResourceInterface.php
+++ b/setup/module/Magento/Setup/src/Module/ResourceInterface.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
 /**
  * Resource Model Interface
diff --git a/setup/module/Magento/Module/src/SchemaLocator.php b/setup/module/Magento/Setup/src/Module/SchemaLocator.php
similarity index 98%
rename from setup/module/Magento/Module/src/SchemaLocator.php
rename to setup/module/Magento/Setup/src/Module/SchemaLocator.php
index b1ebfeb7376..d431a653a75 100644
--- a/setup/module/Magento/Module/src/SchemaLocator.php
+++ b/setup/module/Magento/Setup/src/Module/SchemaLocator.php
@@ -24,7 +24,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
 use Magento\Config\SchemaLocatorInterface;
 use Magento\Config\ConfigFactory;
diff --git a/setup/module/Magento/Module/src/Setup.php b/setup/module/Magento/Setup/src/Module/Setup.php
similarity index 50%
rename from setup/module/Magento/Module/src/Setup.php
rename to setup/module/Magento/Setup/src/Module/Setup.php
index f600dd7ffbf..a2492be4c40 100644
--- a/setup/module/Magento/Module/src/Setup.php
+++ b/setup/module/Magento/Setup/src/Module/Setup.php
@@ -21,29 +21,15 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
-use Magento\Module\Setup\Connection\AdapterInterface;
-use Magento\Module\Setup\FileResolver as SetupFileResolver;
-use Magento\Module\Resource\Resource;
-use Magento\Module\Updater\SetupInterface;
-use Magento\Setup\Model\Logger;
+use Magento\Setup\Module\Setup\Connection\AdapterInterface;
+use Magento\Setup\Module\Setup\FileResolver as SetupFileResolver;
+use Magento\Setup\Module\Updater\SetupInterface;
+use Magento\Setup\Model\LoggerInterface;
 
 class Setup implements SetupInterface
 {
-    /**
-     * Setup resource name
-     * @var string
-     */
-    protected $resourceName;
-
-    /**
-     * Setup module configuration object
-     *
-     * @var array
-     */
-    protected $moduleConfig;
-
     /**
      * Call afterApplyAllUpdates method flag
      *
@@ -54,7 +40,7 @@ class Setup implements SetupInterface
     /**
      * Setup Connection
      *
-     * @var \Magento\Framework\DB\Adapter\AdapterInterface
+     * @var \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     protected $connection = null;
 
@@ -72,11 +58,6 @@ class Setup implements SetupInterface
      */
     protected $setupCache = array();
 
-    /**
-     * @var ResourceInterface
-     */
-    protected $resource;
-
     /**
      * Filesystem instance
      *
@@ -85,48 +66,49 @@ class Setup implements SetupInterface
     protected $filesystem;
 
     /**
+     * Setup File Resolver
+     *
      * @var SetupFileResolver
      */
     protected $setupFileResolver;
 
     /**
-     * @var Logger
+     * Logger
+     *
+     * @var LoggerInterface
      */
     protected $logger;
 
     /**
+     * Table Prefix
+     *
      * @var string
      */
     protected $tablePrefix;
 
     /**
+     * Constructor
+     *
      * @param AdapterInterface $connection
-     * @param ModuleListInterface $moduleList
      * @param SetupFileResolver $setupFileResolver
-     * @param Logger $logger
-     * @param $moduleName
+     * @param LoggerInterface $logger
      * @param array $connectionConfig
      */
     public function __construct(
         AdapterInterface $connection,
-        ModuleListInterface $moduleList,
         SetupFileResolver $setupFileResolver,
-        Logger $logger,
-        $moduleName,
+        LoggerInterface $logger,
         array $connectionConfig = array()
     ) {
         $this->logger = $logger;
         $this->connection = $connection->getConnection($connectionConfig);
-        $this->moduleConfig = $moduleList->getModule($moduleName);
-        $this->resource = new Resource($this->connection);
         $this->setupFileResolver = $setupFileResolver;
-        $this->resourceName = $setupFileResolver->getResourceCode($moduleName);
     }
 
     /**
      * Get connection object
      *
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface
      */
     public function getConnection()
     {
@@ -146,18 +128,6 @@ class Setup implements SetupInterface
         return $this;
     }
 
-    /**
-     * Set table prefix
-     *
-     * @param string $tablePrefix
-     * @return void
-     */
-    public function setTablePrefix($tablePrefix)
-    {
-        $this->tablePrefix = $tablePrefix;
-        $this->resource->setTablePrefix($this->tablePrefix);
-    }
-
     /**
      * Get table name (validated by db adapter) by table placeholder
      *
@@ -192,220 +162,6 @@ class Setup implements SetupInterface
         return $tableName;
     }
 
-    /**
-     * Apply data updates to the system after upgrading.
-     *
-     * @return $this
-     */
-    public function applyDataUpdates()
-    {
-        return $this;
-    }
-
-    /**
-     * Apply module resource install, upgrade and data scripts
-     *
-     * @return $this|true
-     */
-    public function applyUpdates()
-    {
-        if (!$this->resourceName) {
-            return $this;
-        }
-        $dbVer = $this->resource->getDbVersion($this->resourceName);
-        $configVer = $this->moduleConfig['schema_version'];
-
-        // Module is installed
-        if ($dbVer !== false) {
-            $status = version_compare($configVer, $dbVer);
-            switch ($status) {
-                case self::VERSION_COMPARE_LOWER:
-                    $this->_rollbackResourceDb($configVer, $dbVer);
-                    break;
-                case self::VERSION_COMPARE_GREATER:
-                    $this->_upgradeResourceDb($dbVer, $configVer);
-                    break;
-                default:
-                    return true;
-                    break;
-            }
-        } elseif ($configVer) {
-            $this->_installResourceDb($configVer);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Run resource installation file
-     *
-     * @param string $newVersion
-     * @return $this
-     */
-    protected function _installResourceDb($newVersion)
-    {
-        $oldVersion = $this->_modifyResourceDb(self::TYPE_DB_INSTALL, '', $newVersion);
-        $this->_modifyResourceDb(self::TYPE_DB_UPGRADE, $oldVersion, $newVersion);
-        $this->resource->setDbVersion($this->resourceName, $newVersion);
-
-        return $this;
-    }
-
-    /**
-     * Run resource upgrade files from $oldVersion to $newVersion
-     *
-     * @param string $oldVersion
-     * @param string $newVersion
-     * @return $this
-     */
-    protected function _upgradeResourceDb($oldVersion, $newVersion)
-    {
-        $this->_modifyResourceDb(self::TYPE_DB_UPGRADE, $oldVersion, $newVersion);
-        $this->resource->setDbVersion($this->resourceName, $newVersion);
-
-        return $this;
-    }
-
-    /**
-     * Roll back resource
-     *
-     * @param string $newVersion
-     * @param string $oldVersion
-     * @return $this
-     */
-    protected function _rollbackResourceDb($newVersion, $oldVersion)
-    {
-        $this->_modifyResourceDb(self::TYPE_DB_ROLLBACK, $newVersion, $oldVersion);
-        return $this;
-    }
-
-    /**
-     * Uninstall resource
-     *
-     * @param string $version existing resource version
-     * @return $this
-     */
-    protected function _uninstallResourceDb($version)
-    {
-        $this->_modifyResourceDb(self::TYPE_DB_UNINSTALL, $version, '');
-        return $this;
-    }
-
-    /**
-     * Retrieve available Database install/upgrade files for current module
-     *
-     * @param string $actionType
-     * @param string $fromVersion
-     * @param string $toVersion
-     * @return array
-     */
-    protected function _getAvailableDbFiles($actionType, $fromVersion, $toVersion)
-    {
-        $modName = (string)$this->moduleConfig['name'];
-
-        $dbFiles = array();
-        $typeFiles = array();
-        $regExpDb = sprintf('#%s-(.*)\.(php|sql)$#i', $actionType);
-        $regExpType = sprintf('#%s-%s-(.*)\.(php|sql)$#i', 'mysql4', $actionType);
-        foreach ($this->setupFileResolver->get($modName) as $file) {
-            $matches = array();
-            if (preg_match($regExpDb, $file, $matches)) {
-                $dbFiles[$matches[1]] = $this->setupFileResolver->getAbsolutePath($file);
-            } elseif (preg_match($regExpType, $file, $matches)) {
-                $typeFiles[$matches[1]] = $this->setupFileResolver->getAbsolutePath($file);
-            }
-        }
-
-        if (empty($typeFiles) && empty($dbFiles)) {
-            return array();
-        }
-
-        foreach ($typeFiles as $version => $file) {
-            $dbFiles[$version] = $file;
-        }
-
-        return $this->_getModifySqlFiles($actionType, $fromVersion, $toVersion, $dbFiles);
-    }
-
-    /**
-     * Save resource version
-     *
-     * @param string $actionType
-     * @param string $version
-     * @return $this
-     */
-    protected function _setResourceVersion($actionType, $version)
-    {
-        switch ($actionType) {
-            case self::TYPE_DB_INSTALL:
-            case self::TYPE_DB_UPGRADE:
-                $this->resource->setDbVersion($this->resourceName, $version);
-                break;
-            case self::TYPE_DATA_INSTALL:
-            case self::TYPE_DATA_UPGRADE:
-            default:
-                break;
-        }
-
-        return $this;
-    }
-
-    /**
-     * Run module modification files. Return version of last applied upgrade (false if no upgrades applied)
-     * @param string $actionType
-     * @param string $fromVersion
-     * @param string $toVersion
-     * @return false|string
-     * @throws \Exception
-     */
-    protected function _modifyResourceDb($actionType, $fromVersion, $toVersion)
-    {
-        switch ($actionType) {
-            case self::TYPE_DB_INSTALL:
-            case self::TYPE_DB_UPGRADE:
-                $files = $this->_getAvailableDbFiles($actionType, $fromVersion, $toVersion);
-                break;
-            case self::TYPE_DATA_INSTALL:
-            case self::TYPE_DATA_UPGRADE:
-                break;
-            default:
-                $files = array();
-                break;
-        }
-        if (empty($files) || !$this->getConnection()) {
-            return false;
-        }
-
-        $version = false;
-
-        foreach ($files as $file) {
-            $fileName = $file['fileName'];
-            $fileType = pathinfo($fileName, PATHINFO_EXTENSION);
-            try {
-                switch ($fileType) {
-                    case 'php':
-                        $result = $this->_includeFile($fileName);
-                        break;
-                    default:
-                        $result = false;
-                        break;
-                }
-
-                if ($result) {
-                    $this->_setResourceVersion($actionType, $file['toVersion']);
-                    //@todo log
-                } else {
-                    //@todo log "Failed resource setup: {$fileName}";
-                }
-            } catch (\Exception $e) {
-                $this->logger->logError($e);
-                throw new \Exception(sprintf('Error in file: "%s" - %s', $fileName, $e->getMessage()), 0, $e);
-            }
-            $version = $file['toVersion'];
-        }
-        return $version;
-    }
-
     /**
      * Include file by path
      * This method should perform only file inclusion.
@@ -415,68 +171,20 @@ class Setup implements SetupInterface
      * @param string $fileName
      * @return mixed
      */
-    protected function _includeFile($fileName)
+    protected function includeFile($fileName)
     {
+        $this->logger->log("Include {$fileName}");
         return include $fileName;
     }
 
     /**
-     * Get data files for modifications
+     * Apply data updates to the system after upgrading.
      *
-     * @param string $actionType
-     * @param string $fromVersion
-     * @param string $toVersion
-     * @param array $arrFiles
-     * @return array
+     * @return $this
      */
-    protected function _getModifySqlFiles($actionType, $fromVersion, $toVersion, $arrFiles)
+    public function applyDataUpdates()
     {
-        $arrRes = [];
-        switch ($actionType) {
-            case self::TYPE_DB_INSTALL:
-            case self::TYPE_DATA_INSTALL:
-                uksort($arrFiles, 'version_compare');
-                foreach ($arrFiles as $version => $file) {
-                    if (version_compare($version, $toVersion) !== self::VERSION_COMPARE_GREATER) {
-                        $arrRes[0] = [
-                            'toVersion' => $version,
-                            'fileName'  => $file
-                        ];
-                    }
-                }
-                break;
-
-            case self::TYPE_DB_UPGRADE:
-            case self::TYPE_DATA_UPGRADE:
-                uksort($arrFiles, 'version_compare');
-                foreach ($arrFiles as $version => $file) {
-                    $versionInfo = explode('-', $version);
-
-                    // In array must be 2 elements: 0 => version from, 1 => version to
-                    if (count($versionInfo) !== 2) {
-                        break;
-                    }
-                    $infoFrom = $versionInfo[0];
-                    $infoTo   = $versionInfo[1];
-                    if (version_compare($infoFrom, $fromVersion, '>=')
-                        && version_compare($infoTo, $fromVersion, '>')
-                        && version_compare($infoTo, $toVersion, '<=')
-                        && version_compare($infoFrom, $toVersion, '<')
-                    ) {
-                        $arrRes[] = [
-                            'toVersion' => $infoTo,
-                            'fileName'  => $file
-                        ];
-                    }
-                }
-                break;
-
-            case self::TYPE_DB_ROLLBACK:
-            case self::TYPE_DB_UNINSTALL:
-            default:
-                break;
-        }
-        return $arrRes;
+        return $this;
     }
 
     /******************* UTILITY METHODS *****************/
@@ -510,7 +218,7 @@ class Setup implements SetupInterface
             return $this->setupCache[$table][$parentId][$rowId];
         }
         return isset(
-            $this->setupCache[$table][$parentId][$rowId][$field]
+        $this->setupCache[$table][$parentId][$rowId][$field]
         ) ? $this->setupCache[$table][$parentId][$rowId][$field] : false;
     }
 
@@ -654,7 +362,7 @@ class Setup implements SetupInterface
 
     /**
      * Run each time after applying of all updates,
-     * if setup model setted $_callAfterApplyAllUpdates flag to true
+     * if setup model's $_callAfterApplyAllUpdates flag is set to true
      *
      * @return $this
      */
@@ -663,6 +371,13 @@ class Setup implements SetupInterface
         return $this;
     }
 
+    /**
+     * Add configuration data to core_config_data table
+     *
+     * @param string $key
+     * @param string $value
+     * @return void
+     */
     public function addConfigData($key, $value)
     {
         $this->getConnection()->insert(
@@ -674,4 +389,15 @@ class Setup implements SetupInterface
             true
         );
     }
+
+    /**
+     * Set table prefix
+     *
+     * @param string $tablePrefix
+     * @return void
+     */
+    public function setTablePrefix($tablePrefix)
+    {
+        $this->tablePrefix = $tablePrefix;
+    }
 }
diff --git a/setup/module/Magento/Setup/src/Module/Setup/Config.php b/setup/module/Magento/Setup/src/Module/Setup/Config.php
new file mode 100644
index 00000000000..e754d3af8bc
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Module/Setup/Config.php
@@ -0,0 +1,251 @@
+<?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.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Module\Setup;
+
+use Magento\Filesystem\Directory\Write;
+use Magento\Filesystem\Filesystem;
+
+/**
+ * Deployment configuration model
+ */
+class Config
+{
+    /**#@+
+     * Possible variables of the deployment configuration
+     */
+    const KEY_DATE    = 'date';
+    const KEY_DB_HOST = 'db_host';
+    const KEY_DB_NAME = 'db_name';
+    const KEY_DB_USER = 'db_user';
+    const KEY_DB_PASS = 'db_pass';
+    const KEY_DB_PREFIX = 'db_prefix';
+    const KEY_DB_MODEL = 'db_model';
+    const KEY_DB_INIT_STATEMENTS = 'db_init_statements';
+    const KEY_SESSION_SAVE = 'session_save';
+    const KEY_BACKEND_FRONTNAME = 'backend_frontname';
+    const KEY_ENCRYPTION_KEY = 'key';
+    /**#@- */
+
+    /**#@+
+     * Paths to deployment config file and template
+     */
+    const DEPLOYMENT_CONFIG_FILE = 'local.xml';
+    const DEPLOYMENT_CONFIG_FILE_TEMPLATE = 'local.xml.template';
+    /**#@- */
+
+    /**
+     * The data values + default values
+     *
+     * @var string[]
+     */
+    private $data = [
+        self::KEY_DATE => '',
+        self::KEY_DB_HOST => '',
+        self::KEY_DB_NAME => '',
+        self::KEY_DB_USER => '',
+        self::KEY_DB_PASS => '',
+        self::KEY_DB_PREFIX => '',
+        self::KEY_DB_MODEL => 'mysql4',
+        self::KEY_DB_INIT_STATEMENTS => 'SET NAMES utf8;',
+        self::KEY_SESSION_SAVE => 'files',
+        self::KEY_BACKEND_FRONTNAME => 'backend',
+        self::KEY_ENCRYPTION_KEY => '',
+    ];
+
+    /**
+     * Filesystem
+     *
+     * @var Filesystem
+     */
+    protected $filesystem;
+
+    /**
+     * Config Directory
+     *
+     * @var Write
+     */
+    protected $configDirectory;
+
+    /**
+     * Default Constructor
+     *
+     * @param Filesystem $filesystem
+     * @param string[] $data
+     */
+    public function __construct(
+        Filesystem $filesystem,
+        $data = []
+    ) {
+        $this->filesystem = $filesystem;
+        $this->configDirectory = $filesystem->getDirectoryWrite('etc');
+
+        if ($data) {
+            $this->update($data);
+        }
+    }
+
+    /**
+     * Retrieve config data
+     *
+     * @return string[]
+     */
+    public function getConfigData()
+    {
+        return $this->data;
+    }
+
+    /**
+     * Get a value from config data by key
+     *
+     * @param string $key
+     * @return null|string
+     */
+    public function get($key)
+    {
+        return isset($this->data[$key]) ? $this->data[$key] : null;
+    }
+
+    /**
+     * Update data
+     *
+     * @param string[] $data
+     * @return void
+     */
+    public function update($data)
+    {
+        $new = [];
+        foreach (array_keys($this->data) as $key) {
+            $new[$key] = isset($data[$key]) ? $data[$key] : $this->data[$key];
+        }
+        $this->checkData($new);
+        $this->data = $new;
+    }
+
+    /**
+     * Loads configuration the deployment configuration file
+     *
+     * @return void
+     */
+    public function loadFromFile()
+    {
+        $xmlData = $this->configDirectory->readFile(self::DEPLOYMENT_CONFIG_FILE);
+        $xmlObj = @simplexml_load_string($xmlData, NULL, LIBXML_NOCDATA);
+        $xmlConfig = json_decode(json_encode((array)$xmlObj), true);
+        $data = $this->convertFromConfigData((array)$xmlConfig);
+        $this->update($data);
+    }
+
+    /**
+     * Exports data to a deployment configuration file
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function saveToFile()
+    {
+        $contents = $this->configDirectory->readFile(self::DEPLOYMENT_CONFIG_FILE_TEMPLATE);
+        foreach ($this->data as $index => $value) {
+            $contents = str_replace('{{' . $index . '}}', '<![CDATA[' . $value . ']]>', $contents);
+        }
+        if (preg_match('(\{\{.+?\}\})', $contents, $matches)) {
+            throw new \Exception("Some of the keys have not been replaced in the template: {$matches[1]}");
+        }
+
+        $this->configDirectory->writeFile(self::DEPLOYMENT_CONFIG_FILE, $contents, LOCK_EX);
+        $this->configDirectory->changePermissions(self::DEPLOYMENT_CONFIG_FILE, 0777);
+    }
+
+    /**
+     * Convert config
+     *
+     * @param array $source
+     * @return array
+     */
+    private function convertFromConfigData(array $source)
+    {
+        $result = array();
+        if (isset($source['connection']['host']) && !is_array($source['connection']['host'])) {
+            $result[self::KEY_DB_HOST] = $source['connection']['host'];
+        }
+        if (isset($source['connection']['dbName']) && !is_array($source['connection']['dbName'])) {
+            $result[self::KEY_DB_NAME] = $source['connection']['dbName'];
+        }
+        if (isset($source['connection']['username']) && !is_array($source['connection']['username'])) {
+            $result[self::KEY_DB_USER] = $source['connection']['username'];
+        }
+        if (isset($source['connection']['password']) && !is_array($source['connection']['password'])) {
+            $result[self::KEY_DB_PASS] = $source['connection']['password'];
+        }
+        if (isset($source['db']['table_prefix']) && !is_array($source['db']['table_prefix'])) {
+            $result[self::KEY_DB_PREFIX] = $source['db']['table_prefix'];
+        }
+        if (isset($source['session_save']) && !is_array($source['session_save'])) {
+            $result[self::KEY_SESSION_SAVE] = $source['session_save'];
+        }
+        if (isset($source['config']['address']['admin']) && !is_array($source['config']['address']['admin'])) {
+            $result[self::KEY_BACKEND_FRONTNAME] = $source['config']['address']['admin'];
+        }
+        if (isset($source['connection']['initStatements']) && !is_array($source['connection']['initStatements']) ) {
+            $result[self::KEY_DB_INIT_STATEMENTS] = $source['connection']['initStatements'];
+        }
+        if (isset($source['crypt']['key'])) {
+            $result[self::KEY_ENCRYPTION_KEY] = $source['crypt']['key'];
+        }
+        if (isset($source['install']['date'])) {
+            $result[self::KEY_DATE] = $source['install']['date'];
+        }
+        return $result;
+    }
+
+    /**
+     * Check database connection data
+     *
+     * @param array $data
+     * @return void
+     * @throws \Exception
+     */
+    private function checkData(array $data)
+    {
+        if (empty($data[self::KEY_ENCRYPTION_KEY])) {
+            throw new \Exception('Encryption key must not be empty.');
+        }
+        if (empty($data[self::KEY_DATE])) {
+            throw new \Exception('Installation date must not be empty.');
+        }
+        if (empty($data[self::KEY_DB_NAME])) {
+            throw new \Exception('The Database Name field cannot be empty.');
+        }
+        $prefix = $data[self::KEY_DB_PREFIX];
+        if ($prefix != '') {
+            $prefix = strtolower($prefix);
+            if (!preg_match('/^[a-z]+[a-z0-9_]*$/', $prefix)) {
+                throw new \Exception(
+                    'The table prefix should contain only letters (a-z), numbers (0-9) or underscores (_); '
+                    . 'the first character should be a letter.'
+                );
+            }
+        }
+    }
+}
diff --git a/setup/module/Magento/Setup/src/Module/Setup/ConfigFactory.php b/setup/module/Magento/Setup/src/Module/Setup/ConfigFactory.php
new file mode 100644
index 00000000000..8832d904477
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Module/Setup/ConfigFactory.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.
+ *
+ * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Setup\Module\Setup;
+
+use Zend\ServiceManager\ServiceLocatorInterface;
+
+class ConfigFactory
+{
+    /**
+     * @var ServiceLocatorInterface
+     */
+    protected $serviceLocator;
+
+    /**
+     * @param ServiceLocatorInterface $serviceLocator
+     */
+    public function __construct(ServiceLocatorInterface $serviceLocator)
+    {
+        $this->serviceLocator = $serviceLocator;
+    }
+
+    /**
+     * @param string[] $data
+     * @return Config
+     */
+    public function create(array $data = [])
+    {
+        return new Config(
+            $this->serviceLocator->get('Magento\Filesystem\Filesystem'),
+            $data
+        );
+    }
+}
diff --git a/setup/module/Magento/Module/src/Setup/Connection/Adapter.php b/setup/module/Magento/Setup/src/Module/Setup/Connection/Adapter.php
similarity index 70%
rename from setup/module/Magento/Module/src/Setup/Connection/Adapter.php
rename to setup/module/Magento/Setup/src/Module/Setup/Connection/Adapter.php
index 9e70b489291..2664c03792c 100644
--- a/setup/module/Magento/Module/src/Setup/Connection/Adapter.php
+++ b/setup/module/Magento/Setup/src/Module/Setup/Connection/Adapter.php
@@ -21,9 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module\Setup\Connection;
+namespace Magento\Setup\Module\Setup\Connection;
 
-use Magento\Framework\DB\Adapter\Pdo\Mysql;
+use Magento\Setup\Framework\DB\Adapter\Pdo\Mysql;
+use Magento\Setup\Module\Setup\Config;
 
 class Adapter implements AdapterInterface
 {
@@ -31,16 +32,16 @@ class Adapter implements AdapterInterface
      * Get connection
      *
      * @param array $config
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface|null
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface|null
      */
     public function getConnection(array $config = array())
     {
         return new Mysql(
             [
-                'driver'         => "Pdo",
-                'dsn'            => "mysql:dbname=" . $config['db_name'] . ";host=" . $config['db_host'],
-                'username'       => $config['db_user'],
-                'password'       => isset($config['db_pass']) ? $config['db_pass'] : null,
+                'driver' => 'Pdo',
+                'dsn' => "mysql:dbname=" . $config[Config::KEY_DB_NAME] . ";host=" . $config[Config::KEY_DB_HOST],
+                'username' => $config[Config::KEY_DB_USER],
+                'password' => isset($config[Config::KEY_DB_PASS]) ? $config[Config::KEY_DB_PASS] : null,
                 'driver_options' => [
                     \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"]
             ]
diff --git a/setup/module/Magento/Module/src/Setup/Connection/AdapterInterface.php b/setup/module/Magento/Setup/src/Module/Setup/Connection/AdapterInterface.php
similarity index 89%
rename from setup/module/Magento/Module/src/Setup/Connection/AdapterInterface.php
rename to setup/module/Magento/Setup/src/Module/Setup/Connection/AdapterInterface.php
index 9405adf750d..209006c6cd4 100644
--- a/setup/module/Magento/Module/src/Setup/Connection/AdapterInterface.php
+++ b/setup/module/Magento/Setup/src/Module/Setup/Connection/AdapterInterface.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module\Setup\Connection;
+namespace Magento\Setup\Module\Setup\Connection;
 
 interface AdapterInterface
 {
@@ -29,7 +29,7 @@ interface AdapterInterface
      * Get connection
      *
      * @param array $config
-     * @return \Magento\Framework\DB\Adapter\AdapterInterface|null
+     * @return \Magento\Setup\Framework\DB\Adapter\AdapterInterface|null
      */
     public function getConnection(array $config = array());
 }
diff --git a/setup/module/Magento/Module/src/Setup/FileResolver.php b/setup/module/Magento/Setup/src/Module/Setup/FileResolver.php
similarity index 64%
rename from setup/module/Magento/Module/src/Setup/FileResolver.php
rename to setup/module/Magento/Setup/src/Module/Setup/FileResolver.php
index a9e6a83c5ad..0276737fb45 100644
--- a/setup/module/Magento/Module/src/Setup/FileResolver.php
+++ b/setup/module/Magento/Setup/src/Module/Setup/FileResolver.php
@@ -22,37 +22,44 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module\Setup;
+namespace Magento\Setup\Module\Setup;
 
 use Zend\Stdlib\Glob;
-use Magento\Config\FileResolverInterface;
 use Magento\Config\FileIteratorFactory;
-use Magento\Config\ConfigFactory;
+use Magento\Config\ConfigFactory as SystemConfigFactory;
 
-class FileResolver implements FileResolverInterface
+class FileResolver
 {
     /**
+     * File Iterator Factory
+     *
      * @var FileIteratorFactory
      */
     protected $iteratorFactory;
 
     /**
-     * @var ConfigFactory
+     * Configuration Factory
+     *
+     * @var SystemConfigFactory
      */
     protected $configFactory;
 
     /**
+     * Configurations
+     *
      * @var Config
      */
     protected $config;
 
     /**
+     * Default Constructor
+     *
      * @param FileIteratorFactory $iteratorFactory
-     * @param ConfigFactory $configFactory
+     * @param SystemConfigFactory $configFactory
      */
     public function __construct(
         FileIteratorFactory $iteratorFactory,
-        ConfigFactory $configFactory
+        SystemConfigFactory $configFactory
     ) {
         $this->iteratorFactory = $iteratorFactory;
         $this->configFactory = $configFactory;
@@ -60,15 +67,18 @@ class FileResolver implements FileResolverInterface
     }
 
     /**
+     * Get SQL setup files by pattern
+     *
      * @param string $moduleName
+     * @param string $fileNamePattern
      * @return array
      */
-    public function get($moduleName)
+    public function getSqlSetupFiles($moduleName, $fileNamePattern = '*.php')
     {
         $paths = [];
         $modulePath = str_replace('_', '/', $moduleName);
         // Collect files by /app/code/{modulePath}/sql/*/*.php pattern
-        $files = $this->getFiles($this->config->getMagentoModulePath() . $modulePath . '/sql/*/*.php');
+        $files = $this->getFiles($this->config->getMagentoModulePath() . $modulePath . '/sql/*/' . $fileNamePattern);
         foreach ($files as $file) {
             $paths[] = $this->getRelativePath($file);
         }
@@ -95,33 +105,62 @@ class FileResolver implements FileResolverInterface
     }
 
     /**
+     * Get Files
+     *
      * @param string $path
      * @return array|false
      */
     protected function getFiles($path)
     {
-        return Glob::glob($this->config->getMagentoBasePath() . $path);
+        return Glob::glob($this->config->getMagentoBasePath() . $path, Glob::GLOB_BRACE);
     }
 
     /**
+     * Get Directories
+     *
+     * @param string $path
+     * @return array|false
+     */
+    protected function getDirs($path)
+    {
+        return Glob::glob($this->config->getMagentoBasePath() . $path, Glob::GLOB_ONLYDIR);
+    }
+
+    /**
+     * Get Resource Code by Module Name
+     *
      * @param string $moduleName
      * @return string
      */
     public function getResourceCode($moduleName)
     {
-        $codes = [];
+        $sqlResources  = [];
+        $dataResources = [];
         $modulePath = str_replace('_', '/', $moduleName);
+
         // Collect files by /app/code/{modulePath}/sql/*/ pattern
-        $files = $this->getFiles($this->config->getMagentoModulePath() . $modulePath . '/sql/*/');
-        foreach ($files as $file) {
-            $pieces = explode('/', rtrim($this->fixSeparator($file), '/'));
-            $codes[] = array_pop($pieces);
+        $resourceDirs = $this->getDirs($this->config->getMagentoModulePath() . $modulePath . '/sql/*/');
+        if (!empty($resourceDirs)) {
+            foreach ($resourceDirs as $resourceDir) {
+                $sqlResources[] = basename($resourceDir);
+            }
         }
 
-        return array_shift($codes);
+        // Collect files by /app/code/{modulePath}/sql/*/ pattern
+        $resourceDirs = $this->getDirs($this->config->getMagentoModulePath() . $modulePath . '/data/*/');
+        if (!empty($resourceDirs)) {
+            foreach ($resourceDirs as $resourceDir) {
+                $dataResources[] = basename($resourceDir);
+            }
+        }
+
+        $resources = array_unique(array_merge($sqlResources, $dataResources));
+        return array_shift($resources);
     }
 
     /**
+     * Get Absolute Path
+     *
      * @param string $path
      * @return string
      */
diff --git a/setup/module/Magento/Module/src/SetupFactory.php b/setup/module/Magento/Setup/src/Module/SetupFactory.php
similarity index 52%
rename from setup/module/Magento/Module/src/SetupFactory.php
rename to setup/module/Magento/Setup/src/Module/SetupFactory.php
index b589e4d82c4..317730befe2 100644
--- a/setup/module/Magento/Module/src/SetupFactory.php
+++ b/setup/module/Magento/Setup/src/Module/SetupFactory.php
@@ -22,80 +22,110 @@
  * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Module;
+namespace Magento\Setup\Module;
 
-use Magento\Module\Setup\Connection\AdapterInterface;
-use Magento\Setup\Model\Logger;
+use Magento\Setup\Module\Setup\ConfigFactory as DeploymentConfigFactory;
+use Magento\Setup\Module\Setup\Connection\AdapterInterface;
+use Magento\Setup\Module\Setup\Config;
+use Magento\Setup\Model\LoggerInterface;
 
 class SetupFactory
 {
     /**
+     * @var DeploymentConfigFactory
+     */
+    private $deploymentConfigFactory;
+
+    /**
+     * Adapter
+     *
      * @var AdapterInterface
      */
     protected $adapter;
 
     /**
+     * List of all Modules
+     *
      * @var ModuleListInterface
      */
     protected $moduleList;
 
     /**
+     * File Resolver
+     *
      * @var Setup\FileResolver
      */
     protected $fileResolver;
 
     /**
-     * @var array
-     */
-    protected $configuration = [];
-
-    /**
-     * @var Logger
-     */
-    protected $logger;
-
-    /**
+     * Default Constructor
+     *
+     * @param DeploymentConfigFactory $deploymentConfigFactory
      * @param AdapterInterface $connection
      * @param ModuleListInterface $moduleList
      * @param Setup\FileResolver $setupFileResolver
-     * @param Logger $logger
      */
     public function __construct(
+        DeploymentConfigFactory $deploymentConfigFactory,
         AdapterInterface $connection,
         ModuleListInterface $moduleList,
-        Setup\FileResolver $setupFileResolver,
-        Logger $logger
+        Setup\FileResolver $setupFileResolver
     ) {
-        $this->logger = $logger;
+        $this->deploymentConfigFactory = $deploymentConfigFactory;
         $this->adapter = $connection;
         $this->moduleList = $moduleList;
         $this->fileResolver = $setupFileResolver;
     }
 
     /**
-     * @param array $config
+     * Creates Setup
+     *
+     * @param LoggerInterface $log
+     * @return Setup
      */
-    public function setConfig(array $config)
+    public function createSetup(LoggerInterface $log)
     {
-        $this->configuration = $config;
+        return new Setup(
+            $this->adapter,
+            $this->fileResolver,
+            $log,
+            $this->loadConfigData()
+        );
     }
 
     /**
+     * Creates SetupModule
+     *
+     * @param LoggerInterface $log
      * @param string $moduleName
-     * @return Setup
+     * @return SetupModule
      */
-    public function create($moduleName)
+    public function createSetupModule(LoggerInterface $log, $moduleName)
     {
-        $setup =  new Setup(
+        $configData = $this->loadConfigData();
+        $result = new SetupModule(
             $this->adapter,
             $this->moduleList,
             $this->fileResolver,
-            $this->logger,
+            $log,
             $moduleName,
-            $this->configuration
+            $configData
         );
-        $setup->setTablePrefix($this->configuration['db_prefix']);
+        if (isset($configData[Config::KEY_DB_PREFIX])) {
+            $result->setTablePrefix($configData[Config::KEY_DB_PREFIX]);
+        }
+        return $result;
+    }
 
-        return $setup;
+    /**
+     * Load deployment configuration data
+     *
+     * @return array
+     */
+    private function loadConfigData()
+    {
+        $config = $this->deploymentConfigFactory->create();
+        $config->loadFromFile();
+        return $config->getConfigData();
     }
 }
diff --git a/setup/module/Magento/Setup/src/Module/SetupModule.php b/setup/module/Magento/Setup/src/Module/SetupModule.php
new file mode 100644
index 00000000000..939f43ceb99
--- /dev/null
+++ b/setup/module/Magento/Setup/src/Module/SetupModule.php
@@ -0,0 +1,269 @@
+<?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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Setup\Module;
+
+use Magento\Setup\Module\Setup\Connection\AdapterInterface;
+use Magento\Setup\Module\Setup\FileResolver as SetupFileResolver;
+use Magento\Setup\Module\Resource\Resource;
+use Magento\Setup\Model\LoggerInterface;
+
+class SetupModule extends Setup
+{
+    /**
+     * Setup resource name
+     * @var string
+     */
+    protected $resourceName;
+
+    /**
+     * Setup module configuration object
+     *
+     * @var array
+     */
+    protected $moduleConfig;
+
+    /**
+     * Resource
+     *
+     * @var ResourceInterface
+     */
+    protected $resource;
+
+    /**
+     * Constructor
+     *
+     * @param AdapterInterface $connection
+     * @param ModuleListInterface $moduleList
+     * @param SetupFileResolver $setupFileResolver
+     * @param LoggerInterface $log
+     * @param string $moduleName
+     * @param array $connectionConfig
+     */
+    public function __construct(
+        AdapterInterface $connection,
+        ModuleListInterface $moduleList,
+        SetupFileResolver $setupFileResolver,
+        LoggerInterface $log,
+        $moduleName,
+        array $connectionConfig = array()
+    ) {
+        parent::__construct($connection, $setupFileResolver, $log, $connectionConfig);
+        $this->moduleConfig = $moduleList->getModule($moduleName);
+        $this->resource = new Resource($this->connection);
+        $this->resourceName = $this->setupFileResolver->getResourceCode($moduleName);
+    }
+
+    /**
+     * Apply module recurring post schema updates
+     *
+     * @return $this
+     * @throws \Exception
+     */
+    public function applyRecurringUpdates()
+    {
+        $moduleName = (string)$this->moduleConfig['name'];
+        foreach ($this->setupFileResolver->getSqlSetupFiles($moduleName, self::TYPE_DB_RECURRING . '.php') as $file) {
+            try {
+                $file = $this->setupFileResolver->getAbsolutePath($file);
+                $this->includeFile($file);
+            } catch (\Exception $e) {
+                throw new \Exception(sprintf('Error in file: "%s" - %s', $file, $e->getMessage()), 0, $e);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve available Database install/upgrade files for current module
+     *
+     * @param string $actionType
+     * @param string $fromVersion
+     * @param string $toVersion
+     * @return array
+     */
+    protected function getAvailableDbFiles($actionType, $fromVersion, $toVersion)
+    {
+        $moduleName = (string)$this->moduleConfig['name'];
+        $dbFiles = array();
+        $typeFiles = array();
+        $regExpDb = sprintf('#%s-(.*)\.(php|sql)$#i', $actionType);
+        $regExpType = sprintf('#%s-%s-(.*)\.(php|sql)$#i', 'mysql4', $actionType);
+        foreach ($this->setupFileResolver->getSqlSetupFiles($moduleName, '*.{php,sql}') as $file) {
+            $matches = array();
+            if (preg_match($regExpDb, $file, $matches)) {
+                $dbFiles[$matches[1]] = $this->setupFileResolver->getAbsolutePath($file);
+            } elseif (preg_match($regExpType, $file, $matches)) {
+                $typeFiles[$matches[1]] = $this->setupFileResolver->getAbsolutePath($file);
+            }
+        }
+
+        if (empty($typeFiles) && empty($dbFiles)) {
+            return array();
+        }
+
+        foreach ($typeFiles as $version => $file) {
+            $dbFiles[$version] = $file;
+        }
+
+        return $this->prepareUpgradeFileCollection($actionType, $fromVersion, $toVersion, $dbFiles);
+    }
+
+    /**
+     * Apply module resource install, upgrade and data scripts
+     *
+     * @return $this
+     */
+    public function applyUpdates()
+    {
+        if (!$this->resourceName) {
+            return $this;
+        }
+        $dbVer = $this->resource->getDbVersion($this->resourceName);
+        $configVer = $this->moduleConfig['schema_version'];
+
+        // Module is installed
+        if ($dbVer !== false) {
+            if (version_compare($configVer, $dbVer) == self::VERSION_COMPARE_GREATER) {
+                $this->applySchemaUpdates(self::TYPE_DB_UPGRADE, $dbVer, $configVer);
+                $this->resource->setDbVersion($this->resourceName, $configVer);
+            }
+        } elseif ($configVer) {
+            $oldVersion = $this->applySchemaUpdates(self::TYPE_DB_INSTALL, '', $configVer);
+            $this->applySchemaUpdates(self::TYPE_DB_UPGRADE, $oldVersion, $configVer);
+            $this->resource->setDbVersion($this->resourceName, $configVer);
+        }
+        return $this;
+    }
+
+    /**
+     * Run module modification files. Return version of last applied upgrade (false if no upgrades applied)
+     * @param string $actionType
+     * @param string $fromVersion
+     * @param string $toVersion
+     * @return false|string
+     * @throws \Exception
+     */
+    protected function applySchemaUpdates($actionType, $fromVersion, $toVersion)
+    {
+        $files = $this->getAvailableDbFiles($actionType, $fromVersion, $toVersion);
+
+        if (empty($files) || !$this->getConnection()) {
+            return false;
+        }
+
+        $version = false;
+        foreach ($files as $file) {
+            $fileName = $file['fileName'];
+            $fileType = pathinfo($fileName, PATHINFO_EXTENSION);
+            try {
+                switch ($fileType) {
+                    case 'php':
+                        $result = $this->includeFile($fileName);
+                        break;
+                    default:
+                        $result = false;
+                        break;
+                }
+
+                if ($result) {
+                    $this->resource->setDbVersion($this->resourceName, $file['toVersion']);
+                    //@todo log
+                } else {
+                    //@todo log "Failed resource setup: {$fileName}";
+                }
+            } catch (\Exception $e) {
+                throw new \Exception(sprintf('Error in file: "%s" - %s', $fileName, $e->getMessage()), 0, $e);
+            }
+            $version = $file['toVersion'];
+        }
+        return $version;
+    }
+
+    /**
+     * Get data files for modifications
+     *
+     * @param string $actionType
+     * @param string $fromVersion
+     * @param string $toVersion
+     * @param array $arrFiles
+     * @return array
+     */
+    protected function prepareUpgradeFileCollection($actionType, $fromVersion, $toVersion, $arrFiles)
+    {
+        $arrRes = [];
+        switch ($actionType) {
+            case self::TYPE_DB_INSTALL:
+                uksort($arrFiles, 'version_compare');
+                foreach ($arrFiles as $version => $file) {
+                    if (version_compare($version, $toVersion) !== self::VERSION_COMPARE_GREATER) {
+                        $arrRes[0] = [
+                            'toVersion' => $version,
+                            'fileName'  => $file
+                        ];
+                    }
+                }
+                break;
+
+            case self::TYPE_DB_UPGRADE:
+                uksort($arrFiles, 'version_compare');
+                foreach ($arrFiles as $version => $file) {
+                    $versionInfo = explode('-', $version);
+
+                    // In array must be 2 elements: 0 => version from, 1 => version to
+                    if (count($versionInfo) !== 2) {
+                        break;
+                    }
+                    $infoFrom = $versionInfo[0];
+                    $infoTo   = $versionInfo[1];
+                    if (version_compare($infoFrom, $fromVersion, '>=')
+                        && version_compare($infoTo, $fromVersion, '>')
+                        && version_compare($infoTo, $toVersion, '<=')
+                        && version_compare($infoFrom, $toVersion, '<')
+                    ) {
+                        $arrRes[] = [
+                            'toVersion' => $infoTo,
+                            'fileName'  => $file
+                        ];
+                    }
+                }
+                break;
+
+            default:
+                break;
+        }
+        return $arrRes;
+    }
+
+    /**
+     * Set table prefix
+     *
+     * @param string $tablePrefix
+     * @return void
+     */
+    public function setTablePrefix($tablePrefix)
+    {
+        parent::setTablePrefix($tablePrefix);
+        $this->resource->setTablePrefix($this->tablePrefix);
+    }
+}
diff --git a/setup/module/Magento/Module/src/Updater/SetupInterface.php b/setup/module/Magento/Setup/src/Module/Updater/SetupInterface.php
similarity index 82%
rename from setup/module/Magento/Module/src/Updater/SetupInterface.php
rename to setup/module/Magento/Setup/src/Module/Updater/SetupInterface.php
index 9822d520f5d..0793e80319d 100644
--- a/setup/module/Magento/Module/src/Updater/SetupInterface.php
+++ b/setup/module/Magento/Setup/src/Module/Updater/SetupInterface.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Module\Updater;
+namespace Magento\Setup\Module\Updater;
 
 interface SetupInterface
 {
@@ -37,21 +37,12 @@ interface SetupInterface
 
     const TYPE_DB_UPGRADE = 'upgrade';
 
-    const TYPE_DB_ROLLBACK = 'rollback';
-
-    const TYPE_DB_UNINSTALL = 'uninstall';
+    const TYPE_DB_RECURRING = 'recurring';
 
     const TYPE_DATA_INSTALL = 'data-install';
 
     const TYPE_DATA_UPGRADE = 'data-upgrade';
 
-    /**
-     * Apply module resource install, upgrade and data scripts
-     *
-     * @return \Magento\Framework\Module\Updater\SetupInterface
-     */
-    public function applyUpdates();
-
     /**
      * Check call afterApplyAllUpdates method for setup class
      *
@@ -63,7 +54,7 @@ interface SetupInterface
     /**
      * Run each time after applying of all updates,
      *
-     * @return \Magento\Framework\Module\Updater\SetupInterface
+     * @return \Magento\Setup\Module\Updater\SetupInterface
      */
     public function afterApplyAllUpdates();
 
diff --git a/setup/pub/magento/setup/install.js b/setup/pub/magento/setup/install.js
index 04ace8ac1ad..731d8d86e01 100644
--- a/setup/pub/magento/setup/install.js
+++ b/setup/pub/magento/setup/install.js
@@ -77,7 +77,11 @@ angular.module('install', ['ngStorage'])
                     $scope.nextState();
                 }
             });
-            $scope.checkProgress();
+            progress.clear(function (response) {
+                if (response.data.success) {
+                    $scope.checkProgress();
+                }
+            });
         };
     }])
     .service('progress', ['$http', function ($http) {
@@ -87,6 +91,9 @@ angular.module('install', ['ngStorage'])
             },
             post: function (data, callback) {
                 $http.post('install/start', data).success(callback);
+            },
+            clear: function (callback) {
+                $http.get('install/clear-progress').then(callback);
             }
         };
-    }]);
\ No newline at end of file
+    }]);
diff --git a/setup/pub/magento/setup/web-configuration.js b/setup/pub/magento/setup/web-configuration.js
index 4355f358b51..9cd2d5c946a 100644
--- a/setup/pub/magento/setup/web-configuration.js
+++ b/setup/pub/magento/setup/web-configuration.js
@@ -37,7 +37,7 @@ angular.module('web-configuration', ['ngStorage'])
                 allowed: true
             },
             encrypt: {
-                key: '',
+                key: null,
                 type: 'magento'
             },
             advanced: {
@@ -57,6 +57,12 @@ angular.module('web-configuration', ['ngStorage'])
             obj.expanded = !obj.expanded;
         }
 
+        $scope.$watch('config.encrypt.type', function() {
+            if(angular.equals($scope.config.encrypt.type, 'magento')){
+                $scope.config.encrypt.key = null;
+            }
+        });
+
         $scope.showEncryptKey = function() {
             return angular.equals($scope.config.encrypt.type, 'user');
         }
-- 
GitLab